pull/591/merge
Kim Kulling 2015-06-30 00:21:11 +02:00
commit 83defdddc4
422 changed files with 146927 additions and 146894 deletions

17
.editorconfig 100644
View File

@ -0,0 +1,17 @@
# 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

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
.idea
build build
.project .project
*.kdev4* *.kdev4*

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

@ -4,8 +4,8 @@ PROJECT( Assimp )
option(BUILD_SHARED_LIBS "Build package with shared libraries." ON) option(BUILD_SHARED_LIBS "Build package with shared libraries." ON)
if(NOT BUILD_SHARED_LIBS) if(NOT BUILD_SHARED_LIBS)
#set(CMAKE_EXE_LINKER_FLAGS "-static") #set(CMAKE_EXE_LINKER_FLAGS "-static")
set(LINK_SEARCH_START_STATIC TRUE) set(LINK_SEARCH_START_STATIC TRUE)
endif(NOT BUILD_SHARED_LIBS) endif(NOT BUILD_SHARED_LIBS)
# Define here the needed parameters # Define here the needed parameters
@ -23,27 +23,27 @@ add_definitions( -DOPENDDL_NO_USE_CPP11 )
# Get the current working branch # Get the current working branch
execute_process( execute_process(
COMMAND git rev-parse --abbrev-ref HEAD COMMAND git rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_BRANCH OUTPUT_VARIABLE GIT_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
) )
# Get the latest abbreviated commit hash of the working branch # Get the latest abbreviated commit hash of the working branch
execute_process( execute_process(
COMMAND git log -1 --format=%h COMMAND git log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_HASH OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
) )
if(NOT GIT_COMMIT_HASH) if(NOT GIT_COMMIT_HASH)
set(GIT_COMMIT_HASH 0) set(GIT_COMMIT_HASH 0)
endif(NOT GIT_COMMIT_HASH) endif(NOT GIT_COMMIT_HASH)
configure_file( configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/revision.h.in ${CMAKE_CURRENT_SOURCE_DIR}/revision.h.in
${CMAKE_CURRENT_BINARY_DIR}/revision.h ${CMAKE_CURRENT_BINARY_DIR}/revision.h
) )
include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_BINARY_DIR})
@ -59,16 +59,16 @@ option(ASSIMP_ANDROID_JNIIOSYSTEM "Android JNI IOSystem support is active" OFF)
# Workaround to be able to deal with compiler bug "Too many sections" with mingw. # Workaround to be able to deal with compiler bug "Too many sections" with mingw.
if( CMAKE_COMPILER_IS_MINGW ) if( CMAKE_COMPILER_IS_MINGW )
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_IFC_IMPORTER ) ADD_DEFINITIONS(-DASSIMP_BUILD_NO_IFC_IMPORTER )
endif() endif()
if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW) if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # this is a very important switch and some libraries seem now to have it.... set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") # this is a very important switch and some libraries seem now to have it....
# hide all not-exported symbols # hide all not-exported symbols
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall" ) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall" )
elseif(MSVC) elseif(MSVC)
# enable multi-core compilation with MSVC # enable multi-core compilation with MSVC
add_definitions(/MP) add_definitions(/MP)
endif() endif()
INCLUDE (FindPkgConfig) INCLUDE (FindPkgConfig)
@ -81,51 +81,51 @@ INCLUDE (PrecompiledHeader)
# source tree. During an out-of-source build, however, do not litter this # source tree. During an out-of-source build, however, do not litter this
# directory, since that is probably what the user wanted to avoid. # directory, since that is probably what the user wanted to avoid.
IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" ) SET( CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" ) SET( CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/lib" )
SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" ) SET( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin" )
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR ) ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
# Cache these to allow the user to override them manually. # Cache these to allow the user to override them manually.
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE PATH SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE PATH
"Path the built library files are installed to." ) "Path the built library files are installed to." )
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
"Path the header files are installed to." ) "Path the header files are installed to." )
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
"Path the tool executables are installed to." ) "Path the tool executables are installed to." )
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools") SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
# Only generate this target if no higher-level project already has # Only generate this target if no higher-level project already has
IF (NOT TARGET uninstall) IF (NOT TARGET uninstall)
# add make uninstall capability # add make uninstall capability
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
ENDIF() ENDIF()
# Globally enable Boost resp. the Boost workaround – it is also needed by the # Globally enable Boost resp. the Boost workaround – it is also needed by the
# tools which include the Assimp headers. # tools which include the Assimp headers.
option ( ASSIMP_ENABLE_BOOST_WORKAROUND option ( ASSIMP_ENABLE_BOOST_WORKAROUND
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available." "If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
ON ON
) )
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND ) IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
INCLUDE_DIRECTORIES( code/BoostWorkaround ) INCLUDE_DIRECTORIES( code/BoostWorkaround )
ADD_DEFINITIONS( -DASSIMP_BUILD_BOOST_WORKAROUND ) ADD_DEFINITIONS( -DASSIMP_BUILD_BOOST_WORKAROUND )
MESSAGE( STATUS "Building a non-boost version of Assimp." ) MESSAGE( STATUS "Building a non-boost version of Assimp." )
ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND ) ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
SET( Boost_DETAILED_FAILURE_MSG ON ) SET( Boost_DETAILED_FAILURE_MSG ON )
SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57" "1.57.0" "1.58" "1.58.0" ) SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" "1.55.0" "1.56" "1.56.0" "1.57" "1.57.0" "1.58" "1.58.0" )
FIND_PACKAGE( Boost ) FIND_PACKAGE( Boost )
IF ( NOT Boost_FOUND ) IF ( NOT Boost_FOUND )
MESSAGE( FATAL_ERROR MESSAGE( FATAL_ERROR
"Boost libraries (http://www.boost.org/) not found. " "Boost libraries (http://www.boost.org/) not found. "
"You can build a non-boost version of Assimp with slightly reduced " "You can build a non-boost version of Assimp with slightly reduced "
"functionality by specifying -DASSIMP_ENABLE_BOOST_WORKAROUND=ON." "functionality by specifying -DASSIMP_ENABLE_BOOST_WORKAROUND=ON."
) )
ENDIF ( NOT Boost_FOUND ) ENDIF ( NOT Boost_FOUND )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ) INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} )
ENDIF ( ASSIMP_ENABLE_BOOST_WORKAROUND ) ENDIF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
# cmake configuration files # cmake configuration files
@ -134,8 +134,8 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${C
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})
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 )
@ -146,134 +146,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 )
ADD_SUBDIRECTORY( tools/assimp_view/ ) ADD_SUBDIRECTORY( tools/assimp_view/ )
ENDIF ( WIN32 ) ENDIF ( WIN32 )
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.
@ -281,50 +281,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

@ -2,30 +2,30 @@ find_package(Threads REQUIRED)
include(ExternalProject) include(ExternalProject)
if(MSYS OR MINGW) if(MSYS OR MINGW)
set(DISABLE_PTHREADS ON) set(DISABLE_PTHREADS ON)
else() else()
set(DISABLE_PTHREADS OFF) set(DISABLE_PTHREADS OFF)
endif() endif()
if (MSVC) if (MSVC)
set(RELEASE_LIB_DIR ReleaseLibs) set(RELEASE_LIB_DIR ReleaseLibs)
set(DEBUG_LIB_DIR DebugLibs) set(DEBUG_LIB_DIR DebugLibs)
else() else()
set(RELEASE_LIB_DIR "") set(RELEASE_LIB_DIR "")
set(DEBUG_LIB_DIR "") set(DEBUG_LIB_DIR "")
endif() endif()
set(GTEST_CMAKE_ARGS set(GTEST_CMAKE_ARGS
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}" "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
"-Dgtest_force_shared_crt=ON" "-Dgtest_force_shared_crt=ON"
"-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}") "-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}")
set(GTEST_RELEASE_LIB_DIR "") set(GTEST_RELEASE_LIB_DIR "")
set(GTEST_DEBUGLIB_DIR "") set(GTEST_DEBUGLIB_DIR "")
if (MSVC) if (MSVC)
set(GTEST_CMAKE_ARGS ${GTEST_CMAKE_ARGS} set(GTEST_CMAKE_ARGS ${GTEST_CMAKE_ARGS}
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${DEBUG_LIB_DIR}" "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${DEBUG_LIB_DIR}"
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${RELEASE_LIB_DIR}") "-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${RELEASE_LIB_DIR}")
set(GTEST_LIB_DIR) set(GTEST_LIB_DIR)
endif() endif()
set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest") set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
@ -33,40 +33,40 @@ set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
# try to find git - if found, setup gtest # try to find git - if found, setup gtest
find_package(Git) find_package(Git)
if(NOT GIT_FOUND) if(NOT GIT_FOUND)
set(AddGTest_FOUND false CACHE BOOL "Was gtest setup correctly?") set(AddGTest_FOUND false CACHE BOOL "Was gtest setup correctly?")
else(NOT GIT_FOUND) else(NOT GIT_FOUND)
set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?") set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?")
ExternalProject_Add(gtest
GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
TIMEOUT 10
PREFIX "${GTEST_PREFIX}"
CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
LOG_DOWNLOAD ON
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) 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

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

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -53,129 +53,129 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory> #include <memory>
using namespace Assimp; using namespace Assimp;
namespace Assimp { namespace Assimp {
namespace { namespace {
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
// Scope utility to write a 3DS file chunk. // Scope utility to write a 3DS file chunk.
// //
// Upon construction, the chunk header is written with the chunk type (flags) // Upon construction, the chunk header is written with the chunk type (flags)
// filled out, but the chunk size left empty. Upon destruction, the correct chunk // filled out, but the chunk size left empty. Upon destruction, the correct chunk
// size based on the then-position of the output stream cursor is filled in. // size based on the then-position of the output stream cursor is filled in.
class ChunkWriter { class ChunkWriter {
enum { enum {
CHUNK_SIZE_NOT_SET = 0xdeadbeef CHUNK_SIZE_NOT_SET = 0xdeadbeef
, SIZE_OFFSET = 2 , SIZE_OFFSET = 2
}; };
public: public:
ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type) ChunkWriter(StreamWriterLE& writer, uint16_t chunk_type)
: writer(writer) : writer(writer)
{ {
chunk_start_pos = writer.GetCurrentPos(); chunk_start_pos = writer.GetCurrentPos();
writer.PutU2(chunk_type); writer.PutU2(chunk_type);
writer.PutU4(CHUNK_SIZE_NOT_SET); writer.PutU4(CHUNK_SIZE_NOT_SET);
} }
~ChunkWriter() { ~ChunkWriter() {
std::size_t head_pos = writer.GetCurrentPos(); std::size_t head_pos = writer.GetCurrentPos();
ai_assert(head_pos > chunk_start_pos); ai_assert(head_pos > chunk_start_pos);
const std::size_t chunk_size = head_pos - chunk_start_pos; const std::size_t chunk_size = head_pos - chunk_start_pos;
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET); writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
writer.PutU4(chunk_size); writer.PutU4(chunk_size);
writer.SetCurrentPos(head_pos); writer.SetCurrentPos(head_pos);
} }
private: private:
StreamWriterLE& writer; StreamWriterLE& writer;
std::size_t chunk_start_pos; std::size_t chunk_start_pos;
}; };
// Return an unique name for a given |mesh| attached to |node| that // Return an unique name for a given |mesh| attached to |node| that
// preserves the mesh's given name if it has one. |index| is the index // preserves the mesh's given name if it has one. |index| is the index
// of the mesh in |aiScene::mMeshes|. // of the mesh in |aiScene::mMeshes|.
std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) { std::string GetMeshName(const aiMesh& mesh, unsigned int index, const aiNode& node) {
static const std::string underscore = "_"; static const std::string underscore = "_";
char postfix[10] = {0}; char postfix[10] = {0};
ASSIMP_itoa10(postfix, index); ASSIMP_itoa10(postfix, index);
std::string result = node.mName.C_Str(); std::string result = node.mName.C_Str();
if (mesh.mName.length > 0) { if (mesh.mName.length > 0) {
result += underscore + mesh.mName.C_Str(); result += underscore + mesh.mName.C_Str();
} }
return result + underscore + postfix; return result + underscore + postfix;
} }
// Return an unique name for a given |mat| with original position |index| // Return an unique name for a given |mat| with original position |index|
// in |aiScene::mMaterials|. The name preserves the original material // in |aiScene::mMaterials|. The name preserves the original material
// name if possible. // name if possible.
std::string GetMaterialName(const aiMaterial& mat, unsigned int index) { std::string GetMaterialName(const aiMaterial& mat, unsigned int index) {
static const std::string underscore = "_"; static const std::string underscore = "_";
char postfix[10] = {0}; char postfix[10] = {0};
ASSIMP_itoa10(postfix, index); ASSIMP_itoa10(postfix, index);
aiString mat_name; aiString mat_name;
if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) { if (AI_SUCCESS == mat.Get(AI_MATKEY_NAME, mat_name)) {
return mat_name.C_Str() + underscore + postfix; return mat_name.C_Str() + underscore + postfix;
} }
return "Material" + underscore + postfix; return "Material" + underscore + postfix;
} }
// Collect world transformations for each node // Collect world transformations for each node
void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) { void CollectTrafos(const aiNode* node, std::map<const aiNode*, aiMatrix4x4>& trafos) {
const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4(); const aiMatrix4x4& parent = node->mParent ? trafos[node->mParent] : aiMatrix4x4();
trafos[node] = parent * node->mTransformation; trafos[node] = parent * node->mTransformation;
for (unsigned int i = 0; i < node->mNumChildren; ++i) { for (unsigned int i = 0; i < node->mNumChildren; ++i) {
CollectTrafos(node->mChildren[i], trafos); CollectTrafos(node->mChildren[i], trafos);
} }
} }
// Generate a flat list of the meshes (by index) assigned to each node // Generate a flat list of the meshes (by index) assigned to each node
void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) { void CollectMeshes(const aiNode* node, std::multimap<const aiNode*, unsigned int>& meshes) {
for (unsigned int i = 0; i < node->mNumMeshes; ++i) { for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
meshes.insert(std::make_pair(node, node->mMeshes[i])); meshes.insert(std::make_pair(node, node->mMeshes[i]));
} }
for (unsigned int i = 0; i < node->mNumChildren; ++i) { for (unsigned int i = 0; i < node->mNumChildren; ++i) {
CollectMeshes(node->mChildren[i], meshes); CollectMeshes(node->mChildren[i], meshes);
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp // Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties) void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
{ {
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb")); boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
if(!outfile) { if(!outfile) {
throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile)); throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
} }
// TODO: This extra copy should be avoided and all of this made a preprocess // TODO: This extra copy should be avoided and all of this made a preprocess
// requirement of the 3DS exporter. // requirement of the 3DS exporter.
// //
// 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively. // 3DS meshes can be max 0xffff (16 Bit) vertices and faces, respectively.
// SplitLargeMeshes can do this, but it requires the correct limit to be set // SplitLargeMeshes can do this, but it requires the correct limit to be set
// which is not possible with the current way of specifying preprocess steps // which is not possible with the current way of specifying preprocess steps
// in |Exporter::ExportFormatEntry|. // in |Exporter::ExportFormatEntry|.
aiScene* scenecopy_tmp; aiScene* scenecopy_tmp;
SceneCombiner::CopyScene(&scenecopy_tmp,pScene); SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp); std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
SplitLargeMeshesProcess_Triangle tri_splitter; SplitLargeMeshesProcess_Triangle tri_splitter;
tri_splitter.SetLimit(0xffff); tri_splitter.SetLimit(0xffff);
tri_splitter.Execute(scenecopy.get()); tri_splitter.Execute(scenecopy.get());
SplitLargeMeshesProcess_Vertex vert_splitter; SplitLargeMeshesProcess_Vertex vert_splitter;
vert_splitter.SetLimit(0xffff); vert_splitter.SetLimit(0xffff);
vert_splitter.Execute(scenecopy.get()); vert_splitter.Execute(scenecopy.get());
// Invoke the actual exporter // Invoke the actual exporter
Discreet3DSExporter exporter(outfile, scenecopy.get()); Discreet3DSExporter exporter(outfile, scenecopy.get());
} }
} // end of namespace Assimp } // end of namespace Assimp
@ -185,379 +185,379 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, c
: scene(scene) : scene(scene)
, writer(outfile) , writer(outfile)
{ {
CollectTrafos(scene->mRootNode, trafos); CollectTrafos(scene->mRootNode, trafos);
CollectMeshes(scene->mRootNode, meshes); CollectMeshes(scene->mRootNode, meshes);
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAIN);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH); ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
WriteMaterials(); WriteMaterials();
WriteMeshes(); WriteMeshes();
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
writer.PutF4(1.0f); writer.PutF4(1.0f);
} }
} }
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER); ChunkWriter chunk(writer, Discreet3DS::CHUNK_KEYFRAMER);
WriteHierarchy(*scene->mRootNode, -1, -1); WriteHierarchy(*scene->mRootNode, -1, -1);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level) int Discreet3DSExporter::WriteHierarchy(const aiNode& node, int seq, int sibling_level)
{ {
// 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec // 3DS scene hierarchy is serialized as in http://www.martinreddy.net/gfx/3d/3DS.spec
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
// Assimp node names are unique and distinct from all mesh-node // Assimp node names are unique and distinct from all mesh-node
// names we generate; thus we can use them as-is // names we generate; thus we can use them as-is
WriteString(node.mName); WriteString(node.mName);
// Two unknown int16 values - it is even unclear if 0 is a safe value // Two unknown int16 values - it is even unclear if 0 is a safe value
// but luckily importers do not know better either. // but luckily importers do not know better either.
writer.PutI4(0); writer.PutI4(0);
int16_t hierarchy_pos = static_cast<int16_t>(seq); int16_t hierarchy_pos = static_cast<int16_t>(seq);
if (sibling_level != -1) { if (sibling_level != -1) {
hierarchy_pos = sibling_level; hierarchy_pos = sibling_level;
} }
// Write the hierarchy position // Write the hierarchy position
writer.PutI2(hierarchy_pos); writer.PutI2(hierarchy_pos);
} }
} }
// TODO: write transformation chunks // TODO: write transformation chunks
++seq; ++seq;
sibling_level = seq; sibling_level = seq;
// Write all children // Write all children
for (unsigned int i = 0; i < node.mNumChildren; ++i) { for (unsigned int i = 0; i < node.mNumChildren; ++i) {
seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level); seq = WriteHierarchy(*node.mChildren[i], seq, i == 0 ? -1 : sibling_level);
} }
// Write all meshes as separate nodes to be able to reference the meshes by name // Write all meshes as separate nodes to be able to reference the meshes by name
for (unsigned int i = 0; i < node.mNumMeshes; ++i) { for (unsigned int i = 0; i < node.mNumMeshes; ++i) {
const bool first_child = node.mNumChildren == 0 && i == 0; const bool first_child = node.mNumChildren == 0 && i == 0;
const unsigned int mesh_idx = node.mMeshes[i]; const unsigned int mesh_idx = node.mMeshes[i];
const aiMesh& mesh = *scene->mMeshes[mesh_idx]; const aiMesh& mesh = *scene->mMeshes[mesh_idx];
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO); ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKINFO);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME); ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRACKOBJNAME);
WriteString(GetMeshName(mesh, mesh_idx, node)); WriteString(GetMeshName(mesh, mesh_idx, node));
writer.PutI4(0); writer.PutI4(0);
writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level)); writer.PutI2(static_cast<int16_t>(first_child ? seq : sibling_level));
++seq; ++seq;
} }
} }
return seq; return seq;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteMaterials() void Discreet3DSExporter::WriteMaterials()
{ {
for (unsigned int i = 0; i < scene->mNumMaterials; ++i) { for (unsigned int i = 0; i < scene->mNumMaterials; ++i) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATERIAL);
const aiMaterial& mat = *scene->mMaterials[i]; const aiMaterial& mat = *scene->mMaterials[i];
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MATNAME);
const std::string& name = GetMaterialName(mat, i); const std::string& name = GetMaterialName(mat, i);
WriteString(name); WriteString(name);
} }
aiColor3D color; aiColor3D color;
if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_DIFFUSE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_DIFFUSE);
WriteColor(color); WriteColor(color);
} }
if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_SPECULAR, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SPECULAR);
WriteColor(color); WriteColor(color);
} }
if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_AMBIENT, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_AMBIENT);
WriteColor(color); WriteColor(color);
} }
if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_COLOR_EMISSIVE, color) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SELF_ILLUM);
WriteColor(color); WriteColor(color);
} }
aiShadingMode shading_mode = aiShadingMode_Flat; aiShadingMode shading_mode = aiShadingMode_Flat;
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
Discreet3DS::shadetype3ds shading_mode_out; Discreet3DS::shadetype3ds shading_mode_out;
switch(shading_mode) { switch(shading_mode) {
case aiShadingMode_Flat: case aiShadingMode_Flat:
case aiShadingMode_NoShading: case aiShadingMode_NoShading:
shading_mode_out = Discreet3DS::Flat; shading_mode_out = Discreet3DS::Flat;
break; break;
case aiShadingMode_Gouraud: case aiShadingMode_Gouraud:
case aiShadingMode_Toon: case aiShadingMode_Toon:
case aiShadingMode_OrenNayar: case aiShadingMode_OrenNayar:
case aiShadingMode_Minnaert: case aiShadingMode_Minnaert:
shading_mode_out = Discreet3DS::Gouraud; shading_mode_out = Discreet3DS::Gouraud;
break; break;
case aiShadingMode_Phong: case aiShadingMode_Phong:
case aiShadingMode_Blinn: case aiShadingMode_Blinn:
case aiShadingMode_CookTorrance: case aiShadingMode_CookTorrance:
case aiShadingMode_Fresnel: case aiShadingMode_Fresnel:
shading_mode_out = Discreet3DS::Phong; shading_mode_out = Discreet3DS::Phong;
break; break;
default: default:
shading_mode_out = Discreet3DS::Flat; shading_mode_out = Discreet3DS::Flat;
ai_assert(false); ai_assert(false);
}; };
writer.PutU2(static_cast<uint16_t>(shading_mode_out)); writer.PutU2(static_cast<uint16_t>(shading_mode_out));
} }
float f; float f;
if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_SHININESS, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS);
WritePercentChunk(f); WritePercentChunk(f);
} }
if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) { if (mat.Get(AI_MATKEY_SHININESS_STRENGTH, f) == AI_SUCCESS) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHININESS_PERCENT);
WritePercentChunk(f); WritePercentChunk(f);
} }
int twosided; int twosided;
if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) { if (mat.Get(AI_MATKEY_TWOSIDED, twosided) == AI_SUCCESS && twosided != 0) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_TWO_SIDE);
writer.PutI2(1); writer.PutI2(1);
} }
WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE); WriteTexture(mat, aiTextureType_DIFFUSE, Discreet3DS::CHUNK_MAT_TEXTURE);
WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP); WriteTexture(mat, aiTextureType_HEIGHT, Discreet3DS::CHUNK_MAT_BUMPMAP);
WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP); WriteTexture(mat, aiTextureType_OPACITY, Discreet3DS::CHUNK_MAT_OPACMAP);
WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP); WriteTexture(mat, aiTextureType_SHININESS, Discreet3DS::CHUNK_MAT_MAT_SHINMAP);
WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP); WriteTexture(mat, aiTextureType_SPECULAR, Discreet3DS::CHUNK_MAT_SPECMAP);
WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP); WriteTexture(mat, aiTextureType_EMISSIVE, Discreet3DS::CHUNK_MAT_SELFIMAP);
WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP); WriteTexture(mat, aiTextureType_REFLECTION, Discreet3DS::CHUNK_MAT_REFLMAP);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags) void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags)
{ {
aiString path; aiString path;
aiTextureMapMode map_mode[2] = { aiTextureMapMode map_mode[2] = {
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
}; };
float blend = 1.0f; float blend = 1.0f;
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) { if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
return; return;
} }
// TODO: handle embedded textures properly // TODO: handle embedded textures properly
if (path.data[0] == '*') { if (path.data[0] == '*') {
DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str())); DefaultLogger::get()->error("Ignoring embedded texture for export: " + std::string(path.C_Str()));
return; return;
} }
ChunkWriter chunk(writer, chunk_flags); ChunkWriter chunk(writer, chunk_flags);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPFILE);
WriteString(path); WriteString(path);
} }
WritePercentChunk(blend); WritePercentChunk(blend);
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_MAP_TILING);
uint16_t val = 0; // WRAP uint16_t val = 0; // WRAP
if (map_mode[0] == aiTextureMapMode_Mirror) { if (map_mode[0] == aiTextureMapMode_Mirror) {
val = 0x2; val = 0x2;
} }
else if (map_mode[0] == aiTextureMapMode_Decal) { else if (map_mode[0] == aiTextureMapMode_Decal) {
val = 0x10; val = 0x10;
} }
writer.PutU2(val); writer.PutU2(val);
} }
// TODO: export texture transformation (i.e. UV offset, scale, rotation) // TODO: export texture transformation (i.e. UV offset, scale, rotation)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteMeshes() void Discreet3DSExporter::WriteMeshes()
{ {
// NOTE: 3DS allows for instances. However: // NOTE: 3DS allows for instances. However:
// i) not all importers support reading them // i) not all importers support reading them
// ii) instances are not as flexible as they are in assimp, in particular, // ii) instances are not as flexible as they are in assimp, in particular,
// nodes can carry (and instance) only one mesh. // nodes can carry (and instance) only one mesh.
// //
// This exporter currently deep clones all instanced meshes, i.e. for each mesh // This exporter currently deep clones all instanced meshes, i.e. for each mesh
// attached to a node a full TRIMESH chunk is written to the file. // attached to a node a full TRIMESH chunk is written to the file.
// //
// Furthermore, the TRIMESH is transformed into world space so that it will // Furthermore, the TRIMESH is transformed into world space so that it will
// appear correctly if importers don't read the scene hierarchy at all. // appear correctly if importers don't read the scene hierarchy at all.
for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) { for (MeshesByNodeMap::const_iterator it = meshes.begin(); it != meshes.end(); ++it) {
const aiNode& node = *(*it).first; const aiNode& node = *(*it).first;
const unsigned int mesh_idx = (*it).second; const unsigned int mesh_idx = (*it).second;
const aiMesh& mesh = *scene->mMeshes[mesh_idx]; const aiMesh& mesh = *scene->mMeshes[mesh_idx];
// This should not happen if the SLM step is correctly executed // This should not happen if the SLM step is correctly executed
// before the scene is handed to the exporter // before the scene is handed to the exporter
ai_assert(mesh.mNumVertices <= 0xffff); ai_assert(mesh.mNumVertices <= 0xffff);
ai_assert(mesh.mNumFaces <= 0xffff); ai_assert(mesh.mNumFaces <= 0xffff);
const aiMatrix4x4& trafo = trafos[&node]; const aiMatrix4x4& trafo = trafos[&node];
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK); ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJBLOCK);
// Mesh name is tied to the node it is attached to so it can later be referenced // Mesh name is tied to the node it is attached to so it can later be referenced
const std::string& name = GetMeshName(mesh, mesh_idx, node); const std::string& name = GetMeshName(mesh, mesh_idx, node);
WriteString(name); WriteString(name);
// TRIMESH chunk // TRIMESH chunk
ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH); ChunkWriter chunk2(writer, Discreet3DS::CHUNK_TRIMESH);
// Vertices in world space // Vertices in world space
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST); ChunkWriter chunk(writer, Discreet3DS::CHUNK_VERTLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices); const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count); writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) { for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
const aiVector3D& v = trafo * mesh.mVertices[i]; const aiVector3D& v = trafo * mesh.mVertices[i];
writer.PutF4(v.x); writer.PutF4(v.x);
writer.PutF4(v.y); writer.PutF4(v.y);
writer.PutF4(v.z); writer.PutF4(v.z);
} }
} }
// UV coordinates // UV coordinates
if (mesh.HasTextureCoords(0)) { if (mesh.HasTextureCoords(0)) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST); ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAPLIST);
const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices); const uint16_t count = static_cast<uint16_t>(mesh.mNumVertices);
writer.PutU2(count); writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumVertices; ++i) { for (unsigned int i = 0; i < mesh.mNumVertices; ++i) {
const aiVector3D& v = mesh.mTextureCoords[0][i]; const aiVector3D& v = mesh.mTextureCoords[0][i];
writer.PutF4(v.x); writer.PutF4(v.x);
writer.PutF4(v.y); writer.PutF4(v.y);
} }
} }
// Faces (indices) // Faces (indices)
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST); ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACELIST);
ai_assert(mesh.mNumFaces <= 0xffff); ai_assert(mesh.mNumFaces <= 0xffff);
// Count triangles, discard lines and points // Count triangles, discard lines and points
uint16_t count = 0; uint16_t count = 0;
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
const aiFace& f = mesh.mFaces[i]; const aiFace& f = mesh.mFaces[i];
if (f.mNumIndices < 3) { if (f.mNumIndices < 3) {
continue; continue;
} }
// TRIANGULATE step is a pre-requisite so we should not see polys here // TRIANGULATE step is a pre-requisite so we should not see polys here
ai_assert(f.mNumIndices == 3); ai_assert(f.mNumIndices == 3);
++count; ++count;
} }
writer.PutU2(count); writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
const aiFace& f = mesh.mFaces[i]; const aiFace& f = mesh.mFaces[i];
if (f.mNumIndices < 3) { if (f.mNumIndices < 3) {
continue; continue;
} }
for (unsigned int j = 0; j < 3; ++j) { for (unsigned int j = 0; j < 3; ++j) {
ai_assert(f.mIndices[j] <= 0xffff); ai_assert(f.mIndices[j] <= 0xffff);
writer.PutI2(static_cast<uint16_t>(f.mIndices[j])); writer.PutI2(static_cast<uint16_t>(f.mIndices[j]));
} }
// Edge visibility flag // Edge visibility flag
writer.PutI2(0x0); writer.PutI2(0x0);
} }
// TODO: write smoothing groups (CHUNK_SMOOLIST) // TODO: write smoothing groups (CHUNK_SMOOLIST)
WriteFaceMaterialChunk(mesh); WriteFaceMaterialChunk(mesh);
} }
// Transformation matrix by which the mesh vertices have been pre-transformed with. // Transformation matrix by which the mesh vertices have been pre-transformed with.
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX); ChunkWriter chunk(writer, Discreet3DS::CHUNK_TRMATRIX);
for (unsigned int r = 0; r < 4; ++r) { for (unsigned int r = 0; r < 4; ++r) {
for (unsigned int c = 0; c < 3; ++c) { for (unsigned int c = 0; c < 3; ++c) {
writer.PutF4(trafo[r][c]); writer.PutF4(trafo[r][c]);
} }
} }
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh) void Discreet3DSExporter::WriteFaceMaterialChunk(const aiMesh& mesh)
{ {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT); ChunkWriter chunk(writer, Discreet3DS::CHUNK_FACEMAT);
const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex); const std::string& name = GetMaterialName(*scene->mMaterials[mesh.mMaterialIndex], mesh.mMaterialIndex);
WriteString(name); WriteString(name);
// Because assimp splits meshes by material, only a single // Because assimp splits meshes by material, only a single
// FACEMAT chunk needs to be written // FACEMAT chunk needs to be written
ai_assert(mesh.mNumFaces <= 0xffff); ai_assert(mesh.mNumFaces <= 0xffff);
const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces); const uint16_t count = static_cast<uint16_t>(mesh.mNumFaces);
writer.PutU2(count); writer.PutU2(count);
for (unsigned int i = 0; i < mesh.mNumFaces; ++i) { for (unsigned int i = 0; i < mesh.mNumFaces; ++i) {
writer.PutU2(static_cast<uint16_t>(i)); writer.PutU2(static_cast<uint16_t>(i));
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteString(const std::string& s) { void Discreet3DSExporter::WriteString(const std::string& s) {
for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) { for (std::string::const_iterator it = s.begin(); it != s.end(); ++it) {
writer.PutI1(*it); writer.PutI1(*it);
} }
writer.PutI1('\0'); writer.PutI1('\0');
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteString(const aiString& s) { void Discreet3DSExporter::WriteString(const aiString& s) {
for (std::size_t i = 0; i < s.length; ++i) { for (std::size_t i = 0; i < s.length; ++i) {
writer.PutI1(s.data[i]); writer.PutI1(s.data[i]);
} }
writer.PutI1('\0'); writer.PutI1('\0');
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WriteColor(const aiColor3D& color) { void Discreet3DSExporter::WriteColor(const aiColor3D& color) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF); ChunkWriter chunk(writer, Discreet3DS::CHUNK_RGBF);
writer.PutF4(color.r); writer.PutF4(color.r);
writer.PutF4(color.g); writer.PutF4(color.g);
writer.PutF4(color.b); writer.PutF4(color.b);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void Discreet3DSExporter::WritePercentChunk(float f) { void Discreet3DSExporter::WritePercentChunk(float f) {
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF); ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTF);
writer.PutF4(f); writer.PutF4(f);
} }

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -55,7 +55,7 @@ struct aiNode;
struct aiMaterial; struct aiMaterial;
struct aiMesh; struct aiMesh;
namespace Assimp namespace Assimp
{ {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
@ -64,32 +64,32 @@ namespace Assimp
class Discreet3DSExporter class Discreet3DSExporter
{ {
public: public:
Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* pScene); Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* pScene);
private: private:
void WriteMeshes(); void WriteMeshes();
void WriteMaterials(); void WriteMaterials();
void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags); void WriteTexture(const aiMaterial& mat, aiTextureType type, uint16_t chunk_flags);
void WriteFaceMaterialChunk(const aiMesh& mesh); void WriteFaceMaterialChunk(const aiMesh& mesh);
int WriteHierarchy(const aiNode& node, int level, int sibling_level); int WriteHierarchy(const aiNode& node, int level, int sibling_level);
void WriteString(const std::string& s); void WriteString(const std::string& s);
void WriteString(const aiString& s); void WriteString(const aiString& s);
void WriteColor(const aiColor3D& color); void WriteColor(const aiColor3D& color);
void WritePercentChunk(float f); void WritePercentChunk(float f);
private: private:
const aiScene* const scene; const aiScene* const scene;
StreamWriterLE writer; StreamWriterLE writer;
std::map<const aiNode*, aiMatrix4x4> trafos; std::map<const aiNode*, aiMatrix4x4> trafos;
typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap; typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
MeshesByNodeMap meshes; MeshesByNodeMap meshes;
}; };

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,282 +1,282 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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
#include "3DSHelper.h" #include "3DSHelper.h"
#include "StreamReader.h" #include "StreamReader.h"
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
using namespace D3DS; using namespace D3DS;
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files /** Importer class for 3D Studio r3 and r4 3DS files
*/ */
class Discreet3DSImporter : public BaseImporter class Discreet3DSImporter : public BaseImporter
{ {
public: public:
Discreet3DSImporter(); Discreet3DSImporter();
~Discreet3DSImporter(); ~Discreet3DSImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a temporary material to the outer representation /** Converts a temporary material to the outer representation
*/ */
void ConvertMaterial(D3DS::Material& p_cMat, void ConvertMaterial(D3DS::Material& p_cMat,
aiMaterial& p_pcOut); aiMaterial& p_pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Read a chunk /** Read a chunk
* *
* @param pcOut Receives the current chunk * @param pcOut Receives the current chunk
*/ */
void ReadChunk(Discreet3DS::Chunk* pcOut); void ReadChunk(Discreet3DS::Chunk* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a percentage chunk. mCurrent will point to the next /** Parse a percentage chunk. mCurrent will point to the next
* chunk behind afterwards. If no percentage chunk is found * chunk behind afterwards. If no percentage chunk is found
* QNAN is returned. * QNAN is returned.
*/ */
float ParsePercentageChunk(); float ParsePercentageChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a color chunk. mCurrent will point to the next /** Parse a color chunk. mCurrent will point to the next
* chunk behind afterwards. If no color chunk is found * chunk behind afterwards. If no color chunk is found
* QNAN is returned in all members. * QNAN is returned in all members.
*/ */
void ParseColorChunk(aiColor3D* p_pcOut, void ParseColorChunk(aiColor3D* p_pcOut,
bool p_bAcceptPercent = true); bool p_bAcceptPercent = true);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Skip a chunk in the file /** Skip a chunk in the file
*/ */
void SkipChunk(); void SkipChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Generate the nodegraph /** Generate the nodegraph
*/ */
void GenerateNodeGraph(aiScene* pcOut); void GenerateNodeGraph(aiScene* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a main top-level chunk in the file /** Parse a main top-level chunk in the file
*/ */
void ParseMainChunk(); void ParseMainChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level chunk in the file /** Parse a top-level chunk in the file
*/ */
void ParseChunk(const char* name, unsigned int num); void ParseChunk(const char* name, unsigned int num);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level editor chunk in the file /** Parse a top-level editor chunk in the file
*/ */
void ParseEditorChunk(); void ParseEditorChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a top-level object chunk in the file /** Parse a top-level object chunk in the file
*/ */
void ParseObjectChunk(); void ParseObjectChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a material chunk in the file /** Parse a material chunk in the file
*/ */
void ParseMaterialChunk(); void ParseMaterialChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a mesh chunk in the file /** Parse a mesh chunk in the file
*/ */
void ParseMeshChunk(); void ParseMeshChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a light chunk in the file /** Parse a light chunk in the file
*/ */
void ParseLightChunk(); void ParseLightChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a camera chunk in the file /** Parse a camera chunk in the file
*/ */
void ParseCameraChunk(); void ParseCameraChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a face list chunk in the file /** Parse a face list chunk in the file
*/ */
void ParseFaceChunk(); void ParseFaceChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a keyframe chunk in the file /** Parse a keyframe chunk in the file
*/ */
void ParseKeyframeChunk(); void ParseKeyframeChunk();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a hierarchy chunk in the file /** Parse a hierarchy chunk in the file
*/ */
void ParseHierarchyChunk(uint16_t parent); void ParseHierarchyChunk(uint16_t parent);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Parse a texture chunk in the file /** Parse a texture chunk in the file
*/ */
void ParseTextureChunk(D3DS::Texture* pcOut); void ParseTextureChunk(D3DS::Texture* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert the meshes in the file /** Convert the meshes in the file
*/ */
void ConvertMeshes(aiScene* pcOut); void ConvertMeshes(aiScene* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Replace the default material in the scene /** Replace the default material in the scene
*/ */
void ReplaceDefaultMaterial(); void ReplaceDefaultMaterial();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert the whole scene /** Convert the whole scene
*/ */
void ConvertScene(aiScene* pcOut); void ConvertScene(aiScene* pcOut);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** generate unique vertices for a mesh /** generate unique vertices for a mesh
*/ */
void MakeUnique(D3DS::Mesh& sMesh); void MakeUnique(D3DS::Mesh& sMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Add a node to the node graph /** Add a node to the node graph
*/ */
void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn, void AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,D3DS::Node* pcIn,
aiMatrix4x4& absTrafo); aiMatrix4x4& absTrafo);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Search for a node in the graph. /** Search for a node in the graph.
* Called recursively * Called recursively
*/ */
void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent); void InverseNodeSearch(D3DS::Node* pcNode,D3DS::Node* pcCurrent);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Apply the master scaling factor to the mesh /** Apply the master scaling factor to the mesh
*/ */
void ApplyMasterScale(aiScene* pScene); void ApplyMasterScale(aiScene* pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Clamp all indices in the file to a valid range /** Clamp all indices in the file to a valid range
*/ */
void CheckIndices(D3DS::Mesh& sMesh); void CheckIndices(D3DS::Mesh& sMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Skip the TCB info in a track key /** Skip the TCB info in a track key
*/ */
void SkipTCBInfo(); void SkipTCBInfo();
protected: protected:
/** Stream to read from */ /** Stream to read from */
StreamReaderLE* stream; StreamReaderLE* stream;
/** Last touched node index */ /** Last touched node index */
short mLastNodeIndex; short mLastNodeIndex;
/** Current node, root node */ /** Current node, root node */
D3DS::Node* mCurrentNode, *mRootNode; D3DS::Node* mCurrentNode, *mRootNode;
/** Scene under construction */ /** Scene under construction */
D3DS::Scene* mScene; D3DS::Scene* mScene;
/** Ambient base color of the scene */ /** Ambient base color of the scene */
aiColor3D mClrAmbient; aiColor3D mClrAmbient;
/** Master scaling factor of the scene */ /** Master scaling factor of the scene */
float mMasterScale; float mMasterScale;
/** Path to the background image of the scene */ /** Path to the background image of the scene */
std::string mBackgroundImage; std::string mBackgroundImage;
bool bHasBG; bool bHasBG;
/** true if PRJ file */ /** true if PRJ file */
bool bIsPrj; bool bIsPrj;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,273 +1,273 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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"
struct aiNode; struct aiNode;
struct aiMesh; struct aiMesh;
struct aiMaterial; struct aiMaterial;
struct aiLight; struct aiLight;
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** AC3D (*.ac) importer class /** AC3D (*.ac) importer class
*/ */
class AC3DImporter : public BaseImporter class AC3DImporter : public BaseImporter
{ {
public: public:
AC3DImporter(); AC3DImporter();
~AC3DImporter(); ~AC3DImporter();
// Represents an AC3D material // Represents an AC3D material
struct Material struct Material
{ {
Material() Material()
: rgb (0.6f,0.6f,0.6f) : rgb (0.6f,0.6f,0.6f)
, spec (1.f,1.f,1.f) , spec (1.f,1.f,1.f)
, shin (0.f) , shin (0.f)
, trans (0.f) , trans (0.f)
{} {}
// base color of the material // base color of the material
aiColor3D rgb; aiColor3D rgb;
// ambient color of the material // ambient color of the material
aiColor3D amb; aiColor3D amb;
// emissive color of the material // emissive color of the material
aiColor3D emis; aiColor3D emis;
// specular color of the material // specular color of the material
aiColor3D spec; aiColor3D spec;
// shininess exponent // shininess exponent
float shin; float shin;
// transparency. 0 == opaque // transparency. 0 == opaque
float trans; float trans;
// name of the material. optional. // name of the material. optional.
std::string name; std::string name;
}; };
// Represents an AC3D surface // Represents an AC3D surface
struct Surface struct Surface
{ {
Surface() Surface()
: mat (0) : mat (0)
, flags (0) , flags (0)
{} {}
unsigned int mat,flags; unsigned int mat,flags;
typedef std::pair<unsigned int, aiVector2D > SurfaceEntry; typedef std::pair<unsigned int, aiVector2D > SurfaceEntry;
std::vector< SurfaceEntry > entries; std::vector< SurfaceEntry > entries;
}; };
// Represents an AC3D object // Represents an AC3D object
struct Object struct Object
{ {
Object() Object()
: type (World) : type (World)
, name( "" ) , name( "" )
, children() , children()
, texture( "" ) , texture( "" )
, texRepeat( 1.f, 1.f ) , texRepeat( 1.f, 1.f )
, texOffset( 0.0f, 0.0f ) , texOffset( 0.0f, 0.0f )
, rotation() , rotation()
, translation() , translation()
, vertices() , vertices()
, surfaces() , surfaces()
, numRefs (0) , numRefs (0)
, subDiv (0) , subDiv (0)
{} {}
// Type description // Type description
enum Type enum Type
{ {
World = 0x0, World = 0x0,
Poly = 0x1, Poly = 0x1,
Group = 0x2, Group = 0x2,
Light = 0x4 Light = 0x4
} type; } type;
// name of the object // name of the object
std::string name; std::string name;
// object children // object children
std::vector<Object> children; std::vector<Object> children;
// texture to be assigned to all surfaces of the object // texture to be assigned to all surfaces of the object
std::string texture; std::string texture;
// texture repat factors (scaling for all coordinates) // texture repat factors (scaling for all coordinates)
aiVector2D texRepeat, texOffset; aiVector2D texRepeat, texOffset;
// rotation matrix // rotation matrix
aiMatrix3x3 rotation; aiMatrix3x3 rotation;
// translation vector // translation vector
aiVector3D translation; aiVector3D translation;
// vertices // vertices
std::vector<aiVector3D> vertices; std::vector<aiVector3D> vertices;
// surfaces // surfaces
std::vector<Surface> surfaces; std::vector<Surface> surfaces;
// number of indices (= num verts in verbose format) // number of indices (= num verts in verbose format)
unsigned int numRefs; unsigned int numRefs;
// number of subdivisions to be performed on the // number of subdivisions to be performed on the
// imported data // imported data
unsigned int subDiv; unsigned int subDiv;
// max angle limit for smoothing // max angle limit for smoothing
float crease; float crease;
}; };
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. * See BaseImporter::CanRead() for details.
*/ */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details */ * See #BaseImporter::GetInfo for the details */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details*/ * See BaseImporter::InternReadFile() for details*/
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ReadFile(). /** Called prior to ReadFile().
* The function is a request to the importer to update its configuration * The function is a request to the importer to update its configuration
* basing on the Importer's configuration property list.*/ * basing on the Importer's configuration property list.*/
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Get the next line from the file. /** Get the next line from the file.
* @return false if the end of the file was reached*/ * @return false if the end of the file was reached*/
bool GetNextLine(); bool GetNextLine();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Load the object section. This method is called recursively to /** Load the object section. This method is called recursively to
* load subobjects, the method returns after a 'kids 0' was * load subobjects, the method returns after a 'kids 0' was
* encountered. * encountered.
* @objects List of output objects*/ * @objects List of output objects*/
void LoadObjectSection(std::vector<Object>& objects); void LoadObjectSection(std::vector<Object>& objects);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert all objects into meshes and nodes. /** Convert all objects into meshes and nodes.
* @param object Current object to work on * @param object Current object to work on
* @param meshes Pointer to the list of output meshes * @param meshes Pointer to the list of output meshes
* @param outMaterials List of output materials * @param outMaterials List of output materials
* @param materials Material list * @param materials Material list
* @param Scenegraph node for the object */ * @param Scenegraph node for the object */
aiNode* ConvertObjectSection(Object& object, aiNode* ConvertObjectSection(Object& object,
std::vector<aiMesh*>& meshes, std::vector<aiMesh*>& meshes,
std::vector<aiMaterial*>& outMaterials, std::vector<aiMaterial*>& outMaterials,
const std::vector<Material>& materials, const std::vector<Material>& materials,
aiNode* parent = NULL); aiNode* parent = NULL);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Convert a material /** Convert a material
* @param object Current object * @param object Current object
* @param matSrc Source material description * @param matSrc Source material description
* @param matDest Destination material to be filled */ * @param matDest Destination material to be filled */
void ConvertMaterial(const Object& object, void ConvertMaterial(const Object& object,
const Material& matSrc, const Material& matSrc,
aiMaterial& matDest); aiMaterial& matDest);
private: private:
// points to the next data line // points to the next data line
const char* buffer; const char* buffer;
// Configuration option: if enabled, up to two meshes // Configuration option: if enabled, up to two meshes
// are generated per material: those faces who have // are generated per material: those faces who have
// their bf cull flags set are separated. // their bf cull flags set are separated.
bool configSplitBFCull; bool configSplitBFCull;
// Configuration switch: subdivision surfaces are only // Configuration switch: subdivision surfaces are only
// evaluated if the value is true. // evaluated if the value is true.
bool configEvalSubdivision; bool configEvalSubdivision;
// counts how many objects we have in the tree. // counts how many objects we have in the tree.
// basing on this information we can find a // basing on this information we can find a
// good estimate how many meshes we'll have in the final scene. // good estimate how many meshes we'll have in the final scene.
unsigned int mNumMeshes; unsigned int mNumMeshes;
// current list of light sources // current list of light sources
std::vector<aiLight*>* mLights; std::vector<aiLight*>* mLights;
// name counters // name counters
unsigned int lights, groups, polys, worlds; unsigned int lights, groups, polys, worlds;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC #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-2015, 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

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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

@ -6,8 +6,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -61,7 +61,7 @@ struct aiCamera;
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER #ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
/** Importer class for 3D Studio r3 and r4 3DS files /** Importer class for 3D Studio r3 and r4 3DS files
@ -74,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-2015, 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.
*/ */
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
#include "CInterfaceIOWrapper.h" #include "CInterfaceIOWrapper.h"
#include "SceneCombiner.h" #include "SceneCombiner.h"
#include "ScenePrivate.h" #include "ScenePrivate.h"
#include "../include/assimp/Exporter.hpp" #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

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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,131 +1,130 @@
/*
/* Open Asset Import Library (assimp)
Open Asset Import Library (assimp) ----------------------------------------------------------------------
----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 .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 "BaseImporter.h"
#include <string>
#include <string> #include <vector>
#include <vector>
struct aiNodeAnim;
struct aiNodeAnim; struct aiNode;
struct aiNode; struct aiAnimation;
struct aiAnimation;
namespace Assimp{
namespace Assimp{
class B3DImporter : public BaseImporter{
class B3DImporter : public BaseImporter{ public:
public:
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
virtual bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
protected:
protected:
virtual const aiImporterDesc* GetInfo () const;
virtual const aiImporterDesc* GetInfo () const; virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
virtual void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
private:
private:
int ReadByte();
int ReadByte(); int ReadInt();
int ReadInt(); float ReadFloat();
float ReadFloat(); aiVector2D ReadVec2();
aiVector2D ReadVec2(); aiVector3D ReadVec3();
aiVector3D ReadVec3(); aiQuaternion ReadQuat();
aiQuaternion ReadQuat(); std::string ReadString();
std::string ReadString(); std::string ReadChunk();
std::string ReadChunk(); void ExitChunk();
void ExitChunk(); unsigned ChunkSize();
unsigned ChunkSize();
template<class T>
template<class T> T *to_array( const std::vector<T> &v );
T *to_array( const std::vector<T> &v );
struct Vertex{
struct Vertex{ aiVector3D vertex;
aiVector3D vertex; aiVector3D normal;
aiVector3D normal; aiVector3D texcoords;
aiVector3D texcoords; unsigned char bones[4];
unsigned char bones[4]; float weights[4];
float weights[4]; };
};
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
void ReadTEXS();
void ReadTEXS(); void ReadBRUS();
void ReadBRUS();
void ReadVRTS();
void ReadVRTS(); void ReadTRIS( int v0 );
void ReadTRIS( int v0 ); void ReadMESH();
void ReadMESH(); void ReadBONE( int id );
void ReadBONE( int id ); void ReadKEYS( aiNodeAnim *nodeAnim );
void ReadKEYS( aiNodeAnim *nodeAnim ); void ReadANIM();
void ReadANIM();
aiNode *ReadNODE( aiNode *parent );
aiNode *ReadNODE( aiNode *parent );
void ReadBB3D( aiScene *scene );
void ReadBB3D( aiScene *scene );
unsigned _pos;
unsigned _pos; // unsigned _size;
// unsigned _size; std::vector<unsigned char> _buf;
std::vector<unsigned char> _buf; std::vector<unsigned> _stack;
std::vector<unsigned> _stack;
std::vector<std::string> _textures;
std::vector<std::string> _textures; std::vector<aiMaterial*> _materials;
std::vector<aiMaterial*> _materials;
int _vflags,_tcsets,_tcsize;
int _vflags,_tcsets,_tcsize; std::vector<Vertex> _vertices;
std::vector<Vertex> _vertices;
std::vector<aiNode*> _nodes;
std::vector<aiNode*> _nodes; std::vector<aiMesh*> _meshes;
std::vector<aiMesh*> _meshes; std::vector<aiNodeAnim*> _nodeAnims;
std::vector<aiNodeAnim*> _nodeAnims; std::vector<aiAnimation*> _animations;
std::vector<aiAnimation*> _animations; };
};
}
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,171 +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-2015, 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"
struct aiNode; struct aiNode;
namespace Assimp namespace Assimp
{ {
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/** Loader class to read Motion Capturing data from a .bvh file. /** 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 * 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 * the hierarchy. It contains no actual mesh data, but we generate a dummy mesh
* inside the loader just to be able to see something. * inside the loader just to be able to see something.
*/ */
class BVHLoader : public BaseImporter class BVHLoader : public BaseImporter
{ {
/** Possible animation channels for which the motion data holds the values */ /** Possible animation channels for which the motion data holds the values */
enum ChannelType enum ChannelType
{ {
Channel_PositionX, Channel_PositionX,
Channel_PositionY, Channel_PositionY,
Channel_PositionZ, Channel_PositionZ,
Channel_RotationX, Channel_RotationX,
Channel_RotationY, Channel_RotationY,
Channel_RotationZ Channel_RotationZ
}; };
/** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */ /** Collected list of node. Will be bones of the dummy mesh some day, addressed by their array index */
struct Node struct Node
{ {
const aiNode* mNode; const aiNode* mNode;
std::vector<ChannelType> mChannels; std::vector<ChannelType> mChannels;
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
Node() { } Node() { }
Node( const aiNode* pNode) : mNode( pNode) { } Node( const aiNode* pNode) : mNode( pNode) { }
}; };
public: public:
BVHLoader(); BVHLoader();
~BVHLoader(); ~BVHLoader();
public: public:
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool cs) const;
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
protected: protected:
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
protected: protected:
/** Reads the file */ /** Reads the file */
void ReadStructure( aiScene* pScene); void ReadStructure( aiScene* pScene);
/** Reads the hierarchy */ /** Reads the hierarchy */
void ReadHierarchy( aiScene* pScene); void ReadHierarchy( aiScene* pScene);
/** Reads a node and recursively its childs and returns the created node. */ /** Reads a node and recursively its childs and returns the created node. */
aiNode* ReadNode(); aiNode* ReadNode();
/** Reads an end node and returns the created node. */ /** Reads an end node and returns the created node. */
aiNode* ReadEndSite( const std::string& pParentName); aiNode* ReadEndSite( const std::string& pParentName);
/** Reads a node offset for the given node */ /** Reads a node offset for the given node */
void ReadNodeOffset( aiNode* pNode); void ReadNodeOffset( aiNode* pNode);
/** Reads the animation channels into the given node */ /** Reads the animation channels into the given node */
void ReadNodeChannels( BVHLoader::Node& pNode); void ReadNodeChannels( BVHLoader::Node& pNode);
/** Reads the motion data */ /** Reads the motion data */
void ReadMotion( aiScene* pScene); void ReadMotion( aiScene* pScene);
/** Retrieves the next token */ /** Retrieves the next token */
std::string GetNextToken(); std::string GetNextToken();
/** Reads the next token as a float */ /** Reads the next token as a float */
float GetNextTokenAsFloat(); float GetNextTokenAsFloat();
/** Aborts the file reading with an exception */ /** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
/** Constructs an animation for the motion data and stores it in the given scene */ /** Constructs an animation for the motion data and stores it in the given scene */
void CreateAnimation( aiScene* pScene); void CreateAnimation( aiScene* pScene);
protected: protected:
/** Filename, for a verbose error message */ /** Filename, for a verbose error message */
std::string mFileName; std::string mFileName;
/** Buffer to hold the loaded file */ /** Buffer to hold the loaded file */
std::vector<char> mBuffer; std::vector<char> mBuffer;
/** Next char to read from the buffer */ /** Next char to read from the buffer */
std::vector<char>::const_iterator mReader; std::vector<char>::const_iterator mReader;
/** Current line, for error messages */ /** Current line, for error messages */
unsigned int mLine; unsigned int mLine;
/** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index. /** Collected list of nodes. Will be bones of the dummy mesh some day, addressed by their array index.
* Also contain the motion data for the node's channels * Also contain the motion data for the node's channels
*/ */
std::vector<Node> mNodes; std::vector<Node> mNodes;
/** basic Animation parameters */ /** basic Animation parameters */
float mAnimTickDuration; float mAnimTickDuration;
unsigned int mAnimNumFrames; unsigned int mAnimNumFrames;
bool noSkeletonMesh; bool noSkeletonMesh;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_BVHLOADER_H_INC #endif // AI_BVHLOADER_H_INC

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,105 +1,105 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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 "BaseImporter.h" #include "BaseImporter.h"
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/scene.h" #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-2015, 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

@ -53,95 +53,95 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
void Bitmap::Save(aiTexture* texture, IOStream* file) { void Bitmap::Save(aiTexture* texture, IOStream* file) {
if(file != NULL) { if(file != NULL) {
Header header; Header header;
DIB dib; DIB dib;
dib.size = DIB::dib_size; dib.size = DIB::dib_size;
dib.width = texture->mWidth; dib.width = texture->mWidth;
dib.height = texture->mHeight; dib.height = texture->mHeight;
dib.planes = 1; dib.planes = 1;
dib.bits_per_pixel = 8 * mBytesPerPixel; dib.bits_per_pixel = 8 * mBytesPerPixel;
dib.compression = 0; dib.compression = 0;
dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height; dib.image_size = (((dib.width * mBytesPerPixel) + 3) & 0x0000FFFC) * dib.height;
dib.x_resolution = 0; dib.x_resolution = 0;
dib.y_resolution = 0; dib.y_resolution = 0;
dib.nb_colors = 0; dib.nb_colors = 0;
dib.nb_important_colors = 0; dib.nb_important_colors = 0;
header.type = 0x4D42; // 'BM' header.type = 0x4D42; // 'BM'
header.offset = Header::header_size + DIB::dib_size; header.offset = Header::header_size + DIB::dib_size;
header.size = header.offset + dib.image_size; header.size = header.offset + dib.image_size;
header.reserved1 = 0; header.reserved1 = 0;
header.reserved2 = 0; header.reserved2 = 0;
WriteHeader(header, file); WriteHeader(header, file);
WriteDIB(dib, file); WriteDIB(dib, file);
WriteData(texture, file); WriteData(texture, file);
} }
} }
template<typename T> template<typename T>
inline std::size_t Copy(uint8_t* data, T& field) { inline std::size_t Copy(uint8_t* data, T& field) {
std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field); std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
} }
void Bitmap::WriteHeader(Header& header, IOStream* file) { void Bitmap::WriteHeader(Header& header, IOStream* file) {
uint8_t data[Header::header_size]; uint8_t data[Header::header_size];
std::size_t offset = 0; std::size_t offset = 0;
offset += Copy(&data[offset], header.type); offset += Copy(&data[offset], header.type);
offset += Copy(&data[offset], header.size); offset += Copy(&data[offset], header.size);
offset += Copy(&data[offset], header.reserved1); offset += Copy(&data[offset], header.reserved1);
offset += Copy(&data[offset], header.reserved2); offset += Copy(&data[offset], header.reserved2);
offset += Copy(&data[offset], header.offset); offset += Copy(&data[offset], header.offset);
file->Write(data, Header::header_size, 1); file->Write(data, Header::header_size, 1);
} }
void Bitmap::WriteDIB(DIB& dib, IOStream* file) { void Bitmap::WriteDIB(DIB& dib, IOStream* file) {
uint8_t data[DIB::dib_size]; uint8_t data[DIB::dib_size];
std::size_t offset = 0; std::size_t offset = 0;
offset += Copy(&data[offset], dib.size); offset += Copy(&data[offset], dib.size);
offset += Copy(&data[offset], dib.width); offset += Copy(&data[offset], dib.width);
offset += Copy(&data[offset], dib.height); offset += Copy(&data[offset], dib.height);
offset += Copy(&data[offset], dib.planes); offset += Copy(&data[offset], dib.planes);
offset += Copy(&data[offset], dib.bits_per_pixel); offset += Copy(&data[offset], dib.bits_per_pixel);
offset += Copy(&data[offset], dib.compression); offset += Copy(&data[offset], dib.compression);
offset += Copy(&data[offset], dib.image_size); offset += Copy(&data[offset], dib.image_size);
offset += Copy(&data[offset], dib.x_resolution); offset += Copy(&data[offset], dib.x_resolution);
offset += Copy(&data[offset], dib.y_resolution); offset += Copy(&data[offset], dib.y_resolution);
offset += Copy(&data[offset], dib.nb_colors); offset += Copy(&data[offset], dib.nb_colors);
offset += Copy(&data[offset], dib.nb_important_colors); offset += Copy(&data[offset], dib.nb_important_colors);
file->Write(data, DIB::dib_size, 1); file->Write(data, DIB::dib_size, 1);
} }
void Bitmap::WriteData(aiTexture* texture, IOStream* file) { void Bitmap::WriteData(aiTexture* texture, IOStream* file) {
static const std::size_t padding_offset = 4; static const std::size_t padding_offset = 4;
static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0}; static const uint8_t padding_data[padding_offset] = {0x0, 0x0, 0x0, 0x0};
unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset; unsigned int padding = (padding_offset - ((mBytesPerPixel * texture->mWidth) % padding_offset)) % padding_offset;
uint8_t pixel[mBytesPerPixel]; uint8_t pixel[mBytesPerPixel];
for(std::size_t i = 0; i < texture->mHeight; ++i) { for(std::size_t i = 0; i < texture->mHeight; ++i) {
for(std::size_t j = 0; j < texture->mWidth; ++j) { for(std::size_t j = 0; j < texture->mWidth; ++j) {
const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format const aiTexel& texel = texture->pcData[(texture->mHeight - i - 1) * texture->mWidth + j]; // Bitmap files are stored in bottom-up format
pixel[0] = texel.r; pixel[0] = texel.r;
pixel[1] = texel.g; pixel[1] = texel.g;
pixel[2] = texel.b; pixel[2] = texel.b;
pixel[3] = texel.a; pixel[3] = texel.a;
file->Write(pixel, mBytesPerPixel, 1); file->Write(pixel, mBytesPerPixel, 1);
} }
file->Write(padding_data, padding, 1); file->Write(padding_data, padding, 1);
} }
} }
} }

View File

@ -57,85 +57,85 @@ namespace Assimp {
class IOStream; class IOStream;
class Bitmap { class Bitmap {
protected: protected:
struct Header { struct Header {
uint16_t type; uint16_t type;
uint32_t size; uint32_t size;
uint16_t reserved1; uint16_t reserved1;
uint16_t reserved2; uint16_t reserved2;
uint32_t offset; uint32_t offset;
// We define the struct size because sizeof(Header) might return a wrong result because of structure padding. // We define the struct size because sizeof(Header) might return a wrong result because of structure padding.
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
static const std::size_t header_size = static const std::size_t header_size =
sizeof(uint16_t) + // type sizeof(uint16_t) + // type
sizeof(uint32_t) + // size sizeof(uint32_t) + // size
sizeof(uint16_t) + // reserved1 sizeof(uint16_t) + // reserved1
sizeof(uint16_t) + // reserved2 sizeof(uint16_t) + // reserved2
sizeof(uint32_t); // offset sizeof(uint32_t); // offset
}; };
struct DIB { struct DIB {
uint32_t size; uint32_t size;
int32_t width; int32_t width;
int32_t height; int32_t height;
uint16_t planes; uint16_t planes;
uint16_t bits_per_pixel; uint16_t bits_per_pixel;
uint32_t compression; uint32_t compression;
uint32_t image_size; uint32_t image_size;
int32_t x_resolution; int32_t x_resolution;
int32_t y_resolution; int32_t y_resolution;
uint32_t nb_colors; uint32_t nb_colors;
uint32_t nb_important_colors; uint32_t nb_important_colors;
// We define the struct size because sizeof(DIB) might return a wrong result because of structure padding. // We define the struct size because sizeof(DIB) might return a wrong result because of structure padding.
// Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field). // Moreover, we must use this ugly and error prone syntax because Visual Studio neither support constexpr or sizeof(name_of_field).
static const std::size_t dib_size = static const std::size_t dib_size =
sizeof(uint32_t) + // size sizeof(uint32_t) + // size
sizeof(int32_t) + // width sizeof(int32_t) + // width
sizeof(int32_t) + // height sizeof(int32_t) + // height
sizeof(uint16_t) + // planes sizeof(uint16_t) + // planes
sizeof(uint16_t) + // bits_per_pixel sizeof(uint16_t) + // bits_per_pixel
sizeof(uint32_t) + // compression sizeof(uint32_t) + // compression
sizeof(uint32_t) + // image_size sizeof(uint32_t) + // image_size
sizeof(int32_t) + // x_resolution sizeof(int32_t) + // x_resolution
sizeof(int32_t) + // y_resolution sizeof(int32_t) + // y_resolution
sizeof(uint32_t) + // nb_colors sizeof(uint32_t) + // nb_colors
sizeof(uint32_t); // nb_important_colors sizeof(uint32_t); // nb_important_colors
}; };
static const std::size_t mBytesPerPixel = 4; static const std::size_t mBytesPerPixel = 4;
public: public:
static void Save(aiTexture* texture, IOStream* file); static void Save(aiTexture* texture, IOStream* file);
protected: protected:
static void WriteHeader(Header& header, IOStream* file); static void WriteHeader(Header& header, IOStream* file);
static void WriteDIB(DIB& dib, IOStream* file); static void WriteDIB(DIB& dib, IOStream* file);
static void WriteData(aiTexture* texture, IOStream* file); static void WriteData(aiTexture* texture, IOStream* file);
}; };

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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp namespace Assimp
{ {
template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: "; template< > const std::string LogFunctions< BlenderBMeshConverter >::log_prefix = "BLEND_BMESH: ";
} }
using namespace Assimp; using namespace Assimp;
@ -61,142 +61,142 @@ using namespace Assimp::Formatter;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ): BlenderBMeshConverter::BlenderBMeshConverter( const Mesh* mesh ):
BMesh( mesh ), BMesh( mesh ),
triMesh( NULL ) triMesh( NULL )
{ {
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BlenderBMeshConverter::~BlenderBMeshConverter( ) BlenderBMeshConverter::~BlenderBMeshConverter( )
{ {
DestroyTriMesh( ); DestroyTriMesh( );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderBMeshConverter::ContainsBMesh( ) const bool BlenderBMeshConverter::ContainsBMesh( ) const
{ {
// TODO - Should probably do some additional verification here // TODO - Should probably do some additional verification here
return BMesh->totpoly && BMesh->totloop && BMesh->totvert; return BMesh->totpoly && BMesh->totloop && BMesh->totvert;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const Mesh* BlenderBMeshConverter::TriangulateBMesh( ) const Mesh* BlenderBMeshConverter::TriangulateBMesh( )
{ {
AssertValidMesh( ); AssertValidMesh( );
AssertValidSizes( ); AssertValidSizes( );
PrepareTriMesh( ); PrepareTriMesh( );
for ( int i = 0; i < BMesh->totpoly; ++i ) for ( int i = 0; i < BMesh->totpoly; ++i )
{ {
const MPoly& poly = BMesh->mpoly[ i ]; const MPoly& poly = BMesh->mpoly[ i ];
ConvertPolyToFaces( poly ); ConvertPolyToFaces( poly );
} }
return triMesh; return triMesh;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::AssertValidMesh( ) void BlenderBMeshConverter::AssertValidMesh( )
{ {
if ( !ContainsBMesh( ) ) if ( !ContainsBMesh( ) )
{ {
ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" ); ThrowException( "BlenderBMeshConverter requires a BMesh with \"polygons\" - please call BlenderBMeshConverter::ContainsBMesh to check this first" );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::AssertValidSizes( ) void BlenderBMeshConverter::AssertValidSizes( )
{ {
if ( BMesh->totpoly != static_cast<int>( BMesh->mpoly.size( ) ) ) if ( BMesh->totpoly != static_cast<int>( BMesh->mpoly.size( ) ) )
{ {
ThrowException( "BMesh poly array has incorrect size" ); ThrowException( "BMesh poly array has incorrect size" );
} }
if ( BMesh->totloop != static_cast<int>( BMesh->mloop.size( ) ) ) if ( BMesh->totloop != static_cast<int>( BMesh->mloop.size( ) ) )
{ {
ThrowException( "BMesh loop array has incorrect size" ); ThrowException( "BMesh loop array has incorrect size" );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::PrepareTriMesh( ) void BlenderBMeshConverter::PrepareTriMesh( )
{ {
if ( triMesh ) if ( triMesh )
{ {
DestroyTriMesh( ); DestroyTriMesh( );
} }
triMesh = new Mesh( *BMesh ); triMesh = new Mesh( *BMesh );
triMesh->totface = 0; triMesh->totface = 0;
triMesh->mface.clear( ); triMesh->mface.clear( );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::DestroyTriMesh( ) void BlenderBMeshConverter::DestroyTriMesh( )
{ {
delete triMesh; delete triMesh;
triMesh = NULL; triMesh = NULL;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly ) void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
{ {
const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ]; const MLoop* polyLoop = &BMesh->mloop[ poly.loopstart ];
if ( poly.totloop == 3 || poly.totloop == 4 ) if ( poly.totloop == 3 || poly.totloop == 4 )
{ {
AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 ); AddFace( polyLoop[ 0 ].v, polyLoop[ 1 ].v, polyLoop[ 2 ].v, poly.totloop == 4 ? polyLoop[ 3 ].v : 0 );
// UVs are optional, so only convert when present. // UVs are optional, so only convert when present.
if ( BMesh->mloopuv.size() ) if ( BMesh->mloopuv.size() )
{ {
if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) ) if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
{ {
ThrowException( "BMesh uv loop array has incorrect size" ); ThrowException( "BMesh uv loop array has incorrect size" );
} }
const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ]; const MLoopUV* loopUV = &BMesh->mloopuv[ poly.loopstart ];
AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 ); AddTFace( loopUV[ 0 ].uv, loopUV[ 1 ].uv, loopUV[ 2 ].uv, poly.totloop == 4 ? loopUV[ 3 ].uv : 0 );
} }
} }
else if ( poly.totloop > 4 ) else if ( poly.totloop > 4 )
{ {
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE #if ASSIMP_BLEND_WITH_GLU_TESSELLATE
BlenderTessellatorGL tessGL( *this ); BlenderTessellatorGL tessGL( *this );
tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert ); tessGL.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
#elif ASSIMP_BLEND_WITH_POLY_2_TRI #elif ASSIMP_BLEND_WITH_POLY_2_TRI
BlenderTessellatorP2T tessP2T( *this ); BlenderTessellatorP2T tessP2T( *this );
tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert ); tessP2T.Tessellate( polyLoop, poly.totloop, triMesh->mvert );
#endif #endif
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 ) void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
{ {
MFace face; MFace face;
face.v1 = v1; face.v1 = v1;
face.v2 = v2; face.v2 = v2;
face.v3 = v3; face.v3 = v3;
face.v4 = v4; face.v4 = v4;
// TODO - Work out how materials work // TODO - Work out how materials work
face.mat_nr = 0; face.mat_nr = 0;
triMesh->mface.push_back( face ); triMesh->mface.push_back( face );
triMesh->totface = triMesh->mface.size( ); triMesh->totface = triMesh->mface.size( );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 ) void BlenderBMeshConverter::AddTFace( const float* uv1, const float *uv2, const float *uv3, const float* uv4 )
{ {
MTFace mtface; MTFace mtface;
memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 ); memcpy( &mtface.uv[ 0 ], uv1, sizeof(float) * 2 );
memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 ); memcpy( &mtface.uv[ 1 ], uv2, sizeof(float) * 2 );
memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 ); memcpy( &mtface.uv[ 2 ], uv3, sizeof(float) * 2 );
if ( uv4 ) if ( uv4 )
{ {
memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 ); memcpy( &mtface.uv[ 3 ], uv4, sizeof(float) * 2 );
} }
triMesh->mtface.push_back( mtface ); triMesh->mtface.push_back( mtface );
} }
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER

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,373 +1,373 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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.
*/ */
#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> #include <boost/foreach.hpp>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
#define for_each BOOST_FOREACH #define for_each BOOST_FOREACH
bool match4(StreamReaderAny& stream, const char* string) { bool match4(StreamReaderAny& stream, const char* string) {
char tmp[] = { char tmp[] = {
(stream).GetI1(), (stream).GetI1(),
(stream).GetI1(), (stream).GetI1(),
(stream).GetI1(), (stream).GetI1(),
(stream).GetI1() (stream).GetI1()
}; };
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]); return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
} }
struct Type { struct Type {
size_t size; size_t size;
std::string name; std::string name;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DNAParser :: Parse () void DNAParser :: Parse ()
{ {
StreamReaderAny& stream = *db.reader.get(); StreamReaderAny& stream = *db.reader.get();
DNA& dna = db.dna; DNA& dna = db.dna;
if(!match4(stream,"SDNA")) { if(!match4(stream,"SDNA")) {
throw DeadlyImportError("BlenderDNA: Expected SDNA chunk"); throw DeadlyImportError("BlenderDNA: Expected SDNA chunk");
} }
// name dictionary // name dictionary
if(!match4(stream,"NAME")) { if(!match4(stream,"NAME")) {
throw DeadlyImportError("BlenderDNA: Expected NAME field"); throw DeadlyImportError("BlenderDNA: Expected NAME field");
} }
std::vector<std::string> names (stream.GetI4()); std::vector<std::string> names (stream.GetI4());
for_each(std::string& s, names) { for_each(std::string& s, names) {
while (char c = stream.GetI1()) { while (char c = stream.GetI1()) {
s += c; s += c;
} }
} }
// type dictionary // type dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
if(!match4(stream,"TYPE")) { if(!match4(stream,"TYPE")) {
throw DeadlyImportError("BlenderDNA: Expected TYPE field"); throw DeadlyImportError("BlenderDNA: Expected TYPE field");
} }
std::vector<Type> types (stream.GetI4()); std::vector<Type> types (stream.GetI4());
for_each(Type& s, types) { for_each(Type& s, types) {
while (char c = stream.GetI1()) { while (char c = stream.GetI1()) {
s.name += c; s.name += c;
} }
} }
// type length dictionary // type length dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
if(!match4(stream,"TLEN")) { if(!match4(stream,"TLEN")) {
throw DeadlyImportError("BlenderDNA: Expected TLEN field"); throw DeadlyImportError("BlenderDNA: Expected TLEN field");
} }
for_each(Type& s, types) { for_each(Type& s, types) {
s.size = stream.GetI2(); s.size = stream.GetI2();
} }
// structures dictionary // structures dictionary
for (;stream.GetCurrentPos() & 0x3; stream.GetI1()); for (;stream.GetCurrentPos() & 0x3; stream.GetI1());
if(!match4(stream,"STRC")) { if(!match4(stream,"STRC")) {
throw DeadlyImportError("BlenderDNA: Expected STRC field"); throw DeadlyImportError("BlenderDNA: Expected STRC field");
} }
size_t end = stream.GetI4(), fields = 0; size_t end = stream.GetI4(), fields = 0;
dna.structures.reserve(end); dna.structures.reserve(end);
for(size_t i = 0; i != end; ++i) { for(size_t i = 0; i != end; ++i) {
uint16_t n = stream.GetI2(); uint16_t n = stream.GetI2();
if (n >= types.size()) { if (n >= types.size()) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Invalid type index in structure name" ,n, "BlenderDNA: Invalid type index in structure name" ,n,
" (there are only ", types.size(), " entries)" " (there are only ", types.size(), " entries)"
)); ));
} }
// maintain separate indexes // maintain separate indexes
dna.indices[types[n].name] = dna.structures.size(); dna.indices[types[n].name] = dna.structures.size();
dna.structures.push_back(Structure()); dna.structures.push_back(Structure());
Structure& s = dna.structures.back(); Structure& s = dna.structures.back();
s.name = types[n].name; s.name = types[n].name;
//s.index = dna.structures.size()-1; //s.index = dna.structures.size()-1;
n = stream.GetI2(); n = stream.GetI2();
s.fields.reserve(n); s.fields.reserve(n);
size_t offset = 0; size_t offset = 0;
for (size_t m = 0; m < n; ++m, ++fields) { for (size_t m = 0; m < n; ++m, ++fields) {
uint16_t j = stream.GetI2(); uint16_t j = stream.GetI2();
if (j >= types.size()) { if (j >= types.size()) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Invalid type index in structure field ", j, "BlenderDNA: Invalid type index in structure field ", j,
" (there are only ", types.size(), " entries)" " (there are only ", types.size(), " entries)"
)); ));
} }
s.fields.push_back(Field()); s.fields.push_back(Field());
Field& f = s.fields.back(); Field& f = s.fields.back();
f.offset = offset; f.offset = offset;
f.type = types[j].name; f.type = types[j].name;
f.size = types[j].size; f.size = types[j].size;
j = stream.GetI2(); j = stream.GetI2();
if (j >= names.size()) { if (j >= names.size()) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Invalid name index in structure field ", j, "BlenderDNA: Invalid name index in structure field ", j,
" (there are only ", names.size(), " entries)" " (there are only ", names.size(), " entries)"
)); ));
} }
f.name = names[j]; f.name = names[j];
f.flags = 0u; f.flags = 0u;
// pointers always specify the size of the pointee instead of their own. // pointers always specify the size of the pointee instead of their own.
// The pointer asterisk remains a property of the lookup name. // The pointer asterisk remains a property of the lookup name.
if (f.name[0] == '*') { if (f.name[0] == '*') {
f.size = db.i64bit ? 8 : 4; f.size = db.i64bit ? 8 : 4;
f.flags |= FieldFlag_Pointer; f.flags |= FieldFlag_Pointer;
} }
// arrays, however, specify the size of a single element so we // arrays, however, specify the size of a single element so we
// need to parse the (possibly multi-dimensional) array declaration // need to parse the (possibly multi-dimensional) array declaration
// in order to obtain the actual size of the array in the file. // in order to obtain the actual size of the array in the file.
// Also we need to alter the lookup name to include no array // Also we need to alter the lookup name to include no array
// brackets anymore or size fixup won't work (if our size does // brackets anymore or size fixup won't work (if our size does
// not match the size read from the DNA). // not match the size read from the DNA).
if (*f.name.rbegin() == ']') { if (*f.name.rbegin() == ']') {
const std::string::size_type rb = f.name.find('['); const std::string::size_type rb = f.name.find('[');
if (rb == std::string::npos) { if (rb == std::string::npos) {
throw DeadlyImportError((format(), throw DeadlyImportError((format(),
"BlenderDNA: Encountered invalid array declaration ", "BlenderDNA: Encountered invalid array declaration ",
f.name f.name
)); ));
} }
f.flags |= FieldFlag_Array; f.flags |= FieldFlag_Array;
DNA::ExtractArraySize(f.name,f.array_sizes); DNA::ExtractArraySize(f.name,f.array_sizes);
f.name = f.name.substr(0,rb); f.name = f.name.substr(0,rb);
f.size *= f.array_sizes[0] * f.array_sizes[1]; f.size *= f.array_sizes[0] * f.array_sizes[1];
} }
// maintain separate indexes // maintain separate indexes
s.indices[f.name] = s.fields.size()-1; s.indices[f.name] = s.fields.size()-1;
offset += f.size; offset += f.size;
} }
s.size = offset; s.size = offset;
} }
DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(), DefaultLogger::get()->debug((format(),"BlenderDNA: Got ",dna.structures.size(),
" structures with totally ",fields," fields")); " structures with totally ",fields," fields"));
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
dna.DumpToFile(); dna.DumpToFile();
#endif #endif
dna.AddPrimitiveStructures(); dna.AddPrimitiveStructures();
dna.RegisterConverters(); dna.RegisterConverters();
} }
#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. // we dont't bother using the VFS here for this is only for debugging.
// (and all your bases are belong to us). // (and all your bases are belong to us).
std::ofstream f("dna.txt"); std::ofstream f("dna.txt");
if (f.fail()) { if (f.fail()) {
DefaultLogger::get()->error("Could not dump dna to dna.txt"); DefaultLogger::get()->error("Could not dump dna to dna.txt");
return; return;
} }
f << "Field format: type name offset size" << "\n"; f << "Field format: type name offset size" << "\n";
f << "Structure format: name size" << "\n"; f << "Structure format: name size" << "\n";
for_each(const Structure& s, structures) { for_each(const Structure& s, structures) {
f << s.name << " " << s.size << "\n\n"; f << s.name << " " << s.size << "\n\n";
for_each(const Field& ff, s.fields) { for_each(const Field& ff, s.fields) {
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl; f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
} }
f << std::endl; f << std::endl;
} }
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt"); DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
} }
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
/*static*/ void DNA :: ExtractArraySize( /*static*/ void DNA :: ExtractArraySize(
const std::string& out, const std::string& out,
size_t array_sizes[2] size_t array_sizes[2]
) )
{ {
array_sizes[0] = array_sizes[1] = 1; array_sizes[0] = array_sizes[1] = 1;
std::string::size_type pos = out.find('['); std::string::size_type pos = out.find('[');
if (pos++ == std::string::npos) { if (pos++ == std::string::npos) {
return; return;
} }
array_sizes[0] = strtoul10(&out[pos]); array_sizes[0] = strtoul10(&out[pos]);
pos = out.find('[',pos); pos = out.find('[',pos);
if (pos++ == std::string::npos) { if (pos++ == std::string::npos) {
return; return;
} }
array_sizes[1] = strtoul10(&out[pos]); array_sizes[1] = strtoul10(&out[pos]);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure( boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
const Structure& structure, const Structure& structure,
const FileDatabase& db const FileDatabase& db
) const ) const
{ {
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name); std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
if (it == converters.end()) { if (it == converters.end()) {
return boost::shared_ptr< ElemBase >(); return boost::shared_ptr< ElemBase >();
} }
boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))(); boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
(structure.*((*it).second.second))(ret,db); (structure.*((*it).second.second))(ret,db);
return ret; return ret;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
DNA::FactoryPair DNA :: GetBlobToStructureConverter( DNA::FactoryPair DNA :: GetBlobToStructureConverter(
const Structure& structure, const Structure& structure,
const FileDatabase& /*db*/ const FileDatabase& /*db*/
) const ) const
{ {
std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name); std::map<std::string, FactoryPair>::const_iterator it = converters.find(structure.name);
return it == converters.end() ? FactoryPair() : (*it).second; return it == converters.end() ? FactoryPair() : (*it).second;
} }
// basing on http://www.blender.org/development/architecture/notes-on-sdna/ // basing on http://www.blender.org/development/architecture/notes-on-sdna/
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void DNA :: AddPrimitiveStructures() void DNA :: AddPrimitiveStructures()
{ {
// NOTE: these are just dummies. Their presence enforces // NOTE: these are just dummies. Their presence enforces
// Structure::Convert<target_type> to be called on these // Structure::Convert<target_type> to be called on these
// empty structures. These converters are special // empty structures. These converters are special
// overloads which scan the name of the structure and // overloads which scan the name of the structure and
// perform the required data type conversion if one // perform the required data type conversion if one
// of these special names is found in the structure // of these special names is found in the structure
// in question. // in question.
indices["int"] = structures.size(); indices["int"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "int"; structures.back().name = "int";
structures.back().size = 4; structures.back().size = 4;
indices["short"] = structures.size(); indices["short"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "short"; structures.back().name = "short";
structures.back().size = 2; structures.back().size = 2;
indices["char"] = structures.size(); indices["char"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "char"; structures.back().name = "char";
structures.back().size = 1; structures.back().size = 1;
indices["float"] = structures.size(); indices["float"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "float"; structures.back().name = "float";
structures.back().size = 4; structures.back().size = 4;
indices["double"] = structures.size(); indices["double"] = structures.size();
structures.push_back( Structure() ); structures.push_back( Structure() );
structures.back().name = "double"; structures.back().name = "double";
structures.back().size = 8; structures.back().size = 8;
// no long, seemingly. // no long, seemingly.
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void SectionParser :: Next() void SectionParser :: Next()
{ {
stream.SetCurrentPos(current.start + current.size); stream.SetCurrentPos(current.start + current.size);
const char tmp[] = { const char tmp[] = {
stream.GetI1(), stream.GetI1(),
stream.GetI1(), stream.GetI1(),
stream.GetI1(), stream.GetI1(),
stream.GetI1() stream.GetI1()
}; };
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1); current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
current.size = stream.GetI4(); current.size = stream.GetI4();
current.address.val = ptr64 ? stream.GetU8() : stream.GetU4(); current.address.val = ptr64 ? stream.GetU8() : stream.GetU4();
current.dna_index = stream.GetI4(); current.dna_index = stream.GetI4();
current.num = stream.GetI4(); current.num = stream.GetI4();
current.start = stream.GetCurrentPos(); current.start = stream.GetCurrentPos();
if (stream.GetRemainingSizeToLimit() < current.size) { if (stream.GetRemainingSizeToLimit() < current.size) {
throw DeadlyImportError("BLEND: invalid size of file block"); throw DeadlyImportError("BLEND: invalid size of file block");
} }
#ifdef ASSIMP_BUILD_BLENDER_DEBUG #ifdef ASSIMP_BUILD_BLENDER_DEBUG
DefaultLogger::get()->debug(current.id); DefaultLogger::get()->debug(current.id);
#endif #endif
} }
#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,204 +1,204 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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> #include <boost/foreach.hpp>
#include <deque> #include <deque>
#include "./../include/assimp/material.h" #include "./../include/assimp/material.h"
struct aiTexture; struct aiTexture;
#define for_each(x,y) BOOST_FOREACH(x,y) #define for_each(x,y) BOOST_FOREACH(x,y)
namespace Assimp { namespace Assimp {
namespace Blender { namespace Blender {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */ /** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
// -------------------------------------------------------------------- // --------------------------------------------------------------------
template <template <typename,typename> class TCLASS, typename T> template <template <typename,typename> class TCLASS, typename T>
struct TempArray { struct TempArray {
typedef TCLASS< T*,std::allocator<T*> > mywrap; typedef TCLASS< T*,std::allocator<T*> > mywrap;
TempArray() { TempArray() {
} }
~TempArray () { ~TempArray () {
for_each(T* elem, arr) { for_each(T* elem, arr) {
delete elem; delete elem;
} }
} }
void dismiss() { void dismiss() {
arr.clear(); arr.clear();
} }
mywrap* operator -> () { mywrap* operator -> () {
return &arr; return &arr;
} }
operator mywrap& () { operator mywrap& () {
return arr; return arr;
} }
operator const mywrap& () const { operator const mywrap& () const {
return arr; return arr;
} }
mywrap& get () { mywrap& get () {
return arr; return arr;
} }
const mywrap& get () const { const mywrap& get () const {
return arr; return arr;
} }
T* operator[] (size_t idx) const { T* operator[] (size_t idx) const {
return arr[idx]; return arr[idx];
} }
T*& operator[] (size_t idx) { T*& operator[] (size_t idx) {
return arr[idx]; return arr[idx];
} }
private: private:
// no copy semantics // no copy semantics
void operator= (const TempArray&) { void operator= (const TempArray&) {
} }
TempArray(const TempArray& arr) { TempArray(const TempArray& arr) {
} }
private: private:
mywrap arr; mywrap arr;
}; };
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(disable:4351) # pragma warning(disable:4351)
#endif #endif
struct ObjectCompare { struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const { bool operator() (const Object* left, const Object* right) const {
return strcmp(left->id.name, right->id.name) == -1; return strcmp(left->id.name, right->id.name) == -1;
} }
}; };
// When keeping objects in sets, sort them by their name. // When keeping objects in sets, sort them by their name.
typedef std::set<const Object*, ObjectCompare> ObjectSet; typedef std::set<const Object*, ObjectCompare> ObjectSet;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
/** ConversionData acts as intermediate storage location for /** ConversionData acts as intermediate storage location for
* the various ConvertXXX routines in BlenderImporter.*/ * the various ConvertXXX routines in BlenderImporter.*/
// -------------------------------------------------------------------- // --------------------------------------------------------------------
struct ConversionData struct ConversionData
{ {
ConversionData(const FileDatabase& db) ConversionData(const FileDatabase& db)
: sentinel_cnt() : sentinel_cnt()
, next_texture() , next_texture()
, db(db) , db(db)
{} {}
struct ObjectCompare { struct ObjectCompare {
bool operator() (const Object* left, const Object* right) const { bool operator() (const Object* left, const Object* right) const {
return strcmp(left->id.name, right->id.name) == -1; return strcmp(left->id.name, right->id.name) == -1;
} }
}; };
ObjectSet objects; ObjectSet objects;
TempArray <std::vector, aiMesh> meshes; TempArray <std::vector, aiMesh> meshes;
TempArray <std::vector, aiCamera> cameras; TempArray <std::vector, aiCamera> cameras;
TempArray <std::vector, aiLight> lights; TempArray <std::vector, aiLight> lights;
TempArray <std::vector, aiMaterial> materials; TempArray <std::vector, aiMaterial> materials;
TempArray <std::vector, aiTexture> textures; TempArray <std::vector, aiTexture> textures;
// set of all materials referenced by at least one mesh in the scene // set of all materials referenced by at least one mesh in the scene
std::deque< boost::shared_ptr< Material > > materials_raw; std::deque< boost::shared_ptr< Material > > materials_raw;
// counter to name sentinel textures inserted as substitutes for procedural textures. // counter to name sentinel textures inserted as substitutes for procedural textures.
unsigned int sentinel_cnt; unsigned int sentinel_cnt;
// next texture ID for each texture type, respectively // next texture ID for each texture type, respectively
unsigned int next_texture[aiTextureType_UNKNOWN+1]; unsigned int next_texture[aiTextureType_UNKNOWN+1];
// original file data // original file data
const FileDatabase& db; const FileDatabase& db;
}; };
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(default:4351) # pragma warning(default:4351)
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline const char* GetTextureTypeDisplayString(Tex::Type t) inline const char* GetTextureTypeDisplayString(Tex::Type t)
{ {
switch (t) { switch (t) {
case Tex::Type_CLOUDS : return "Clouds"; case Tex::Type_CLOUDS : return "Clouds";
case Tex::Type_WOOD : return "Wood"; case Tex::Type_WOOD : return "Wood";
case Tex::Type_MARBLE : return "Marble"; case Tex::Type_MARBLE : return "Marble";
case Tex::Type_MAGIC : return "Magic"; case Tex::Type_MAGIC : return "Magic";
case Tex::Type_BLEND : return "Blend"; case Tex::Type_BLEND : return "Blend";
case Tex::Type_STUCCI : return "Stucci"; case Tex::Type_STUCCI : return "Stucci";
case Tex::Type_NOISE : return "Noise"; case Tex::Type_NOISE : return "Noise";
case Tex::Type_PLUGIN : return "Plugin"; case Tex::Type_PLUGIN : return "Plugin";
case Tex::Type_MUSGRAVE : return "Musgrave"; case Tex::Type_MUSGRAVE : return "Musgrave";
case Tex::Type_VORONOI : return "Voronoi"; case Tex::Type_VORONOI : return "Voronoi";
case Tex::Type_DISTNOISE : return "DistortedNoise"; case Tex::Type_DISTNOISE : return "DistortedNoise";
case Tex::Type_ENVMAP : return "EnvMap"; case Tex::Type_ENVMAP : return "EnvMap";
case Tex::Type_IMAGE : return "Image"; case Tex::Type_IMAGE : return "Image";
default: default:
break; break;
} }
return "<Unknown>"; return "<Unknown>";
} }
} // ! Blender } // ! Blender
} // ! Assimp } // ! Assimp
#endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H #endif // ! INCLUDED_AI_BLEND_INTERMEDIATE_H

File diff suppressed because it is too large Load Diff

View File

@ -1,230 +1,230 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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> #include <boost/shared_ptr.hpp>
struct aiNode; struct aiNode;
struct aiMesh; struct aiMesh;
struct aiLight; struct aiLight;
struct aiCamera; struct aiCamera;
struct aiMaterial; struct aiMaterial;
namespace Assimp { namespace Assimp {
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} }
// BlenderDNA.h // BlenderDNA.h
namespace Blender { namespace Blender {
class FileDatabase; class FileDatabase;
struct ElemBase; struct ElemBase;
} }
// BlenderScene.h // BlenderScene.h
namespace Blender { namespace Blender {
struct Scene; struct Scene;
struct Object; struct Object;
struct Mesh; struct Mesh;
struct Camera; struct Camera;
struct Lamp; struct Lamp;
struct MTex; struct MTex;
struct Image; struct Image;
struct Material; struct Material;
} }
// BlenderIntermediate.h // BlenderIntermediate.h
namespace Blender { namespace Blender {
struct ConversionData; struct ConversionData;
template <template <typename,typename> class TCLASS, typename T> struct TempArray; template <template <typename,typename> class TCLASS, typename T> struct TempArray;
} }
// BlenderModifier.h // BlenderModifier.h
namespace Blender { namespace Blender {
class BlenderModifierShowcase; class BlenderModifierShowcase;
class BlenderModifier; class BlenderModifier;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Load blenders official binary format. The actual file structure (the `DNA` how they /** Load blenders official binary format. The actual file structure (the `DNA` how they
* call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the * call it is outsourced to BlenderDNA.cpp/BlenderDNA.h. This class only performs the
* conversion from intermediate format to aiScene. */ * conversion from intermediate format to aiScene. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter> class BlenderImporter : public BaseImporter, public LogFunctions<BlenderImporter>
{ {
public: public:
BlenderImporter(); BlenderImporter();
~BlenderImporter(); ~BlenderImporter();
public: public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, bool CanRead( const std::string& pFile,
IOSystem* pIOHandler, IOSystem* pIOHandler,
bool checkSig bool checkSig
) const; ) const;
protected: protected:
// -------------------- // --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// -------------------- // --------------------
void GetExtensionList(std::set<std::string>& app); void GetExtensionList(std::set<std::string>& app);
// -------------------- // --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// -------------------- // --------------------
void InternReadFile( const std::string& pFile, void InternReadFile( const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler IOSystem* pIOHandler
); );
// -------------------- // --------------------
void ParseBlendFile(Blender::FileDatabase& out, void ParseBlendFile(Blender::FileDatabase& out,
boost::shared_ptr<IOStream> stream boost::shared_ptr<IOStream> stream
); );
// -------------------- // --------------------
void ExtractScene(Blender::Scene& out, void ExtractScene(Blender::Scene& out,
const Blender::FileDatabase& file const Blender::FileDatabase& file
); );
// -------------------- // --------------------
void ConvertBlendFile(aiScene* out, void ConvertBlendFile(aiScene* out,
const Blender::Scene& in, const Blender::Scene& in,
const Blender::FileDatabase& file const Blender::FileDatabase& file
); );
private: private:
// -------------------- // --------------------
aiNode* ConvertNode(const Blender::Scene& in, aiNode* ConvertNode(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
Blender::ConversionData& conv_info, Blender::ConversionData& conv_info,
const aiMatrix4x4& parentTransform const aiMatrix4x4& parentTransform
); );
// -------------------- // --------------------
void ConvertMesh(const Blender::Scene& in, void ConvertMesh(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Mesh* mesh, const Blender::Mesh* mesh,
Blender::ConversionData& conv_data, Blender::ConversionData& conv_data,
Blender::TempArray<std::vector,aiMesh>& temp Blender::TempArray<std::vector,aiMesh>& temp
); );
// -------------------- // --------------------
aiLight* ConvertLight(const Blender::Scene& in, aiLight* ConvertLight(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Lamp* mesh, const Blender::Lamp* mesh,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
aiCamera* ConvertCamera(const Blender::Scene& in, aiCamera* ConvertCamera(const Blender::Scene& in,
const Blender::Object* obj, const Blender::Object* obj,
const Blender::Camera* mesh, const Blender::Camera* mesh,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
void BuildMaterials( void BuildMaterials(
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
) ; ) ;
// -------------------- // --------------------
void ResolveTexture( void ResolveTexture(
aiMaterial* out, aiMaterial* out,
const Blender::Material* mat, const Blender::Material* mat,
const Blender::MTex* tex, const Blender::MTex* tex,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
// -------------------- // --------------------
void ResolveImage( void ResolveImage(
aiMaterial* out, aiMaterial* out,
const Blender::Material* mat, const Blender::Material* mat,
const Blender::MTex* tex, const Blender::MTex* tex,
const Blender::Image* img, const Blender::Image* img,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
void AddSentinelTexture( void AddSentinelTexture(
aiMaterial* out, aiMaterial* out,
const Blender::Material* mat, const Blender::Material* mat,
const Blender::MTex* tex, const Blender::MTex* tex,
Blender::ConversionData& conv_data Blender::ConversionData& conv_data
); );
private: // static stuff, mostly logging and error reporting. private: // static stuff, mostly logging and error reporting.
// -------------------- // --------------------
static void CheckActualType(const Blender::ElemBase* dt, static void CheckActualType(const Blender::ElemBase* dt,
const char* check const char* check
); );
// -------------------- // --------------------
static void NotSupportedObjectType(const Blender::Object* obj, static void NotSupportedObjectType(const Blender::Object* obj,
const char* type const char* type
); );
private: private:
Blender::BlenderModifierShowcase* modifier_cache; Blender::BlenderModifierShowcase* modifier_cache;
}; // !class BlenderImporter }; // !class BlenderImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC #endif // AI_UNREALIMPORTER_H_INC

View File

@ -1,328 +1,328 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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).
*/ */
#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 "../include/assimp/scene.h"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp> #include <boost/scoped_array.hpp>
#include <boost/pointer_cast.hpp> #include <boost/pointer_cast.hpp>
#include <functional> #include <functional>
using namespace Assimp; using namespace Assimp;
using namespace Assimp::Blender; using namespace Assimp::Blender;
template <typename T> BlenderModifier* god() { template <typename T> BlenderModifier* god() {
return new T(); return new T();
} }
// add all available modifiers here // add all available modifiers here
typedef BlenderModifier* (*fpCreateModifier)(); typedef BlenderModifier* (*fpCreateModifier)();
static const fpCreateModifier creators[] = { static const fpCreateModifier creators[] = {
&god<BlenderModifier_Mirror>, &god<BlenderModifier_Mirror>,
&god<BlenderModifier_Subdivision>, &god<BlenderModifier_Subdivision>,
NULL // sentinel NULL // sentinel
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// just testing out some new macros to simplify logging // just testing out some new macros to simplify logging
#define ASSIMP_LOG_WARN_F(string,...)\ #define ASSIMP_LOG_WARN_F(string,...)\
DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->warn((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_ERROR_F(string,...)\ #define ASSIMP_LOG_ERROR_F(string,...)\
DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->error((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_DEBUG_F(string,...)\ #define ASSIMP_LOG_DEBUG_F(string,...)\
DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->debug((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_INFO_F(string,...)\ #define ASSIMP_LOG_INFO_F(string,...)\
DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__)) DefaultLogger::get()->info((Formatter::format(string),__VA_ARGS__))
#define ASSIMP_LOG_WARN(string)\ #define ASSIMP_LOG_WARN(string)\
DefaultLogger::get()->warn(string) DefaultLogger::get()->warn(string)
#define ASSIMP_LOG_ERROR(string)\ #define ASSIMP_LOG_ERROR(string)\
DefaultLogger::get()->error(string) DefaultLogger::get()->error(string)
#define ASSIMP_LOG_DEBUG(string)\ #define ASSIMP_LOG_DEBUG(string)\
DefaultLogger::get()->debug(string) DefaultLogger::get()->debug(string)
#define ASSIMP_LOG_INFO(string)\ #define ASSIMP_LOG_INFO(string)\
DefaultLogger::get()->info(string) DefaultLogger::get()->info(string)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
struct SharedModifierData : ElemBase struct SharedModifierData : ElemBase
{ {
ModifierData modifier; ModifierData modifier;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object ) void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_data, const Scene& in, const Object& orig_object )
{ {
size_t cnt = 0u, ful = 0u; size_t cnt = 0u, ful = 0u;
// NOTE: this cast is potentially unsafe by design, so we need to perform type checks before // NOTE: this cast is potentially unsafe by design, so we need to perform type checks before
// we're allowed to dereference the pointers without risking to crash. We might still be // we're allowed to dereference the pointers without risking to crash. We might still be
// invoking UB btw - we're assuming that the ModifierData member of the respective modifier // invoking UB btw - we're assuming that the ModifierData member of the respective modifier
// structures is at offset sizeof(vftable) with no padding. // structures is at offset sizeof(vftable) with no padding.
const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() ); const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) { for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
ai_assert(cur->dna_type); ai_assert(cur->dna_type);
const Structure* s = conv_data.db.dna.Get( cur->dna_type ); const Structure* s = conv_data.db.dna.Get( cur->dna_type );
if (!s) { if (!s) {
ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type); ASSIMP_LOG_WARN_F("BlendModifier: could not resolve DNA name: ",cur->dna_type);
continue; continue;
} }
// this is a common trait of all XXXMirrorData structures in BlenderDNA // this is a common trait of all XXXMirrorData structures in BlenderDNA
const Field* f = s->Get("modifier"); const Field* f = s->Get("modifier");
if (!f || f->offset != 0) { if (!f || f->offset != 0) {
ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0"); ASSIMP_LOG_WARN("BlendModifier: expected a `modifier` member at offset 0");
continue; continue;
} }
s = conv_data.db.dna.Get( f->type ); s = conv_data.db.dna.Get( f->type );
if (!s || s->name != "ModifierData") { if (!s || s->name != "ModifierData") {
ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member"); ASSIMP_LOG_WARN("BlendModifier: expected a ModifierData structure as first member");
continue; continue;
} }
// now, we can be sure that we should be fine to dereference *cur* as // now, we can be sure that we should be fine to dereference *cur* as
// ModifierData (with the above note). // ModifierData (with the above note).
const ModifierData& dat = cur->modifier; const ModifierData& dat = cur->modifier;
const fpCreateModifier* curgod = creators; const fpCreateModifier* curgod = creators;
std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end(); std::vector< BlenderModifier* >::iterator curmod = cached_modifiers->begin(), endmod = cached_modifiers->end();
for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly for (;*curgod;++curgod,++curmod) { // allocate modifiers on the fly
if (curmod == endmod) { if (curmod == endmod) {
cached_modifiers->push_back((*curgod)()); cached_modifiers->push_back((*curgod)());
endmod = cached_modifiers->end(); endmod = cached_modifiers->end();
curmod = endmod-1; curmod = endmod-1;
} }
BlenderModifier* const modifier = *curmod; BlenderModifier* const modifier = *curmod;
if(modifier->IsActive(dat)) { if(modifier->IsActive(dat)) {
modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object); modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
cnt++; cnt++;
curgod = NULL; curgod = NULL;
break; break;
} }
} }
if (curgod) { if (curgod) {
ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name); ASSIMP_LOG_WARN_F("Couldn't find a handler for modifier: ",dat.name);
} }
} }
// Even though we managed to resolve some or all of the modifiers on this // Even though we managed to resolve some or all of the modifiers on this
// object, we still can't say whether our modifier implementations were // object, we still can't say whether our modifier implementations were
// able to fully do their job. // able to fully do their job.
if (ful) { if (ful) {
ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name, ASSIMP_LOG_DEBUG_F("BlendModifier: found handlers for ",cnt," of ",ful," modifiers on `",orig_object.id.name,
"`, check log messages above for errors"); "`, check log messages above for errors");
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin) bool BlenderModifier_Mirror :: IsActive (const ModifierData& modin)
{ {
return modin.type == ModifierData::eModifierType_Mirror; return modin.type == ModifierData::eModifierType_Mirror;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier, void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
const Scene& /*in*/, const Scene& /*in*/,
const Object& orig_object ) const Object& orig_object )
{ {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier); const MirrorModifierData& mir = static_cast<const MirrorModifierData&>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror); ai_assert(mir.modifier.type == ModifierData::eModifierType_Mirror);
conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes); conv_data.meshes->reserve(conv_data.meshes->size() + out.mNumMeshes);
// XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ... // XXX not entirely correct, mirroring on two axes results in 4 distinct objects in blender ...
// take all input meshes and clone them // take all input meshes and clone them
for (unsigned int i = 0; i < out.mNumMeshes; ++i) { for (unsigned int i = 0; i < out.mNumMeshes; ++i) {
aiMesh* mesh; aiMesh* mesh;
SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]); SceneCombiner::Copy(&mesh,conv_data.meshes[out.mMeshes[i]]);
const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f; const float xs = mir.flag & MirrorModifierData::Flags_AXIS_X ? -1.f : 1.f;
const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f; const float ys = mir.flag & MirrorModifierData::Flags_AXIS_Y ? -1.f : 1.f;
const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f; const float zs = mir.flag & MirrorModifierData::Flags_AXIS_Z ? -1.f : 1.f;
if (mir.mirror_ob) { if (mir.mirror_ob) {
const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] ); const aiVector3D center( mir.mirror_ob->obmat[3][0],mir.mirror_ob->obmat[3][1],mir.mirror_ob->obmat[3][2] );
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i]; aiVector3D& v = mesh->mVertices[i];
v.x = center.x + xs*(center.x - v.x); v.x = center.x + xs*(center.x - v.x);
v.y = center.y + ys*(center.y - v.y); v.y = center.y + ys*(center.y - v.y);
v.z = center.z + zs*(center.z - v.z); v.z = center.z + zs*(center.z - v.z);
} }
} }
else { else {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mVertices[i]; aiVector3D& v = mesh->mVertices[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
if (mesh->mNormals) { if (mesh->mNormals) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mNormals[i]; aiVector3D& v = mesh->mNormals[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
if (mesh->mTangents) { if (mesh->mTangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTangents[i]; aiVector3D& v = mesh->mTangents[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
if (mesh->mBitangents) { if (mesh->mBitangents) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mBitangents[i]; aiVector3D& v = mesh->mBitangents[i];
v.x *= xs;v.y *= ys;v.z *= zs; v.x *= xs;v.y *= ys;v.z *= zs;
} }
} }
const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f; const float us = mir.flag & MirrorModifierData::Flags_MIRROR_U ? -1.f : 1.f;
const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f; const float vs = mir.flag & MirrorModifierData::Flags_MIRROR_V ? -1.f : 1.f;
for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) { for (unsigned int n = 0; mesh->HasTextureCoords(n); ++n) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
aiVector3D& v = mesh->mTextureCoords[n][i]; aiVector3D& v = mesh->mTextureCoords[n][i];
v.x *= us;v.y *= vs; v.x *= us;v.y *= vs;
} }
} }
// Only reverse the winding order if an odd number of axes were mirrored. // Only reverse the winding order if an odd number of axes were mirrored.
if (xs * ys * zs < 0) { if (xs * ys * zs < 0) {
for( unsigned int i = 0; i < mesh->mNumFaces; i++) { for( unsigned int i = 0; i < mesh->mNumFaces; i++) {
aiFace& face = mesh->mFaces[i]; aiFace& face = mesh->mFaces[i];
for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi) for( unsigned int fi = 0; fi < face.mNumIndices / 2; ++fi)
std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]); std::swap( face.mIndices[fi], face.mIndices[face.mNumIndices - 1 - fi]);
} }
} }
conv_data.meshes->push_back(mesh); conv_data.meshes->push_back(mesh);
} }
unsigned int* nind = new unsigned int[out.mNumMeshes*2]; unsigned int* nind = new unsigned int[out.mNumMeshes*2];
std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind); std::copy(out.mMeshes,out.mMeshes+out.mNumMeshes,nind);
std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes, std::transform(out.mMeshes,out.mMeshes+out.mNumMeshes,nind+out.mNumMeshes,
std::bind1st(std::plus< unsigned int >(),out.mNumMeshes)); std::bind1st(std::plus< unsigned int >(),out.mNumMeshes));
delete[] out.mMeshes; delete[] out.mMeshes;
out.mMeshes = nind; out.mMeshes = nind;
out.mNumMeshes *= 2; out.mNumMeshes *= 2;
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `", ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Mirror` modifier to `",
orig_object.id.name,"`"); orig_object.id.name,"`");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin) bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
{ {
return modin.type == ModifierData::eModifierType_Subsurf; return modin.type == ModifierData::eModifierType_Subsurf;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier, void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data, const ElemBase& orig_modifier,
const Scene& /*in*/, const Scene& /*in*/,
const Object& orig_object ) const Object& orig_object )
{ {
// hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers() // hijacking the ABI, see the big note in BlenderModifierShowcase::ApplyModifiers()
const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier); const SubsurfModifierData& mir = static_cast<const SubsurfModifierData&>(orig_modifier);
ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf); ai_assert(mir.modifier.type == ModifierData::eModifierType_Subsurf);
Subdivider::Algorithm algo; Subdivider::Algorithm algo;
switch (mir.subdivType) switch (mir.subdivType)
{ {
case SubsurfModifierData::TYPE_CatmullClarke: case SubsurfModifierData::TYPE_CatmullClarke:
algo = Subdivider::CATMULL_CLARKE; algo = Subdivider::CATMULL_CLARKE;
break; break;
case SubsurfModifierData::TYPE_Simple: case SubsurfModifierData::TYPE_Simple:
ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke"); ASSIMP_LOG_WARN("BlendModifier: The `SIMPLE` subdivision algorithm is not currently implemented, using Catmull-Clarke");
algo = Subdivider::CATMULL_CLARKE; algo = Subdivider::CATMULL_CLARKE;
break; break;
default: default:
ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType); ASSIMP_LOG_WARN_F("BlendModifier: Unrecognized subdivision algorithm: ",mir.subdivType);
return; return;
}; };
boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo)); boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
ai_assert(subd); ai_assert(subd);
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes]; aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]()); boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true); subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes); std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `", ASSIMP_LOG_INFO_F("BlendModifier: Applied the `Subdivision` modifier to `",
orig_object.id.name,"`"); orig_object.id.name,"`");
} }
#endif #endif

View File

@ -1,155 +1,155 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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,256 +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
#include "BlenderDNA.h" #include "BlenderDNA.h"
#include "BlenderScene.h" #include "BlenderScene.h"
namespace Assimp { namespace Assimp {
namespace Blender { namespace Blender {
template <> void Structure :: Convert<Object> ( template <> void Structure :: Convert<Object> (
Object& dest, Object& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Group> ( template <> void Structure :: Convert<Group> (
Group& dest, Group& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MTex> ( template <> void Structure :: Convert<MTex> (
MTex& dest, MTex& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<TFace> ( template <> void Structure :: Convert<TFace> (
TFace& dest, TFace& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<SubsurfModifierData> ( template <> void Structure :: Convert<SubsurfModifierData> (
SubsurfModifierData& dest, SubsurfModifierData& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MFace> ( template <> void Structure :: Convert<MFace> (
MFace& dest, MFace& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Lamp> ( template <> void Structure :: Convert<Lamp> (
Lamp& dest, Lamp& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MDeformWeight> ( template <> void Structure :: Convert<MDeformWeight> (
MDeformWeight& dest, MDeformWeight& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<PackedFile> ( template <> void Structure :: Convert<PackedFile> (
PackedFile& dest, PackedFile& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Base> ( template <> void Structure :: Convert<Base> (
Base& dest, Base& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MTFace> ( template <> void Structure :: Convert<MTFace> (
MTFace& dest, MTFace& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Material> ( template <> void Structure :: Convert<Material> (
Material& dest, Material& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MTexPoly> ( template <> void Structure :: Convert<MTexPoly> (
MTexPoly& dest, MTexPoly& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Mesh> ( template <> void Structure :: Convert<Mesh> (
Mesh& dest, Mesh& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MDeformVert> ( template <> void Structure :: Convert<MDeformVert> (
MDeformVert& dest, MDeformVert& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<World> ( template <> void Structure :: Convert<World> (
World& dest, World& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MLoopCol> ( template <> void Structure :: Convert<MLoopCol> (
MLoopCol& dest, MLoopCol& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MVert> ( template <> void Structure :: Convert<MVert> (
MVert& dest, MVert& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MEdge> ( template <> void Structure :: Convert<MEdge> (
MEdge& dest, MEdge& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MLoopUV> ( template <> void Structure :: Convert<MLoopUV> (
MLoopUV& dest, MLoopUV& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<GroupObject> ( template <> void Structure :: Convert<GroupObject> (
GroupObject& dest, GroupObject& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<ListBase> ( template <> void Structure :: Convert<ListBase> (
ListBase& dest, ListBase& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MLoop> ( template <> void Structure :: Convert<MLoop> (
MLoop& dest, MLoop& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<ModifierData> ( template <> void Structure :: Convert<ModifierData> (
ModifierData& dest, ModifierData& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<ID> ( template <> void Structure :: Convert<ID> (
ID& dest, ID& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MCol> ( template <> void Structure :: Convert<MCol> (
MCol& dest, MCol& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MPoly> ( template <> void Structure :: Convert<MPoly> (
MPoly& dest, MPoly& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Scene> ( template <> void Structure :: Convert<Scene> (
Scene& dest, Scene& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Library> ( template <> void Structure :: Convert<Library> (
Library& dest, Library& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Tex> ( template <> void Structure :: Convert<Tex> (
Tex& dest, Tex& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Camera> ( template <> void Structure :: Convert<Camera> (
Camera& dest, Camera& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<MirrorModifierData> ( template <> void Structure :: Convert<MirrorModifierData> (
MirrorModifierData& dest, MirrorModifierData& dest,
const FileDatabase& db const FileDatabase& db
) const ) const
; ;
template <> void Structure :: Convert<Image> ( template <> void Structure :: Convert<Image> (
Image& dest, Image& dest,
const FileDatabase& db const FileDatabase& db
) const ) 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -56,7 +56,7 @@ static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
namspace Assimp namspace Assimp
{ {
template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: "; template< > const std::string LogFunctions< BlenderTessellatorGL >::log_prefix = "BLEND_TESS_GL: ";
} }
using namespace Assimp; using namespace Assimp;
@ -68,7 +68,7 @@ using namespace Assimp::Blender;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ): BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
converter( &converter ) converter( &converter )
{ {
} }
@ -80,167 +80,167 @@ BlenderTessellatorGL::~BlenderTessellatorGL( )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices ) void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
{ {
AssertVertexCount( vertexCount ); AssertVertexCount( vertexCount );
std::vector< VertexGL > polyLoopGL; std::vector< VertexGL > polyLoopGL;
GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices ); GenerateLoopVerts( polyLoopGL, polyLoop, vertexCount, vertices );
TessDataGL tessData; TessDataGL tessData;
Tesssellate( polyLoopGL, tessData ); Tesssellate( polyLoopGL, tessData );
TriangulateDrawCalls( tessData ); TriangulateDrawCalls( tessData );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::AssertVertexCount( int vertexCount ) void BlenderTessellatorGL::AssertVertexCount( int vertexCount )
{ {
if ( vertexCount <= 4 ) if ( vertexCount <= 4 )
{ {
ThrowException( "Expected more than 4 vertices for tessellation" ); ThrowException( "Expected more than 4 vertices for tessellation" );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices ) void BlenderTessellatorGL::GenerateLoopVerts( std::vector< VertexGL >& polyLoopGL, const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
{ {
for ( int i = 0; i < vertexCount; ++i ) for ( int i = 0; i < vertexCount; ++i )
{ {
const MLoop& loopItem = polyLoop[ i ]; const MLoop& loopItem = polyLoop[ i ];
const MVert& vertex = vertices[ loopItem.v ]; const MVert& vertex = vertices[ loopItem.v ];
polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) ); polyLoopGL.push_back( VertexGL( vertex.co[ 0 ], vertex.co[ 1 ], vertex.co[ 2 ], loopItem.v, BLEND_TESS_MAGIC ) );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData ) void BlenderTessellatorGL::Tesssellate( std::vector< VertexGL >& polyLoopGL, TessDataGL& tessData )
{ {
GLUtesselator* tessellator = gluNewTess( ); GLUtesselator* tessellator = gluNewTess( );
gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) ); gluTessCallback( tessellator, GLU_TESS_BEGIN_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateBegin ) );
gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) ); gluTessCallback( tessellator, GLU_TESS_END_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEnd ) );
gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) ); gluTessCallback( tessellator, GLU_TESS_VERTEX_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateVertex ) );
gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) ); gluTessCallback( tessellator, GLU_TESS_COMBINE_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateCombine ) );
gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) ); gluTessCallback( tessellator, GLU_TESS_EDGE_FLAG_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateEdgeFlag ) );
gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) ); gluTessCallback( tessellator, GLU_TESS_ERROR_DATA, reinterpret_cast< void ( CALLBACK * )( ) >( TessellateError ) );
gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO ); gluTessProperty( tessellator, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO );
gluTessBeginPolygon( tessellator, &tessData ); gluTessBeginPolygon( tessellator, &tessData );
gluTessBeginContour( tessellator ); gluTessBeginContour( tessellator );
for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i ) for ( unsigned int i = 0; i < polyLoopGL.size( ); ++i )
{ {
gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] ); gluTessVertex( tessellator, reinterpret_cast< GLdouble* >( &polyLoopGL[ i ] ), &polyLoopGL[ i ] );
} }
gluTessEndContour( tessellator ); gluTessEndContour( tessellator );
gluTessEndPolygon( tessellator ); gluTessEndPolygon( tessellator );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData ) void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
{ {
// NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically // NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
// need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case // need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
// GLU tessellate changes or tristrips and fans are wanted. // GLU tessellate changes or tristrips and fans are wanted.
// See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml // See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i ) for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
{ {
const DrawCallGL& drawCallGL = tessData.drawCalls[ i ]; const DrawCallGL& drawCallGL = tessData.drawCalls[ i ];
const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ]; const VertexGL* vertices = &tessData.vertices[ drawCallGL.baseVertex ];
if ( drawCallGL.drawMode == GL_TRIANGLES ) if ( drawCallGL.drawMode == GL_TRIANGLES )
{ {
MakeFacesFromTris( vertices, drawCallGL.vertexCount ); MakeFacesFromTris( vertices, drawCallGL.vertexCount );
} }
else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP ) else if ( drawCallGL.drawMode == GL_TRIANGLE_STRIP )
{ {
MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount ); MakeFacesFromTriStrip( vertices, drawCallGL.vertexCount );
} }
else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN ) else if ( drawCallGL.drawMode == GL_TRIANGLE_FAN )
{ {
MakeFacesFromTriFan( vertices, drawCallGL.vertexCount ); MakeFacesFromTriFan( vertices, drawCallGL.vertexCount );
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount ) void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
{ {
int triangleCount = vertexCount / 3; int triangleCount = vertexCount / 3;
for ( int i = 0; i < triangleCount; ++i ) for ( int i = 0; i < triangleCount; ++i )
{ {
int vertexBase = i * 3; int vertexBase = i * 3;
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index ); converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount ) void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
{ {
int triangleCount = vertexCount - 2; int triangleCount = vertexCount - 2;
for ( int i = 0; i < triangleCount; ++i ) for ( int i = 0; i < triangleCount; ++i )
{ {
int vertexBase = i; int vertexBase = i;
converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index ); converter->AddFace( vertices[ vertexBase + 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount ) void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
{ {
int triangleCount = vertexCount - 2; int triangleCount = vertexCount - 2;
for ( int i = 0; i < triangleCount; ++i ) for ( int i = 0; i < triangleCount; ++i )
{ {
int vertexBase = i; int vertexBase = i;
converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index ); converter->AddFace( vertices[ 0 ].index, vertices[ vertexBase + 1 ].index, vertices[ vertexBase + 2 ].index );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData ) void BlenderTessellatorGL::TessellateBegin( GLenum drawModeGL, void* userData )
{ {
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData ); TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) ); tessData.drawCalls.push_back( DrawCallGL( drawModeGL, tessData.vertices.size( ) ) );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TessellateEnd( void* ) void BlenderTessellatorGL::TessellateEnd( void* )
{ {
// Do nothing // Do nothing
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData ) void BlenderTessellatorGL::TessellateVertex( const void* vtxData, void* userData )
{ {
TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData ); TessDataGL& tessData = *reinterpret_cast< TessDataGL* >( userData );
const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData ); const VertexGL& vertex = *reinterpret_cast< const VertexGL* >( vtxData );
if ( vertex.magic != BLEND_TESS_MAGIC ) if ( vertex.magic != BLEND_TESS_MAGIC )
{ {
ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" ); ThrowException( "Point returned by GLU Tessellate was probably not one of ours. This indicates we need a new way to store vertex information" );
} }
tessData.vertices.push_back( vertex ); tessData.vertices.push_back( vertex );
if ( tessData.drawCalls.size( ) == 0 ) if ( tessData.drawCalls.size( ) == 0 )
{ {
ThrowException( "\"Vertex\" callback received before \"Begin\"" ); ThrowException( "\"Vertex\" callback received before \"Begin\"" );
} }
++( tessData.drawCalls.back( ).vertexCount ); ++( tessData.drawCalls.back( ).vertexCount );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData ) void BlenderTessellatorGL::TessellateCombine( const GLdouble intersection[ 3 ], const GLdouble* [ 4 ], const GLfloat [ 4 ], GLdouble** out, void* userData )
{ {
ThrowException( "Intersected polygon loops are not yet supported" ); ThrowException( "Intersected polygon loops are not yet supported" );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* ) void BlenderTessellatorGL::TessellateEdgeFlag( GLboolean, void* )
{ {
// Do nothing // Do nothing
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* ) void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
{ {
ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) ); ThrowException( reinterpret_cast< const char* >( gluErrorString( errorCode ) ) );
} }
#endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE #endif // ASSIMP_BLEND_WITH_GLU_TESSELLATE
@ -249,7 +249,7 @@ void BlenderTessellatorGL::TessellateError( GLenum errorCode, void* )
namespace Assimp namespace Assimp
{ {
template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: "; template< > const std::string LogFunctions< BlenderTessellatorP2T >::log_prefix = "BLEND_TESS_P2T: ";
} }
using namespace Assimp; using namespace Assimp;
@ -257,7 +257,7 @@ using namespace Assimp::Blender;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ): BlenderTessellatorP2T::BlenderTessellatorP2T( BlenderBMeshConverter& converter ):
converter( &converter ) converter( &converter )
{ {
} }
@ -269,178 +269,178 @@ BlenderTessellatorP2T::~BlenderTessellatorP2T( )
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices ) void BlenderTessellatorP2T::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
{ {
AssertVertexCount( vertexCount ); AssertVertexCount( vertexCount );
// NOTE - We have to hope that points in a Blender polygon are roughly on the same plane. // NOTE - We have to hope that points in a Blender polygon are roughly on the same plane.
// There may be some triangulation artifacts if they are wildly different. // There may be some triangulation artifacts if they are wildly different.
std::vector< PointP2T > points; std::vector< PointP2T > points;
Copy3DVertices( polyLoop, vertexCount, vertices, points ); Copy3DVertices( polyLoop, vertexCount, vertices, points );
PlaneP2T plane = FindLLSQPlane( points ); PlaneP2T plane = FindLLSQPlane( points );
aiMatrix4x4 transform = GeneratePointTransformMatrix( plane ); aiMatrix4x4 transform = GeneratePointTransformMatrix( plane );
TransformAndFlattenVectices( transform, points ); TransformAndFlattenVectices( transform, points );
std::vector< p2t::Point* > pointRefs; std::vector< p2t::Point* > pointRefs;
ReferencePoints( points, pointRefs ); ReferencePoints( points, pointRefs );
p2t::CDT cdt( pointRefs ); p2t::CDT cdt( pointRefs );
cdt.Triangulate( ); cdt.Triangulate( );
std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( ); std::vector< p2t::Triangle* > triangles = cdt.GetTriangles( );
MakeFacesFromTriangles( triangles ); MakeFacesFromTriangles( triangles );
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::AssertVertexCount( int vertexCount ) void BlenderTessellatorP2T::AssertVertexCount( int vertexCount )
{ {
if ( vertexCount <= 4 ) if ( vertexCount <= 4 )
{ {
ThrowException( "Expected more than 4 vertices for tessellation" ); ThrowException( "Expected more than 4 vertices for tessellation" );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices, std::vector< PointP2T >& points ) const
{ {
points.resize( vertexCount ); points.resize( vertexCount );
for ( int i = 0; i < vertexCount; ++i ) for ( int i = 0; i < vertexCount; ++i )
{ {
const MLoop& loop = polyLoop[ i ]; const MLoop& loop = polyLoop[ i ];
const MVert& vert = vertices[ loop.v ]; const MVert& vert = vertices[ loop.v ];
PointP2T& point = points[ i ]; PointP2T& point = points[ i ];
point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] ); point.point3D.Set( vert.co[ 0 ], vert.co[ 1 ], vert.co[ 2 ] );
point.index = loop.v; point.index = loop.v;
point.magic = BLEND_TESS_MAGIC; point.magic = BLEND_TESS_MAGIC;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
{ {
aiVector3D sideA( 1.0f, 0.0f, 0.0f ); aiVector3D sideA( 1.0f, 0.0f, 0.0f );
if ( std::fabs( plane.normal * sideA ) > 0.999f ) if ( std::fabs( plane.normal * sideA ) > 0.999f )
{ {
sideA = aiVector3D( 0.0f, 1.0f, 0.0f ); sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
} }
aiVector3D sideB( plane.normal ^ sideA ); aiVector3D sideB( plane.normal ^ sideA );
sideB.Normalize( ); sideB.Normalize( );
sideA = sideB ^ plane.normal; sideA = sideB ^ plane.normal;
aiMatrix4x4 result; aiMatrix4x4 result;
result.a1 = sideA.x; result.a1 = sideA.x;
result.a2 = sideA.y; result.a2 = sideA.y;
result.a3 = sideA.z; result.a3 = sideA.z;
result.b1 = sideB.x; result.b1 = sideB.x;
result.b2 = sideB.y; result.b2 = sideB.y;
result.b3 = sideB.z; result.b3 = sideB.z;
result.c1 = plane.normal.x; result.c1 = plane.normal.x;
result.c2 = plane.normal.y; result.c2 = plane.normal.y;
result.c3 = plane.normal.z; result.c3 = plane.normal.z;
result.a4 = plane.centre.x; result.a4 = plane.centre.x;
result.b4 = plane.centre.y; result.b4 = plane.centre.y;
result.c4 = plane.centre.z; result.c4 = plane.centre.z;
result.Inverse( ); result.Inverse( );
return result; return result;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
{ {
for ( unsigned int i = 0; i < vertices.size( ); ++i ) for ( unsigned int i = 0; i < vertices.size( ); ++i )
{ {
PointP2T& point = vertices[ i ]; PointP2T& point = vertices[ i ];
point.point3D = transform * point.point3D; point.point3D = transform * point.point3D;
point.point2D.set( point.point3D.y, point.point3D.z ); point.point2D.set( point.point3D.y, point.point3D.z );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
{ {
pointRefs.resize( points.size( ) ); pointRefs.resize( points.size( ) );
for ( unsigned int i = 0; i < points.size( ); ++i ) for ( unsigned int i = 0; i < points.size( ); ++i )
{ {
pointRefs[ i ] = &points[ i ].point2D; pointRefs[ i ] = &points[ i ].point2D;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Yes this is filthy... but we have no choice // Yes this is filthy... but we have no choice
#define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \ #define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \
reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \ reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \
static_cast<uint8_t*>(NULL) ) ) static_cast<uint8_t*>(NULL) ) )
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
{ {
unsigned int pointOffset = OffsetOf( PointP2T, point2D ); unsigned int pointOffset = OffsetOf( PointP2T, point2D );
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset ); PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) ) if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
{ {
ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" ); ThrowException( "Point returned by poly2tri was probably not one of ours. This indicates we need a new way to store vertex information" );
} }
return pointStruct; return pointStruct;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
{ {
for ( unsigned int i = 0; i < triangles.size( ); ++i ) for ( unsigned int i = 0; i < triangles.size( ); ++i )
{ {
p2t::Triangle& Triangle = *triangles[ i ]; p2t::Triangle& Triangle = *triangles[ i ];
PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) ); PointP2T& pointA = GetActualPointStructure( *Triangle.GetPoint( 0 ) );
PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) ); PointP2T& pointB = GetActualPointStructure( *Triangle.GetPoint( 1 ) );
PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) ); PointP2T& pointC = GetActualPointStructure( *Triangle.GetPoint( 2 ) );
converter->AddFace( pointA.index, pointB.index, pointC.index ); converter->AddFace( pointA.index, pointB.index, pointC.index );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
inline float p2tMax( float a, float b ) inline float p2tMax( float a, float b )
{ {
return a > b ? a : b; return a > b ? a : b;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html // Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) const
{ {
float result = 0.0f; float result = 0.0f;
for ( int x = 0; x < 3; ++x ) for ( int x = 0; x < 3; ++x )
{ {
for ( int y = 0; y < 3; ++y ) for ( int y = 0; y < 3; ++y )
{ {
result = p2tMax( std::fabs( mtx[ x ][ y ] ), result ); result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
} }
} }
return result; return result;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Aparently Assimp doesn't have matrix scaling // Aparently Assimp doesn't have matrix scaling
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
{ {
aiMatrix3x3 result; aiMatrix3x3 result;
for ( int x = 0; x < 3; ++x ) for ( int x = 0; x < 3; ++x )
{ {
for ( int y = 0; y < 3; ++y ) for ( int y = 0; y < 3; ++y )
{ {
result[ x ][ y ] = mtx[ x ][ y ] * scale; result[ x ][ y ] = mtx[ x ][ y ] * scale;
} }
} }
return result; return result;
} }
@ -448,70 +448,70 @@ aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float sc
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html // Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
{ {
float scale = FindLargestMatrixElem( mtx ); float scale = FindLargestMatrixElem( mtx );
aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale ); aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
mc = mc * mc * mc; mc = mc * mc * mc;
aiVector3D v( 1.0f ); aiVector3D v( 1.0f );
aiVector3D lastV = v; aiVector3D lastV = v;
for ( int i = 0; i < 100; ++i ) for ( int i = 0; i < 100; ++i )
{ {
v = mc * v; v = mc * v;
v.Normalize( ); v.Normalize( );
if ( ( v - lastV ).SquareLength( ) < 1e-16f ) if ( ( v - lastV ).SquareLength( ) < 1e-16f )
{ {
break; break;
} }
lastV = v; lastV = v;
} }
return v; return v;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html // Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& points ) const
{ {
PlaneP2T result; PlaneP2T result;
aiVector3D sum( 0.0f ); aiVector3D sum( 0.0f );
for ( unsigned int i = 0; i < points.size( ); ++i ) for ( unsigned int i = 0; i < points.size( ); ++i )
{ {
sum += points[ i ].point3D; sum += points[ i ].point3D;
} }
result.centre = sum * ( 1.0f / points.size( ) ); result.centre = sum * ( 1.0f / points.size( ) );
float sumXX = 0.0f; float sumXX = 0.0f;
float sumXY = 0.0f; float sumXY = 0.0f;
float sumXZ = 0.0f; float sumXZ = 0.0f;
float sumYY = 0.0f; float sumYY = 0.0f;
float sumYZ = 0.0f; float sumYZ = 0.0f;
float sumZZ = 0.0f; float sumZZ = 0.0f;
for ( unsigned int i = 0; i < points.size( ); ++i ) for ( unsigned int i = 0; i < points.size( ); ++i )
{ {
aiVector3D offset = points[ i ].point3D - result.centre; aiVector3D offset = points[ i ].point3D - result.centre;
sumXX += offset.x * offset.x; sumXX += offset.x * offset.x;
sumXY += offset.x * offset.y; sumXY += offset.x * offset.y;
sumXZ += offset.x * offset.z; sumXZ += offset.x * offset.z;
sumYY += offset.y * offset.y; sumYY += offset.y * offset.y;
sumYZ += offset.y * offset.z; sumYZ += offset.y * offset.z;
sumZZ += offset.z * offset.z; sumZZ += offset.z * offset.z;
} }
aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ ); aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
float det = mtx.Determinant( ); float det = mtx.Determinant( );
if ( det == 0.0f ) if ( det == 0.0f )
{ {
result.normal = aiVector3D( 0.0f ); result.normal = aiVector3D( 0.0f );
} }
else else
{ {
aiMatrix3x3 invMtx = mtx; aiMatrix3x3 invMtx = mtx;
invMtx.Inverse( ); invMtx.Inverse( );
result.normal = GetEigenVectorFromLargestEigenValue( invMtx ); result.normal = GetEigenVectorFromLargestEigenValue( invMtx );
} }
return result; return result;
} }
#endif // ASSIMP_BLEND_WITH_POLY_2_TRI #endif // ASSIMP_BLEND_WITH_POLY_2_TRI

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,337 +1,337 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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
#include "./../include/assimp/IOStream.hpp" #include "./../include/assimp/IOStream.hpp"
#include "./../include/assimp/cexport.h" #include "./../include/assimp/cexport.h"
#include "./../include/assimp/IOSystem.hpp" #include "./../include/assimp/IOSystem.hpp"
#include "./../include/assimp/DefaultLogger.hpp" #include "./../include/assimp/DefaultLogger.hpp"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <stdint.h> #include <stdint.h>
#include <set> #include <set>
#include <vector> #include <vector>
namespace Assimp { namespace Assimp {
class BlobIOSystem; class BlobIOSystem;
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
/** Redirect IOStream to a blob */ /** Redirect IOStream to a blob */
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
class BlobIOStream : public IOStream class BlobIOStream : public IOStream
{ {
public: public:
BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096) BlobIOStream(BlobIOSystem* creator, const std::string& file, size_t initial = 4096)
: buffer() : buffer()
, cur_size() , cur_size()
, file_size() , file_size()
, cursor() , cursor()
, initial(initial) , initial(initial)
, file(file) , file(file)
, creator(creator) , creator(creator)
{ {
} }
virtual ~BlobIOStream(); virtual ~BlobIOStream();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
aiExportDataBlob* GetBlob() aiExportDataBlob* GetBlob()
{ {
aiExportDataBlob* blob = new aiExportDataBlob(); aiExportDataBlob* blob = new aiExportDataBlob();
blob->size = file_size; blob->size = file_size;
blob->data = buffer; blob->data = buffer;
buffer = NULL; buffer = NULL;
return blob; return blob;
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Read( void *, virtual size_t Read( void *,
size_t, size_t,
size_t ) size_t )
{ {
return 0; return 0;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Write(const void* pvBuffer, virtual size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount)
{ {
pSize *= pCount; pSize *= pCount;
if (cursor + pSize > cur_size) { if (cursor + pSize > cur_size) {
Grow(cursor + pSize); Grow(cursor + pSize);
} }
memcpy(buffer+cursor, pvBuffer, pSize); memcpy(buffer+cursor, pvBuffer, pSize);
cursor += pSize; cursor += pSize;
file_size = std::max(file_size,cursor); file_size = std::max(file_size,cursor);
return pCount; return pCount;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual aiReturn Seek(size_t pOffset, virtual aiReturn Seek(size_t pOffset,
aiOrigin pOrigin) aiOrigin pOrigin)
{ {
switch(pOrigin) switch(pOrigin)
{ {
case aiOrigin_CUR: case aiOrigin_CUR:
cursor += pOffset; cursor += pOffset;
break; break;
case aiOrigin_END: case aiOrigin_END:
cursor = file_size - pOffset; cursor = file_size - pOffset;
break; break;
case aiOrigin_SET: case aiOrigin_SET:
cursor = pOffset; cursor = pOffset;
break; break;
default: default:
return AI_FAILURE; return AI_FAILURE;
} }
if (cursor > file_size) { if (cursor > file_size) {
Grow(cursor); Grow(cursor);
} }
file_size = std::max(cursor,file_size); file_size = std::max(cursor,file_size);
return AI_SUCCESS; return AI_SUCCESS;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t Tell() const virtual size_t Tell() const
{ {
return cursor; return cursor;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual size_t FileSize() const virtual size_t FileSize() const
{ {
return file_size; return file_size;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual void Flush() virtual void Flush()
{ {
// ignore // ignore
} }
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Grow(size_t need = 0) void Grow(size_t need = 0)
{ {
// 1.5 and phi are very heap-friendly growth factors (the first // 1.5 and phi are very heap-friendly growth factors (the first
// allows for frequent re-use of heap blocks, the second // allows for frequent re-use of heap blocks, the second
// forms a fibonacci sequence with similar characteristics - // forms a fibonacci sequence with similar characteristics -
// since this heavily depends on the heap implementation // since this heavily depends on the heap implementation
// and other factors as well, i'll just go with 1.5 since // and other factors as well, i'll just go with 1.5 since
// it is quicker to compute). // it is quicker to compute).
size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) )); size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));
const uint8_t* const old = buffer; const uint8_t* const old = buffer;
buffer = new uint8_t[new_size]; buffer = new uint8_t[new_size];
if (old) { if (old) {
memcpy(buffer,old,cur_size); memcpy(buffer,old,cur_size);
delete[] old; delete[] old;
} }
cur_size = new_size; cur_size = new_size;
} }
private: private:
uint8_t* buffer; uint8_t* buffer;
size_t cur_size,file_size, cursor, initial; size_t cur_size,file_size, cursor, initial;
const std::string file; const std::string file;
BlobIOSystem* const creator; BlobIOSystem* const creator;
}; };
#define AI_BLOBIO_MAGIC "$blobfile" #define AI_BLOBIO_MAGIC "$blobfile"
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
/** Redirect IOSystem to a blob */ /** Redirect IOSystem to a blob */
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
class BlobIOSystem : public IOSystem class BlobIOSystem : public IOSystem
{ {
friend class BlobIOStream; friend class BlobIOStream;
typedef std::pair<std::string, aiExportDataBlob*> BlobEntry; typedef std::pair<std::string, aiExportDataBlob*> BlobEntry;
public: public:
BlobIOSystem() BlobIOSystem()
{ {
} }
virtual ~BlobIOSystem() virtual ~BlobIOSystem()
{ {
BOOST_FOREACH(BlobEntry& blobby, blobs) { BOOST_FOREACH(BlobEntry& blobby, blobs) {
delete blobby.second; delete blobby.second;
} }
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
const char* GetMagicFileName() const const char* GetMagicFileName() const
{ {
return AI_BLOBIO_MAGIC; return AI_BLOBIO_MAGIC;
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
aiExportDataBlob* GetBlobChain() aiExportDataBlob* GetBlobChain()
{ {
// one must be the master // one must be the master
aiExportDataBlob* master = NULL, *cur; aiExportDataBlob* master = NULL, *cur;
BOOST_FOREACH(const BlobEntry& blobby, blobs) { BOOST_FOREACH(const BlobEntry& blobby, blobs) {
if (blobby.first == AI_BLOBIO_MAGIC) { if (blobby.first == AI_BLOBIO_MAGIC) {
master = blobby.second; master = blobby.second;
break; break;
} }
} }
if (!master) { if (!master) {
DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly."); DefaultLogger::get()->error("BlobIOSystem: no data written or master file was not closed properly.");
return NULL; return NULL;
} }
master->name.Set(""); master->name.Set("");
cur = master; cur = master;
BOOST_FOREACH(const BlobEntry& blobby, blobs) { BOOST_FOREACH(const BlobEntry& blobby, blobs) {
if (blobby.second == master) { if (blobby.second == master) {
continue; continue;
} }
cur->next = blobby.second; cur->next = blobby.second;
cur = cur->next; cur = cur->next;
// extract the file extension from the file written // extract the file extension from the file written
const std::string::size_type s = blobby.first.find_first_of('.'); const std::string::size_type s = blobby.first.find_first_of('.');
cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1)); cur->name.Set(s == std::string::npos ? blobby.first : blobby.first.substr(s+1));
} }
// give up blob ownership // give up blob ownership
blobs.clear(); blobs.clear();
return master; return master;
} }
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual bool Exists( const char* pFile) const { virtual bool Exists( const char* pFile) const {
return created.find(std::string(pFile)) != created.end(); return created.find(std::string(pFile)) != created.end();
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual char getOsSeparator() const { virtual char getOsSeparator() const {
return '/'; return '/';
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual IOStream* Open(const char* pFile, virtual IOStream* Open(const char* pFile,
const char* pMode) const char* pMode)
{ {
if (pMode[0] != 'w') { if (pMode[0] != 'w') {
return NULL; return NULL;
} }
created.insert(std::string(pFile)); created.insert(std::string(pFile));
return new BlobIOStream(this,std::string(pFile)); return new BlobIOStream(this,std::string(pFile));
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
virtual void Close( IOStream* pFile) virtual void Close( IOStream* pFile)
{ {
delete pFile; delete pFile;
} }
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void OnDestruct(const std::string& filename, BlobIOStream* child) void OnDestruct(const std::string& filename, BlobIOStream* child)
{ {
// we don't know in which the files are closed, so we // we don't know in which the files are closed, so we
// can't reliably say that the first must be the master // can't reliably say that the first must be the master
// file ... // file ...
blobs.push_back( BlobEntry(filename,child->GetBlob()) ); blobs.push_back( BlobEntry(filename,child->GetBlob()) );
} }
private: private:
std::set<std::string> created; std::set<std::string> created;
std::vector< BlobEntry > blobs; std::vector< BlobEntry > blobs;
}; };
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
BlobIOStream :: ~BlobIOStream() BlobIOStream :: ~BlobIOStream()
{ {
creator->OnDestruct(file,this); creator->OnDestruct(file,this);
delete[] buffer; delete[] buffer;
} }
} // end Assimp } // end Assimp
#endif #endif

View File

@ -1,286 +1,286 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 Helper class tp perform various byte oder swappings /** @file Helper class tp perform various byte oder swappings
(e.g. little to big endian) */ (e.g. little to big endian) */
#ifndef AI_BYTESWAPPER_H_INC #ifndef AI_BYTESWAPPER_H_INC
#define AI_BYTESWAPPER_H_INC #define AI_BYTESWAPPER_H_INC
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
#include <stdint.h> #include <stdint.h>
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
#include <stdlib.h> #include <stdlib.h>
#endif #endif
namespace Assimp { namespace Assimp {
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
/** Defines some useful byte order swap routines. /** Defines some useful byte order swap routines.
* *
* This is required to read big-endian model formats on little-endian machines, * 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. */ * and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
class ByteSwap class ByteSwap
{ {
ByteSwap() {} ByteSwap() {}
public: public:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Swap two bytes of data /** Swap two bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */ * @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap2(void* _szOut) static inline void Swap2(void* _szOut)
{ {
ai_assert(_szOut); ai_assert(_szOut);
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut); uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
*szOut = _byteswap_ushort(*szOut); *szOut = _byteswap_ushort(*szOut);
#else #else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[1]); std::swap(szOut[0],szOut[1]);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Swap four bytes of data /** Swap four bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */ * @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap4(void* _szOut) static inline void Swap4(void* _szOut)
{ {
ai_assert(_szOut); ai_assert(_szOut);
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut); uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
*szOut = _byteswap_ulong(*szOut); *szOut = _byteswap_ulong(*szOut);
#else #else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[3]); std::swap(szOut[0],szOut[3]);
std::swap(szOut[1],szOut[2]); std::swap(szOut[1],szOut[2]);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** Swap eight bytes of data /** Swap eight bytes of data
* @param[inout] _szOut A void* to save the reintcasts for the caller. */ * @param[inout] _szOut A void* to save the reintcasts for the caller. */
static inline void Swap8(void* _szOut) static inline void Swap8(void* _szOut)
{ {
ai_assert(_szOut); ai_assert(_szOut);
#if _MSC_VER >= 1400 #if _MSC_VER >= 1400
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut); uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
*szOut = _byteswap_uint64(*szOut); *szOut = _byteswap_uint64(*szOut);
#else #else
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut); uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
std::swap(szOut[0],szOut[7]); std::swap(szOut[0],szOut[7]);
std::swap(szOut[1],szOut[6]); std::swap(szOut[1],szOut[6]);
std::swap(szOut[2],szOut[5]); std::swap(szOut[2],szOut[5]);
std::swap(szOut[3],szOut[4]); std::swap(szOut[3],szOut[4]);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap a float. Not a joke. /** ByteSwap a float. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(float* fOut) { static inline void Swap(float* fOut) {
Swap4(fOut); Swap4(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap a double. Not a joke. /** ByteSwap a double. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(double* fOut) { static inline void Swap(double* fOut) {
Swap8(fOut); Swap8(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap an int16t. Not a joke. /** ByteSwap an int16t. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(int16_t* fOut) { static inline void Swap(int16_t* fOut) {
Swap2(fOut); Swap2(fOut);
} }
static inline void Swap(uint16_t* fOut) { static inline void Swap(uint16_t* fOut) {
Swap2(fOut); Swap2(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap an int32t. Not a joke. /** ByteSwap an int32t. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(int32_t* fOut){ static inline void Swap(int32_t* fOut){
Swap4(fOut); Swap4(fOut);
} }
static inline void Swap(uint32_t* fOut){ static inline void Swap(uint32_t* fOut){
Swap4(fOut); Swap4(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** ByteSwap an int64t. Not a joke. /** ByteSwap an int64t. Not a joke.
* @param[inout] fOut ehm. .. */ * @param[inout] fOut ehm. .. */
static inline void Swap(int64_t* fOut) { static inline void Swap(int64_t* fOut) {
Swap8(fOut); Swap8(fOut);
} }
static inline void Swap(uint64_t* fOut) { static inline void Swap(uint64_t* fOut) {
Swap8(fOut); Swap8(fOut);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
//! Templatized ByteSwap //! Templatized ByteSwap
//! \returns param tOut as swapped //! \returns param tOut as swapped
template<typename Type> template<typename Type>
static inline Type Swapped(Type tOut) static inline Type Swapped(Type tOut)
{ {
return _swapper<Type,sizeof(Type)>()(tOut); return _swapper<Type,sizeof(Type)>()(tOut);
} }
private: private:
template <typename T, size_t size> struct _swapper; template <typename T, size_t size> struct _swapper;
}; };
template <typename T> struct ByteSwap::_swapper<T,2> { template <typename T> struct ByteSwap::_swapper<T,2> {
T operator() (T tOut) { T operator() (T tOut) {
Swap2(&tOut); Swap2(&tOut);
return tOut; return tOut;
} }
}; };
template <typename T> struct ByteSwap::_swapper<T,4> { template <typename T> struct ByteSwap::_swapper<T,4> {
T operator() (T tOut) { T operator() (T tOut) {
Swap4(&tOut); Swap4(&tOut);
return tOut; return tOut;
} }
}; };
template <typename T> struct ByteSwap::_swapper<T,8> { template <typename T> struct ByteSwap::_swapper<T,8> {
T operator() (T tOut) { T operator() (T tOut) {
Swap8(&tOut); Swap8(&tOut);
return tOut; return tOut;
} }
}; };
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
// ByteSwap macros for BigEndian/LittleEndian support // ByteSwap macros for BigEndian/LittleEndian support
// -------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------
#if (defined AI_BUILD_BIG_ENDIAN) #if (defined AI_BUILD_BIG_ENDIAN)
# define AI_LE(t) (t) # define AI_LE(t) (t)
# define AI_BE(t) ByteSwap::Swapped(t) # define AI_BE(t) ByteSwap::Swapped(t)
# define AI_LSWAP2(p) # define AI_LSWAP2(p)
# define AI_LSWAP4(p) # define AI_LSWAP4(p)
# define AI_LSWAP8(p) # define AI_LSWAP8(p)
# define AI_LSWAP2P(p) # define AI_LSWAP2P(p)
# define AI_LSWAP4P(p) # define AI_LSWAP4P(p)
# define AI_LSWAP8P(p) # define AI_LSWAP8P(p)
# define LE_NCONST const # define LE_NCONST const
# define AI_SWAP2(p) ByteSwap::Swap2(&(p)) # define AI_SWAP2(p) ByteSwap::Swap2(&(p))
# define AI_SWAP4(p) ByteSwap::Swap4(&(p)) # define AI_SWAP4(p) ByteSwap::Swap4(&(p))
# define AI_SWAP8(p) ByteSwap::Swap8(&(p)) # define AI_SWAP8(p) ByteSwap::Swap8(&(p))
# define AI_SWAP2P(p) ByteSwap::Swap2((p)) # define AI_SWAP2P(p) ByteSwap::Swap2((p))
# define AI_SWAP4P(p) ByteSwap::Swap4((p)) # define AI_SWAP4P(p) ByteSwap::Swap4((p))
# define AI_SWAP8P(p) ByteSwap::Swap8((p)) # define AI_SWAP8P(p) ByteSwap::Swap8((p))
# define BE_NCONST # define BE_NCONST
#else #else
# define AI_BE(t) (t) # define AI_BE(t) (t)
# define AI_LE(t) ByteSwap::Swapped(t) # define AI_LE(t) ByteSwap::Swapped(t)
# define AI_SWAP2(p) # define AI_SWAP2(p)
# define AI_SWAP4(p) # define AI_SWAP4(p)
# define AI_SWAP8(p) # define AI_SWAP8(p)
# define AI_SWAP2P(p) # define AI_SWAP2P(p)
# define AI_SWAP4P(p) # define AI_SWAP4P(p)
# define AI_SWAP8P(p) # define AI_SWAP8P(p)
# define BE_NCONST const # define BE_NCONST const
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p)) # define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p)) # define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p)) # define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
# define AI_LSWAP2P(p) ByteSwap::Swap2((p)) # define AI_LSWAP2P(p) ByteSwap::Swap2((p))
# define AI_LSWAP4P(p) ByteSwap::Swap4((p)) # define AI_LSWAP4P(p) ByteSwap::Swap4((p))
# define AI_LSWAP8P(p) ByteSwap::Swap8((p)) # define AI_LSWAP8P(p) ByteSwap::Swap8((p))
# define LE_NCONST # define LE_NCONST
#endif #endif
namespace Intern { namespace Intern {
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
template <typename T, bool doit> template <typename T, bool doit>
struct ByteSwapper { struct ByteSwapper {
void operator() (T* inout) { void operator() (T* inout) {
ByteSwap::Swap(inout); ByteSwap::Swap(inout);
} }
}; };
template <typename T> template <typename T>
struct ByteSwapper<T,false> { struct ByteSwapper<T,false> {
void operator() (T*) { void operator() (T*) {
} }
}; };
// -------------------------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------
template <bool SwapEndianess, typename T, bool RuntimeSwitch> template <bool SwapEndianess, typename T, bool RuntimeSwitch>
struct Getter { struct Getter {
void operator() (T* inout, bool le) { void operator() (T* inout, bool le) {
#ifdef AI_BUILD_BIG_ENDIAN #ifdef AI_BUILD_BIG_ENDIAN
le = le; le = le;
#else #else
le = !le; le = !le;
#endif #endif
if (le) { if (le) {
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout); ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
} }
else ByteSwapper<T,false> () (inout); else ByteSwapper<T,false> () (inout);
} }
}; };
template <bool SwapEndianess, typename T> template <bool SwapEndianess, typename T>
struct Getter<SwapEndianess,T,false> { struct Getter<SwapEndianess,T,false> {
void operator() (T* inout, bool /*le*/) { void operator() (T* inout, bool /*le*/) {
// static branch // static branch
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout); ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
} }
}; };
} // end Intern } // end Intern
} // end Assimp } // end Assimp
#endif //!! AI_BYTESWAPPER_H_INC #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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -55,19 +55,19 @@ struct aiMaterial;
struct aiImporterDesc; struct aiImporterDesc;
namespace _melange_ { namespace _melange_ {
class BaseObject; // c4d_file.h class BaseObject; // c4d_file.h
class PolygonObject; class PolygonObject;
class BaseMaterial; class BaseMaterial;
class BaseShader; class BaseShader;
} }
namespace Assimp { namespace Assimp {
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Importer class to load Cinema4D files using the Melange library to be obtained from /** Importer class to load Cinema4D files using the Melange library to be obtained from
@ -79,42 +79,42 @@ class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter>
{ {
public: public:
C4DImporter(); C4DImporter();
~C4DImporter(); ~C4DImporter();
public: public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// -------------------- // --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// -------------------- // --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// -------------------- // --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
void ReadMaterials(_melange_::BaseMaterial* mat); void ReadMaterials(_melange_::BaseMaterial* mat);
void RecurseHierarchy(_melange_::BaseObject* object, aiNode* parent); void RecurseHierarchy(_melange_::BaseObject* object, aiNode* parent);
aiMesh* ReadMesh(_melange_::BaseObject* object); aiMesh* ReadMesh(_melange_::BaseObject* object);
unsigned int ResolveMaterial(_melange_::PolygonObject* obj); unsigned int ResolveMaterial(_melange_::PolygonObject* obj);
bool ReadShader(aiMaterial* out, _melange_::BaseShader* shader); bool ReadShader(aiMaterial* out, _melange_::BaseShader* shader);
std::vector<aiMesh*> meshes; std::vector<aiMesh*> meshes;
std::vector<aiMaterial*> materials; std::vector<aiMaterial*> materials;
typedef std::map<_melange_::BaseMaterial*, unsigned int> MaterialMap; typedef std::map<_melange_::BaseMaterial*, unsigned int> MaterialMap;
MaterialMap material_mapping; MaterialMap material_mapping;
}; // !class C4DImporter }; // !class C4DImporter

View File

@ -1,160 +1,160 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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" #include "../include/assimp/IOStream.hpp"
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
namespace Assimp { namespace Assimp {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOStreamWrapper : public IOStream class CIOStreamWrapper : public IOStream
{ {
friend class CIOSystemWrapper; friend class CIOSystemWrapper;
public: public:
CIOStreamWrapper(aiFile* pFile) CIOStreamWrapper(aiFile* pFile)
: mFile(pFile) : mFile(pFile)
{} {}
// ................................................................... // ...................................................................
size_t Read(void* pvBuffer, size_t Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount size_t pCount
){ ){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount); return mFile->ReadProc(mFile,(char*)pvBuffer,pSize,pCount);
} }
// ................................................................... // ...................................................................
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount size_t pCount
){ ){
// need to typecast here as C has no void* // need to typecast here as C has no void*
return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount); return mFile->WriteProc(mFile,(const char*)pvBuffer,pSize,pCount);
} }
// ................................................................... // ...................................................................
aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset,
aiOrigin pOrigin aiOrigin pOrigin
){ ){
return mFile->SeekProc(mFile,pOffset,pOrigin); return mFile->SeekProc(mFile,pOffset,pOrigin);
} }
// ................................................................... // ...................................................................
size_t Tell(void) const { size_t Tell(void) const {
return mFile->TellProc(mFile); return mFile->TellProc(mFile);
} }
// ................................................................... // ...................................................................
size_t FileSize() const { size_t FileSize() const {
return mFile->FileSizeProc(mFile); return mFile->FileSizeProc(mFile);
} }
// ................................................................... // ...................................................................
void Flush () { void Flush () {
return mFile->FlushProc(mFile); return mFile->FlushProc(mFile);
} }
private: private:
aiFile* mFile; aiFile* mFile;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Custom IOStream implementation for the C-API // Custom IOStream implementation for the C-API
class CIOSystemWrapper : public IOSystem class CIOSystemWrapper : public IOSystem
{ {
public: public:
CIOSystemWrapper(aiFileIO* pFile) CIOSystemWrapper(aiFileIO* pFile)
: mFileSystem(pFile) : mFileSystem(pFile)
{} {}
// ................................................................... // ...................................................................
bool Exists( const char* pFile) const { bool Exists( const char* pFile) const {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb"); aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,"rb");
if (p){ if (p){
mFileSystem->CloseProc(mFileSystem,p); mFileSystem->CloseProc(mFileSystem,p);
return true; return true;
} }
return false; return false;
} }
// ................................................................... // ...................................................................
char getOsSeparator() const { char getOsSeparator() const {
#ifndef _WIN32 #ifndef _WIN32
return '/'; return '/';
#else #else
return '\\'; return '\\';
#endif #endif
} }
// ................................................................... // ...................................................................
IOStream* Open(const char* pFile,const char* pMode = "rb") { IOStream* Open(const char* pFile,const char* pMode = "rb") {
aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode); aiFile* p = mFileSystem->OpenProc(mFileSystem,pFile,pMode);
if (!p) { if (!p) {
return NULL; return NULL;
} }
return new CIOStreamWrapper(p); return new CIOStreamWrapper(p);
} }
// ................................................................... // ...................................................................
void Close( IOStream* pFile) { void Close( IOStream* pFile) {
if (!pFile) { if (!pFile) {
return; return;
} }
mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile); mFileSystem->CloseProc(mFileSystem,((CIOStreamWrapper*) pFile)->mFile);
delete pFile; delete pFile;
} }
private: private:
aiFileIO* mFileSystem; aiFileIO* mFileSystem;
}; };
} }
#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,174 +1,174 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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"
#include "StreamReader.h" #include "StreamReader.h"
struct aiNode; struct aiNode;
namespace Assimp { namespace Assimp {
class LineSplitter; class LineSplitter;
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format; typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
} }
// COBScene.h // COBScene.h
namespace COB { namespace COB {
struct ChunkInfo; struct ChunkInfo;
struct Node; struct Node;
struct Scene; struct Scene;
} }
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
/** Importer class to load TrueSpace files (cob,scn) up to v6. /** Importer class to load TrueSpace files (cob,scn) up to v6.
* *
* Currently relatively limited, loads only ASCII files and needs more test coverage. */ * Currently relatively limited, loads only ASCII files and needs more test coverage. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class COBImporter : public BaseImporter class COBImporter : public BaseImporter
{ {
public: public:
COBImporter(); COBImporter();
~COBImporter(); ~COBImporter();
public: public:
// -------------------- // --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// -------------------- // --------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// -------------------- // --------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// -------------------- // --------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Prepend 'COB: ' and throw msg.*/ /** Prepend 'COB: ' and throw msg.*/
AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN static void ThrowException(const std::string& msg) AI_WONT_RETURN_SUFFIX;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Read from an ascii scene/object file /** @brief Read from an ascii scene/object file
* @param out Receives output data. * @param out Receives output data.
* @param stream Stream to read from. */ * @param stream Stream to read from. */
void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream); void ReadAsciiFile(COB::Scene& out, StreamReaderLE* stream);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** @brief Read from a binary scene/object file /** @brief Read from a binary scene/object file
* @param out Receives output data. * @param out Receives output data.
* @param stream Stream to read from. */ * @param stream Stream to read from. */
void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream); void ReadBinaryFile(COB::Scene& out, StreamReaderLE* stream);
private: private:
// Conversion to Assimp output format // Conversion to Assimp output format
aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill); aiNode* BuildNodes(const COB::Node& root,const COB::Scene& scin,aiScene* fill);
private: private:
// ASCII file support // ASCII file support
void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name); void UnsupportedChunk_Ascii(LineSplitter& splitter, const COB::ChunkInfo& nfo, const char* name);
void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter); void ReadChunkInfo_Ascii(COB::ChunkInfo& out, const LineSplitter& splitter);
void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadBasicNodeInfo_Ascii(COB::Node& msh, LineSplitter& splitter, const COB::ChunkInfo& nfo);
template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in); template <typename T> void ReadFloat3Tuple_Ascii(T& fill, const char** in);
void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadPolH_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadBitM_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadMat1_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadGrou_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadBone_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadCame_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadLght_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadUnit_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo); void ReadChan_Ascii(COB::Scene& out, LineSplitter& splitter, const COB::ChunkInfo& nfo);
// ASCII file logging stuff to add proper line numbers to messages // ASCII file logging stuff to add proper line numbers to messages
static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message); static void LogWarn_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message); static void LogError_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message); static void LogInfo_Ascii (const LineSplitter& splitter, const Formatter::format& message);
static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message); static void LogDebug_Ascii(const LineSplitter& splitter, const Formatter::format& message);
static void LogWarn_Ascii (const Formatter::format& message); static void LogWarn_Ascii (const Formatter::format& message);
static void LogError_Ascii (const Formatter::format& message); static void LogError_Ascii (const Formatter::format& message);
static void LogInfo_Ascii (const Formatter::format& message); static void LogInfo_Ascii (const Formatter::format& message);
static void LogDebug_Ascii (const Formatter::format& message); static void LogDebug_Ascii (const Formatter::format& message);
// Binary file support // Binary file support
void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name); void UnsupportedChunk_Binary(StreamReaderLE& reader, const COB::ChunkInfo& nfo, const char* name);
void ReadString_Binary(std::string& out, StreamReaderLE& reader); void ReadString_Binary(std::string& out, StreamReaderLE& reader);
void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadBasicNodeInfo_Binary(COB::Node& msh, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadBitM_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo); void ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const COB::ChunkInfo& nfo);
}; // !class COBImporter }; // !class COBImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_UNREALIMPORTER_H_INC #endif // AI_UNREALIMPORTER_H_INC

View File

@ -1,274 +1,274 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 <deque> #include <deque>
#include "BaseImporter.h" #include "BaseImporter.h"
#include "./../include/assimp/material.h" #include "./../include/assimp/material.h"
namespace Assimp { namespace Assimp {
namespace COB { namespace COB {
// ------------------ // ------------------
/** Represents a single vertex index in a face */ /** Represents a single vertex index in a face */
struct VertexIndex struct VertexIndex
{ {
// intentionally uninitialized // intentionally uninitialized
unsigned int pos_idx,uv_idx; unsigned int pos_idx,uv_idx;
}; };
// ------------------ // ------------------
/** COB Face data structure */ /** COB Face data structure */
struct Face struct Face
{ {
// intentionally uninitialized // intentionally uninitialized
unsigned int material, flags; unsigned int material, flags;
std::vector<VertexIndex> indices; std::vector<VertexIndex> indices;
}; };
// ------------------ // ------------------
/** COB chunk header information */ /** COB chunk header information */
struct ChunkInfo struct ChunkInfo
{ {
enum {NO_SIZE=UINT_MAX}; enum {NO_SIZE=UINT_MAX};
ChunkInfo () ChunkInfo ()
: id (0) : id (0)
, parent_id (0) , parent_id (0)
, version (0) , version (0)
, size (NO_SIZE) , size (NO_SIZE)
{} {}
// Id of this chunk, unique within file // Id of this chunk, unique within file
unsigned int id; unsigned int id;
// and the corresponding parent // and the corresponding parent
unsigned int parent_id; unsigned int parent_id;
// version. v1.23 becomes 123 // version. v1.23 becomes 123
unsigned int version; unsigned int version;
// chunk size in bytes, only relevant for binary files // chunk size in bytes, only relevant for binary files
// NO_SIZE is also valid. // NO_SIZE is also valid.
unsigned int size; unsigned int size;
}; };
// ------------------ // ------------------
/** A node in the scenegraph */ /** A node in the scenegraph */
struct Node : public ChunkInfo struct Node : public ChunkInfo
{ {
enum Type { enum Type {
TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE TYPE_MESH,TYPE_GROUP,TYPE_LIGHT,TYPE_CAMERA,TYPE_BONE
}; };
virtual ~Node() {} virtual ~Node() {}
Node(Type type) : type(type), unit_scale(1.f){} Node(Type type) : type(type), unit_scale(1.f){}
Type type; Type type;
// used during resolving // used during resolving
typedef std::deque<const Node*> ChildList; typedef std::deque<const Node*> ChildList;
mutable ChildList temp_children; mutable ChildList temp_children;
// unique name // unique name
std::string name; std::string name;
// local mesh transformation // local mesh transformation
aiMatrix4x4 transform; aiMatrix4x4 transform;
// scaling for this node to get to the metric system // scaling for this node to get to the metric system
float unit_scale; float unit_scale;
}; };
// ------------------ // ------------------
/** COB Mesh data structure */ /** COB Mesh data structure */
struct Mesh : public Node struct Mesh : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
enum DrawFlags { enum DrawFlags {
SOLID = 0x1, SOLID = 0x1,
TRANS = 0x2, TRANS = 0x2,
WIRED = 0x4, WIRED = 0x4,
BBOX = 0x8, BBOX = 0x8,
HIDE = 0x10 HIDE = 0x10
}; };
Mesh() Mesh()
: Node(TYPE_MESH) : Node(TYPE_MESH)
, draw_flags(SOLID) , draw_flags(SOLID)
{} {}
// vertex elements // vertex elements
std::vector<aiVector2D> texture_coords; std::vector<aiVector2D> texture_coords;
std::vector<aiVector3D> vertex_positions; std::vector<aiVector3D> vertex_positions;
// face data // face data
std::vector<Face> faces; std::vector<Face> faces;
// misc. drawing flags // misc. drawing flags
unsigned int draw_flags; unsigned int draw_flags;
// used during resolving // used during resolving
typedef std::deque<Face*> FaceRefList; typedef std::deque<Face*> FaceRefList;
typedef std::map< unsigned int,FaceRefList > TempMap; typedef std::map< unsigned int,FaceRefList > TempMap;
TempMap temp_map; TempMap temp_map;
}; };
// ------------------ // ------------------
/** COB Group data structure */ /** COB Group data structure */
struct Group : public Node struct Group : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
Group() : Node(TYPE_GROUP) {} Group() : Node(TYPE_GROUP) {}
}; };
// ------------------ // ------------------
/** COB Bone data structure */ /** COB Bone data structure */
struct Bone : public Node struct Bone : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
Bone() : Node(TYPE_BONE) {} Bone() : Node(TYPE_BONE) {}
}; };
// ------------------ // ------------------
/** COB Light data structure */ /** COB Light data structure */
struct Light : public Node struct Light : public Node
{ {
enum LightType { enum LightType {
SPOT,LOCAL,INFINITE SPOT,LOCAL,INFINITE
}; };
using ChunkInfo::operator=; using ChunkInfo::operator=;
Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {} Light() : Node(TYPE_LIGHT),angle(),inner_angle(),ltype(SPOT) {}
aiColor3D color; aiColor3D color;
float angle,inner_angle; float angle,inner_angle;
LightType ltype; LightType ltype;
}; };
// ------------------ // ------------------
/** COB Camera data structure */ /** COB Camera data structure */
struct Camera : public Node struct Camera : public Node
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
Camera() : Node(TYPE_CAMERA) {} Camera() : Node(TYPE_CAMERA) {}
}; };
// ------------------ // ------------------
/** COB Texture data structure */ /** COB Texture data structure */
struct Texture struct Texture
{ {
std::string path; std::string path;
aiUVTransform transform; aiUVTransform transform;
}; };
// ------------------ // ------------------
/** COB Material data structure */ /** COB Material data structure */
struct Material : ChunkInfo struct Material : ChunkInfo
{ {
using ChunkInfo::operator=; using ChunkInfo::operator=;
enum Shader { enum Shader {
FLAT,PHONG,METAL FLAT,PHONG,METAL
}; };
enum AutoFacet { enum AutoFacet {
FACETED,AUTOFACETED,SMOOTH FACETED,AUTOFACETED,SMOOTH
}; };
Material() : alpha(),exp(),ior(),ka(),ks(1.f), Material() : alpha(),exp(),ior(),ka(),ks(1.f),
matnum(UINT_MAX), matnum(UINT_MAX),
shader(FLAT),autofacet(FACETED), shader(FLAT),autofacet(FACETED),
autofacet_angle() autofacet_angle()
{} {}
std::string type; std::string type;
aiColor3D rgb; aiColor3D rgb;
float alpha, exp, ior,ka,ks; float alpha, exp, ior,ka,ks;
unsigned int matnum; unsigned int matnum;
Shader shader; Shader shader;
AutoFacet autofacet; AutoFacet autofacet;
float autofacet_angle; float autofacet_angle;
boost::shared_ptr<Texture> tex_env,tex_bump,tex_color; boost::shared_ptr<Texture> tex_env,tex_bump,tex_color;
}; };
// ------------------ // ------------------
/** Embedded bitmap, for instance for the thumbnail image */ /** Embedded bitmap, for instance for the thumbnail image */
struct Bitmap : ChunkInfo struct Bitmap : ChunkInfo
{ {
Bitmap() : orig_size() {} Bitmap() : orig_size() {}
struct BitmapHeader struct BitmapHeader
{ {
}; };
BitmapHeader head; BitmapHeader head;
size_t orig_size; size_t orig_size;
std::vector<char> buff_zipped; std::vector<char> buff_zipped;
}; };
typedef std::deque< boost::shared_ptr<Node> > NodeList; typedef std::deque< boost::shared_ptr<Node> > NodeList;
typedef std::vector< Material > MaterialList; typedef std::vector< Material > MaterialList;
// ------------------ // ------------------
/** Represents a master COB scene, even if we loaded just a single COB file */ /** Represents a master COB scene, even if we loaded just a single COB file */
struct Scene struct Scene
{ {
NodeList nodes; NodeList nodes;
MaterialList materials; MaterialList materials;
// becomes *0 later // becomes *0 later
Bitmap thumbnail; Bitmap thumbnail;
}; };
} // end COB } // end COB
} // end Assimp } // end Assimp
#endif #endif

View File

@ -1,306 +1,306 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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.
*/ */
#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" #include "../include/assimp/Importer.hpp"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
#include "../include/assimp/anim.h" #include "../include/assimp/anim.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
using namespace Assimp; using namespace Assimp;
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
"CharacterStudio Motion Importer (MoCap)", "CharacterStudio Motion Importer (MoCap)",
"", "",
"", "",
"", "",
aiImporterFlags_SupportTextFlavour, aiImporterFlags_SupportTextFlavour,
0, 0,
0, 0,
0, 0,
0, 0,
"csm" "csm"
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
CSMImporter::CSMImporter() CSMImporter::CSMImporter()
: noSkeletonMesh() : noSkeletonMesh()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
CSMImporter::~CSMImporter() CSMImporter::~CSMImporter()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file. // Returns whether the class can handle the format of the given file.
bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{ {
// check file extension // check file extension
const std::string extension = GetExtension(pFile); const std::string extension = GetExtension(pFile);
if( extension == "csm") if( extension == "csm")
return true; return true;
if ((checkSig || !extension.length()) && pIOHandler) { if ((checkSig || !extension.length()) && pIOHandler) {
const char* tokens[] = {"$Filename"}; const char* tokens[] = {"$Filename"};
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1); return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Build a string of all file extensions supported // Build a string of all file extensions supported
const aiImporterDesc* CSMImporter::GetInfo () const const aiImporterDesc* CSMImporter::GetInfo () const
{ {
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader // Setup configuration properties for the loader
void CSMImporter::SetupProperties(const Importer* pImp) void CSMImporter::SetupProperties(const Importer* pImp)
{ {
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0; noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void CSMImporter::InternReadFile( const std::string& pFile, void CSMImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler) aiScene* pScene, IOSystem* pIOHandler)
{ {
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb")); boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
// Check whether we can read from the file // Check whether we can read from the file
if( file.get() == NULL) { if( file.get() == NULL) {
throw DeadlyImportError( "Failed to open CSM file " + pFile + "."); throw DeadlyImportError( "Failed to open CSM file " + pFile + ".");
} }
// allocate storage and copy the contents of the file to a memory buffer // allocate storage and copy the contents of the file to a memory buffer
std::vector<char> mBuffer2; std::vector<char> mBuffer2;
TextFileToBuffer(file.get(),mBuffer2); TextFileToBuffer(file.get(),mBuffer2);
const char* buffer = &mBuffer2[0]; const char* buffer = &mBuffer2[0];
aiAnimation* anim = new aiAnimation(); aiAnimation* anim = new aiAnimation();
int first = 0, last = 0x00ffffff; int first = 0, last = 0x00ffffff;
// now process the file and look out for '$' sections // now process the file and look out for '$' sections
while (1) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
if ('\0' == *buffer) if ('\0' == *buffer)
break; break;
if ('$' == *buffer) { if ('$' == *buffer) {
++buffer; ++buffer;
if (TokenMatchI(buffer,"firstframe",10)) { if (TokenMatchI(buffer,"firstframe",10)) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
first = strtol10(buffer,&buffer); first = strtol10(buffer,&buffer);
} }
else if (TokenMatchI(buffer,"lastframe",9)) { else if (TokenMatchI(buffer,"lastframe",9)) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
last = strtol10(buffer,&buffer); last = strtol10(buffer,&buffer);
} }
else if (TokenMatchI(buffer,"rate",4)) { else if (TokenMatchI(buffer,"rate",4)) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
float d; float d;
buffer = fast_atoreal_move<float>(buffer,d); buffer = fast_atoreal_move<float>(buffer,d);
anim->mTicksPerSecond = d; anim->mTicksPerSecond = d;
} }
else if (TokenMatchI(buffer,"order",5)) { else if (TokenMatchI(buffer,"order",5)) {
std::vector< aiNodeAnim* > anims_temp; std::vector< aiNodeAnim* > anims_temp;
anims_temp.reserve(30); anims_temp.reserve(30);
while (1) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$') if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
break; // next section break; // next section
// Construct a new node animation channel and setup its name // Construct a new node animation channel and setup its name
anims_temp.push_back(new aiNodeAnim()); anims_temp.push_back(new aiNodeAnim());
aiNodeAnim* nda = anims_temp.back(); aiNodeAnim* nda = anims_temp.back();
char* ot = nda->mNodeName.data; char* ot = nda->mNodeName.data;
while (!IsSpaceOrNewLine(*buffer)) while (!IsSpaceOrNewLine(*buffer))
*ot++ = *buffer++; *ot++ = *buffer++;
*ot = '\0'; *ot = '\0';
nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data); nda->mNodeName.length = (size_t)(ot-nda->mNodeName.data);
} }
anim->mNumChannels = anims_temp.size(); anim->mNumChannels = anims_temp.size();
if (!anim->mNumChannels) if (!anim->mNumChannels)
throw DeadlyImportError("CSM: Empty $order section"); throw DeadlyImportError("CSM: Empty $order section");
// copy over to the output animation // copy over to the output animation
anim->mChannels = new aiNodeAnim*[anim->mNumChannels]; anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels); ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
} }
else if (TokenMatchI(buffer,"points",6)) { else if (TokenMatchI(buffer,"points",6)) {
if (!anim->mNumChannels) if (!anim->mNumChannels)
throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'"); throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
// If we know how many frames we'll read, we can preallocate some storage // If we know how many frames we'll read, we can preallocate some storage
unsigned int alloc = 100; unsigned int alloc = 100;
if (last != 0x00ffffff) if (last != 0x00ffffff)
{ {
alloc = last-first; alloc = last-first;
alloc += alloc>>2u; // + 25% alloc += alloc>>2u; // + 25%
for (unsigned int i = 0; i < anim->mNumChannels;++i) for (unsigned int i = 0; i < anim->mNumChannels;++i)
anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc]; anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
} }
unsigned int filled = 0; unsigned int filled = 0;
// Now read all point data. // Now read all point data.
while (1) { while (1) {
SkipSpaces(&buffer); SkipSpaces(&buffer);
if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) { if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$')) {
break; // next section break; // next section
} }
// read frame // read frame
const int frame = ::strtoul10(buffer,&buffer); const int frame = ::strtoul10(buffer,&buffer);
last = std::max(frame,last); last = std::max(frame,last);
first = std::min(frame,last); first = std::min(frame,last);
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* s = anim->mChannels[i]; aiNodeAnim* s = anim->mChannels[i];
if (s->mNumPositionKeys == alloc) { /* need to reallocate? */ if (s->mNumPositionKeys == alloc) { /* need to reallocate? */
aiVectorKey* old = s->mPositionKeys; aiVectorKey* old = s->mPositionKeys;
s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2]; s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc); ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
delete[] old; delete[] old;
} }
// read x,y,z // read x,y,z
if(!SkipSpacesAndLineEnd(&buffer)) if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord"); throw DeadlyImportError("CSM: Unexpected EOF occured reading sample x coord");
if (TokenMatchI(buffer, "DROPOUT", 7)) { if (TokenMatchI(buffer, "DROPOUT", 7)) {
// seems this is invalid marker data; at least the doc says it's possible // seems this is invalid marker data; at least the doc says it's possible
DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)"); DefaultLogger::get()->warn("CSM: Encountered invalid marker data (DROPOUT)");
} }
else { else {
aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys; aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
sub->mTime = (double)frame; sub->mTime = (double)frame;
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
if(!SkipSpacesAndLineEnd(&buffer)) if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord"); throw DeadlyImportError("CSM: Unexpected EOF occured reading sample y coord");
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
if(!SkipSpacesAndLineEnd(&buffer)) if(!SkipSpacesAndLineEnd(&buffer))
throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord"); throw DeadlyImportError("CSM: Unexpected EOF occured reading sample z coord");
buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z); buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
++s->mNumPositionKeys; ++s->mNumPositionKeys;
} }
} }
// update allocation granularity // update allocation granularity
if (filled == alloc) if (filled == alloc)
alloc *= 2; alloc *= 2;
++filled; ++filled;
} }
// all channels must be complete in order to continue safely. // all channels must be complete in order to continue safely.
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
if (!anim->mChannels[i]->mNumPositionKeys) if (!anim->mChannels[i]->mNumPositionKeys)
throw DeadlyImportError("CSM: Invalid marker track"); throw DeadlyImportError("CSM: Invalid marker track");
} }
} }
} }
else { else {
// advance to the next line // advance to the next line
SkipLine(&buffer); SkipLine(&buffer);
} }
} }
// Setup a proper animation duration // Setup a proper animation duration
anim->mDuration = last - std::min( first, 0 ); anim->mDuration = last - std::min( first, 0 );
// build a dummy root node with the tiny markers as children // build a dummy root node with the tiny markers as children
pScene->mRootNode = new aiNode(); pScene->mRootNode = new aiNode();
pScene->mRootNode->mName.Set("$CSM_DummyRoot"); pScene->mRootNode->mName.Set("$CSM_DummyRoot");
pScene->mRootNode->mNumChildren = anim->mNumChannels; pScene->mRootNode->mNumChildren = anim->mNumChannels;
pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels]; pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
for (unsigned int i = 0; i < anim->mNumChannels;++i) { for (unsigned int i = 0; i < anim->mNumChannels;++i) {
aiNodeAnim* na = anim->mChannels[i]; aiNodeAnim* na = anim->mChannels[i];
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode(); aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
nd->mName = anim->mChannels[i]->mNodeName; nd->mName = anim->mChannels[i]->mNodeName;
nd->mParent = pScene->mRootNode; nd->mParent = pScene->mRootNode;
aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation); aiMatrix4x4::Translation(na->mPositionKeys[0].mValue, nd->mTransformation);
} }
// Store the one and only animation in the scene // Store the one and only animation in the scene
pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1]; pScene->mAnimations = new aiAnimation*[pScene->mNumAnimations=1];
pScene->mAnimations[0] = anim; pScene->mAnimations[0] = anim;
anim->mName.Set("$CSM_MasterAnim"); anim->mName.Set("$CSM_MasterAnim");
// mark the scene as incomplete and run SkeletonMeshBuilder on it // mark the scene as incomplete and run SkeletonMeshBuilder on it
pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE; pScene->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
if (!noSkeletonMesh) { if (!noSkeletonMesh) {
SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true); SkeletonMeshBuilder maker(pScene,pScene->mRootNode,true);
} }
} }
#endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER #endif // !! ASSIMP_BUILD_NO_CSM_IMPORTER

View File

@ -1,91 +1,91 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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
#include "BaseImporter.h" #include "BaseImporter.h"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Importer class to load MOCAPs in CharacterStudio Motion format. /** Importer class to load MOCAPs in CharacterStudio Motion format.
* *
* A very rudimentary loader for the moment. No support for the hierarchy, * A very rudimentary loader for the moment. No support for the hierarchy,
* every marker is returned as child of root. * every marker is returned as child of root.
* *
* Link to file format specification: * Link to file format specification:
* <max_8_dvd>\samples\Motion\Docs\CSM.rtf * <max_8_dvd>\samples\Motion\Docs\CSM.rtf
*/ */
class CSMImporter : public BaseImporter class CSMImporter : public BaseImporter
{ {
public: public:
CSMImporter(); CSMImporter();
~CSMImporter(); ~CSMImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void InternReadFile( const std::string& pFile, aiScene* pScene, void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
bool noSkeletonMesh; bool noSkeletonMesh;
}; // end of class CSMImporter }; // end of class CSMImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_AC3DIMPORTER_H_INC #endif // AI_AC3DIMPORTER_H_INC

View File

@ -1,317 +1,317 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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
*/ */
// internal headers // internal headers
#include "CalcTangentsProcess.h" #include "CalcTangentsProcess.h"
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "TinyFormatter.h" #include "TinyFormatter.h"
#include "qnan.h" #include "qnan.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-2015, 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,202 +1,202 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 "../include/assimp/material.h" #include "../include/assimp/material.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/light.h" #include "../include/assimp/light.h"
#include "../include/assimp/Exporter.hpp" #include "../include/assimp/Exporter.hpp"
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <map> #include <map>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
struct aiScene; struct aiScene;
struct aiNode; struct aiNode;
namespace Assimp namespace Assimp
{ {
/// Helper class to export a given scene to a Collada file. Just for my personal /// Helper class to export a given scene to a Collada file. Just for my personal
/// comfort when implementing it. /// comfort when implementing it.
class ColladaExporter class ColladaExporter
{ {
public: public:
/// Constructor for a specific scene to export /// Constructor for a specific scene to export
ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file); ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file);
/// Destructor /// Destructor
virtual ~ColladaExporter(); virtual ~ColladaExporter();
protected: protected:
/// Starts writing the contents /// Starts writing the contents
void WriteFile(); void WriteFile();
/// Writes the asset header /// Writes the asset header
void WriteHeader(); void WriteHeader();
/// Writes the embedded textures /// Writes the embedded textures
void WriteTextures(); void WriteTextures();
/// Writes the material setup /// Writes the material setup
void WriteMaterials(); void WriteMaterials();
/// Writes the cameras library /// Writes the cameras library
void WriteCamerasLibrary(); void WriteCamerasLibrary();
// Write a camera entry // Write a camera entry
void WriteCamera(size_t pIndex); void WriteCamera(size_t pIndex);
/// Writes the cameras library /// Writes the cameras library
void WriteLightsLibrary(); void WriteLightsLibrary();
// Write a camera entry // Write a camera entry
void WriteLight(size_t pIndex); void WriteLight(size_t pIndex);
void WritePointLight(const aiLight *const light); void WritePointLight(const aiLight *const light);
void WriteDirectionalLight(const aiLight *const light); void WriteDirectionalLight(const aiLight *const light);
void WriteSpotLight(const aiLight *const light); void WriteSpotLight(const aiLight *const light);
void WriteAmbienttLight(const aiLight *const light); void WriteAmbienttLight(const aiLight *const light);
/// Writes the geometry library /// Writes the geometry library
void WriteGeometryLibrary(); void WriteGeometryLibrary();
/// Writes the given mesh /// Writes the given mesh
void WriteGeometry( size_t pIndex); void WriteGeometry( size_t pIndex);
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color }; enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color };
/// Writes a float array of the given type /// Writes a float array of the given type
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount); void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const float* pData, size_t pElementCount);
/// Writes the scene library /// Writes the scene library
void WriteSceneLibrary(); void WriteSceneLibrary();
/// Recursively writes the given node /// Recursively writes the given node
void WriteNode( aiNode* pNode); void WriteNode( aiNode* pNode);
/// Enters a new xml element, which increases the indentation /// Enters a new xml element, which increases the indentation
void PushTag() { startstr.append( " "); } void PushTag() { startstr.append( " "); }
/// Leaves an element, decreasing the indentation /// Leaves an element, decreasing the indentation
void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); } void PopTag() { ai_assert( startstr.length() > 1); startstr.erase( startstr.length() - 2); }
/// Creates a mesh ID for the given mesh /// Creates a mesh ID for the given mesh
std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); } std::string GetMeshId( size_t pIndex) const { return std::string( "meshId" ) + boost::lexical_cast<std::string> (pIndex); }
public: public:
/// Stringstream to write all output into /// Stringstream to write all output into
std::stringstream mOutput; std::stringstream mOutput;
protected: protected:
/// The IOSystem for output /// The IOSystem for output
IOSystem* mIOSystem; IOSystem* mIOSystem;
/// Path of the directory where the scene will be exported /// Path of the directory where the scene will be exported
const std::string mPath; const std::string mPath;
/// Name of the file (without extension) where the scene will be exported /// Name of the file (without extension) where the scene will be exported
const std::string mFile; const std::string mFile;
/// The scene to be written /// The scene to be written
const aiScene* mScene; const aiScene* mScene;
bool mSceneOwned; bool mSceneOwned;
/// current line start string, contains the current indentation for simple stream insertion /// current line start string, contains the current indentation for simple stream insertion
std::string startstr; std::string startstr;
/// current line end string for simple stream insertion /// current line end string for simple stream insertion
std::string endstr; std::string endstr;
// pair of color and texture - texture precedences color // pair of color and texture - texture precedences color
struct Surface struct Surface
{ {
bool exist; bool exist;
aiColor4D color; aiColor4D color;
std::string texture; std::string texture;
size_t channel; size_t channel;
Surface() { exist = false; channel = 0; } Surface() { exist = false; channel = 0; }
}; };
struct Property struct Property
{ {
bool exist; bool exist;
float value; float value;
Property() Property()
: exist(false) : exist(false)
, value(0.0f) , value(0.0f)
{} {}
}; };
// summarize a material in an convinient way. // summarize a material in an convinient way.
struct Material struct Material
{ {
std::string name; std::string name;
std::string shading_model; std::string shading_model;
Surface ambient, diffuse, specular, emissive, reflective, transparent, normal; Surface ambient, diffuse, specular, emissive, reflective, transparent, normal;
Property shininess, transparency, index_refraction; Property shininess, transparency, index_refraction;
Material() {} Material() {}
}; };
std::vector<Material> materials; std::vector<Material> materials;
std::map<unsigned int, std::string> textures; std::map<unsigned int, std::string> textures;
protected: protected:
/// Dammit C++ - y u no compile two-pass? No I have to add all methods below the struct definitions /// 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 /// 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); 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 /// Writes an image entry for the given surface
void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd); void WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd);
/// Writes the two parameters necessary for referencing a texture in an effect entry /// 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); void WriteTextureParamEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pMatName);
/// Writes a color-or-texture entry into an effect definition /// Writes a color-or-texture entry into an effect definition
void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName); void WriteTextureColorEntry( const Surface& pSurface, const std::string& pTypeName, const std::string& pImageName);
/// Writes a scalar property /// Writes a scalar property
void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName); void WriteFloatEntry( const Property& pProperty, const std::string& pTypeName);
}; };
} }
#endif // !! AI_COLLADAEXPORTER_H_INC #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,252 +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-2015, 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"
struct aiNode; struct aiNode;
struct aiCamera; struct aiCamera;
struct aiLight; struct aiLight;
struct aiTexture; struct aiTexture;
struct aiAnimation; struct aiAnimation;
namespace Assimp namespace Assimp
{ {
struct ColladaMeshIndex struct ColladaMeshIndex
{ {
std::string mMeshID; std::string mMeshID;
size_t mSubMesh; size_t mSubMesh;
std::string mMaterial; std::string mMaterial;
ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial) ColladaMeshIndex( const std::string& pMeshID, size_t pSubMesh, const std::string& pMaterial)
: mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial) : mMeshID( pMeshID), mSubMesh( pSubMesh), mMaterial( pMaterial)
{ } { }
bool operator < (const ColladaMeshIndex& p) const bool operator < (const ColladaMeshIndex& p) const
{ {
if( mMeshID == p.mMeshID) if( mMeshID == p.mMeshID)
{ {
if( mSubMesh == p.mSubMesh) if( mSubMesh == p.mSubMesh)
return mMaterial < p.mMaterial; return mMaterial < p.mMaterial;
else else
return mSubMesh < p.mSubMesh; return mSubMesh < p.mSubMesh;
} else } else
{ {
return mMeshID < p.mMeshID; return mMeshID < p.mMeshID;
} }
} }
}; };
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing /** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
* more useless stuff, so I limited the data to what I think is useful for games. * more useless stuff, so I limited the data to what I think is useful for games.
*/ */
class ColladaLoader : public BaseImporter class ColladaLoader : public BaseImporter
{ {
public: public:
ColladaLoader(); ColladaLoader();
~ColladaLoader(); ~ColladaLoader();
public: public:
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const; bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
protected: protected:
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details * See #BaseImporter::GetInfo for the details
*/ */
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details * See BaseImporter::InternReadFile() for details
*/ */
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler); void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
/** Recursively constructs a scene node for the given parser node and returns it. */ /** Recursively constructs a scene node for the given parser node and returns it. */
aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode); aiNode* BuildHierarchy( const ColladaParser& pParser, const Collada::Node* pNode);
/** Resolve node instances */ /** Resolve node instances */
void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode, void ResolveNodeInstances( const ColladaParser& pParser, const Collada::Node* pNode,
std::vector<const Collada::Node*>& resolved); std::vector<const Collada::Node*>& resolved);
/** Builds meshes for the given node and references them */ /** Builds meshes for the given node and references them */
void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildMeshesForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
/** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */ /** Creates a mesh for the given ColladaMesh face subset and returns the newly created mesh */
aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh, aiMesh* CreateMesh( const ColladaParser& pParser, const Collada::Mesh* pSrcMesh, const Collada::SubMesh& pSubMesh,
const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace); const Collada::Controller* pSrcController, size_t pStartVertex, size_t pStartFace);
/** Builds cameras for the given node and references them */ /** Builds cameras for the given node and references them */
void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildCamerasForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
/** Builds lights for the given node and references them */ /** Builds lights for the given node and references them */
void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode, void BuildLightsForNode( const ColladaParser& pParser, const Collada::Node* pNode,
aiNode* pTarget); aiNode* pTarget);
/** Stores all meshes in the given scene */ /** Stores all meshes in the given scene */
void StoreSceneMeshes( aiScene* pScene); void StoreSceneMeshes( aiScene* pScene);
/** Stores all materials in the given scene */ /** Stores all materials in the given scene */
void StoreSceneMaterials( aiScene* pScene); void StoreSceneMaterials( aiScene* pScene);
/** Stores all lights in the given scene */ /** Stores all lights in the given scene */
void StoreSceneLights( aiScene* pScene); void StoreSceneLights( aiScene* pScene);
/** Stores all cameras in the given scene */ /** Stores all cameras in the given scene */
void StoreSceneCameras( aiScene* pScene); void StoreSceneCameras( aiScene* pScene);
/** Stores all textures in the given scene */ /** Stores all textures in the given scene */
void StoreSceneTextures( aiScene* pScene); void StoreSceneTextures( aiScene* pScene);
/** Stores all animations /** Stores all animations
* @param pScene target scene to store the anims * @param pScene target scene to store the anims
*/ */
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser); void StoreAnimations( aiScene* pScene, const ColladaParser& pParser);
/** Stores all animations for the given source anim and its nested child animations /** Stores all animations for the given source anim and its nested child animations
* @param pScene target scene to store the anims * @param pScene target scene to store the anims
* @param pSrcAnim the source animation to process * @param pSrcAnim the source animation to process
* @param pPrefix Prefix to the name in case of nested animations * @param pPrefix Prefix to the name in case of nested animations
*/ */
void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix); void StoreAnimations( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pPrefix);
/** Constructs the animation for the given source anim */ /** Constructs the animation for the given source anim */
void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName); void CreateAnimation( aiScene* pScene, const ColladaParser& pParser, const Collada::Animation* pSrcAnim, const std::string& pName);
/** Constructs materials from the collada material definitions */ /** Constructs materials from the collada material definitions */
void BuildMaterials( ColladaParser& pParser, aiScene* pScene); void BuildMaterials( ColladaParser& pParser, aiScene* pScene);
/** Fill materials from the collada material definitions */ /** Fill materials from the collada material definitions */
void FillMaterials( const ColladaParser& pParser, aiScene* pScene); void FillMaterials( const ColladaParser& pParser, aiScene* pScene);
/** Resolve UV channel mappings*/ /** Resolve UV channel mappings*/
void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler, void ApplyVertexToEffectSemanticMapping(Collada::Sampler& sampler,
const Collada::SemanticMappingTable& table); const Collada::SemanticMappingTable& table);
/** Add a texture and all of its sampling properties to a material*/ /** Add a texture and all of its sampling properties to a material*/
void AddTexture ( aiMaterial& mat, const ColladaParser& pParser, void AddTexture ( aiMaterial& mat, const ColladaParser& pParser,
const Collada::Effect& effect, const Collada::Effect& effect,
const Collada::Sampler& sampler, const Collada::Sampler& sampler,
aiTextureType type, unsigned int idx = 0); aiTextureType type, unsigned int idx = 0);
/** Resolves the texture name for the given effect texture entry */ /** Resolves the texture name for the given effect texture entry */
aiString FindFilenameForEffectTexture( const ColladaParser& pParser, aiString FindFilenameForEffectTexture( const ColladaParser& pParser,
const Collada::Effect& pEffect, const std::string& pName); const Collada::Effect& pEffect, const std::string& pName);
/** Converts a path read from a collada file to the usual representation */ /** Converts a path read from a collada file to the usual representation */
void ConvertPath( aiString& ss); void ConvertPath( aiString& ss);
/** Reads a float value from an accessor and its data array. /** Reads a float value from an accessor and its data array.
* @param pAccessor The accessor to use for reading * @param pAccessor The accessor to use for reading
* @param pData The data array to read from * @param pData The data array to read from
* @param pIndex The index of the element to retrieve * @param pIndex The index of the element to retrieve
* @param pOffset Offset into the element, for multipart elements such as vectors or matrices * @param pOffset Offset into the element, for multipart elements such as vectors or matrices
* @return the specified value * @return the specified value
*/ */
float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const; float ReadFloat( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex, size_t pOffset) const;
/** Reads a string value from an accessor and its data array. /** Reads a string value from an accessor and its data array.
* @param pAccessor The accessor to use for reading * @param pAccessor The accessor to use for reading
* @param pData The data array to read from * @param pData The data array to read from
* @param pIndex The index of the element to retrieve * @param pIndex The index of the element to retrieve
* @return the specified value * @return the specified value
*/ */
const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const; const std::string& ReadString( const Collada::Accessor& pAccessor, const Collada::Data& pData, size_t pIndex) const;
/** Recursively collects all nodes into the given array */ /** Recursively collects all nodes into the given array */
void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const; void CollectNodes( const aiNode* pNode, std::vector<const aiNode*>& poNodes) const;
/** Finds a node in the collada scene by the given name */ /** Finds a node in the collada scene by the given name */
const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const; const Collada::Node* FindNode( const Collada::Node* pNode, const std::string& pName) const;
/** Finds a node in the collada scene by the given SID */ /** Finds a node in the collada scene by the given SID */
const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const; const Collada::Node* FindNodeBySID( const Collada::Node* pNode, const std::string& pSID) const;
/** Finds a proper name for a node derived from the collada-node's properties */ /** Finds a proper name for a node derived from the collada-node's properties */
std::string FindNameForNode( const Collada::Node* pNode); std::string FindNameForNode( const Collada::Node* pNode);
protected: protected:
/** Filename, for a verbose error message */ /** Filename, for a verbose error message */
std::string mFileName; std::string mFileName;
/** Which mesh-material compound was stored under which mesh ID */ /** Which mesh-material compound was stored under which mesh ID */
std::map<ColladaMeshIndex, size_t> mMeshIndexByID; std::map<ColladaMeshIndex, size_t> mMeshIndexByID;
/** Which material was stored under which index in the scene */ /** Which material was stored under which index in the scene */
std::map<std::string, size_t> mMaterialIndexByName; std::map<std::string, size_t> mMaterialIndexByName;
/** Accumulated meshes for the target scene */ /** Accumulated meshes for the target scene */
std::vector<aiMesh*> mMeshes; std::vector<aiMesh*> mMeshes;
/** Temporary material list */ /** Temporary material list */
std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats; std::vector<std::pair<Collada::Effect*, aiMaterial*> > newMats;
/** Temporary camera list */ /** Temporary camera list */
std::vector<aiCamera*> mCameras; std::vector<aiCamera*> mCameras;
/** Temporary light list */ /** Temporary light list */
std::vector<aiLight*> mLights; std::vector<aiLight*> mLights;
/** Temporary texture list */ /** Temporary texture list */
std::vector<aiTexture*> mTextures; std::vector<aiTexture*> mTextures;
/** Accumulated animations for the target scene */ /** Accumulated animations for the target scene */
std::vector<aiAnimation*> mAnims; std::vector<aiAnimation*> mAnims;
bool noSkeletonMesh; bool noSkeletonMesh;
bool ignoreUpDirection; bool ignoreUpDirection;
bool invertTransparency; bool invertTransparency;
/** Used by FindNameForNode() to generate unique node names */ /** Used by FindNameForNode() to generate unique node names */
unsigned int mNodeNameCounter; unsigned int mNodeNameCounter;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_COLLADALOADER_H_INC #endif // AI_COLLADALOADER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,352 +1,352 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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" #include "../include/assimp/ai_assert.h"
#include <boost/format.hpp> #include <boost/format.hpp>
namespace Assimp namespace Assimp
{ {
// ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------
/** Parser helper class for the Collada loader. /** Parser helper class for the Collada loader.
* *
* Does all the XML reading and builds internal data structures from it, * Does all the XML reading and builds internal data structures from it,
* but leaves the resolving of all the references to the loader. * but leaves the resolving of all the references to the loader.
*/ */
class ColladaParser class ColladaParser
{ {
friend class ColladaLoader; friend class ColladaLoader;
protected: protected:
/** Constructor from XML file */ /** Constructor from XML file */
ColladaParser( IOSystem* pIOHandler, const std::string& pFile); ColladaParser( IOSystem* pIOHandler, const std::string& pFile);
/** Destructor */ /** Destructor */
~ColladaParser(); ~ColladaParser();
/** Reads the contents of the file */ /** Reads the contents of the file */
void ReadContents(); void ReadContents();
/** Reads the structure of the file */ /** Reads the structure of the file */
void ReadStructure(); void ReadStructure();
/** Reads asset informations such as coordinate system informations and legal blah */ /** Reads asset informations such as coordinate system informations and legal blah */
void ReadAssetInfo(); void ReadAssetInfo();
/** Reads the animation library */ /** Reads the animation library */
void ReadAnimationLibrary(); void ReadAnimationLibrary();
/** Reads an animation into the given parent structure */ /** Reads an animation into the given parent structure */
void ReadAnimation( Collada::Animation* pParent); void ReadAnimation( Collada::Animation* pParent);
/** Reads an animation sampler into the given anim channel */ /** Reads an animation sampler into the given anim channel */
void ReadAnimationSampler( Collada::AnimationChannel& pChannel); void ReadAnimationSampler( Collada::AnimationChannel& pChannel);
/** Reads the skeleton controller library */ /** Reads the skeleton controller library */
void ReadControllerLibrary(); void ReadControllerLibrary();
/** Reads a controller into the given mesh structure */ /** Reads a controller into the given mesh structure */
void ReadController( Collada::Controller& pController); void ReadController( Collada::Controller& pController);
/** Reads the joint definitions for the given controller */ /** Reads the joint definitions for the given controller */
void ReadControllerJoints( Collada::Controller& pController); void ReadControllerJoints( Collada::Controller& pController);
/** Reads the joint weights for the given controller */ /** Reads the joint weights for the given controller */
void ReadControllerWeights( Collada::Controller& pController); void ReadControllerWeights( Collada::Controller& pController);
/** Reads the image library contents */ /** Reads the image library contents */
void ReadImageLibrary(); void ReadImageLibrary();
/** Reads an image entry into the given image */ /** Reads an image entry into the given image */
void ReadImage( Collada::Image& pImage); void ReadImage( Collada::Image& pImage);
/** Reads the material library */ /** Reads the material library */
void ReadMaterialLibrary(); void ReadMaterialLibrary();
/** Reads a material entry into the given material */ /** Reads a material entry into the given material */
void ReadMaterial( Collada::Material& pMaterial); void ReadMaterial( Collada::Material& pMaterial);
/** Reads the camera library */ /** Reads the camera library */
void ReadCameraLibrary(); void ReadCameraLibrary();
/** Reads a camera entry into the given camera */ /** Reads a camera entry into the given camera */
void ReadCamera( Collada::Camera& pCamera); void ReadCamera( Collada::Camera& pCamera);
/** Reads the light library */ /** Reads the light library */
void ReadLightLibrary(); void ReadLightLibrary();
/** Reads a light entry into the given light */ /** Reads a light entry into the given light */
void ReadLight( Collada::Light& pLight); void ReadLight( Collada::Light& pLight);
/** Reads the effect library */ /** Reads the effect library */
void ReadEffectLibrary(); void ReadEffectLibrary();
/** Reads an effect entry into the given effect*/ /** Reads an effect entry into the given effect*/
void ReadEffect( Collada::Effect& pEffect); void ReadEffect( Collada::Effect& pEffect);
/** Reads an COMMON effect profile */ /** Reads an COMMON effect profile */
void ReadEffectProfileCommon( Collada::Effect& pEffect); void ReadEffectProfileCommon( Collada::Effect& pEffect);
/** Read sampler properties */ /** Read sampler properties */
void ReadSamplerProperties( Collada::Sampler& pSampler); void ReadSamplerProperties( Collada::Sampler& pSampler);
/** Reads an effect entry containing a color or a texture defining that color */ /** Reads an effect entry containing a color or a texture defining that color */
void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler); void ReadEffectColor( aiColor4D& pColor, Collada::Sampler& pSampler);
/** Reads an effect entry containing a float */ /** Reads an effect entry containing a float */
void ReadEffectFloat( float& pFloat); void ReadEffectFloat( float& pFloat);
/** Reads an effect parameter specification of any kind */ /** Reads an effect parameter specification of any kind */
void ReadEffectParam( Collada::EffectParam& pParam); void ReadEffectParam( Collada::EffectParam& pParam);
/** Reads the geometry library contents */ /** Reads the geometry library contents */
void ReadGeometryLibrary(); void ReadGeometryLibrary();
/** Reads a geometry from the geometry library. */ /** Reads a geometry from the geometry library. */
void ReadGeometry( Collada::Mesh* pMesh); void ReadGeometry( Collada::Mesh* pMesh);
/** Reads a mesh from the geometry library */ /** Reads a mesh from the geometry library */
void ReadMesh( Collada::Mesh* pMesh); void ReadMesh( Collada::Mesh* pMesh);
/** Reads a source element - a combination of raw data and an accessor defining /** Reads a source element - a combination of raw data and an accessor defining
* things that should not be redefinable. Yes, that's another rant. * things that should not be redefinable. Yes, that's another rant.
*/ */
void ReadSource(); void ReadSource();
/** Reads a data array holding a number of elements, and stores it in the global library. /** Reads a data array holding a number of elements, and stores it in the global library.
* Currently supported are array of floats and arrays of strings. * Currently supported are array of floats and arrays of strings.
*/ */
void ReadDataArray(); void ReadDataArray();
/** Reads an accessor and stores it in the global library under the given ID - /** Reads an accessor and stores it in the global library under the given ID -
* accessors use the ID of the parent <source> element * accessors use the ID of the parent <source> element
*/ */
void ReadAccessor( const std::string& pID); void ReadAccessor( const std::string& pID);
/** Reads input declarations of per-vertex mesh data into the given mesh */ /** Reads input declarations of per-vertex mesh data into the given mesh */
void ReadVertexData( Collada::Mesh* pMesh); void ReadVertexData( Collada::Mesh* pMesh);
/** Reads input declarations of per-index mesh data into the given mesh */ /** Reads input declarations of per-index mesh data into the given mesh */
void ReadIndexData( Collada::Mesh* pMesh); void ReadIndexData( Collada::Mesh* pMesh);
/** Reads a single input channel element and stores it in the given array, if valid */ /** Reads a single input channel element and stores it in the given array, if valid */
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels); void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */ /** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType); size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
/** Copies the data for a single primitive into the mesh, based on the InputChannels */ /** Copies the data for a single primitive into the mesh, based on the InputChannels */
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels, Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t currentPrimitive, const std::vector<size_t>& indices); size_t currentPrimitive, const std::vector<size_t>& indices);
/** Reads one triangle of a tristrip into the mesh */ /** Reads one triangle of a tristrip into the mesh */
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh, void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices); std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */ /** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh); void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);
/** Reads the library of node hierarchies and scene parts */ /** Reads the library of node hierarchies and scene parts */
void ReadSceneLibrary(); void ReadSceneLibrary();
/** Reads a scene node's contents including children and stores it in the given node */ /** Reads a scene node's contents including children and stores it in the given node */
void ReadSceneNode( Collada::Node* pNode); void ReadSceneNode( Collada::Node* pNode);
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */ /** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType); void ReadNodeTransformation( Collada::Node* pNode, Collada::TransformType pType);
/** Reads a mesh reference in a node and adds it to the node's mesh list */ /** Reads a mesh reference in a node and adds it to the node's mesh list */
void ReadNodeGeometry( Collada::Node* pNode); void ReadNodeGeometry( Collada::Node* pNode);
/** Reads the collada scene */ /** Reads the collada scene */
void ReadScene(); void ReadScene();
// Processes bind_vertex_input and bind elements // Processes bind_vertex_input and bind elements
void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl); void ReadMaterialVertexInputBinding( Collada::SemanticMappingTable& tbl);
protected: protected:
/** Aborts the file reading with an exception */ /** Aborts the file reading with an exception */
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
/** Skips all data until the end node of the current element */ /** Skips all data until the end node of the current element */
void SkipElement(); void SkipElement();
/** Skips all data until the end node of the given element */ /** Skips all data until the end node of the given element */
void SkipElement( const char* pElement); void SkipElement( const char* pElement);
/** Compares the current xml element name to the given string and returns true if equal */ /** Compares the current xml element name to the given string and returns true if equal */
bool IsElement( const char* pName) const; bool IsElement( const char* pName) const;
/** Tests for the opening tag of the given element, throws an exception if not found */ /** Tests for the opening tag of the given element, throws an exception if not found */
void TestOpening( const char* pName); void TestOpening( const char* pName);
/** Tests for the closing tag of the given element, throws an exception if not found */ /** Tests for the closing tag of the given element, throws an exception if not found */
void TestClosing( const char* pName); void TestClosing( const char* pName);
/** Checks the present element for the presence of the attribute, returns its index /** Checks the present element for the presence of the attribute, returns its index
or throws an exception if not found */ or throws an exception if not found */
int GetAttribute( const char* pAttr) const; int GetAttribute( const char* pAttr) const;
/** Returns the index of the named attribute or -1 if not found. Does not throw, /** Returns the index of the named attribute or -1 if not found. Does not throw,
therefore useful for optional attributes */ therefore useful for optional attributes */
int TestAttribute( const char* pAttr) const; int TestAttribute( const char* pAttr) const;
/** Reads the text contents of an element, throws an exception if not given. /** Reads the text contents of an element, throws an exception if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char* GetTextContent(); const char* GetTextContent();
/** Reads the text contents of an element, returns NULL if not given. /** Reads the text contents of an element, returns NULL if not given.
Skips leading whitespace. */ Skips leading whitespace. */
const char* TestTextContent(); const char* TestTextContent();
/** Reads a single bool from current text content */ /** Reads a single bool from current text content */
bool ReadBoolFromTextContent(); bool ReadBoolFromTextContent();
/** Reads a single float from current text content */ /** Reads a single float from current text content */
float ReadFloatFromTextContent(); float ReadFloatFromTextContent();
/** Calculates the resulting transformation from all the given transform steps */ /** Calculates the resulting transformation from all the given transform steps */
aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const; aiMatrix4x4 CalculateResultTransform( const std::vector<Collada::Transform>& pTransforms) const;
/** Determines the input data type for the given semantic string */ /** Determines the input data type for the given semantic string */
Collada::InputType GetTypeForSemantic( const std::string& pSemantic); Collada::InputType GetTypeForSemantic( const std::string& pSemantic);
/** Finds the item in the given library by its reference, throws if not found */ /** Finds the item in the given library by its reference, throws if not found */
template <typename Type> const Type& ResolveLibraryReference( template <typename Type> const Type& ResolveLibraryReference(
const std::map<std::string, Type>& pLibrary, const std::string& pURL) const; const std::map<std::string, Type>& pLibrary, const std::string& pURL) const;
protected: protected:
/** Filename, for a verbose error message */ /** Filename, for a verbose error message */
std::string mFileName; std::string mFileName;
/** XML reader, member for everyday use */ /** XML reader, member for everyday use */
irr::io::IrrXMLReader* mReader; irr::io::IrrXMLReader* mReader;
/** All data arrays found in the file by ID. Might be referred to by actually /** All data arrays found in the file by ID. Might be referred to by actually
everyone. Collada, you are a steaming pile of indirection. */ everyone. Collada, you are a steaming pile of indirection. */
typedef std::map<std::string, Collada::Data> DataLibrary; typedef std::map<std::string, Collada::Data> DataLibrary;
DataLibrary mDataLibrary; DataLibrary mDataLibrary;
/** Same for accessors which define how the data in a data array is accessed. */ /** Same for accessors which define how the data in a data array is accessed. */
typedef std::map<std::string, Collada::Accessor> AccessorLibrary; typedef std::map<std::string, Collada::Accessor> AccessorLibrary;
AccessorLibrary mAccessorLibrary; AccessorLibrary mAccessorLibrary;
/** Mesh library: mesh by ID */ /** Mesh library: mesh by ID */
typedef std::map<std::string, Collada::Mesh*> MeshLibrary; typedef std::map<std::string, Collada::Mesh*> MeshLibrary;
MeshLibrary mMeshLibrary; MeshLibrary mMeshLibrary;
/** node library: root node of the hierarchy part by ID */ /** node library: root node of the hierarchy part by ID */
typedef std::map<std::string, Collada::Node*> NodeLibrary; typedef std::map<std::string, Collada::Node*> NodeLibrary;
NodeLibrary mNodeLibrary; NodeLibrary mNodeLibrary;
/** Image library: stores texture properties by ID */ /** Image library: stores texture properties by ID */
typedef std::map<std::string, Collada::Image> ImageLibrary; typedef std::map<std::string, Collada::Image> ImageLibrary;
ImageLibrary mImageLibrary; ImageLibrary mImageLibrary;
/** Effect library: surface attributes by ID */ /** Effect library: surface attributes by ID */
typedef std::map<std::string, Collada::Effect> EffectLibrary; typedef std::map<std::string, Collada::Effect> EffectLibrary;
EffectLibrary mEffectLibrary; EffectLibrary mEffectLibrary;
/** Material library: surface material by ID */ /** Material library: surface material by ID */
typedef std::map<std::string, Collada::Material> MaterialLibrary; typedef std::map<std::string, Collada::Material> MaterialLibrary;
MaterialLibrary mMaterialLibrary; MaterialLibrary mMaterialLibrary;
/** Light library: surface light by ID */ /** Light library: surface light by ID */
typedef std::map<std::string, Collada::Light> LightLibrary; typedef std::map<std::string, Collada::Light> LightLibrary;
LightLibrary mLightLibrary; LightLibrary mLightLibrary;
/** Camera library: surface material by ID */ /** Camera library: surface material by ID */
typedef std::map<std::string, Collada::Camera> CameraLibrary; typedef std::map<std::string, Collada::Camera> CameraLibrary;
CameraLibrary mCameraLibrary; CameraLibrary mCameraLibrary;
/** Controller library: joint controllers by ID */ /** Controller library: joint controllers by ID */
typedef std::map<std::string, Collada::Controller> ControllerLibrary; typedef std::map<std::string, Collada::Controller> ControllerLibrary;
ControllerLibrary mControllerLibrary; ControllerLibrary mControllerLibrary;
/** Pointer to the root node. Don't delete, it just points to one of /** Pointer to the root node. Don't delete, it just points to one of
the nodes in the node library. */ the nodes in the node library. */
Collada::Node* mRootNode; Collada::Node* mRootNode;
/** Root animation container */ /** Root animation container */
Collada::Animation mAnims; Collada::Animation mAnims;
/** Size unit: how large compared to a meter */ /** Size unit: how large compared to a meter */
float mUnitSize; float mUnitSize;
/** Which is the up vector */ /** Which is the up vector */
enum { UP_X, UP_Y, UP_Z } mUpDirection; enum { UP_X, UP_Y, UP_Z } mUpDirection;
/** Collada file format version */ /** Collada file format version */
Collada::FormatVersion mFormat; Collada::FormatVersion mFormat;
}; };
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Check for element match // Check for element match
inline bool ColladaParser::IsElement( const char* pName) const inline bool ColladaParser::IsElement( const char* pName) const
{ {
ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); ai_assert( mReader->getNodeType() == irr::io::EXN_ELEMENT);
return ::strcmp( mReader->getNodeName(), pName) == 0; return ::strcmp( mReader->getNodeName(), pName) == 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Finds the item in the given library by its reference, throws if not found // Finds the item in the given library by its reference, throws if not found
template <typename Type> template <typename Type>
const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const const Type& ColladaParser::ResolveLibraryReference( const std::map<std::string, Type>& pLibrary, const std::string& pURL) const
{ {
typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL); typename std::map<std::string, Type>::const_iterator it = pLibrary.find( pURL);
if( it == pLibrary.end()) if( it == pLibrary.end())
ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL)); ThrowException( boost::str( boost::format( "Unable to resolve library reference \"%s\".") % pURL));
return it->second; return it->second;
} }
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_COLLADAPARSER_H_INC #endif // AI_COLLADAPARSER_H_INC

File diff suppressed because it is too large Load Diff

View File

@ -1,147 +1,147 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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" #include "../include/assimp/material.h"
#include "../include/assimp/types.h" #include "../include/assimp/types.h"
class ComputeUVMappingTest; class ComputeUVMappingTest;
namespace Assimp namespace Assimp
{ {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** ComputeUVMappingProcess - converts special mappings, such as spherical, /** ComputeUVMappingProcess - converts special mappings, such as spherical,
* cylindrical or boxed to proper UV coordinates for rendering. * cylindrical or boxed to proper UV coordinates for rendering.
*/ */
class ComputeUVMappingProcess : public BaseProcess class ComputeUVMappingProcess : public BaseProcess
{ {
public: public:
ComputeUVMappingProcess(); ComputeUVMappingProcess();
~ComputeUVMappingProcess(); ~ComputeUVMappingProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag field. /** Returns whether the processing step is present in the given flag field.
* @param pFlags The processing flags the importer was called with. A bitwise * @param pFlags The processing flags the importer was called with. A bitwise
* combination of #aiPostProcessSteps. * combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, false if not. * @return true if the process is present in this flag fields, false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes spherical UV coordinates for a mesh /** Computes spherical UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param axis Main axis * @param axis Main axis
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, void ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis,
aiVector3D* out); aiVector3D* out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes cylindrical UV coordinates for a mesh /** Computes cylindrical UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param axis Main axis * @param axis Main axis
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, void ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis,
aiVector3D* out); aiVector3D* out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes planar UV coordinates for a mesh /** Computes planar UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param axis Main axis * @param axis Main axis
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, void ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis,
aiVector3D* out); aiVector3D* out);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Computes cubic UV coordinates for a mesh /** Computes cubic UV coordinates for a mesh
* *
* @param mesh Mesh to be processed * @param mesh Mesh to be processed
* @param out Receives output UV coordinates * @param out Receives output UV coordinates
*/ */
void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out); void ComputeBoxMapping(aiMesh* mesh, aiVector3D* out);
private: private:
// temporary structure to describe a mapping // temporary structure to describe a mapping
struct MappingInfo struct MappingInfo
{ {
MappingInfo(aiTextureMapping _type) MappingInfo(aiTextureMapping _type)
: type (_type) : type (_type)
, axis (0.f,1.f,0.f) , axis (0.f,1.f,0.f)
, uv (0u) , uv (0u)
{} {}
aiTextureMapping type; aiTextureMapping type;
aiVector3D axis; aiVector3D axis;
unsigned int uv; unsigned int uv;
bool operator== (const MappingInfo& other) bool operator== (const MappingInfo& other)
{ {
return type == other.type && axis == other.axis; return type == other.type && axis == other.axis;
} }
}; };
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_COMPUTEUVMAPPING_H_INC #endif // AI_COMPUTEUVMAPPING_H_INC

View File

@ -1,331 +1,331 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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 "ConvertToLHProcess.h" #include "ConvertToLHProcess.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
#include "../include/assimp/postprocess.h" #include "../include/assimp/postprocess.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
using namespace Assimp; using namespace Assimp;
#ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS #ifndef ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
MakeLeftHandedProcess::MakeLeftHandedProcess() MakeLeftHandedProcess::MakeLeftHandedProcess()
: BaseProcess() { : BaseProcess() {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
MakeLeftHandedProcess::~MakeLeftHandedProcess() { MakeLeftHandedProcess::~MakeLeftHandedProcess() {
// empty // empty
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const bool MakeLeftHandedProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_MakeLeftHanded); return 0 != (pFlags & aiProcess_MakeLeftHanded);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void MakeLeftHandedProcess::Execute( aiScene* pScene) void MakeLeftHandedProcess::Execute( aiScene* pScene)
{ {
// Check for an existent root node to proceed // Check for an existent root node to proceed
ai_assert(pScene->mRootNode != NULL); ai_assert(pScene->mRootNode != NULL);
DefaultLogger::get()->debug("MakeLeftHandedProcess begin"); DefaultLogger::get()->debug("MakeLeftHandedProcess begin");
// recursively convert all the nodes // recursively convert all the nodes
ProcessNode( pScene->mRootNode, aiMatrix4x4()); ProcessNode( pScene->mRootNode, aiMatrix4x4());
// process the meshes accordingly // process the meshes accordingly
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a) for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
ProcessMesh( pScene->mMeshes[a]); ProcessMesh( pScene->mMeshes[a]);
// process the materials accordingly // process the materials accordingly
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a) for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
ProcessMaterial( pScene->mMaterials[a]); ProcessMaterial( pScene->mMaterials[a]);
// transform all animation channels as well // transform all animation channels as well
for( unsigned int a = 0; a < pScene->mNumAnimations; a++) for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
{ {
aiAnimation* anim = pScene->mAnimations[a]; aiAnimation* anim = pScene->mAnimations[a];
for( unsigned int b = 0; b < anim->mNumChannels; b++) for( unsigned int b = 0; b < anim->mNumChannels; b++)
{ {
aiNodeAnim* nodeAnim = anim->mChannels[b]; aiNodeAnim* nodeAnim = anim->mChannels[b];
ProcessAnimation( nodeAnim); ProcessAnimation( nodeAnim);
} }
} }
DefaultLogger::get()->debug("MakeLeftHandedProcess finished"); DefaultLogger::get()->debug("MakeLeftHandedProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively converts a node, all of its children and all of its meshes // Recursively converts a node, all of its children and all of its meshes
void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation) void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation)
{ {
// mirror all base vectors at the local Z axis // mirror all base vectors at the local Z axis
pNode->mTransformation.c1 = -pNode->mTransformation.c1; pNode->mTransformation.c1 = -pNode->mTransformation.c1;
pNode->mTransformation.c2 = -pNode->mTransformation.c2; pNode->mTransformation.c2 = -pNode->mTransformation.c2;
pNode->mTransformation.c3 = -pNode->mTransformation.c3; pNode->mTransformation.c3 = -pNode->mTransformation.c3;
pNode->mTransformation.c4 = -pNode->mTransformation.c4; pNode->mTransformation.c4 = -pNode->mTransformation.c4;
// now invert the Z axis again to keep the matrix determinant positive. // now invert the Z axis again to keep the matrix determinant positive.
// The local meshes will be inverted accordingly so that the result should look just fine again. // The local meshes will be inverted accordingly so that the result should look just fine again.
pNode->mTransformation.a3 = -pNode->mTransformation.a3; pNode->mTransformation.a3 = -pNode->mTransformation.a3;
pNode->mTransformation.b3 = -pNode->mTransformation.b3; pNode->mTransformation.b3 = -pNode->mTransformation.b3;
pNode->mTransformation.c3 = -pNode->mTransformation.c3; pNode->mTransformation.c3 = -pNode->mTransformation.c3;
pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways... pNode->mTransformation.d3 = -pNode->mTransformation.d3; // useless, but anyways...
// continue for all children // continue for all children
for( size_t a = 0; a < pNode->mNumChildren; ++a ) { for( size_t a = 0; a < pNode->mNumChildren; ++a ) {
ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation ); ProcessNode( pNode->mChildren[ a ], pParentGlobalRotation * pNode->mTransformation );
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single mesh to left handed coordinates. // Converts a single mesh to left handed coordinates.
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
{ {
// mirror positions, normals and stuff along the Z axis // mirror positions, normals and stuff along the Z axis
for( size_t a = 0; a < pMesh->mNumVertices; ++a) for( size_t a = 0; a < pMesh->mNumVertices; ++a)
{ {
pMesh->mVertices[a].z *= -1.0f; pMesh->mVertices[a].z *= -1.0f;
if( pMesh->HasNormals()) if( pMesh->HasNormals())
pMesh->mNormals[a].z *= -1.0f; pMesh->mNormals[a].z *= -1.0f;
if( pMesh->HasTangentsAndBitangents()) if( pMesh->HasTangentsAndBitangents())
{ {
pMesh->mTangents[a].z *= -1.0f; pMesh->mTangents[a].z *= -1.0f;
pMesh->mBitangents[a].z *= -1.0f; pMesh->mBitangents[a].z *= -1.0f;
} }
} }
// mirror offset matrices of all bones // mirror offset matrices of all bones
for( size_t a = 0; a < pMesh->mNumBones; ++a) for( size_t a = 0; a < pMesh->mNumBones; ++a)
{ {
aiBone* bone = pMesh->mBones[a]; aiBone* bone = pMesh->mBones[a];
bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3; bone->mOffsetMatrix.a3 = -bone->mOffsetMatrix.a3;
bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3; bone->mOffsetMatrix.b3 = -bone->mOffsetMatrix.b3;
bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3; bone->mOffsetMatrix.d3 = -bone->mOffsetMatrix.d3;
bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1; bone->mOffsetMatrix.c1 = -bone->mOffsetMatrix.c1;
bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2; bone->mOffsetMatrix.c2 = -bone->mOffsetMatrix.c2;
bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4; bone->mOffsetMatrix.c4 = -bone->mOffsetMatrix.c4;
} }
// mirror bitangents as well as they're derived from the texture coords // mirror bitangents as well as they're derived from the texture coords
if( pMesh->HasTangentsAndBitangents()) if( pMesh->HasTangentsAndBitangents())
{ {
for( unsigned int a = 0; a < pMesh->mNumVertices; a++) for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
pMesh->mBitangents[a] *= -1.0f; pMesh->mBitangents[a] *= -1.0f;
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single material to left handed coordinates. // Converts a single material to left handed coordinates.
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
{ {
aiMaterial* mat = (aiMaterial*)_mat; aiMaterial* mat = (aiMaterial*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) { for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a]; aiMaterialProperty* prop = mat->mProperties[a];
// Mapping axis for UV mappings? // Mapping axis for UV mappings?
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) { if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */ ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
aiVector3D* pff = (aiVector3D*)prop->mData; aiVector3D* pff = (aiVector3D*)prop->mData;
pff->z *= -1.f; pff->z *= -1.f;
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts the given animation to LH coordinates. // Converts the given animation to LH coordinates.
void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim) void MakeLeftHandedProcess::ProcessAnimation( aiNodeAnim* pAnim)
{ {
// position keys // position keys
for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++) for( unsigned int a = 0; a < pAnim->mNumPositionKeys; a++)
pAnim->mPositionKeys[a].mValue.z *= -1.0f; pAnim->mPositionKeys[a].mValue.z *= -1.0f;
// rotation keys // rotation keys
for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) for( unsigned int a = 0; a < pAnim->mNumRotationKeys; a++)
{ {
/* That's the safe version, but the float errors add up. So we try the short version instead /* That's the safe version, but the float errors add up. So we try the short version instead
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix(); aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3; rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2; rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
aiQuaternion rotquat( rotmat); aiQuaternion rotquat( rotmat);
pAnim->mRotationKeys[a].mValue = rotquat; pAnim->mRotationKeys[a].mValue = rotquat;
*/ */
pAnim->mRotationKeys[a].mValue.x *= -1.0f; pAnim->mRotationKeys[a].mValue.x *= -1.0f;
pAnim->mRotationKeys[a].mValue.y *= -1.0f; pAnim->mRotationKeys[a].mValue.y *= -1.0f;
} }
} }
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS #endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS #ifndef ASSIMP_BUILD_NO_FLIPUVS_PROCESS
// # FlipUVsProcess // # FlipUVsProcess
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FlipUVsProcess::FlipUVsProcess() FlipUVsProcess::FlipUVsProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FlipUVsProcess::~FlipUVsProcess() FlipUVsProcess::~FlipUVsProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FlipUVsProcess::IsActive( unsigned int pFlags) const bool FlipUVsProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_FlipUVs); return 0 != (pFlags & aiProcess_FlipUVs);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FlipUVsProcess::Execute( aiScene* pScene) void FlipUVsProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FlipUVsProcess begin"); DefaultLogger::get()->debug("FlipUVsProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]); ProcessMesh(pScene->mMeshes[i]);
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
ProcessMaterial(pScene->mMaterials[i]); ProcessMaterial(pScene->mMaterials[i]);
DefaultLogger::get()->debug("FlipUVsProcess finished"); DefaultLogger::get()->debug("FlipUVsProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single material // Converts a single material
void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat) void FlipUVsProcess::ProcessMaterial (aiMaterial* _mat)
{ {
aiMaterial* mat = (aiMaterial*)_mat; aiMaterial* mat = (aiMaterial*)_mat;
for (unsigned int a = 0; a < mat->mNumProperties;++a) { for (unsigned int a = 0; a < mat->mNumProperties;++a) {
aiMaterialProperty* prop = mat->mProperties[a]; aiMaterialProperty* prop = mat->mProperties[a];
if( !prop ) { if( !prop ) {
DefaultLogger::get()->debug( "Property is null" ); DefaultLogger::get()->debug( "Property is null" );
continue; continue;
} }
// UV transformation key? // UV transformation key?
if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) { if (!::strcmp( prop->mKey.data, "$tex.uvtrafo")) {
ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */ ai_assert( prop->mDataLength >= sizeof(aiUVTransform)); /* something is wrong with the validation if we end up here */
aiUVTransform* uv = (aiUVTransform*)prop->mData; aiUVTransform* uv = (aiUVTransform*)prop->mData;
// just flip it, that's everything // just flip it, that's everything
uv->mTranslation.y *= -1.f; uv->mTranslation.y *= -1.f;
uv->mRotation *= -1.f; uv->mRotation *= -1.f;
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single mesh // Converts a single mesh
void FlipUVsProcess::ProcessMesh( aiMesh* pMesh) void FlipUVsProcess::ProcessMesh( aiMesh* pMesh)
{ {
// mirror texture y coordinate // mirror texture y coordinate
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) { for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
if( !pMesh->HasTextureCoords( a ) ) { if( !pMesh->HasTextureCoords( a ) ) {
break; break;
} }
for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) { for( unsigned int b = 0; b < pMesh->mNumVertices; b++ ) {
pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y; pMesh->mTextureCoords[ a ][ b ].y = 1.0f - pMesh->mTextureCoords[ a ][ b ].y;
} }
} }
} }
#endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS #endif // !ASSIMP_BUILD_NO_FLIPUVS_PROCESS
#ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS #ifndef ASSIMP_BUILD_NO_FLIPWINDING_PROCESS
// # FlipWindingOrderProcess // # FlipWindingOrderProcess
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
FlipWindingOrderProcess::FlipWindingOrderProcess() FlipWindingOrderProcess::FlipWindingOrderProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
FlipWindingOrderProcess::~FlipWindingOrderProcess() FlipWindingOrderProcess::~FlipWindingOrderProcess()
{} {}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const bool FlipWindingOrderProcess::IsActive( unsigned int pFlags) const
{ {
return 0 != (pFlags & aiProcess_FlipWindingOrder); return 0 != (pFlags & aiProcess_FlipWindingOrder);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void FlipWindingOrderProcess::Execute( aiScene* pScene) void FlipWindingOrderProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("FlipWindingOrderProcess begin"); DefaultLogger::get()->debug("FlipWindingOrderProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
ProcessMesh(pScene->mMeshes[i]); ProcessMesh(pScene->mMeshes[i]);
DefaultLogger::get()->debug("FlipWindingOrderProcess finished"); DefaultLogger::get()->debug("FlipWindingOrderProcess finished");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Converts a single mesh // Converts a single mesh
void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh) void FlipWindingOrderProcess::ProcessMesh( aiMesh* pMesh)
{ {
// invert the order of all faces in this mesh // invert the order of all faces in this mesh
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{ {
aiFace& face = pMesh->mFaces[a]; aiFace& face = pMesh->mFaces[a];
for( unsigned int b = 0; b < face.mNumIndices / 2; b++) for( unsigned int b = 0; b < face.mNumIndices / 2; b++)
std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]); std::swap( face.mIndices[b], face.mIndices[ face.mNumIndices - 1 - b]);
} }
} }
#endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS #endif // !! ASSIMP_BUILD_NO_FLIPWINDING_PROCESS

View File

@ -1,168 +1,168 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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; struct aiNode;
struct aiMaterial; struct aiMaterial;
namespace Assimp { namespace Assimp {
// ----------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------
/** @brief The MakeLeftHandedProcess converts all imported data to a left-handed /** @brief The MakeLeftHandedProcess converts all imported data to a left-handed
* coordinate system. * coordinate system.
* *
* This implies a mirroring of the Z axis of the coordinate system. But to keep * 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 * transformation matrices free from reflections we shift the reflection to other
* places. We mirror the meshes and adapt the rotations. * places. We mirror the meshes and adapt the rotations.
* *
* @note RH-LH and LH-RH is the same, so this class can be used for both * @note RH-LH and LH-RH is the same, so this class can be used for both
*/ */
class MakeLeftHandedProcess : public BaseProcess class MakeLeftHandedProcess : public BaseProcess
{ {
public: public:
MakeLeftHandedProcess(); MakeLeftHandedProcess();
~MakeLeftHandedProcess(); ~MakeLeftHandedProcess();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Recursively converts a node and all of its children /** Recursively converts a node and all of its children
*/ */
void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation); void ProcessNode( aiNode* pNode, const aiMatrix4x4& pParentGlobalRotation);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a single mesh to left handed coordinates. /** Converts a single mesh to left handed coordinates.
* This means that positions, normals and tangents are mirrored at * This means that positions, normals and tangents are mirrored at
* the local Z axis and the order of all faces are inverted. * the local Z axis and the order of all faces are inverted.
* @param pMesh The mesh to convert. * @param pMesh The mesh to convert.
*/ */
void ProcessMesh( aiMesh* pMesh); void ProcessMesh( aiMesh* pMesh);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts a single material to left-handed coordinates /** Converts a single material to left-handed coordinates
* @param pMat Material to convert * @param pMat Material to convert
*/ */
void ProcessMaterial( aiMaterial* pMat); void ProcessMaterial( aiMaterial* pMat);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Converts the given animation to LH coordinates. /** Converts the given animation to LH coordinates.
* The rotation and translation keys are transformed, the scale keys * The rotation and translation keys are transformed, the scale keys
* work in local space and can therefore be left untouched. * work in local space and can therefore be left untouched.
* @param pAnim The bone animation to transform * @param pAnim The bone animation to transform
*/ */
void ProcessAnimation( aiNodeAnim* pAnim); void ProcessAnimation( aiNodeAnim* pAnim);
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Postprocessing step to flip the face order of the imported data /** Postprocessing step to flip the face order of the imported data
*/ */
class FlipWindingOrderProcess : public BaseProcess class FlipWindingOrderProcess : public BaseProcess
{ {
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
FlipWindingOrderProcess(); FlipWindingOrderProcess();
/** Destructor, private as well */ /** Destructor, private as well */
~FlipWindingOrderProcess(); ~FlipWindingOrderProcess();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
void ProcessMesh( aiMesh* pMesh); void ProcessMesh( aiMesh* pMesh);
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Postprocessing step to flip the UV coordinate system of the import data /** Postprocessing step to flip the UV coordinate system of the import data
*/ */
class FlipUVsProcess : public BaseProcess class FlipUVsProcess : public BaseProcess
{ {
friend class Importer; friend class Importer;
public: public:
/** Constructor to be privately used by Importer */ /** Constructor to be privately used by Importer */
FlipUVsProcess(); FlipUVsProcess();
/** Destructor, private as well */ /** Destructor, private as well */
~FlipUVsProcess(); ~FlipUVsProcess();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
protected: protected:
void ProcessMesh( aiMesh* pMesh); void ProcessMesh( aiMesh* pMesh);
void ProcessMaterial( aiMaterial* mat); void ProcessMaterial( aiMaterial* mat);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_CONVERTTOLHPROCESS_H_INC #endif // AI_CONVERTTOLHPROCESS_H_INC

View File

@ -1,233 +1,233 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 DXFHelper.h /** @file DXFHelper.h
* @brief Internal utilities for the DXF loader. * @brief Internal utilities for the DXF loader.
*/ */
#ifndef INCLUDED_DXFHELPER_H #ifndef INCLUDED_DXFHELPER_H
#define INCLUDED_DXFHELPER_H #define INCLUDED_DXFHELPER_H
#include "LineSplitter.h" #include "LineSplitter.h"
#include "TinyFormatter.h" #include "TinyFormatter.h"
#include "StreamReader.h" #include "StreamReader.h"
#include "fast_atof.h" #include "fast_atof.h"
#include <vector> #include <vector>
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
namespace Assimp { namespace Assimp {
namespace DXF { namespace DXF {
// read pairs of lines, parse group code and value and provide utilities // read pairs of lines, parse group code and value and provide utilities
// to convert the data to the target data type. // to convert the data to the target data type.
class LineReader class LineReader
{ {
public: public:
LineReader(StreamReaderLE& reader) LineReader(StreamReaderLE& reader)
// do NOT skip empty lines. In DXF files, they count as valid data. // do NOT skip empty lines. In DXF files, they count as valid data.
: splitter(reader,false,true) : splitter(reader,false,true)
, end() , end()
{ {
} }
public: public:
// ----------------------------------------- // -----------------------------------------
bool Is(int gc, const char* what) const { bool Is(int gc, const char* what) const {
return groupcode == gc && !strcmp(what,value.c_str()); return groupcode == gc && !strcmp(what,value.c_str());
} }
// ----------------------------------------- // -----------------------------------------
bool Is(int gc) const { bool Is(int gc) const {
return groupcode == gc; return groupcode == gc;
} }
// ----------------------------------------- // -----------------------------------------
int GroupCode() const { int GroupCode() const {
return groupcode; return groupcode;
} }
// ----------------------------------------- // -----------------------------------------
const std::string& Value() const { const std::string& Value() const {
return value; return value;
} }
// ----------------------------------------- // -----------------------------------------
bool End() const { bool End() const {
return !((bool)*this); return !((bool)*this);
} }
public: public:
// ----------------------------------------- // -----------------------------------------
unsigned int ValueAsUnsignedInt() const { unsigned int ValueAsUnsignedInt() const {
return strtoul10(value.c_str()); return strtoul10(value.c_str());
} }
// ----------------------------------------- // -----------------------------------------
int ValueAsSignedInt() const { int ValueAsSignedInt() const {
return strtol10(value.c_str()); return strtol10(value.c_str());
} }
// ----------------------------------------- // -----------------------------------------
float ValueAsFloat() const { float ValueAsFloat() const {
return fast_atof(value.c_str()); return fast_atof(value.c_str());
} }
public: public:
// ----------------------------------------- // -----------------------------------------
/** pseudo-iterator increment to advance to the next (groupcode/value) pair */ /** pseudo-iterator increment to advance to the next (groupcode/value) pair */
LineReader& operator++() { LineReader& operator++() {
if (end) { if (end) {
if (end == 1) { if (end == 1) {
++end; ++end;
} }
return *this; return *this;
} }
try { try {
groupcode = strtol10(splitter->c_str()); groupcode = strtol10(splitter->c_str());
splitter++; splitter++;
value = *splitter; value = *splitter;
splitter++; splitter++;
// automatically skip over {} meta blocks (these are for application use // automatically skip over {} meta blocks (these are for application use
// and currently not relevant for Assimp). // and currently not relevant for Assimp).
if (value.length() && value[0] == '{') { if (value.length() && value[0] == '{') {
size_t cnt = 0; size_t cnt = 0;
for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++); for(;splitter->length() && splitter->at(0) != '}'; splitter++, cnt++);
splitter++; splitter++;
DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)")); DefaultLogger::get()->debug((Formatter::format("DXF: skipped over control group ("),cnt," lines)"));
} }
} catch(std::logic_error&) { } catch(std::logic_error&) {
ai_assert(!splitter); ai_assert(!splitter);
} }
if (!splitter) { if (!splitter) {
end = 1; end = 1;
} }
return *this; return *this;
} }
// ----------------------------------------- // -----------------------------------------
LineReader& operator++(int) { LineReader& operator++(int) {
return ++(*this); return ++(*this);
} }
// ----------------------------------------- // -----------------------------------------
operator bool() const { operator bool() const {
return end <= 1; return end <= 1;
} }
private: private:
LineSplitter splitter; LineSplitter splitter;
int groupcode; int groupcode;
std::string value; std::string value;
int end; int end;
}; };
// represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed. // represents a POLYLINE or a LWPOLYLINE. or even a 3DFACE The data is converted as needed.
struct PolyLine struct PolyLine
{ {
PolyLine() PolyLine()
: flags() : flags()
{} {}
std::vector<aiVector3D> positions; std::vector<aiVector3D> positions;
std::vector<aiColor4D> colors; std::vector<aiColor4D> colors;
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
std::vector<unsigned int> counts; std::vector<unsigned int> counts;
unsigned int flags; unsigned int flags;
std::string layer; std::string layer;
std::string desc; std::string desc;
}; };
// reference to a BLOCK. Specifies its own coordinate system. // reference to a BLOCK. Specifies its own coordinate system.
struct InsertBlock struct InsertBlock
{ {
InsertBlock() InsertBlock()
: scale(1.f,1.f,1.f) : scale(1.f,1.f,1.f)
, angle() , angle()
{} {}
aiVector3D pos; aiVector3D pos;
aiVector3D scale; aiVector3D scale;
float angle; float angle;
std::string name; std::string name;
}; };
// keeps track of all geometry in a single BLOCK. // keeps track of all geometry in a single BLOCK.
struct Block struct Block
{ {
std::vector< boost::shared_ptr<PolyLine> > lines; std::vector< boost::shared_ptr<PolyLine> > lines;
std::vector<InsertBlock> insertions; std::vector<InsertBlock> insertions;
std::string name; std::string name;
aiVector3D base; aiVector3D base;
}; };
struct FileData struct FileData
{ {
// note: the LAST block always contains the stuff from ENTITIES. // note: the LAST block always contains the stuff from ENTITIES.
std::vector<Block> blocks; std::vector<Block> blocks;
}; };
}} }}
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,152 +1,152 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 DXFLoader.h /** @file DXFLoader.h
* @brief Declaration of the .dxf importer class. * @brief Declaration of the .dxf importer class.
*/ */
#ifndef AI_DXFLOADER_H_INCLUDED #ifndef AI_DXFLOADER_H_INCLUDED
#define AI_DXFLOADER_H_INCLUDED #define AI_DXFLOADER_H_INCLUDED
#include "BaseImporter.h" #include "BaseImporter.h"
namespace Assimp { namespace Assimp {
namespace DXF { namespace DXF {
class LineReader; class LineReader;
struct FileData; struct FileData;
struct PolyLine; struct PolyLine;
struct Block; struct Block;
struct InsertBlock; struct InsertBlock;
typedef std::map<std::string, const DXF::Block*> BlockMap; typedef std::map<std::string, const DXF::Block*> BlockMap;
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** DXF importer implementation. /** DXF importer implementation.
* *
*/ */
class DXFImporter : public BaseImporter class DXFImporter : public BaseImporter
{ {
public: public:
DXFImporter(); DXFImporter();
~DXFImporter(); ~DXFImporter();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file. /** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */ * See BaseImporter::CanRead() for details. */
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Return importer meta information. /** Return importer meta information.
* See #BaseImporter::GetInfo for the details*/ * See #BaseImporter::GetInfo for the details*/
const aiImporterDesc* GetInfo () const; const aiImporterDesc* GetInfo () const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Imports the given file into the given scene structure. /** Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details */ * See BaseImporter::InternReadFile() for details */
void InternReadFile( const std::string& pFile, void InternReadFile( const std::string& pFile,
aiScene* pScene, aiScene* pScene,
IOSystem* pIOHandler); IOSystem* pIOHandler);
private: private:
// ----------------------------------------------------- // -----------------------------------------------------
void SkipSection(DXF::LineReader& reader); void SkipSection(DXF::LineReader& reader);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseHeader(DXF::LineReader& reader, void ParseHeader(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseEntities(DXF::LineReader& reader, void ParseEntities(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseBlocks(DXF::LineReader& reader, void ParseBlocks(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseBlock(DXF::LineReader& reader, void ParseBlock(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParseInsertion(DXF::LineReader& reader, void ParseInsertion(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParsePolyLine(DXF::LineReader& reader, void ParsePolyLine(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ParsePolyLineVertex(DXF::LineReader& reader, void ParsePolyLineVertex(DXF::LineReader& reader,
DXF::PolyLine& line); DXF::PolyLine& line);
// ----------------------------------------------------- // -----------------------------------------------------
void Parse3DFace(DXF::LineReader& reader, void Parse3DFace(DXF::LineReader& reader,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ConvertMeshes(aiScene* pScene, void ConvertMeshes(aiScene* pScene,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void GenerateHierarchy(aiScene* pScene, void GenerateHierarchy(aiScene* pScene,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void GenerateMaterials(aiScene* pScene, void GenerateMaterials(aiScene* pScene,
DXF::FileData& output); DXF::FileData& output);
// ----------------------------------------------------- // -----------------------------------------------------
void ExpandBlockReferences(DXF::Block& bl, void ExpandBlockReferences(DXF::Block& bl,
const DXF::BlockMap& blocks_by_name); const DXF::BlockMap& blocks_by_name);
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_3DSIMPORTER_H_INC #endif // AI_3DSIMPORTER_H_INC

View File

@ -1,465 +1,465 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 DeboneProcess.cpp /// @file DeboneProcess.cpp
/** Implementation of the DeboneProcess post processing step */ /** Implementation of the DeboneProcess post processing step */
// internal headers of the post-processing framework // internal headers of the post-processing framework
#include "ProcessHelper.h" #include "ProcessHelper.h"
#include "DeboneProcess.h" #include "DeboneProcess.h"
#include <stdio.h> #include <stdio.h>
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer // Constructor to be privately used by Importer
DeboneProcess::DeboneProcess() DeboneProcess::DeboneProcess()
{ {
mNumBones = 0; mNumBones = 0;
mNumBonesCanDoWithout = 0; mNumBonesCanDoWithout = 0;
mThreshold = AI_DEBONE_THRESHOLD; mThreshold = AI_DEBONE_THRESHOLD;
mAllOrNone = false; mAllOrNone = false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor, private as well // Destructor, private as well
DeboneProcess::~DeboneProcess() DeboneProcess::~DeboneProcess()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field. // Returns whether the processing step is present in the given flag field.
bool DeboneProcess::IsActive( unsigned int pFlags) const bool DeboneProcess::IsActive( unsigned int pFlags) const
{ {
return (pFlags & aiProcess_Debone) != 0; return (pFlags & aiProcess_Debone) != 0;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void DeboneProcess::SetupProperties(const Importer* pImp) void DeboneProcess::SetupProperties(const Importer* pImp)
{ {
// get the current value of the property // get the current value of the property
mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false; mAllOrNone = pImp->GetPropertyInteger(AI_CONFIG_PP_DB_ALL_OR_NONE,0)?true:false;
mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD); mThreshold = pImp->GetPropertyFloat(AI_CONFIG_PP_DB_THRESHOLD,AI_DEBONE_THRESHOLD);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data. // Executes the post processing step on the given imported data.
void DeboneProcess::Execute( aiScene* pScene) void DeboneProcess::Execute( aiScene* pScene)
{ {
DefaultLogger::get()->debug("DeboneProcess begin"); DefaultLogger::get()->debug("DeboneProcess begin");
if(!pScene->mNumMeshes) { if(!pScene->mNumMeshes) {
return; return;
} }
std::vector<bool> splitList(pScene->mNumMeshes); std::vector<bool> splitList(pScene->mNumMeshes);
for( unsigned int a = 0; a < pScene->mNumMeshes; a++) { for( unsigned int a = 0; a < pScene->mNumMeshes; a++) {
splitList[a] = ConsiderMesh( pScene->mMeshes[a] ); splitList[a] = ConsiderMesh( pScene->mMeshes[a] );
} }
int numSplits = 0; int numSplits = 0;
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) { if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) { for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
if(splitList[a]) { if(splitList[a]) {
numSplits++; numSplits++;
} }
} }
} }
if(numSplits) { if(numSplits) {
// we need to do something. Let's go. // we need to do something. Let's go.
//mSubMeshIndices.clear(); // really needed? //mSubMeshIndices.clear(); // really needed?
mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway mSubMeshIndices.resize(pScene->mNumMeshes); // because we're doing it here anyway
// build a new array of meshes for the scene // build a new array of meshes for the scene
std::vector<aiMesh*> meshes; std::vector<aiMesh*> meshes;
for(unsigned int a=0;a<pScene->mNumMeshes;a++) for(unsigned int a=0;a<pScene->mNumMeshes;a++)
{ {
aiMesh* srcMesh = pScene->mMeshes[a]; aiMesh* srcMesh = pScene->mMeshes[a];
std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes; std::vector<std::pair<aiMesh*,const aiBone*> > newMeshes;
if(splitList[a]) { if(splitList[a]) {
SplitMesh(srcMesh,newMeshes); SplitMesh(srcMesh,newMeshes);
} }
// mesh was split // mesh was split
if(!newMeshes.empty()) { if(!newMeshes.empty()) {
unsigned int out = 0, in = srcMesh->mNumBones; unsigned int out = 0, in = srcMesh->mNumBones;
// store new meshes and indices of the new meshes // store new meshes and indices of the new meshes
for(unsigned int b=0;b<newMeshes.size();b++) { for(unsigned int b=0;b<newMeshes.size();b++) {
const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0; const aiString *find = newMeshes[b].second?&newMeshes[b].second->mName:0;
aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0; aiNode *theNode = find?pScene->mRootNode->FindNode(*find):0;
std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode); std::pair<unsigned int,aiNode*> push_pair(meshes.size(),theNode);
mSubMeshIndices[a].push_back(push_pair); mSubMeshIndices[a].push_back(push_pair);
meshes.push_back(newMeshes[b].first); meshes.push_back(newMeshes[b].first);
out+=newMeshes[b].first->mNumBones; out+=newMeshes[b].first->mNumBones;
} }
if(!DefaultLogger::isNullLogger()) { if(!DefaultLogger::isNullLogger()) {
char buffer[1024]; char buffer[1024];
::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out); ::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
DefaultLogger::get()->info(buffer); DefaultLogger::get()->info(buffer);
} }
// and destroy the source mesh. It should be completely contained inside the new submeshes // and destroy the source mesh. It should be completely contained inside the new submeshes
delete srcMesh; delete srcMesh;
} }
else { else {
// Mesh is kept unchanged - store it's new place in the mesh array // Mesh is kept unchanged - store it's new place in the mesh array
mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0)); mSubMeshIndices[a].push_back(std::pair<unsigned int,aiNode*>(meshes.size(),(aiNode*)0));
meshes.push_back(srcMesh); meshes.push_back(srcMesh);
} }
} }
// rebuild the scene's mesh array // rebuild the scene's mesh array
pScene->mNumMeshes = meshes.size(); pScene->mNumMeshes = meshes.size();
delete [] pScene->mMeshes; delete [] pScene->mMeshes;
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]; pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
std::copy( meshes.begin(), meshes.end(), pScene->mMeshes); std::copy( meshes.begin(), meshes.end(), pScene->mMeshes);
// recurse through all nodes and translate the node's mesh indices to fit the new mesh array // recurse through all nodes and translate the node's mesh indices to fit the new mesh array
UpdateNode( pScene->mRootNode); UpdateNode( pScene->mRootNode);
} }
DefaultLogger::get()->debug("DeboneProcess end"); DefaultLogger::get()->debug("DeboneProcess end");
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Counts bones total/removable in a given mesh. // Counts bones total/removable in a given mesh.
bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh) bool DeboneProcess::ConsiderMesh(const aiMesh* pMesh)
{ {
if(!pMesh->HasBones()) { if(!pMesh->HasBones()) {
return false; return false;
} }
bool split = false; bool split = false;
//interstitial faces not permitted //interstitial faces not permitted
bool isInterstitialRequired = false; bool isInterstitialRequired = false;
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false); std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX); std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
const unsigned int cUnowned = UINT_MAX; const unsigned int cUnowned = UINT_MAX;
const unsigned int cCoowned = UINT_MAX-1; const unsigned int cCoowned = UINT_MAX-1;
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) { for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
float w = pMesh->mBones[i]->mWeights[j].mWeight; float w = pMesh->mBones[i]->mWeights[j].mWeight;
if(w==0.0f) { if(w==0.0f) {
continue; continue;
} }
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId; unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
if(w>=mThreshold) { if(w>=mThreshold) {
if(vertexBones[vid]!=cUnowned) { if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry if(vertexBones[vid]==i) //double entry
{ {
DefaultLogger::get()->warn("Encountered double entry in bone weights"); DefaultLogger::get()->warn("Encountered double entry in bone weights");
} }
else //TODO: track attraction in order to break tie else //TODO: track attraction in order to break tie
{ {
vertexBones[vid] = cCoowned; vertexBones[vid] = cCoowned;
} }
} }
else vertexBones[vid] = i; else vertexBones[vid] = i;
} }
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
isBoneNecessary[i] = w<mThreshold; isBoneNecessary[i] = w<mThreshold;
} }
} }
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
isInterstitialRequired = true; isInterstitialRequired = true;
} }
} }
if(isInterstitialRequired) { if(isInterstitialRequired) {
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]]; unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) { for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]]; unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
if(v!=w) { if(v!=w) {
if(v<pMesh->mNumBones) isBoneNecessary[v] = true; if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
if(w<pMesh->mNumBones) isBoneNecessary[w] = true; if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
} }
} }
} }
} }
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
mNumBonesCanDoWithout++; mNumBonesCanDoWithout++;
split = true; split = true;
} }
mNumBones++; mNumBones++;
} }
return split; return split;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Splits the given mesh by bone count. // Splits the given mesh by bone count.
void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const void DeboneProcess::SplitMesh( const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const
{ {
// same deal here as ConsiderMesh basically // same deal here as ConsiderMesh basically
std::vector<bool> isBoneNecessary(pMesh->mNumBones,false); std::vector<bool> isBoneNecessary(pMesh->mNumBones,false);
std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX); std::vector<unsigned int> vertexBones(pMesh->mNumVertices,UINT_MAX);
const unsigned int cUnowned = UINT_MAX; const unsigned int cUnowned = UINT_MAX;
const unsigned int cCoowned = UINT_MAX-1; const unsigned int cCoowned = UINT_MAX-1;
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) { for(unsigned int j=0;j<pMesh->mBones[i]->mNumWeights;j++) {
float w = pMesh->mBones[i]->mWeights[j].mWeight; float w = pMesh->mBones[i]->mWeights[j].mWeight;
if(w==0.0f) { if(w==0.0f) {
continue; continue;
} }
unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId; unsigned int vid = pMesh->mBones[i]->mWeights[j].mVertexId;
if(w>=mThreshold) { if(w>=mThreshold) {
if(vertexBones[vid]!=cUnowned) { if(vertexBones[vid]!=cUnowned) {
if(vertexBones[vid]==i) //double entry if(vertexBones[vid]==i) //double entry
{ {
//DefaultLogger::get()->warn("Encountered double entry in bone weights"); //DefaultLogger::get()->warn("Encountered double entry in bone weights");
} }
else //TODO: track attraction in order to break tie else //TODO: track attraction in order to break tie
{ {
vertexBones[vid] = cCoowned; vertexBones[vid] = cCoowned;
} }
} }
else vertexBones[vid] = i; else vertexBones[vid] = i;
} }
if(!isBoneNecessary[i]) { if(!isBoneNecessary[i]) {
isBoneNecessary[i] = w<mThreshold; isBoneNecessary[i] = w<mThreshold;
} }
} }
} }
unsigned int nFacesUnowned = 0; unsigned int nFacesUnowned = 0;
std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX); std::vector<unsigned int> faceBones(pMesh->mNumFaces,UINT_MAX);
std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0); std::vector<unsigned int> facesPerBone(pMesh->mNumBones,0);
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
unsigned int nInterstitial = 1; unsigned int nInterstitial = 1;
unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]]; unsigned int v = vertexBones[pMesh->mFaces[i].mIndices[0]];
for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) { for(unsigned int j=1;j<pMesh->mFaces[i].mNumIndices;j++) {
unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]]; unsigned int w = vertexBones[pMesh->mFaces[i].mIndices[j]];
if(v!=w) { if(v!=w) {
if(v<pMesh->mNumBones) isBoneNecessary[v] = true; if(v<pMesh->mNumBones) isBoneNecessary[v] = true;
if(w<pMesh->mNumBones) isBoneNecessary[w] = true; if(w<pMesh->mNumBones) isBoneNecessary[w] = true;
} }
else nInterstitial++; else nInterstitial++;
} }
if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) { if(v<pMesh->mNumBones &&nInterstitial==pMesh->mFaces[i].mNumIndices) {
faceBones[i] = v; //primitive belongs to bone #v faceBones[i] = v; //primitive belongs to bone #v
facesPerBone[v]++; facesPerBone[v]++;
} }
else nFacesUnowned++; else nFacesUnowned++;
} }
// invalidate any "cojoined" faces // invalidate any "cojoined" faces
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]]) if(faceBones[i]<pMesh->mNumBones&&isBoneNecessary[faceBones[i]])
{ {
ai_assert(facesPerBone[faceBones[i]]>0); ai_assert(facesPerBone[faceBones[i]]>0);
facesPerBone[faceBones[i]]--; facesPerBone[faceBones[i]]--;
nFacesUnowned++; nFacesUnowned++;
faceBones[i] = cUnowned; faceBones[i] = cUnowned;
} }
} }
if(nFacesUnowned) { if(nFacesUnowned) {
std::vector<unsigned int> subFaces; std::vector<unsigned int> subFaces;
for(unsigned int i=0;i<pMesh->mNumFaces;i++) { for(unsigned int i=0;i<pMesh->mNumFaces;i++) {
if(faceBones[i]==cUnowned) { if(faceBones[i]==cUnowned) {
subFaces.push_back(i); subFaces.push_back(i);
} }
} }
aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0); aiMesh *baseMesh = MakeSubmesh(pMesh,subFaces,0);
std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0); std::pair<aiMesh*,const aiBone*> push_pair(baseMesh,(const aiBone*)0);
poNewMeshes.push_back(push_pair); poNewMeshes.push_back(push_pair);
} }
for(unsigned int i=0;i<pMesh->mNumBones;i++) { for(unsigned int i=0;i<pMesh->mNumBones;i++) {
if(!isBoneNecessary[i]&&facesPerBone[i]>0) { if(!isBoneNecessary[i]&&facesPerBone[i]>0) {
std::vector<unsigned int> subFaces; std::vector<unsigned int> subFaces;
for(unsigned int j=0;j<pMesh->mNumFaces;j++) { for(unsigned int j=0;j<pMesh->mNumFaces;j++) {
if(faceBones[j]==i) { if(faceBones[j]==i) {
subFaces.push_back(j); subFaces.push_back(j);
} }
} }
unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES; unsigned int f = AI_SUBMESH_FLAGS_SANS_BONES;
aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f); aiMesh *subMesh =MakeSubmesh(pMesh,subFaces,f);
//Lifted from PretransformVertices.cpp //Lifted from PretransformVertices.cpp
ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix); ApplyTransform(subMesh,pMesh->mBones[i]->mOffsetMatrix);
std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]); std::pair<aiMesh*,const aiBone*> push_pair(subMesh,pMesh->mBones[i]);
poNewMeshes.push_back(push_pair); poNewMeshes.push_back(push_pair);
} }
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Recursively updates the node's mesh list to account for the changed mesh list // Recursively updates the node's mesh list to account for the changed mesh list
void DeboneProcess::UpdateNode(aiNode* pNode) const void DeboneProcess::UpdateNode(aiNode* pNode) const
{ {
// rebuild the node's mesh index list // rebuild the node's mesh index list
std::vector<unsigned int> newMeshList; std::vector<unsigned int> newMeshList;
// this will require two passes // this will require two passes
unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size(); unsigned int m = pNode->mNumMeshes, n = mSubMeshIndices.size();
// first pass, look for meshes which have not moved // first pass, look for meshes which have not moved
for(unsigned int a=0;a<m;a++) { for(unsigned int a=0;a<m;a++) {
unsigned int srcIndex = pNode->mMeshes[a]; unsigned int srcIndex = pNode->mMeshes[a];
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex]; const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
unsigned int nSubmeshes = subMeshes.size(); unsigned int nSubmeshes = subMeshes.size();
for(unsigned int b=0;b<nSubmeshes;b++) { for(unsigned int b=0;b<nSubmeshes;b++) {
if(!subMeshes[b].second) { if(!subMeshes[b].second) {
newMeshList.push_back(subMeshes[b].first); newMeshList.push_back(subMeshes[b].first);
} }
} }
} }
// second pass, collect deboned meshes // second pass, collect deboned meshes
for(unsigned int a=0;a<n;a++) for(unsigned int a=0;a<n;a++)
{ {
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a]; const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
unsigned int nSubmeshes = subMeshes.size(); unsigned int nSubmeshes = subMeshes.size();
for(unsigned int b=0;b<nSubmeshes;b++) { for(unsigned int b=0;b<nSubmeshes;b++) {
if(subMeshes[b].second == pNode) { if(subMeshes[b].second == pNode) {
newMeshList.push_back(subMeshes[b].first); newMeshList.push_back(subMeshes[b].first);
} }
} }
} }
if( pNode->mNumMeshes > 0 ) { if( pNode->mNumMeshes > 0 ) {
delete [] pNode->mMeshes; pNode->mMeshes = NULL; delete [] pNode->mMeshes; pNode->mMeshes = NULL;
} }
pNode->mNumMeshes = newMeshList.size(); pNode->mNumMeshes = newMeshList.size();
if(pNode->mNumMeshes) { if(pNode->mNumMeshes) {
pNode->mMeshes = new unsigned int[pNode->mNumMeshes]; pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes); std::copy( newMeshList.begin(), newMeshList.end(), pNode->mMeshes);
} }
// do that also recursively for all children // do that also recursively for all children
for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) { for( unsigned int a = 0; a < pNode->mNumChildren; ++a ) {
UpdateNode( pNode->mChildren[a]); UpdateNode( pNode->mChildren[a]);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Apply the node transformation to a mesh // Apply the node transformation to a mesh
void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const void DeboneProcess::ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const
{ {
// Check whether we need to transform the coordinates at all // Check whether we need to transform the coordinates at all
if (!mat.IsIdentity()) { if (!mat.IsIdentity()) {
if (mesh->HasPositions()) { if (mesh->HasPositions()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mVertices[i] = mat * mesh->mVertices[i]; mesh->mVertices[i] = mat * mesh->mVertices[i];
} }
} }
if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) { if (mesh->HasNormals() || mesh->HasTangentsAndBitangents()) {
aiMatrix4x4 mWorldIT = mat; aiMatrix4x4 mWorldIT = mat;
mWorldIT.Inverse().Transpose(); mWorldIT.Inverse().Transpose();
// TODO: implement Inverse() for aiMatrix3x3 // TODO: implement Inverse() for aiMatrix3x3
aiMatrix3x3 m = aiMatrix3x3(mWorldIT); aiMatrix3x3 m = aiMatrix3x3(mWorldIT);
if (mesh->HasNormals()) { if (mesh->HasNormals()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize(); mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
} }
} }
if (mesh->HasTangentsAndBitangents()) { if (mesh->HasTangentsAndBitangents()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) { for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize(); mesh->mTangents[i] = (m * mesh->mTangents[i]).Normalize();
mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize(); mesh->mBitangents[i] = (m * mesh->mBitangents[i]).Normalize();
} }
} }
} }
} }
} }

View File

@ -1,132 +1,132 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
/** Defines a post processing step to limit the number of bones affecting a single vertex. */ /** Defines a post processing step to limit the number of bones affecting a single vertex. */
#ifndef AI_DEBONEPROCESS_H_INC #ifndef AI_DEBONEPROCESS_H_INC
#define AI_DEBONEPROCESS_H_INC #define AI_DEBONEPROCESS_H_INC
#include <vector> #include <vector>
#include <utility> #include <utility>
#include "BaseProcess.h" #include "BaseProcess.h"
#include "../include/assimp/mesh.h" #include "../include/assimp/mesh.h"
#include "../include/assimp/scene.h" #include "../include/assimp/scene.h"
class DeboneTest; class DeboneTest;
namespace Assimp namespace Assimp
{ {
#if (!defined AI_DEBONE_THRESHOLD) #if (!defined AI_DEBONE_THRESHOLD)
# define AI_DEBONE_THRESHOLD 1.0f # define AI_DEBONE_THRESHOLD 1.0f
#endif // !! AI_DEBONE_THRESHOLD #endif // !! AI_DEBONE_THRESHOLD
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** This post processing step removes bones nearly losslessly or according to /** This post processing step removes bones nearly losslessly or according to
* a configured threshold. In order to remove the bone, the primitives affected by * a configured threshold. In order to remove the bone, the primitives affected by
* the bone are split from the mesh. The split off (new) mesh is boneless. At any * the bone are split from the mesh. The split off (new) mesh is boneless. At any
* point in time, bones without affect upon a given mesh are to be removed. * point in time, bones without affect upon a given mesh are to be removed.
*/ */
class DeboneProcess : public BaseProcess class DeboneProcess : public BaseProcess
{ {
public: public:
DeboneProcess(); DeboneProcess();
~DeboneProcess(); ~DeboneProcess();
public: public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns whether the processing step is present in the given flag. /** Returns whether the processing step is present in the given flag.
* @param pFlags The processing flags the importer was called with. * @param pFlags The processing flags the importer was called with.
* A bitwise combination of #aiPostProcessSteps. * A bitwise combination of #aiPostProcessSteps.
* @return true if the process is present in this flag fields, * @return true if the process is present in this flag fields,
* false if not. * false if not.
*/ */
bool IsActive( unsigned int pFlags) const; bool IsActive( unsigned int pFlags) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Called prior to ExecuteOnScene(). /** Called prior to ExecuteOnScene().
* The function is a request to the process to update its configuration * The function is a request to the process to update its configuration
* basing on the Importer's configuration property list. * basing on the Importer's configuration property list.
*/ */
void SetupProperties(const Importer* pImp); void SetupProperties(const Importer* pImp);
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Executes the post processing step on the given imported data. /** Executes the post processing step on the given imported data.
* At the moment a process is not supposed to fail. * At the moment a process is not supposed to fail.
* @param pScene The imported data to work at. * @param pScene The imported data to work at.
*/ */
void Execute( aiScene* pScene); void Execute( aiScene* pScene);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Counts bones total/removable in a given mesh. /** Counts bones total/removable in a given mesh.
* @param pMesh The mesh to process. * @param pMesh The mesh to process.
*/ */
bool ConsiderMesh( const aiMesh* pMesh); bool ConsiderMesh( const aiMesh* pMesh);
/// Splits the given mesh by bone count. /// Splits the given mesh by bone count.
/// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split. /// @param pMesh the Mesh to split. Is not changed at all, but might be superfluous in case it was split.
/// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary. /// @param poNewMeshes Array of submeshes created in the process. Empty if splitting was not necessary.
void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const; void SplitMesh(const aiMesh* pMesh, std::vector< std::pair< aiMesh*,const aiBone* > >& poNewMeshes) const;
/// Recursively updates the node's mesh list to account for the changed mesh list /// Recursively updates the node's mesh list to account for the changed mesh list
void UpdateNode(aiNode* pNode) const; void UpdateNode(aiNode* pNode) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Apply transformation to a mesh // Apply transformation to a mesh
void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const; void ApplyTransform(aiMesh* mesh, const aiMatrix4x4& mat)const;
public: public:
/** Number of bones present in the scene. */ /** Number of bones present in the scene. */
unsigned int mNumBones; unsigned int mNumBones;
unsigned int mNumBonesCanDoWithout; unsigned int mNumBonesCanDoWithout;
float mThreshold; float mThreshold;
bool mAllOrNone; bool mAllOrNone;
/// Per mesh index: Array of indices of the new submeshes. /// Per mesh index: Array of indices of the new submeshes.
std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices; std::vector< std::vector< std::pair< unsigned int,aiNode* > > > mSubMeshIndices;
}; };
} // end of namespace Assimp } // end of namespace Assimp
#endif // AI_DEBONEPROCESS_H_INC #endif // AI_DEBONEPROCESS_H_INC

View File

@ -1,147 +1,147 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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 DefaultIOStream.cpp /** @file DefaultIOStream.cpp
* @brief Default File I/O implementation for #Importer * @brief Default File I/O implementation for #Importer
*/ */
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
using namespace Assimp; using namespace Assimp;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
DefaultIOStream::~DefaultIOStream() DefaultIOStream::~DefaultIOStream()
{ {
if (mFile) { if (mFile) {
::fclose(mFile); ::fclose(mFile);
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::Read(void* pvBuffer, size_t DefaultIOStream::Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount)
{ {
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount); ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0); return (mFile ? ::fread(pvBuffer, pSize, pCount, mFile) : 0);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::Write(const void* pvBuffer, size_t DefaultIOStream::Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount) size_t pCount)
{ {
ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount); ai_assert(NULL != pvBuffer && 0 != pSize && 0 != pCount);
return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0); return (mFile ? ::fwrite(pvBuffer, pSize, pCount, mFile) : 0);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
aiReturn DefaultIOStream::Seek(size_t pOffset, aiReturn DefaultIOStream::Seek(size_t pOffset,
aiOrigin pOrigin) aiOrigin pOrigin)
{ {
if (!mFile) { if (!mFile) {
return AI_FAILURE; return AI_FAILURE;
} }
// Just to check whether our enum maps one to one with the CRT constants // Just to check whether our enum maps one to one with the CRT constants
BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR && BOOST_STATIC_ASSERT(aiOrigin_CUR == SEEK_CUR &&
aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET); aiOrigin_END == SEEK_END && aiOrigin_SET == SEEK_SET);
// do the seek // do the seek
return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE); return (0 == ::fseek(mFile, (long)pOffset,(int)pOrigin) ? AI_SUCCESS : AI_FAILURE);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::Tell() const size_t DefaultIOStream::Tell() const
{ {
if (!mFile) { if (!mFile) {
return 0; return 0;
} }
return ::ftell(mFile); return ::ftell(mFile);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
size_t DefaultIOStream::FileSize() const size_t DefaultIOStream::FileSize() const
{ {
if (! mFile || mFilename.empty()) { if (! mFile || mFilename.empty()) {
return 0; return 0;
} }
if (SIZE_MAX == cachedSize) { if (SIZE_MAX == cachedSize) {
// Although fseek/ftell would allow us to reuse the exising file handle here, // Although fseek/ftell would allow us to reuse the exising file handle here,
// it is generally unsafe because: // it is generally unsafe because:
// - For binary streams, it is not technically well-defined // - For binary streams, it is not technically well-defined
// - For text files the results are meaningless // - For text files the results are meaningless
// That's why we use the safer variant fstat here. // That's why we use the safer variant fstat here.
// //
// See here for details: // See here for details:
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file // https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
#if defined _WIN32 && !defined __GNUC__ #if defined _WIN32 && !defined __GNUC__
struct __stat64 fileStat; struct __stat64 fileStat;
int err = _stat64( mFilename.c_str(), &fileStat ); int err = _stat64( mFilename.c_str(), &fileStat );
if (0 != err) if (0 != err)
return 0; return 0;
cachedSize = (size_t) (fileStat.st_size); cachedSize = (size_t) (fileStat.st_size);
#else #else
struct stat fileStat; struct stat fileStat;
int err = stat(mFilename.c_str(), &fileStat ); int err = stat(mFilename.c_str(), &fileStat );
if (0 != err) if (0 != err)
return 0; return 0;
cachedSize = (size_t) (fileStat.st_size); cachedSize = (size_t) (fileStat.st_size);
#endif #endif
} }
return cachedSize; return cachedSize;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void DefaultIOStream::Flush() void DefaultIOStream::Flush()
{ {
if (mFile) { if (mFile) {
::fflush(mFile); ::fflush(mFile);
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------

View File

@ -1,142 +1,142 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 Default file I/O using fXXX()-family of functions */ /** @file Default file I/O using fXXX()-family of functions */
#ifndef AI_DEFAULTIOSTREAM_H_INC #ifndef AI_DEFAULTIOSTREAM_H_INC
#define AI_DEFAULTIOSTREAM_H_INC #define AI_DEFAULTIOSTREAM_H_INC
#include <stdio.h> #include <stdio.h>
#include "../include/assimp/IOStream.hpp" #include "../include/assimp/IOStream.hpp"
#include "../include/assimp/importerdesc.h" #include "../include/assimp/importerdesc.h"
#include "Defines.h" #include "Defines.h"
namespace Assimp { namespace Assimp {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
//! @class DefaultIOStream //! @class DefaultIOStream
//! @brief Default IO implementation, use standard IO operations //! @brief Default IO implementation, use standard IO operations
//! @note An instance of this class can exist without a valid file handle //! @note An instance of this class can exist without a valid file handle
//! attached to it. All calls fail, but the instance can nevertheless be //! attached to it. All calls fail, but the instance can nevertheless be
//! used with no restrictions. //! used with no restrictions.
class DefaultIOStream : public IOStream class DefaultIOStream : public IOStream
{ {
friend class DefaultIOSystem; friend class DefaultIOSystem;
#if __ANDROID__ #if __ANDROID__
#if __ANDROID_API__ > 9 #if __ANDROID_API__ > 9
#if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) #if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
friend class AndroidJNIIOSystem; friend class AndroidJNIIOSystem;
#endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT) #endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
#endif // __ANDROID_API__ > 9 #endif // __ANDROID_API__ > 9
#endif // __ANDROID__ #endif // __ANDROID__
protected: protected:
DefaultIOStream(); DefaultIOStream();
DefaultIOStream(FILE* pFile, const std::string &strFilename); DefaultIOStream(FILE* pFile, const std::string &strFilename);
public: public:
/** Destructor public to allow simple deletion to close the file. */ /** Destructor public to allow simple deletion to close the file. */
~DefaultIOStream (); ~DefaultIOStream ();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Read from stream /// Read from stream
size_t Read(void* pvBuffer, size_t Read(void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount); size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Write to stream /// Write to stream
size_t Write(const void* pvBuffer, size_t Write(const void* pvBuffer,
size_t pSize, size_t pSize,
size_t pCount); size_t pCount);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Seek specific position /// Seek specific position
aiReturn Seek(size_t pOffset, aiReturn Seek(size_t pOffset,
aiOrigin pOrigin); aiOrigin pOrigin);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Get current seek position /// Get current seek position
size_t Tell() const; size_t Tell() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Get size of file /// Get size of file
size_t FileSize() const; size_t FileSize() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/// Flush file contents /// Flush file contents
void Flush(); void Flush();
private: private:
// File datastructure, using clib // File datastructure, using clib
FILE* mFile; FILE* mFile;
// Filename // Filename
std::string mFilename; std::string mFilename;
// Cached file size // Cached file size
mutable size_t cachedSize; mutable size_t cachedSize;
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline DefaultIOStream::DefaultIOStream () : inline DefaultIOStream::DefaultIOStream () :
mFile (NULL), mFile (NULL),
mFilename (""), mFilename (""),
cachedSize (SIZE_MAX) cachedSize (SIZE_MAX)
{ {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
inline DefaultIOStream::DefaultIOStream (FILE* pFile, inline DefaultIOStream::DefaultIOStream (FILE* pFile,
const std::string &strFilename) : const std::string &strFilename) :
mFile(pFile), mFile(pFile),
mFilename(strFilename), mFilename(strFilename),
cachedSize (SIZE_MAX) cachedSize (SIZE_MAX)
{ {
// empty // empty
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // ns assimp } // ns assimp
#endif //!!AI_DEFAULTIOSTREAM_H_INC #endif //!!AI_DEFAULTIOSTREAM_H_INC

View File

@ -1,197 +1,197 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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 Default implementation of IOSystem using the standard C file functions */ /** @file Default implementation of IOSystem using the standard C file functions */
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
#include "StringComparison.h" #include "StringComparison.h"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include <stdlib.h> #include <stdlib.h>
#ifdef __unix__ #ifdef __unix__
#include <sys/param.h> #include <sys/param.h>
#include <stdlib.h> #include <stdlib.h>
#endif #endif
using namespace Assimp; using namespace Assimp;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Constructor. // Constructor.
DefaultIOSystem::DefaultIOSystem() DefaultIOSystem::DefaultIOSystem()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Destructor. // Destructor.
DefaultIOSystem::~DefaultIOSystem() DefaultIOSystem::~DefaultIOSystem()
{ {
// nothing to do here // nothing to do here
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Tests for the existence of a file at the given path. // Tests for the existence of a file at the given path.
bool DefaultIOSystem::Exists( const char* pFile) const bool DefaultIOSystem::Exists( const char* pFile) const
{ {
FILE* file = ::fopen( pFile, "rb"); FILE* file = ::fopen( pFile, "rb");
if( !file) if( !file)
return false; return false;
::fclose( file); ::fclose( file);
return true; return true;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Open a new file with a given path. // Open a new file with a given path.
IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode) IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
{ {
ai_assert(NULL != strFile); ai_assert(NULL != strFile);
ai_assert(NULL != strMode); ai_assert(NULL != strMode);
FILE* file = ::fopen( strFile, strMode); FILE* file = ::fopen( strFile, strMode);
if( NULL == file) if( NULL == file)
return NULL; return NULL;
return new DefaultIOStream(file, (std::string) strFile); return new DefaultIOStream(file, (std::string) strFile);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Closes the given file and releases all resources associated with it. // Closes the given file and releases all resources associated with it.
void DefaultIOSystem::Close( IOStream* pFile) void DefaultIOSystem::Close( IOStream* pFile)
{ {
delete pFile; delete pFile;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Returns the operation specific directory separator // Returns the operation specific directory separator
char DefaultIOSystem::getOsSeparator() const char DefaultIOSystem::getOsSeparator() const
{ {
#ifndef _WIN32 #ifndef _WIN32
return '/'; return '/';
#else #else
return '\\'; return '\\';
#endif #endif
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// IOSystem default implementation (ComparePaths isn't a pure virtual function) // IOSystem default implementation (ComparePaths isn't a pure virtual function)
bool IOSystem::ComparePaths (const char* one, const char* second) const bool IOSystem::ComparePaths (const char* one, const char* second) const
{ {
return !ASSIMP_stricmp(one,second); return !ASSIMP_stricmp(one,second);
} }
// maximum path length // maximum path length
// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html // XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
#ifdef PATH_MAX #ifdef PATH_MAX
# define PATHLIMIT PATH_MAX # define PATHLIMIT PATH_MAX
#else #else
# define PATHLIMIT 4096 # define PATHLIMIT 4096
#endif #endif
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Convert a relative path into an absolute path // Convert a relative path into an absolute path
inline void MakeAbsolutePath (const char* in, char* _out) inline void MakeAbsolutePath (const char* in, char* _out)
{ {
ai_assert(in && _out); ai_assert(in && _out);
char* ret; char* ret;
#ifdef _WIN32 #ifdef _WIN32
ret = ::_fullpath(_out, in,PATHLIMIT); ret = ::_fullpath(_out, in,PATHLIMIT);
#else #else
// use realpath // use realpath
ret = realpath(in, _out); ret = realpath(in, _out);
#endif #endif
if(!ret) { if(!ret) {
// preserve the input path, maybe someone else is able to fix // preserve the input path, maybe someone else is able to fix
// the path before it is accessed (e.g. our file system filter) // the path before it is accessed (e.g. our file system filter)
DefaultLogger::get()->warn("Invalid path: "+std::string(in)); DefaultLogger::get()->warn("Invalid path: "+std::string(in));
strcpy(_out,in); strcpy(_out,in);
} }
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// DefaultIOSystem's more specialized implementation // DefaultIOSystem's more specialized implementation
bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
{ {
// chances are quite good both paths are formatted identically, // chances are quite good both paths are formatted identically,
// so we can hopefully return here already // so we can hopefully return here already
if( !ASSIMP_stricmp(one,second) ) if( !ASSIMP_stricmp(one,second) )
return true; return true;
char temp1[PATHLIMIT]; char temp1[PATHLIMIT];
char temp2[PATHLIMIT]; char temp2[PATHLIMIT];
MakeAbsolutePath (one, temp1); MakeAbsolutePath (one, temp1);
MakeAbsolutePath (second, temp2); MakeAbsolutePath (second, temp2);
return !ASSIMP_stricmp(temp1,temp2); return !ASSIMP_stricmp(temp1,temp2);
} }
std::string DefaultIOSystem::fileName(std::string path) std::string DefaultIOSystem::fileName(std::string path)
{ {
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(last + 1); if (last != std::string::npos) ret = ret.substr(last + 1);
return ret; return ret;
} }
std::string DefaultIOSystem::completeBaseName(std::string path) std::string DefaultIOSystem::completeBaseName(std::string path)
{ {
std::string ret = fileName(path); std::string ret = fileName(path);
std::size_t pos = ret.find_last_of('.'); std::size_t pos = ret.find_last_of('.');
if(pos != ret.npos) ret = ret.substr(0, pos); if(pos != ret.npos) ret = ret.substr(0, pos);
return ret; return ret;
} }
std::string DefaultIOSystem::absolutePath(std::string path) std::string DefaultIOSystem::absolutePath(std::string path)
{ {
std::string ret = path; std::string ret = path;
std::size_t last = ret.find_last_of("\\/"); std::size_t last = ret.find_last_of("\\/");
if (last != std::string::npos) ret = ret.substr(0, last); if (last != std::string::npos) ret = ret.substr(0, last);
return ret; return ret;
} }
#undef PATHLIMIT #undef PATHLIMIT

View File

@ -1,98 +1,98 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 Default implementation of IOSystem using the standard C file functions */ /** @file Default implementation of IOSystem using the standard C file functions */
#ifndef AI_DEFAULTIOSYSTEM_H_INC #ifndef AI_DEFAULTIOSYSTEM_H_INC
#define AI_DEFAULTIOSYSTEM_H_INC #define AI_DEFAULTIOSYSTEM_H_INC
#include "../include/assimp/IOSystem.hpp" #include "../include/assimp/IOSystem.hpp"
namespace Assimp { namespace Assimp {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** Default implementation of IOSystem using the standard C file functions */ /** Default implementation of IOSystem using the standard C file functions */
class DefaultIOSystem : public IOSystem class DefaultIOSystem : public IOSystem
{ {
public: public:
/** Constructor. */ /** Constructor. */
DefaultIOSystem(); DefaultIOSystem();
/** Destructor. */ /** Destructor. */
~DefaultIOSystem(); ~DefaultIOSystem();
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Tests for the existence of a file at the given path. */ /** Tests for the existence of a file at the given path. */
bool Exists( const char* pFile) const; bool Exists( const char* pFile) const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Returns the directory separator. */ /** Returns the directory separator. */
char getOsSeparator() const; char getOsSeparator() const;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Open a new file with a given path. */ /** Open a new file with a given path. */
IOStream* Open( const char* pFile, const char* pMode = "rb"); IOStream* Open( const char* pFile, const char* pMode = "rb");
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Closes the given file and releases all resources associated with it. */ /** Closes the given file and releases all resources associated with it. */
void Close( IOStream* pFile); void Close( IOStream* pFile);
// ------------------------------------------------------------------- // -------------------------------------------------------------------
/** Compare two paths */ /** Compare two paths */
bool ComparePaths (const char* one, const char* second) const; bool ComparePaths (const char* one, const char* second) const;
/** @brief get the file name of a full filepath /** @brief get the file name of a full filepath
* example: /tmp/archive.tar.gz -> archive.tar.gz * example: /tmp/archive.tar.gz -> archive.tar.gz
*/ */
static std::string fileName(std::string path); static std::string fileName(std::string path);
/** @brief get the complete base name of a full filepath /** @brief get the complete base name of a full filepath
* example: /tmp/archive.tar.gz -> archive.tar * example: /tmp/archive.tar.gz -> archive.tar
*/ */
static std::string completeBaseName(std::string path); static std::string completeBaseName(std::string path);
/** @brief get the path of a full filepath /** @brief get the path of a full filepath
* example: /tmp/archive.tar.gz -> /tmp/ * example: /tmp/archive.tar.gz -> /tmp/
*/ */
static std::string absolutePath(std::string path); static std::string absolutePath(std::string path);
}; };
} //!ns Assimp } //!ns Assimp
#endif //AI_DEFAULTIOSYSTEM_H_INC #endif //AI_DEFAULTIOSYSTEM_H_INC

View File

@ -1,423 +1,423 @@
/* /*
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Copyright (c) 2006-2015, 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 DefaultLogger.cpp /** @file DefaultLogger.cpp
* @brief Implementation of DefaultLogger (and Logger) * @brief Implementation of DefaultLogger (and Logger)
*/ */
#include "DefaultIOSystem.h" #include "DefaultIOSystem.h"
// Default log streams // Default log streams
#include "Win32DebugLogStream.h" #include "Win32DebugLogStream.h"
#include "StdOStreamLogStream.h" #include "StdOStreamLogStream.h"
#include "FileLogStream.h" #include "FileLogStream.h"
#include "../include/assimp/NullLogger.hpp" #include "../include/assimp/NullLogger.hpp"
#include "../include/assimp/DefaultLogger.hpp" #include "../include/assimp/DefaultLogger.hpp"
#include "../include/assimp/ai_assert.h" #include "../include/assimp/ai_assert.h"
#include <iostream> #include <iostream>
#include <stdio.h> #include <stdio.h>
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
# include <boost/thread/thread.hpp> # include <boost/thread/thread.hpp>
# include <boost/thread/mutex.hpp> # include <boost/thread/mutex.hpp>
boost::mutex loggerMutex; boost::mutex loggerMutex;
#endif #endif
namespace Assimp { namespace Assimp {
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
NullLogger DefaultLogger::s_pNullLogger; NullLogger DefaultLogger::s_pNullLogger;
Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger; Logger *DefaultLogger::m_pLogger = &DefaultLogger::s_pNullLogger;
static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging; static const unsigned int SeverityAll = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Represents a log-stream + its error severity // Represents a log-stream + its error severity
struct LogStreamInfo struct LogStreamInfo
{ {
unsigned int m_uiErrorSeverity; unsigned int m_uiErrorSeverity;
LogStream *m_pStream; LogStream *m_pStream;
// Constructor // Constructor
LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) : LogStreamInfo( unsigned int uiErrorSev, LogStream *pStream ) :
m_uiErrorSeverity( uiErrorSev ), m_uiErrorSeverity( uiErrorSev ),
m_pStream( pStream ) m_pStream( pStream )
{ {
// empty // empty
} }
// Destructor // Destructor
~LogStreamInfo() ~LogStreamInfo()
{ {
delete m_pStream; delete m_pStream;
} }
}; };
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Construct a default log stream // Construct a default log stream
LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams, LogStream* LogStream::createDefaultStream(aiDefaultLogStream streams,
const char* name /*= "AssimpLog.txt"*/, const char* name /*= "AssimpLog.txt"*/,
IOSystem* io /*= NULL*/) IOSystem* io /*= NULL*/)
{ {
switch (streams) switch (streams)
{ {
// This is a platform-specific feature // This is a platform-specific feature
case aiDefaultLogStream_DEBUGGER: case aiDefaultLogStream_DEBUGGER:
#ifdef WIN32 #ifdef WIN32
return new Win32DebugLogStream(); return new Win32DebugLogStream();
#else #else
return NULL; return NULL;
#endif #endif
// Platform-independent default streams // Platform-independent default streams
case aiDefaultLogStream_STDERR: case aiDefaultLogStream_STDERR:
return new StdOStreamLogStream(std::cerr); return new StdOStreamLogStream(std::cerr);
case aiDefaultLogStream_STDOUT: case aiDefaultLogStream_STDOUT:
return new StdOStreamLogStream(std::cout); return new StdOStreamLogStream(std::cout);
case aiDefaultLogStream_FILE: case aiDefaultLogStream_FILE:
return (name && *name ? new FileLogStream(name,io) : NULL); return (name && *name ? new FileLogStream(name,io) : NULL);
default: default:
// We don't know this default log stream, so raise an assertion // We don't know this default log stream, so raise an assertion
ai_assert(false); ai_assert(false);
}; };
// For compilers without dead code path detection // For compilers without dead code path detection
return NULL; return NULL;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Creates the only singleton instance // Creates the only singleton instance
Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/, Logger *DefaultLogger::create(const char* name /*= "AssimpLog.txt"*/,
LogSeverity severity /*= NORMAL*/, LogSeverity severity /*= NORMAL*/,
unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/, unsigned int defStreams /*= aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE*/,
IOSystem* io /*= NULL*/) IOSystem* io /*= NULL*/)
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(loggerMutex); boost::mutex::scoped_lock lock(loggerMutex);
#endif #endif
if (m_pLogger && !isNullLogger() ) if (m_pLogger && !isNullLogger() )
delete m_pLogger; delete m_pLogger;
m_pLogger = new DefaultLogger( severity ); m_pLogger = new DefaultLogger( severity );
// Attach default log streams // Attach default log streams
// Stream the log to the MSVC debugger? // Stream the log to the MSVC debugger?
if (defStreams & aiDefaultLogStream_DEBUGGER) if (defStreams & aiDefaultLogStream_DEBUGGER)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_DEBUGGER));
// Stream the log to COUT? // Stream the log to COUT?
if (defStreams & aiDefaultLogStream_STDOUT) if (defStreams & aiDefaultLogStream_STDOUT)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDOUT));
// Stream the log to CERR? // Stream the log to CERR?
if (defStreams & aiDefaultLogStream_STDERR) if (defStreams & aiDefaultLogStream_STDERR)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_STDERR));
// Stream the log to a file // Stream the log to a file
if (defStreams & aiDefaultLogStream_FILE && name && *name) if (defStreams & aiDefaultLogStream_FILE && name && *name)
m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io)); m_pLogger->attachStream( LogStream::createDefaultStream(aiDefaultLogStream_FILE,name,io));
return m_pLogger; return m_pLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::debug(const char* message) { void Logger::debug(const char* message) {
// SECURITY FIX: otherwise it's easy to produce overruns since // SECURITY FIX: otherwise it's easy to produce overruns since
// sometimes importers will include data from the input file // sometimes importers will include data from the input file
// (i.e. node names) in their messages. // (i.e. node names) in their messages.
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnDebug(message); return OnDebug(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::info(const char* message) { void Logger::info(const char* message) {
// SECURITY FIX: see above // SECURITY FIX: see above
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnInfo(message); return OnInfo(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::warn(const char* message) { void Logger::warn(const char* message) {
// SECURITY FIX: see above // SECURITY FIX: see above
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnWarn(message); return OnWarn(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void Logger::error(const char* message) { void Logger::error(const char* message) {
// SECURITY FIX: see above // SECURITY FIX: see above
if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) { if (strlen(message)>MAX_LOG_MESSAGE_LENGTH) {
return; return;
} }
return OnError(message); return OnError(message);
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
void DefaultLogger::set( Logger *logger ) void DefaultLogger::set( Logger *logger )
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(loggerMutex); boost::mutex::scoped_lock lock(loggerMutex);
#endif #endif
if (!logger)logger = &s_pNullLogger; if (!logger)logger = &s_pNullLogger;
if (m_pLogger && !isNullLogger() ) if (m_pLogger && !isNullLogger() )
delete m_pLogger; delete m_pLogger;
DefaultLogger::m_pLogger = logger; DefaultLogger::m_pLogger = logger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
bool DefaultLogger::isNullLogger() bool DefaultLogger::isNullLogger()
{ {
return m_pLogger == &s_pNullLogger; return m_pLogger == &s_pNullLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Singleton getter // Singleton getter
Logger *DefaultLogger::get() Logger *DefaultLogger::get()
{ {
return m_pLogger; return m_pLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Kills the only instance // Kills the only instance
void DefaultLogger::kill() void DefaultLogger::kill()
{ {
// enter the mutex here to avoid concurrency problems // enter the mutex here to avoid concurrency problems
#ifndef ASSIMP_BUILD_SINGLETHREADED #ifndef ASSIMP_BUILD_SINGLETHREADED
boost::mutex::scoped_lock lock(loggerMutex); boost::mutex::scoped_lock lock(loggerMutex);
#endif #endif
if (m_pLogger == &s_pNullLogger)return; if (m_pLogger == &s_pNullLogger)return;
delete m_pLogger; delete m_pLogger;
m_pLogger = &s_pNullLogger; m_pLogger = &s_pNullLogger;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Debug message // Debug message
void DefaultLogger::OnDebug( const char* message ) void DefaultLogger::OnDebug( const char* message )
{ {
if ( m_Severity == Logger::NORMAL ) if ( m_Severity == Logger::NORMAL )
return; return;
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Debugging ); WriteToStreams( msg, Logger::Debugging );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Logs an info // Logs an info
void DefaultLogger::OnInfo( const char* message ) void DefaultLogger::OnInfo( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Info, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Info, T%u: %s", GetThreadID(), message );
WriteToStreams( msg , Logger::Info ); WriteToStreams( msg , Logger::Info );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Logs a warning // Logs a warning
void DefaultLogger::OnWarn( const char* message ) void DefaultLogger::OnWarn( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Warn, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Warn, T%u: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Warn ); WriteToStreams( msg, Logger::Warn );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Logs an error // Logs an error
void DefaultLogger::OnError( const char* message ) void DefaultLogger::OnError( const char* message )
{ {
char msg[MAX_LOG_MESSAGE_LENGTH + 16]; char msg[MAX_LOG_MESSAGE_LENGTH + 16];
::sprintf(msg,"Error, T%u: %s", GetThreadID(), message ); ::sprintf(msg,"Error, T%u: %s", GetThreadID(), message );
WriteToStreams( msg, Logger::Err ); WriteToStreams( msg, Logger::Err );
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Will attach a new stream // Will attach a new stream
bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity ) bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
{ {
if (!pStream) if (!pStream)
return false; return false;
if (0 == severity) { if (0 == severity) {
severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging; severity = Logger::Info | Logger::Err | Logger::Warn | Logger::Debugging;
} }
for ( StreamIt it = m_StreamArray.begin(); for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it ) ++it )
{ {
if ( (*it)->m_pStream == pStream ) if ( (*it)->m_pStream == pStream )
{ {
(*it)->m_uiErrorSeverity |= severity; (*it)->m_uiErrorSeverity |= severity;
return true; return true;
} }
} }
LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream ); LogStreamInfo *pInfo = new LogStreamInfo( severity, pStream );
m_StreamArray.push_back( pInfo ); m_StreamArray.push_back( pInfo );
return true; return true;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Detatch a stream // Detatch a stream
bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity ) bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
{ {
if (!pStream) if (!pStream)
return false; return false;
if (0 == severity) { if (0 == severity) {
severity = SeverityAll; severity = SeverityAll;
} }
for ( StreamIt it = m_StreamArray.begin(); for ( StreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it ) ++it )
{ {
if ( (*it)->m_pStream == pStream ) if ( (*it)->m_pStream == pStream )
{ {
(*it)->m_uiErrorSeverity &= ~severity; (*it)->m_uiErrorSeverity &= ~severity;
if ( (*it)->m_uiErrorSeverity == 0 ) if ( (*it)->m_uiErrorSeverity == 0 )
{ {
// don't delete the underlying stream 'cause the caller gains ownership again // don't delete the underlying stream 'cause the caller gains ownership again
(**it).m_pStream = NULL; (**it).m_pStream = NULL;
delete *it; delete *it;
m_StreamArray.erase( it ); m_StreamArray.erase( it );
break; break;
} }
return true; return true;
} }
} }
return false; return false;
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Constructor // Constructor
DefaultLogger::DefaultLogger(LogSeverity severity) DefaultLogger::DefaultLogger(LogSeverity severity)
: Logger ( severity ) : Logger ( severity )
, noRepeatMsg (false) , noRepeatMsg (false)
, lastLen( 0 ) , lastLen( 0 )
{ {
lastMsg[0] = '\0'; lastMsg[0] = '\0';
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Destructor // Destructor
DefaultLogger::~DefaultLogger() DefaultLogger::~DefaultLogger()
{ {
for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) { for ( StreamIt it = m_StreamArray.begin(); it != m_StreamArray.end(); ++it ) {
// also frees the underlying stream, we are its owner. // also frees the underlying stream, we are its owner.
delete *it; delete *it;
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Writes message to stream // Writes message to stream
void DefaultLogger::WriteToStreams(const char *message, void DefaultLogger::WriteToStreams(const char *message,
ErrorSeverity ErrorSev ) ErrorSeverity ErrorSev )
{ {
ai_assert(NULL != message); ai_assert(NULL != message);
// Check whether this is a repeated message // Check whether this is a repeated message
if (! ::strncmp( message,lastMsg, lastLen-1)) if (! ::strncmp( message,lastMsg, lastLen-1))
{ {
if (!noRepeatMsg) if (!noRepeatMsg)
{ {
noRepeatMsg = true; noRepeatMsg = true;
message = "Skipping one or more lines with the same contents\n"; message = "Skipping one or more lines with the same contents\n";
} }
else return; else return;
} }
else else
{ {
// append a new-line character to the message to be printed // append a new-line character to the message to be printed
lastLen = ::strlen(message); lastLen = ::strlen(message);
::memcpy(lastMsg,message,lastLen+1); ::memcpy(lastMsg,message,lastLen+1);
::strcat(lastMsg+lastLen,"\n"); ::strcat(lastMsg+lastLen,"\n");
message = lastMsg; message = lastMsg;
noRepeatMsg = false; noRepeatMsg = false;
++lastLen; ++lastLen;
} }
for ( ConstStreamIt it = m_StreamArray.begin(); for ( ConstStreamIt it = m_StreamArray.begin();
it != m_StreamArray.end(); it != m_StreamArray.end();
++it) ++it)
{ {
if ( ErrorSev & (*it)->m_uiErrorSeverity ) if ( ErrorSev & (*it)->m_uiErrorSeverity )
(*it)->m_pStream->write( message); (*it)->m_pStream->write( message);
} }
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
// Returns thread id, if not supported only a zero will be returned. // Returns thread id, if not supported only a zero will be returned.
unsigned int DefaultLogger::GetThreadID() unsigned int DefaultLogger::GetThreadID()
{ {
// fixme: we can get this value via boost::threads // fixme: we can get this value via boost::threads
#ifdef WIN32 #ifdef WIN32
return (unsigned int)::GetCurrentThreadId(); return (unsigned int)::GetCurrentThreadId();
#else #else
return 0; // not supported return 0; // not supported
#endif #endif
} }
// ---------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------
} // !namespace Assimp } // !namespace Assimp

View File

@ -1,64 +1,64 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2015, 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 ProgressHandler.hpp /** @file ProgressHandler.hpp
* @brief Abstract base class 'ProgressHandler'. * @brief Abstract base class 'ProgressHandler'.
*/ */
#ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H #ifndef INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
#define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H #define INCLUDED_AI_DEFAULTPROGRESSHANDLER_H
#include "../include/assimp/ProgressHandler.hpp" #include "../include/assimp/ProgressHandler.hpp"
namespace Assimp { namespace Assimp {
// ------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------
/** @brief Internal default implementation of the #ProgressHandler interface. */ /** @brief Internal default implementation of the #ProgressHandler interface. */
class DefaultProgressHandler class DefaultProgressHandler
: public ProgressHandler { : public ProgressHandler {
virtual bool Update(float /*percentage*/) { virtual bool Update(float /*percentage*/) {
return false; return false;
} }
}; // !class DefaultProgressHandler }; // !class DefaultProgressHandler
} // Namespace Assimp } // Namespace Assimp
#endif #endif

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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -40,10 +40,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// We need those constants, workaround for any platforms where nobody defined them yet // We need those constants, workaround for any platforms where nobody defined them yet
#if (!defined SIZE_MAX) #if (!defined SIZE_MAX)
# define SIZE_MAX (~((size_t)0)) # define SIZE_MAX (~((size_t)0))
#endif #endif
#if (!defined UINT_MAX) #if (!defined UINT_MAX)
# define UINT_MAX (~((unsigned int)0)) # define UINT_MAX (~((unsigned int)0))
#endif #endif

View File

@ -1,125 +1,125 @@
/* /*
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2008, assimp team Copyright (c) 2006-2008, 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 INCLUDED_EXCEPTIONAL_H #ifndef INCLUDED_EXCEPTIONAL_H
#define INCLUDED_EXCEPTIONAL_H #define INCLUDED_EXCEPTIONAL_H
#include <stdexcept> #include <stdexcept>
#include "DefaultIOStream.h" #include "DefaultIOStream.h"
using std::runtime_error; using std::runtime_error;
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(disable : 4275) # pragma warning(disable : 4275)
#endif #endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an /** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
* unrecoverable error occurs while importing. Loading APIs return * unrecoverable error occurs while importing. Loading APIs return
* NULL instead of a valid aiScene then. */ * NULL instead of a valid aiScene then. */
class DeadlyImportError class DeadlyImportError
: public runtime_error : public runtime_error
{ {
public: public:
/** Constructor with arguments */ /** Constructor with arguments */
explicit DeadlyImportError( const std::string& pErrorText) explicit DeadlyImportError( const std::string& pErrorText)
: runtime_error(pErrorText) : runtime_error(pErrorText)
{ {
} }
private: private:
}; };
typedef DeadlyImportError DeadlyExportError; typedef DeadlyImportError DeadlyExportError;
#ifdef _MSC_VER #ifdef _MSC_VER
# pragma warning(default : 4275) # pragma warning(default : 4275)
#endif #endif
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename T> template <typename T>
struct ExceptionSwallower { struct ExceptionSwallower {
T operator ()() const { T operator ()() const {
return T(); return T();
} }
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <typename T> template <typename T>
struct ExceptionSwallower<T*> { struct ExceptionSwallower<T*> {
T* operator ()() const { T* operator ()() const {
return NULL; return NULL;
} }
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <> template <>
struct ExceptionSwallower<aiReturn> { struct ExceptionSwallower<aiReturn> {
aiReturn operator ()() const { aiReturn operator ()() const {
try { try {
throw; throw;
} }
catch (std::bad_alloc&) { catch (std::bad_alloc&) {
return aiReturn_OUTOFMEMORY; return aiReturn_OUTOFMEMORY;
} }
catch (...) { catch (...) {
return aiReturn_FAILURE; return aiReturn_FAILURE;
} }
} }
}; };
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
template <> template <>
struct ExceptionSwallower<void> { struct ExceptionSwallower<void> {
void operator ()() const { void operator ()() const {
return; return;
} }
}; };
#define ASSIMP_BEGIN_EXCEPTION_REGION()\ #define ASSIMP_BEGIN_EXCEPTION_REGION()\
{\ {\
try { try {
#define ASSIMP_END_EXCEPTION_REGION(type)\ #define ASSIMP_END_EXCEPTION_REGION(type)\
} catch(...) {\ } catch(...) {\
return ExceptionSwallower<type>()();\ return ExceptionSwallower<type>()();\
}\ }\
} }
#endif // INCLUDED_EXCEPTIONAL_H #endif // INCLUDED_EXCEPTIONAL_H

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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,24 +23,24 @@ 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 FBXAnimation.cpp /** @file FBXAnimation.cpp
* @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode, * @brief Assimp::FBX::AnimationCurve, Assimp::FBX::AnimationCurveNode,
* Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack * Assimp::FBX::AnimationLayer, Assimp::FBX::AnimationStack
*/ */
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER #ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
@ -56,37 +56,37 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
using namespace Util; using namespace Util;
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/) AnimationCurve::AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& /*doc*/)
: Object(id, element, name) : Object(id, element, name)
{ {
const Scope& sc = GetRequiredScope(element); const Scope& sc = GetRequiredScope(element);
const Element& KeyTime = GetRequiredElement(sc,"KeyTime"); const Element& KeyTime = GetRequiredElement(sc,"KeyTime");
const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat"); const Element& KeyValueFloat = GetRequiredElement(sc,"KeyValueFloat");
ParseVectorDataArray(keys, KeyTime); ParseVectorDataArray(keys, KeyTime);
ParseVectorDataArray(values, KeyValueFloat); ParseVectorDataArray(values, KeyValueFloat);
if(keys.size() != values.size()) { if(keys.size() != values.size()) {
DOMError("the number of key times does not match the number of keyframe values",&KeyTime); DOMError("the number of key times does not match the number of keyframe values",&KeyTime);
} }
// check if the key times are well-ordered
if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
DOMError("the keyframes are not in ascending order",&KeyTime);
}
const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"]; // check if the key times are well-ordered
if(KeyAttrDataFloat) { if(!std::equal(keys.begin(), keys.end() - 1, keys.begin() + 1, std::less<KeyTimeList::value_type>())) {
ParseVectorDataArray(attributes, *KeyAttrDataFloat); DOMError("the keyframes are not in ascending order",&KeyTime);
} }
const Element* KeyAttrFlags = sc["KeyAttrFlags"]; const Element* KeyAttrDataFloat = sc["KeyAttrDataFloat"];
if(KeyAttrFlags) { if(KeyAttrDataFloat) {
ParseVectorDataArray(flags, *KeyAttrFlags); ParseVectorDataArray(attributes, *KeyAttrDataFloat);
} }
const Element* KeyAttrFlags = sc["KeyAttrFlags"];
if(KeyAttrFlags) {
ParseVectorDataArray(flags, *KeyAttrFlags);
}
} }
@ -98,62 +98,62 @@ AnimationCurve::~AnimationCurve()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc, AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/) const char* const * target_prop_whitelist /*= NULL*/, size_t whitelist_size /*= 0*/)
: Object(id, element, name) : Object(id, element, name)
, target() , target()
, doc(doc) , doc(doc)
{ {
const Scope& sc = GetRequiredScope(element); const Scope& sc = GetRequiredScope(element);
// find target node
const char* whitelist[] = {"Model","NodeAttribute"};
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
BOOST_FOREACH(const Connection* con, conns) { // find target node
const char* whitelist[] = {"Model","NodeAttribute"};
const std::vector<const Connection*>& conns = doc.GetConnectionsBySourceSequenced(ID(),whitelist,2);
// link should go for a property BOOST_FOREACH(const Connection* con, conns) {
if (!con->PropertyName().length()) {
continue;
}
if(target_prop_whitelist) { // link should go for a property
const char* const s = con->PropertyName().c_str(); if (!con->PropertyName().length()) {
bool ok = false; continue;
for (size_t i = 0; i < whitelist_size; ++i) { }
if (!strcmp(s, target_prop_whitelist[i])) {
ok = true;
break;
}
}
if (!ok) { if(target_prop_whitelist) {
throw std::range_error("AnimationCurveNode target property is not in whitelist"); const char* const s = con->PropertyName().c_str();
} bool ok = false;
} for (size_t i = 0; i < whitelist_size; ++i) {
if (!strcmp(s, target_prop_whitelist[i])) {
ok = true;
break;
}
}
const Object* const ob = con->DestinationObject(); if (!ok) {
if(!ob) { throw std::range_error("AnimationCurveNode target property is not in whitelist");
DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element); }
continue; }
}
// XXX support constraints as DOM class const Object* const ob = con->DestinationObject();
//ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob)); if(!ob) {
target = ob; DOMWarning("failed to read destination object for AnimationCurveNode->Model link, ignoring",&element);
if(!target) { continue;
continue; }
}
prop = con->PropertyName(); // XXX support constraints as DOM class
break; //ai_assert(dynamic_cast<const Model*>(ob) || dynamic_cast<const NodeAttribute*>(ob));
} target = ob;
if(!target) {
continue;
}
if(!target) { prop = con->PropertyName();
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element); break;
} }
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false); if(!target) {
DOMWarning("failed to resolve target Model/NodeAttribute/Constraint for AnimationCurveNode",&element);
}
props = GetPropertyTable(doc,"AnimationCurveNode.FbxAnimCurveNode",element,sc,false);
} }
@ -167,34 +167,34 @@ AnimationCurveNode::~AnimationCurveNode()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const AnimationCurveMap& AnimationCurveNode::Curves() const const AnimationCurveMap& AnimationCurveNode::Curves() const
{ {
if(curves.empty()) { if(curves.empty()) {
// resolve attached animation curves // resolve attached animation curves
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve"); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurve");
BOOST_FOREACH(const Connection* con, conns) { BOOST_FOREACH(const Connection* con, conns) {
// link should go for a property // link should go for a property
if (!con->PropertyName().length()) { if (!con->PropertyName().length()) {
continue; continue;
} }
const Object* const ob = con->SourceObject(); const Object* const ob = con->SourceObject();
if(!ob) { if(!ob) {
DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element); DOMWarning("failed to read source object for AnimationCurve->AnimationCurveNode link, ignoring",&element);
continue; continue;
} }
const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob); const AnimationCurve* const anim = dynamic_cast<const AnimationCurve*>(ob);
if(!anim) { if(!anim) {
DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element); DOMWarning("source object for ->AnimationCurveNode link is not an AnimationCurve",&element);
continue; continue;
} }
curves[con->PropertyName()] = anim; curves[con->PropertyName()] = anim;
} }
} }
return curves; return curves;
} }
@ -203,10 +203,10 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element& element, const std::s
: Object(id, element, name) : Object(id, element, name)
, doc(doc) , doc(doc)
{ {
const Scope& sc = GetRequiredScope(element); const Scope& sc = GetRequiredScope(element);
// note: the props table here bears little importance and is usually absent // note: the props table here bears little importance and is usually absent
props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true); props = GetPropertyTable(doc,"AnimationLayer.FbxAnimLayer",element,sc, true);
} }
@ -218,86 +218,86 @@ AnimationLayer::~AnimationLayer()
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/, AnimationCurveNodeList AnimationLayer::Nodes(const char* const * target_prop_whitelist /*= NULL*/,
size_t whitelist_size /*= 0*/) const size_t whitelist_size /*= 0*/) const
{ {
AnimationCurveNodeList nodes; AnimationCurveNodeList nodes;
// resolve attached animation nodes // resolve attached animation nodes
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode"); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationCurveNode");
nodes.reserve(conns.size()); nodes.reserve(conns.size());
BOOST_FOREACH(const Connection* con, conns) { BOOST_FOREACH(const Connection* con, conns) {
// link should not go to a property // link should not go to a property
if (con->PropertyName().length()) { if (con->PropertyName().length()) {
continue; continue;
} }
const Object* const ob = con->SourceObject(); const Object* const ob = con->SourceObject();
if(!ob) { if(!ob) {
DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element); DOMWarning("failed to read source object for AnimationCurveNode->AnimationLayer link, ignoring",&element);
continue; continue;
} }
const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob); const AnimationCurveNode* const anim = dynamic_cast<const AnimationCurveNode*>(ob);
if(!anim) { if(!anim) {
DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element); DOMWarning("source object for ->AnimationLayer link is not an AnimationCurveNode",&element);
continue; continue;
} }
if(target_prop_whitelist) { if(target_prop_whitelist) {
const char* s = anim->TargetProperty().c_str(); const char* s = anim->TargetProperty().c_str();
bool ok = false; bool ok = false;
for (size_t i = 0; i < whitelist_size; ++i) { for (size_t i = 0; i < whitelist_size; ++i) {
if (!strcmp(s, target_prop_whitelist[i])) { if (!strcmp(s, target_prop_whitelist[i])) {
ok = true; ok = true;
break; break;
} }
} }
if(!ok) { if(!ok) {
continue; continue;
} }
} }
nodes.push_back(anim); nodes.push_back(anim);
} }
return nodes; // pray for NRVO return nodes; // pray for NRVO
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc) AnimationStack::AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Object(id, element, name) : Object(id, element, name)
{ {
const Scope& sc = GetRequiredScope(element); const Scope& sc = GetRequiredScope(element);
// note: we don't currently use any of these properties so we shouldn't bother if it is missing // note: we don't currently use any of these properties so we shouldn't bother if it is missing
props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true); props = GetPropertyTable(doc,"AnimationStack.FbxAnimStack",element,sc, true);
// resolve attached animation layers // resolve attached animation layers
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer"); const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"AnimationLayer");
layers.reserve(conns.size()); layers.reserve(conns.size());
BOOST_FOREACH(const Connection* con, conns) { BOOST_FOREACH(const Connection* con, conns) {
// link should not go to a property // link should not go to a property
if (con->PropertyName().length()) { if (con->PropertyName().length()) {
continue; continue;
} }
const Object* const ob = con->SourceObject(); const Object* const ob = con->SourceObject();
if(!ob) { if(!ob) {
DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element); DOMWarning("failed to read source object for AnimationLayer->AnimationStack link, ignoring",&element);
continue; continue;
} }
const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob); const AnimationLayer* const anim = dynamic_cast<const AnimationLayer*>(ob);
if(!anim) { if(!anim) {
DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element); DOMWarning("source object for ->AnimationStack link is not an AnimationLayer",&element);
continue; continue;
} }
layers.push_back(anim); layers.push_back(anim);
} }
} }

View File

@ -58,22 +58,22 @@ namespace FBX {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset) Token::Token(const char* sbegin, const char* send, TokenType type, unsigned int offset)
: :
#ifdef DEBUG #ifdef DEBUG
contents(sbegin, static_cast<size_t>(send-sbegin)), contents(sbegin, static_cast<size_t>(send-sbegin)),
#endif #endif
sbegin(sbegin) sbegin(sbegin)
, send(send) , send(send)
, type(type) , type(type)
, line(offset) , line(offset)
, column(BINARY_MARKER) , column(BINARY_MARKER)
{ {
ai_assert(sbegin); ai_assert(sbegin);
ai_assert(send); ai_assert(send);
// binary tokens may have zero length because they are sometimes dummies // binary tokens may have zero length because they are sometimes dummies
// inserted by TokenizeBinary() // inserted by TokenizeBinary()
ai_assert(send >= sbegin); ai_assert(send >= sbegin);
} }
@ -84,85 +84,85 @@ namespace {
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX; AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset) AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offset)
{ {
throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset)); throw DeadlyImportError(Util::AddOffset("FBX-Tokenize",message,offset));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint32_t Offset(const char* begin, const char* cursor) uint32_t Offset(const char* begin, const char* cursor)
{ {
ai_assert(begin <= cursor); ai_assert(begin <= cursor);
return static_cast<unsigned int>(cursor - begin); return static_cast<unsigned int>(cursor - begin);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TokenizeError(const std::string& message, const char* begin, const char* cursor) void TokenizeError(const std::string& message, const char* begin, const char* cursor)
{ {
TokenizeError(message, Offset(begin, cursor)); TokenizeError(message, Offset(begin, cursor));
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint32_t ReadWord(const char* input, const char*& cursor, const char* end) uint32_t ReadWord(const char* input, const char*& cursor, const char* end)
{ {
if(Offset(cursor, end) < 4) { if(Offset(cursor, end) < 4) {
TokenizeError("cannot ReadWord, out of bounds",input, cursor); TokenizeError("cannot ReadWord, out of bounds",input, cursor);
} }
uint32_t word = *reinterpret_cast<const uint32_t*>(cursor); uint32_t word = *reinterpret_cast<const uint32_t*>(cursor);
AI_SWAP4(word); AI_SWAP4(word);
cursor += 4; cursor += 4;
return word; return word;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
uint8_t ReadByte(const char* input, const char*& cursor, const char* end) uint8_t ReadByte(const char* input, const char*& cursor, const char* end)
{ {
if(Offset(cursor, end) < 1) { if(Offset(cursor, end) < 1) {
TokenizeError("cannot ReadByte, out of bounds",input, cursor); TokenizeError("cannot ReadByte, out of bounds",input, cursor);
} }
uint8_t word = *reinterpret_cast<const uint8_t*>(cursor); uint8_t word = *reinterpret_cast<const uint8_t*>(cursor);
++cursor; ++cursor;
return word; return word;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end, unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end,
bool long_length = false, bool long_length = false,
bool allow_null = false) bool allow_null = false)
{ {
const uint32_t len_len = long_length ? 4 : 1; const uint32_t len_len = long_length ? 4 : 1;
if(Offset(cursor, end) < len_len) { if(Offset(cursor, end) < len_len) {
TokenizeError("cannot ReadString, out of bounds reading length",input, cursor); TokenizeError("cannot ReadString, out of bounds reading length",input, cursor);
} }
const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end); const uint32_t length = long_length ? ReadWord(input, cursor, end) : ReadByte(input, cursor, end);
if (Offset(cursor, end) < length) { if (Offset(cursor, end) < length) {
TokenizeError("cannot ReadString, length is out of bounds",input, cursor); TokenizeError("cannot ReadString, length is out of bounds",input, cursor);
} }
sbegin_out = cursor; sbegin_out = cursor;
cursor += length; cursor += length;
send_out = cursor; send_out = cursor;
if(!allow_null) { if(!allow_null) {
for (unsigned int i = 0; i < length; ++i) { for (unsigned int i = 0; i < length; ++i) {
if(sbegin_out[i] == '\0') { if(sbegin_out[i] == '\0') {
TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor); TokenizeError("failed ReadString, unexpected NUL character in string",input, cursor);
} }
} }
} }
return length; return length;
} }
@ -170,203 +170,203 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end)
{ {
if(Offset(cursor, end) < 1) { if(Offset(cursor, end) < 1) {
TokenizeError("cannot ReadData, out of bounds reading length",input, cursor); TokenizeError("cannot ReadData, out of bounds reading length",input, cursor);
} }
const char type = *cursor; const char type = *cursor;
sbegin_out = cursor++; sbegin_out = cursor++;
switch(type) switch(type)
{ {
// 16 bit int // 16 bit int
case 'Y': case 'Y':
cursor += 2; cursor += 2;
break; break;
// 1 bit bool flag (yes/no) // 1 bit bool flag (yes/no)
case 'C': case 'C':
cursor += 1; cursor += 1;
break; break;
// 32 bit int // 32 bit int
case 'I': case 'I':
// <- fall thru // <- fall thru
// float // float
case 'F': case 'F':
cursor += 4; cursor += 4;
break; break;
// double // double
case 'D': case 'D':
cursor += 8; cursor += 8;
break; break;
// 64 bit int // 64 bit int
case 'L': case 'L':
cursor += 8; cursor += 8;
break; break;
// note: do not write cursor += ReadWord(...cursor) as this would be UB // note: do not write cursor += ReadWord(...cursor) as this would be UB
// raw binary data // raw binary data
case 'R': case 'R':
{ {
const uint32_t length = ReadWord(input, cursor, end); const uint32_t length = ReadWord(input, cursor, end);
cursor += length; cursor += length;
break; break;
} }
case 'b': case 'b':
// TODO: what is the 'b' type code? Right now we just skip over it / // TODO: what is the 'b' type code? Right now we just skip over it /
// take the full range we could get // take the full range we could get
cursor = end; cursor = end;
break; break;
// array of * // array of *
case 'f': case 'f':
case 'd': case 'd':
case 'l': case 'l':
case 'i': { case 'i': {
const uint32_t length = ReadWord(input, cursor, end); const uint32_t length = ReadWord(input, cursor, end);
const uint32_t encoding = ReadWord(input, cursor, end); const uint32_t encoding = ReadWord(input, cursor, end);
const uint32_t comp_len = ReadWord(input, cursor, end); const uint32_t comp_len = ReadWord(input, cursor, end);
// compute length based on type and check against the stored value // compute length based on type and check against the stored value
if(encoding == 0) { if(encoding == 0) {
uint32_t stride = 0; uint32_t stride = 0;
switch(type) switch(type)
{ {
case 'f': case 'f':
case 'i': case 'i':
stride = 4; stride = 4;
break; break;
case 'd': case 'd':
case 'l': case 'l':
stride = 8; stride = 8;
break; break;
default: default:
ai_assert(false); ai_assert(false);
}; };
ai_assert(stride > 0); ai_assert(stride > 0);
if(length * stride != comp_len) { if(length * stride != comp_len) {
TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor); TokenizeError("cannot ReadData, calculated data stride differs from what the file claims",input, cursor);
} }
} }
// zip/deflate algorithm (encoding==1)? take given length. anything else? die // zip/deflate algorithm (encoding==1)? take given length. anything else? die
else if (encoding != 1) { else if (encoding != 1) {
TokenizeError("cannot ReadData, unknown encoding",input, cursor); TokenizeError("cannot ReadData, unknown encoding",input, cursor);
} }
cursor += comp_len; cursor += comp_len;
break; break;
} }
// string // string
case 'S': { case 'S': {
const char* sb, *se; const char* sb, *se;
// 0 characters can legally happen in such strings // 0 characters can legally happen in such strings
ReadString(sb, se, input, cursor, end, true, true); ReadString(sb, se, input, cursor, end, true, true);
break; break;
} }
default: default:
TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor); TokenizeError("cannot ReadData, unexpected type code: " + std::string(&type, 1),input, cursor);
} }
if(cursor > end) { if(cursor > end) {
TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor); TokenizeError("cannot ReadData, the remaining size is too small for the data type: " + std::string(&type, 1),input, cursor);
} }
// the type code is contained in the returned range // the type code is contained in the returned range
send_out = cursor; send_out = cursor;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end) bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end)
{ {
// the first word contains the offset at which this block ends // the first word contains the offset at which this block ends
const uint32_t end_offset = ReadWord(input, cursor, end); const uint32_t end_offset = ReadWord(input, cursor, end);
// we may get 0 if reading reached the end of the file - // we may get 0 if reading reached the end of the file -
// fbx files have a mysterious extra footer which I don't know // fbx files have a mysterious extra footer which I don't know
// how to extract any information from, but at least it always // how to extract any information from, but at least it always
// starts with a 0. // starts with a 0.
if(!end_offset) { if(!end_offset) {
return false; return false;
} }
if(end_offset > Offset(input, end)) { if(end_offset > Offset(input, end)) {
TokenizeError("block offset is out of range",input, cursor); TokenizeError("block offset is out of range",input, cursor);
} }
else if(end_offset < Offset(input, cursor)) { else if(end_offset < Offset(input, cursor)) {
TokenizeError("block offset is negative out of range",input, cursor); TokenizeError("block offset is negative out of range",input, cursor);
} }
// the second data word contains the number of properties in the scope // the second data word contains the number of properties in the scope
const uint32_t prop_count = ReadWord(input, cursor, end); const uint32_t prop_count = ReadWord(input, cursor, end);
// the third data word contains the length of the property list // the third data word contains the length of the property list
const uint32_t prop_length = ReadWord(input, cursor, end); const uint32_t prop_length = ReadWord(input, cursor, end);
// now comes the name of the scope/key // now comes the name of the scope/key
const char* sbeg, *send; const char* sbeg, *send;
ReadString(sbeg, send, input, cursor, end); ReadString(sbeg, send, input, cursor, end);
output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) )); output_tokens.push_back(new_Token(sbeg, send, TokenType_KEY, Offset(input, cursor) ));
// now come the individual properties // now come the individual properties
const char* begin_cursor = cursor; const char* begin_cursor = cursor;
for (unsigned int i = 0; i < prop_count; ++i) { for (unsigned int i = 0; i < prop_count; ++i) {
ReadData(sbeg, send, input, cursor, begin_cursor + prop_length); ReadData(sbeg, send, input, cursor, begin_cursor + prop_length);
output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) )); output_tokens.push_back(new_Token(sbeg, send, TokenType_DATA, Offset(input, cursor) ));
if(i != prop_count-1) { if(i != prop_count-1) {
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) )); output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_COMMA, Offset(input, cursor) ));
} }
} }
if (Offset(begin_cursor, cursor) != prop_length) { if (Offset(begin_cursor, cursor) != prop_length) {
TokenizeError("property length not reached, something is wrong",input, cursor); TokenizeError("property length not reached, something is wrong",input, cursor);
} }
// at the end of each nested block, there is a NUL record to indicate // at the end of each nested block, there is a NUL record to indicate
// that the sub-scope exists (i.e. to distinguish between P: and P : {}) // that the sub-scope exists (i.e. to distinguish between P: and P : {})
// this NUL record is 13 bytes long. // this NUL record is 13 bytes long.
#define BLOCK_SENTINEL_LENGTH 13 #define BLOCK_SENTINEL_LENGTH 13
if (Offset(input, cursor) < end_offset) { if (Offset(input, cursor) < end_offset) {
if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) { if (end_offset - Offset(input, cursor) < BLOCK_SENTINEL_LENGTH) {
TokenizeError("insufficient padding bytes at block end",input, cursor); TokenizeError("insufficient padding bytes at block end",input, cursor);
} }
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) )); output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_OPEN_BRACKET, Offset(input, cursor) ));
// XXX this is vulnerable to stack overflowing .. // XXX this is vulnerable to stack overflowing ..
while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) { while(Offset(input, cursor) < end_offset - BLOCK_SENTINEL_LENGTH) {
ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH); ReadScope(output_tokens, input, cursor, input + end_offset - BLOCK_SENTINEL_LENGTH);
} }
output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) )); output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) { for (unsigned int i = 0; i < BLOCK_SENTINEL_LENGTH; ++i) {
if(cursor[i] != '\0') { if(cursor[i] != '\0') {
TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor); TokenizeError("failed to read nested block sentinel, expected all bytes to be 0",input, cursor);
} }
} }
cursor += BLOCK_SENTINEL_LENGTH; cursor += BLOCK_SENTINEL_LENGTH;
} }
if (Offset(input, cursor) != end_offset) { if (Offset(input, cursor) != end_offset) {
TokenizeError("scope length not reached, something is wrong",input, cursor); TokenizeError("scope length not reached, something is wrong",input, cursor);
} }
return true; return true;
} }
@ -375,26 +375,26 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length) void TokenizeBinary(TokenList& output_tokens, const char* input, unsigned int length)
{ {
ai_assert(input); ai_assert(input);
if(length < 0x1b) { if(length < 0x1b) {
TokenizeError("file is too short",0); TokenizeError("file is too short",0);
} }
if (strncmp(input,"Kaydara FBX Binary",18)) { if (strncmp(input,"Kaydara FBX Binary",18)) {
TokenizeError("magic bytes not found",0); TokenizeError("magic bytes not found",0);
} }
//uint32_t offset = 0x1b; //uint32_t offset = 0x1b;
const char* cursor = input + 0x1b; const char* cursor = input + 0x1b;
while (cursor < input + length) { while (cursor < input + length) {
if(!ReadScope(output_tokens, input, cursor, input + length)) { if(!ReadScope(output_tokens, input, cursor, input + length)) {
break; break;
} }
} }
} }
} // !FBX } // !FBX

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -46,21 +46,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
#if _MSC_VER > 1500 || (defined __GNUC___) #if _MSC_VER > 1500 || (defined __GNUC___)
# define ASSIMP_FBX_USE_UNORDERED_MULTIMAP # define ASSIMP_FBX_USE_UNORDERED_MULTIMAP
# else # else
# define fbx_unordered_map map # define fbx_unordered_map map
# define fbx_unordered_multimap multimap # define fbx_unordered_multimap multimap
#endif #endif
#ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP #ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
# include <unordered_map> # include <unordered_map>
# if _MSC_VER > 1600 # if _MSC_VER > 1600
# define fbx_unordered_map unordered_map # define fbx_unordered_map unordered_map
# define fbx_unordered_multimap unordered_multimap # define fbx_unordered_multimap unordered_multimap
# else # else
# define fbx_unordered_map tr1::unordered_map # define fbx_unordered_map tr1::unordered_map
# define fbx_unordered_multimap tr1::unordered_multimap # define fbx_unordered_multimap tr1::unordered_multimap
# endif # endif
#endif #endif
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -5,8 +5,8 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2015, 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.
---------------------------------------------------------------------- ----------------------------------------------------------------------
@ -49,7 +49,7 @@ struct aiScene;
namespace Assimp { namespace Assimp {
namespace FBX { namespace FBX {
class Document; class Document;
/** Convert a FBX #Document to #aiScene /** Convert a FBX #Document to #aiScene

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