Merge branch 'master' into added_check_before_using
commit
6967a02fcb
|
@ -1,2 +1,2 @@
|
||||||
patreon: assimp
|
patreon: assimp
|
||||||
Paypal: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
|
custom: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=4JRJVPXC4QJM4
|
||||||
|
|
|
@ -7,16 +7,53 @@ on:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-ubuntu:
|
job:
|
||||||
|
name: ${{ matrix.os }}-${{ matrix.cxx }}-build-and-test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
name: [ubuntu-gcc, macos-clang, windows-msvc, ubuntu-clang]
|
||||||
|
# For Windows msvc, for Linux and macOS let's use the clang compiler, use gcc for Linux.
|
||||||
|
include:
|
||||||
|
- name: windows-msvc
|
||||||
|
os: windows-latest
|
||||||
|
cxx: cl.exe
|
||||||
|
cc: cl.exe
|
||||||
|
- name: ubuntu-clang
|
||||||
|
os: ubuntu-latest
|
||||||
|
cxx: clang++
|
||||||
|
cc: clang
|
||||||
|
- name: macos-clang
|
||||||
|
os: macos-latest
|
||||||
|
cxx: clang++
|
||||||
|
cc: clang
|
||||||
|
- name: ubuntu-gcc
|
||||||
|
os: ubuntu-latest
|
||||||
|
cxx: g++
|
||||||
|
cc: gcc
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v2
|
||||||
- name: configure
|
|
||||||
run: cmake CMakeLists.txt
|
|
||||||
- name: build
|
|
||||||
run: cmake --build .
|
|
||||||
- name: test
|
|
||||||
run: cd bin && ./unit
|
|
||||||
|
|
||||||
|
- uses: lukka/get-cmake@latest
|
||||||
|
|
||||||
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
|
||||||
|
- uses: lukka/set-shell-env@v1
|
||||||
|
with:
|
||||||
|
CXX: ${{ matrix.cxx }}
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
|
||||||
|
- name: configure and build
|
||||||
|
uses: lukka/run-cmake@v2
|
||||||
|
with:
|
||||||
|
cmakeListsOrSettingsJson: CMakeListsTxtAdvanced
|
||||||
|
cmakeListsTxtPath: '${{ github.workspace }}/CMakeLists.txt'
|
||||||
|
cmakeAppendedArgs: '-GNinja -DCMAKE_BUILD_TYPE=Release'
|
||||||
|
buildWithCMakeArgs: '-- -v'
|
||||||
|
buildDirectory: '${{ github.workspace }}/build/'
|
||||||
|
|
||||||
|
- name: test
|
||||||
|
run: cd build/bin && ./unit
|
||||||
|
shell: bash
|
||||||
|
|
|
@ -108,10 +108,6 @@ OPTION ( ASSIMP_ERROR_MAX
|
||||||
"Enable all warnings."
|
"Enable all warnings."
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
OPTION ( ASSIMP_WERROR
|
|
||||||
"Treat warnings as errors."
|
|
||||||
OFF
|
|
||||||
)
|
|
||||||
OPTION ( ASSIMP_ASAN
|
OPTION ( ASSIMP_ASAN
|
||||||
"Enable AddressSanitizer."
|
"Enable AddressSanitizer."
|
||||||
OFF
|
OFF
|
||||||
|
@ -243,14 +239,14 @@ IF( UNIX )
|
||||||
INCLUDE(GNUInstallDirs)
|
INCLUDE(GNUInstallDirs)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Grouped compiler settings
|
# Grouped compiler settings ########################################
|
||||||
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||||
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++0x ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
# hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
|
||||||
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||||
ELSEIF(MSVC)
|
ELSEIF(MSVC)
|
||||||
|
@ -263,10 +259,10 @@ ELSEIF(MSVC)
|
||||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
|
||||||
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" )
|
||||||
IF(NOT ASSIMP_HUNTER_ENABLED)
|
IF(NOT ASSIMP_HUNTER_ENABLED)
|
||||||
SET(CMAKE_CXX_FLAGS "-fPIC -std=c++11 ${CMAKE_CXX_FLAGS}")
|
SET(CMAKE_CXX_STANDARD 11)
|
||||||
SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
|
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
SET(CMAKE_CXX_FLAGS "-g -fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
|
SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
|
||||||
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
|
||||||
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
||||||
IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
|
IF (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0)
|
||||||
|
@ -311,16 +307,6 @@ IF (ASSIMP_ERROR_MAX)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
IF (ASSIMP_WERROR)
|
|
||||||
MESSAGE(STATUS "Treating warnings as errors")
|
|
||||||
IF (MSVC)
|
|
||||||
ADD_COMPILE_OPTIONS(/WX)
|
|
||||||
ELSE()
|
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror")
|
|
||||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror")
|
|
||||||
ENDIF()
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
IF (ASSIMP_ASAN)
|
IF (ASSIMP_ASAN)
|
||||||
MESSAGE(STATUS "AddressSanitizer enabled")
|
MESSAGE(STATUS "AddressSanitizer enabled")
|
||||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
||||||
|
@ -350,14 +336,6 @@ ELSE()
|
||||||
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
|
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
# Cache these to allow the user to override them manually.
|
|
||||||
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE STRING
|
|
||||||
"Path the built library files are installed to." )
|
|
||||||
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE STRING
|
|
||||||
"Path the header files are installed to." )
|
|
||||||
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
|
|
||||||
"Path the tool executables are installed to." )
|
|
||||||
|
|
||||||
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
|
||||||
|
|
||||||
IF (ASSIMP_INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
IF (ASSIMP_INJECT_DEBUG_POSTFIX AND (is_multi_config OR CMAKE_BUILD_TYPE STREQUAL "Debug"))
|
||||||
|
@ -417,6 +395,28 @@ ELSE()
|
||||||
else()
|
else()
|
||||||
set(BUILD_LIB_TYPE STATIC)
|
set(BUILD_LIB_TYPE STATIC)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
IF( UNIX )
|
||||||
|
# Use GNUInstallDirs for Unix predefined directories
|
||||||
|
INCLUDE(GNUInstallDirs)
|
||||||
|
|
||||||
|
SET( ASSIMP_LIB_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR})
|
||||||
|
SET( ASSIMP_INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
SET( ASSIMP_BIN_INSTALL_DIR ${CMAKE_INSTALL_BINDIR})
|
||||||
|
ELSE()
|
||||||
|
# Cache these to allow the user to override them on non-Unix platforms
|
||||||
|
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE STRING
|
||||||
|
"Path the built library files are installed to." )
|
||||||
|
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE STRING
|
||||||
|
"Path the header files are installed to." )
|
||||||
|
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
|
||||||
|
"Path the tool executables are installed to." )
|
||||||
|
|
||||||
|
SET(CMAKE_INSTALL_FULL_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_INCLUDE_INSTALL_DIR})
|
||||||
|
SET(CMAKE_INSTALL_FULL_LIBDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_LIB_INSTALL_DIR})
|
||||||
|
SET(CMAKE_INSTALL_FULL_BINDIR ${CMAKE_INSTALL_PREFIX}/${ASSIMP_BIN_INSTALL_DIR})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
||||||
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake" @ONLY IMMEDIATE)
|
CONFIGURE_FILE("${CMAKE_CURRENT_SOURCE_DIR}/assimpTargets.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimpTargets.cmake" @ONLY IMMEDIATE)
|
||||||
IF (is_multi_config)
|
IF (is_multi_config)
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
libdir=@CMAKE_INSTALL_FULL_LIBDIR@
|
||||||
exec_prefix=@CMAKE_INSTALL_PREFIX@/
|
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@
|
||||||
libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
|
|
||||||
includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@
|
|
||||||
|
|
||||||
Name: @CMAKE_PROJECT_NAME@
|
Name: @CMAKE_PROJECT_NAME@
|
||||||
Description: Import various well-known 3D model formats in an uniform manner.
|
Description: Import various well-known 3D model formats in an uniform manner.
|
||||||
|
|
|
@ -7,6 +7,8 @@ set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||||
|
|
||||||
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
|
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
|
||||||
|
|
||||||
|
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
if(MSVC_TOOLSET_VERSION)
|
if(MSVC_TOOLSET_VERSION)
|
||||||
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
|
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
|
||||||
|
@ -35,8 +37,6 @@ if(MSVC)
|
||||||
endif()
|
endif()
|
||||||
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
|
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
|
||||||
|
|
||||||
file(TO_NATIVE_PATH "${_IMPORT_PREFIX}" _IMPORT_PREFIX)
|
|
||||||
|
|
||||||
if(ASSIMP_BUILD_SHARED_LIBS)
|
if(ASSIMP_BUILD_SHARED_LIBS)
|
||||||
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")
|
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_SHARED_LIBRARY_SUFFIX@")
|
||||||
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_IMPORT_LIBRARY_SUFFIX@")
|
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_IMPORT_LIBRARY_SUFFIX@")
|
||||||
|
@ -44,22 +44,22 @@ if(MSVC)
|
||||||
# Import target "assimp::assimp" for configuration "Debug"
|
# Import target "assimp::assimp" for configuration "Debug"
|
||||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_IMPLIB_DEBUG "${_IMPORT_PREFIX}/lib/${importLibraryName}"
|
IMPORTED_IMPLIB_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}"
|
||||||
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
|
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}")
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}" )
|
||||||
else()
|
else()
|
||||||
set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||||
|
|
||||||
# Import target "assimp::assimp" for configuration "Debug"
|
# Import target "assimp::assimp" for configuration "Debug"
|
||||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
|
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}")
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
@ -75,23 +75,20 @@ else()
|
||||||
endif()
|
endif()
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
|
IMPORTED_SONAME_DEBUG "${sharedLibraryName}"
|
||||||
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
|
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
||||||
else()
|
else()
|
||||||
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_DEBUG_POSTFIX@@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_LOCATION_DEBUG "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
|
IMPORTED_LOCATION_DEBUG "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}" )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Commands beyond this point should not need to know the version.
|
# Commands beyond this point should not need to know the version.
|
||||||
set(CMAKE_IMPORT_FILE_VERSION)
|
set(CMAKE_IMPORT_FILE_VERSION)
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ set(CMAKE_IMPORT_FILE_VERSION 1)
|
||||||
|
|
||||||
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
|
set(ASSIMP_BUILD_SHARED_LIBS @BUILD_SHARED_LIBS@)
|
||||||
|
|
||||||
|
get_property(LIB64 GLOBAL PROPERTY FIND_LIBRARY_USE_LIB64_PATHS)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
if(MSVC_TOOLSET_VERSION)
|
if(MSVC_TOOLSET_VERSION)
|
||||||
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
|
set(MSVC_PREFIX "vc${MSVC_TOOLSET_VERSION}")
|
||||||
|
@ -35,8 +37,6 @@ if(MSVC)
|
||||||
endif()
|
endif()
|
||||||
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
|
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" )
|
||||||
|
|
||||||
file(TO_NATIVE_PATH "${_IMPORT_PREFIX}" _IMPORT_PREFIX)
|
|
||||||
|
|
||||||
if(ASSIMP_BUILD_SHARED_LIBS)
|
if(ASSIMP_BUILD_SHARED_LIBS)
|
||||||
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")
|
set(sharedLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_SHARED_LIBRARY_SUFFIX@")
|
||||||
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_IMPORT_LIBRARY_SUFFIX@")
|
set(importLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_IMPORT_LIBRARY_SUFFIX@")
|
||||||
|
@ -44,22 +44,22 @@ if(MSVC)
|
||||||
# Import target "assimp::assimp" for configuration "Release"
|
# Import target "assimp::assimp" for configuration "Release"
|
||||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/${importLibraryName}"
|
IMPORTED_IMPLIB_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}"
|
||||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/${sharedLibraryName}"
|
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${importLibraryName}")
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${importLibraryName}")
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/bin/${sharedLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_BINDIR@/${sharedLibraryName}" )
|
||||||
else()
|
else()
|
||||||
set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
set(staticLibraryName "assimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||||
|
|
||||||
# Import target "assimp::assimp" for configuration "Release"
|
# Import target "assimp::assimp" for configuration "Release"
|
||||||
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
set_property(TARGET assimp::assimp APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
|
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}")
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
@ -75,18 +75,17 @@ else()
|
||||||
endif()
|
endif()
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
|
IMPORTED_SONAME_RELEASE "${sharedLibraryName}"
|
||||||
|
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}"
|
||||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${sharedLibraryName}"
|
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${sharedLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${sharedLibraryName}" )
|
||||||
else()
|
else()
|
||||||
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
set(staticLibraryName "libassimp${ASSIMP_LIBRARY_SUFFIX}@CMAKE_STATIC_LIBRARY_SUFFIX@")
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/${staticLibraryName}"
|
IMPORTED_LOCATION_RELEASE "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}"
|
||||||
)
|
)
|
||||||
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
list(APPEND _IMPORT_CHECK_TARGETS assimp::assimp )
|
||||||
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "${_IMPORT_PREFIX}/lib/${staticLibraryName}" )
|
list(APPEND _IMPORT_CHECK_FILES_FOR_assimp::assimp "@CMAKE_INSTALL_FULL_LIBDIR@/${staticLibraryName}" )
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -43,23 +43,13 @@ unset(_targetsDefined)
|
||||||
unset(_targetsNotDefined)
|
unset(_targetsNotDefined)
|
||||||
unset(_expectedTargets)
|
unset(_expectedTargets)
|
||||||
|
|
||||||
|
|
||||||
# Compute the installation prefix relative to this file.
|
|
||||||
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
|
||||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
|
||||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
|
||||||
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
|
|
||||||
if(_IMPORT_PREFIX STREQUAL "/")
|
|
||||||
set(_IMPORT_PREFIX "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Create imported target assimp::assimp
|
# Create imported target assimp::assimp
|
||||||
add_library(assimp::assimp @BUILD_LIB_TYPE@ IMPORTED)
|
add_library(assimp::assimp @BUILD_LIB_TYPE@ IMPORTED)
|
||||||
|
|
||||||
set_target_properties(assimp::assimp PROPERTIES
|
set_target_properties(assimp::assimp PROPERTIES
|
||||||
COMPATIBLE_INTERFACE_STRING "assimp_MAJOR_VERSION"
|
COMPATIBLE_INTERFACE_STRING "assimp_MAJOR_VERSION"
|
||||||
INTERFACE_assimp_MAJOR_VERSION "1"
|
INTERFACE_assimp_MAJOR_VERSION "1"
|
||||||
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include;${_IMPORT_PREFIX}/include"
|
INTERFACE_INCLUDE_DIRECTORIES "@CMAKE_INSTALL_FULL_INCLUDEDIR@"
|
||||||
#INTERFACE_LINK_LIBRARIES "TxtUtils::TxtUtils;MealyMachine::MealyMachine"
|
#INTERFACE_LINK_LIBRARIES "TxtUtils::TxtUtils;MealyMachine::MealyMachine"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -74,9 +64,6 @@ foreach(f ${CONFIG_FILES})
|
||||||
include(${f})
|
include(${f})
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Cleanup temporary variables.
|
|
||||||
set(_IMPORT_PREFIX)
|
|
||||||
|
|
||||||
# Loop over all imported files and verify that they actually exist
|
# Loop over all imported files and verify that they actually exist
|
||||||
foreach(target ${_IMPORT_CHECK_TARGETS} )
|
foreach(target ${_IMPORT_CHECK_TARGETS} )
|
||||||
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
|
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, 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,
|
||||||
|
@ -43,7 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file Implementation of the 3ds importer class */
|
/** @file Implementation of the 3ds importer class */
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
|
|
@ -322,7 +322,7 @@ struct Face : public FaceWithSmoothingGroup {
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# pragma warning(disable : 4315)
|
#pragma warning(disable : 4315)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -441,30 +441,52 @@ struct Material {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
Material(const Material &other) = default;
|
Material(const Material &other) :
|
||||||
Material &operator=(const Material &other) = default;
|
mName(other.mName),
|
||||||
|
mDiffuse(other.mDiffuse),
|
||||||
|
mSpecularExponent(other.mSpecularExponent),
|
||||||
|
mShininessStrength(other.mShininessStrength),
|
||||||
|
mSpecular(other.mSpecular),
|
||||||
|
mAmbient(other.mAmbient),
|
||||||
|
mShading(other.mShading),
|
||||||
|
mTransparency(other.mTransparency),
|
||||||
|
sTexDiffuse(other.sTexDiffuse),
|
||||||
|
sTexOpacity(other.sTexOpacity),
|
||||||
|
sTexSpecular(other.sTexSpecular),
|
||||||
|
sTexReflective(other.sTexReflective),
|
||||||
|
sTexBump(other.sTexBump),
|
||||||
|
sTexEmissive(other.sTexEmissive),
|
||||||
|
sTexShininess(other.sTexShininess),
|
||||||
|
mBumpHeight(other.mBumpHeight),
|
||||||
|
mEmissive(other.mEmissive),
|
||||||
|
sTexAmbient(other.sTexAmbient),
|
||||||
|
mTwoSided(other.mTwoSided) {
|
||||||
|
// empty
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
||||||
Material(Material &&other) AI_NO_EXCEPT
|
Material(Material &&other) AI_NO_EXCEPT :
|
||||||
: mName(std::move(other.mName)),
|
mName(std::move(other.mName)),
|
||||||
mDiffuse(std::move(other.mDiffuse)),
|
mDiffuse(std::move(other.mDiffuse)),
|
||||||
mSpecularExponent(std::move(other.mSpecularExponent)),
|
mSpecularExponent(std::move(other.mSpecularExponent)),
|
||||||
mShininessStrength(std::move(other.mShininessStrength)),
|
mShininessStrength(std::move(other.mShininessStrength)),
|
||||||
mSpecular(std::move(other.mSpecular)),
|
mSpecular(std::move(other.mSpecular)),
|
||||||
mAmbient(std::move(other.mAmbient)),
|
mAmbient(std::move(other.mAmbient)),
|
||||||
mShading(std::move(other.mShading)),
|
mShading(std::move(other.mShading)),
|
||||||
mTransparency(std::move(other.mTransparency)),
|
mTransparency(std::move(other.mTransparency)),
|
||||||
sTexDiffuse(std::move(other.sTexDiffuse)),
|
sTexDiffuse(std::move(other.sTexDiffuse)),
|
||||||
sTexOpacity(std::move(other.sTexOpacity)),
|
sTexOpacity(std::move(other.sTexOpacity)),
|
||||||
sTexSpecular(std::move(other.sTexSpecular)),
|
sTexSpecular(std::move(other.sTexSpecular)),
|
||||||
sTexReflective(std::move(other.sTexReflective)),
|
sTexReflective(std::move(other.sTexReflective)),
|
||||||
sTexBump(std::move(other.sTexBump)),
|
sTexBump(std::move(other.sTexBump)),
|
||||||
sTexEmissive(std::move(other.sTexEmissive)),
|
sTexEmissive(std::move(other.sTexEmissive)),
|
||||||
sTexShininess(std::move(other.sTexShininess)),
|
sTexShininess(std::move(other.sTexShininess)),
|
||||||
mBumpHeight(std::move(other.mBumpHeight)),
|
mBumpHeight(std::move(other.mBumpHeight)),
|
||||||
mEmissive(std::move(other.mEmissive)),
|
mEmissive(std::move(other.mEmissive)),
|
||||||
sTexAmbient(std::move(other.sTexAmbient)),
|
sTexAmbient(std::move(other.sTexAmbient)),
|
||||||
mTwoSided(std::move(other.mTwoSided)) {
|
mTwoSided(std::move(other.mTwoSided)) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
Material &operator=(Material &&other) AI_NO_EXCEPT {
|
Material &operator=(Material &&other) AI_NO_EXCEPT {
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, 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,
|
||||||
|
@ -72,7 +70,6 @@ static const aiImporterDesc desc = {
|
||||||
"3ds prj"
|
"3ds prj"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Begins a new parsing block
|
// Begins a new parsing block
|
||||||
// - Reads the current chunk and validates it
|
// - Reads the current chunk and validates it
|
||||||
|
@ -141,15 +138,13 @@ bool Discreet3DSImporter::CanRead( const std::string& pFile, IOSystem* pIOHandle
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Loader registry entry
|
// Loader registry entry
|
||||||
const aiImporterDesc* Discreet3DSImporter::GetInfo () const
|
const aiImporterDesc* Discreet3DSImporter::GetInfo () const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup configuration properties
|
// Setup configuration properties
|
||||||
void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/)
|
void Discreet3DSImporter::SetupProperties(const Importer* /*pImp*/) {
|
||||||
{
|
|
||||||
// nothing to be done for the moment
|
// nothing to be done for the moment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,7 +195,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
|
||||||
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
|
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replace all occurences of the default material with a
|
// Replace all occurrences of the default material with a
|
||||||
// valid material. Generate it if no material containing
|
// valid material. Generate it if no material containing
|
||||||
// DEFAULT in its name has been found in the file
|
// DEFAULT in its name has been found in the file
|
||||||
ReplaceDefaultMaterial();
|
ReplaceDefaultMaterial();
|
||||||
|
@ -227,8 +222,7 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Applies a master-scaling factor to the imported scene
|
// Applies a master-scaling factor to the imported scene
|
||||||
void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene)
|
void Discreet3DSImporter::ApplyMasterScale(aiScene* pScene) {
|
||||||
{
|
|
||||||
// There are some 3DS files with a zero scaling factor
|
// There are some 3DS files with a zero scaling factor
|
||||||
if (!mMasterScale)mMasterScale = 1.0f;
|
if (!mMasterScale)mMasterScale = 1.0f;
|
||||||
else mMasterScale = 1.0f / mMasterScale;
|
else mMasterScale = 1.0f / mMasterScale;
|
||||||
|
@ -1084,7 +1078,7 @@ void Discreet3DSImporter::ParseMeshChunk()
|
||||||
mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
|
mMesh.mFaceMaterials.resize(mMesh.mFaces.size(),0xcdcdcdcd);
|
||||||
|
|
||||||
// Larger 3DS files could have multiple FACE chunks here
|
// Larger 3DS files could have multiple FACE chunks here
|
||||||
chunkSize = stream->GetRemainingSizeToLimit();
|
chunkSize = (int)stream->GetRemainingSizeToLimit();
|
||||||
if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) )
|
if ( chunkSize > (int) sizeof(Discreet3DS::Chunk ) )
|
||||||
ParseFaceChunk();
|
ParseFaceChunk();
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,15 +65,11 @@ 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:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** 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.
|
||||||
|
|
|
@ -181,7 +181,7 @@ bool D3MFExporter::export3DModel() {
|
||||||
|
|
||||||
writeHeader();
|
writeHeader();
|
||||||
mModelOutput << "<" << XmlTag::model << " " << XmlTag::model_unit << "=\"millimeter\""
|
mModelOutput << "<" << XmlTag::model << " " << XmlTag::model_unit << "=\"millimeter\""
|
||||||
<< "xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">"
|
<< " xmlns=\"http://schemas.microsoft.com/3dmanufacturing/core/2015/02\">"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
mModelOutput << "<" << XmlTag::resources << ">";
|
mModelOutput << "<" << XmlTag::resources << ">";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << std::endl;
|
||||||
|
@ -212,7 +212,7 @@ bool D3MFExporter::export3DModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFExporter::writeHeader() {
|
void D3MFExporter::writeHeader() {
|
||||||
mModelOutput << "<?xml version=\"1.0\" encoding=\"UTF - 8\"?>";
|
mModelOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,16 +254,28 @@ void D3MFExporter::writeBaseMaterials() {
|
||||||
if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) {
|
if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) {
|
||||||
hexDiffuseColor.clear();
|
hexDiffuseColor.clear();
|
||||||
tmp.clear();
|
tmp.clear();
|
||||||
hexDiffuseColor = "#";
|
// rgbs %
|
||||||
|
if(color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1){
|
||||||
|
|
||||||
tmp = DecimalToHexa( (ai_real) color.r );
|
hexDiffuseColor = Rgba2Hex(
|
||||||
hexDiffuseColor += tmp;
|
(int)((ai_real)color.r)*255,
|
||||||
tmp = DecimalToHexa((ai_real)color.g);
|
(int)((ai_real)color.g)*255,
|
||||||
hexDiffuseColor += tmp;
|
(int)((ai_real)color.b)*255,
|
||||||
tmp = DecimalToHexa((ai_real)color.b);
|
(int)((ai_real)color.a)*255,
|
||||||
hexDiffuseColor += tmp;
|
true
|
||||||
tmp = DecimalToHexa((ai_real)color.a);
|
);
|
||||||
hexDiffuseColor += tmp;
|
|
||||||
|
}else{
|
||||||
|
hexDiffuseColor = "#";
|
||||||
|
tmp = DecimalToHexa( (ai_real) color.r );
|
||||||
|
hexDiffuseColor += tmp;
|
||||||
|
tmp = DecimalToHexa((ai_real)color.g);
|
||||||
|
hexDiffuseColor += tmp;
|
||||||
|
tmp = DecimalToHexa((ai_real)color.b);
|
||||||
|
hexDiffuseColor += tmp;
|
||||||
|
tmp = DecimalToHexa((ai_real)color.a);
|
||||||
|
hexDiffuseColor += tmp;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
hexDiffuseColor = "#FFFFFFFF";
|
hexDiffuseColor = "#FFFFFFFF";
|
||||||
}
|
}
|
||||||
|
@ -284,7 +296,7 @@ void D3MFExporter::writeObjects() {
|
||||||
if ( nullptr == currentNode ) {
|
if ( nullptr == currentNode ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mModelOutput << "<" << XmlTag::object << " id=\"" << currentNode->mName.C_Str() << "\" type=\"model\">";
|
mModelOutput << "<" << XmlTag::object << " id=\"" << i + 2 << "\" type=\"model\">";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << std::endl;
|
||||||
for ( unsigned int j = 0; j < currentNode->mNumMeshes; ++j ) {
|
for ( unsigned int j = 0; j < currentNode->mNumMeshes; ++j ) {
|
||||||
aiMesh *currentMesh = mScene->mMeshes[ currentNode->mMeshes[ j ] ];
|
aiMesh *currentMesh = mScene->mMeshes[ currentNode->mMeshes[ j ] ];
|
||||||
|
@ -348,7 +360,7 @@ void D3MFExporter::writeBuild() {
|
||||||
mModelOutput << "<" << XmlTag::build << ">" << std::endl;
|
mModelOutput << "<" << XmlTag::build << ">" << std::endl;
|
||||||
|
|
||||||
for ( size_t i = 0; i < mBuildItems.size(); ++i ) {
|
for ( size_t i = 0; i < mBuildItems.size(); ++i ) {
|
||||||
mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 1 << "\"/>";
|
mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 2 << "\"/>";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << std::endl;
|
||||||
}
|
}
|
||||||
mModelOutput << "</" << XmlTag::build << ">";
|
mModelOutput << "</" << XmlTag::build << ">";
|
||||||
|
|
|
@ -142,11 +142,11 @@ void Parser::LogWarning(const char* szWarn)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szWarn);
|
ai_assert(NULL != szWarn);
|
||||||
|
|
||||||
char szTemp[1024];
|
char szTemp[2048];
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn);
|
sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn);
|
||||||
#else
|
#else
|
||||||
ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
|
ai_snprintf(szTemp,sizeof(szTemp),"Line %u: %s",iLineNumber,szWarn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// output the warning to the logger ...
|
// output the warning to the logger ...
|
||||||
|
|
|
@ -9,6 +9,9 @@ For details, see http://sourceforge.net/projects/libb64
|
||||||
|
|
||||||
const int CHARS_PER_LINE = 72;
|
const int CHARS_PER_LINE = 72;
|
||||||
|
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4244)
|
||||||
|
|
||||||
void base64_init_encodestate(base64_encodestate* state_in)
|
void base64_init_encodestate(base64_encodestate* state_in)
|
||||||
{
|
{
|
||||||
state_in->step = step_A;
|
state_in->step = step_A;
|
||||||
|
@ -107,3 +110,4 @@ int base64_encode_blockend(char* code_out, base64_encodestate* state_in)
|
||||||
return (int)(codechar - code_out);
|
return (int)(codechar - code_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma warning(pop)
|
||||||
|
|
|
@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Conversion of Blender's new BMesh stuff
|
* @brief Conversion of Blender's new BMesh stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
|
@ -181,6 +180,7 @@ void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
|
||||||
face.v2 = v2;
|
face.v2 = v2;
|
||||||
face.v3 = v3;
|
face.v3 = v3;
|
||||||
face.v4 = v4;
|
face.v4 = v4;
|
||||||
|
face.flag = 0;
|
||||||
// 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 );
|
||||||
|
|
|
@ -206,7 +206,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
|
||||||
inflateInit2(&zstream, 16+MAX_WBITS);
|
inflateInit2(&zstream, 16+MAX_WBITS);
|
||||||
|
|
||||||
zstream.next_in = reinterpret_cast<Bytef*>( reader->GetPtr() );
|
zstream.next_in = reinterpret_cast<Bytef*>( reader->GetPtr() );
|
||||||
zstream.avail_in = reader->GetRemainingSize();
|
zstream.avail_in = (uInt) reader->GetRemainingSize();
|
||||||
|
|
||||||
size_t total = 0l;
|
size_t total = 0l;
|
||||||
|
|
||||||
|
|
|
@ -73,11 +73,11 @@ ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
|
||||||
|
|
||||||
aiExportFormatDesc *desc = new aiExportFormatDesc;
|
aiExportFormatDesc *desc = new aiExportFormatDesc;
|
||||||
desc->description = new char[ strlen( orig->description ) + 1 ]();
|
desc->description = new char[ strlen( orig->description ) + 1 ]();
|
||||||
::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
|
::memcpy( (char*) desc->description, orig->description, strlen( orig->description ) );
|
||||||
desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
|
desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
|
||||||
::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
|
::memcpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
|
||||||
desc->id = new char[ strlen( orig->id ) + 1 ]();
|
desc->id = new char[ strlen( orig->id ) + 1 ]();
|
||||||
::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
|
::memcpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
|
||||||
|
|
||||||
return desc;
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -121,6 +121,7 @@ SET( PUBLIC_HEADERS
|
||||||
${HEADER_PATH}/GenericProperty.h
|
${HEADER_PATH}/GenericProperty.h
|
||||||
${HEADER_PATH}/SpatialSort.h
|
${HEADER_PATH}/SpatialSort.h
|
||||||
${HEADER_PATH}/SkeletonMeshBuilder.h
|
${HEADER_PATH}/SkeletonMeshBuilder.h
|
||||||
|
${HEADER_PATH}/SmallVector.h
|
||||||
${HEADER_PATH}/SmoothingGroups.h
|
${HEADER_PATH}/SmoothingGroups.h
|
||||||
${HEADER_PATH}/SmoothingGroups.inl
|
${HEADER_PATH}/SmoothingGroups.inl
|
||||||
${HEADER_PATH}/StandardShapes.h
|
${HEADER_PATH}/StandardShapes.h
|
||||||
|
@ -1133,6 +1134,13 @@ ENDIF ()
|
||||||
ADD_LIBRARY( assimp ${assimp_src} )
|
ADD_LIBRARY( assimp ${assimp_src} )
|
||||||
ADD_LIBRARY(assimp::assimp ALIAS assimp)
|
ADD_LIBRARY(assimp::assimp ALIAS assimp)
|
||||||
|
|
||||||
|
# enable warnings as errors ########################################
|
||||||
|
IF (MSVC)
|
||||||
|
TARGET_COMPILE_OPTIONS(assimp PRIVATE /WX)
|
||||||
|
ELSE()
|
||||||
|
TARGET_COMPILE_OPTIONS(assimp PRIVATE -Werror)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
|
TARGET_INCLUDE_DIRECTORIES ( assimp PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/../include>
|
||||||
|
|
|
@ -178,7 +178,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
|
||||||
*ot++ = *buffer++;
|
*ot++ = *buffer++;
|
||||||
|
|
||||||
*ot = '\0';
|
*ot = '\0';
|
||||||
nda->mNodeName.length = (ai_uint32)(ot-nda->mNodeName.data);
|
nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
|
anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -83,32 +83,61 @@ namespace Assimp {
|
||||||
void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
|
void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Exporter worker function prototypes. Should not be necessary to #ifndef them, it's just a prototype
|
// Exporter worker function prototypes. Do not use const, because some exporter need to convert
|
||||||
// do not use const, because some exporter need to convert the scene temporary
|
// the scene temporary
|
||||||
|
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
||||||
void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneCollada(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_X_EXPORTER
|
||||||
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneXFile(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_STEP_EXPORTER
|
||||||
void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneStep(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_OBJ_EXPORTER
|
||||||
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneObj(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneObjNoMtl(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_STL_EXPORTER
|
||||||
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneSTL(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_PLY_EXPORTER
|
||||||
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
|
||||||
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLTF2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneGLB2(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
|
||||||
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||||
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_X3D_EXPORTER
|
||||||
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||||
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
|
||||||
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
|
void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
|
||||||
void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
void ExportSceneM3DA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
void ExportSceneM3DA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
|
||||||
|
#endif
|
||||||
|
#ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
|
||||||
void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
|
void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
|
||||||
|
#endif
|
||||||
|
|
||||||
static void setupExporterArray(std::vector<Exporter::ExportFormatEntry> &exporters) {
|
static void setupExporterArray(std::vector<Exporter::ExportFormatEntry> &exporters) {
|
||||||
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_COLLADA_EXPORTER
|
||||||
|
|
|
@ -979,7 +979,7 @@ void GetArrayCopy(Type*& dest, ai_uint num ) {
|
||||||
|
|
||||||
dest = new Type[num];
|
dest = new Type[num];
|
||||||
::memcpy(dest, old, sizeof(Type) * num);
|
::memcpy(dest, old, sizeof(Type) * num);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src) {
|
void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src) {
|
||||||
|
@ -994,8 +994,7 @@ void SceneCombiner::CopySceneFlat(aiScene** _dest,const aiScene* src) {
|
||||||
} else {
|
} else {
|
||||||
*_dest = new aiScene();
|
*_dest = new aiScene();
|
||||||
}
|
}
|
||||||
|
CopyScene(_dest, src, false);
|
||||||
::memcpy(*_dest,src,sizeof(aiScene));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1066,7 +1065,7 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
|
||||||
aiMesh* dest = *_dest = new aiMesh();
|
aiMesh* dest = *_dest = new aiMesh();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiMesh));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays
|
// and reallocate all arrays
|
||||||
GetArrayCopy( dest->mVertices, dest->mNumVertices );
|
GetArrayCopy( dest->mVertices, dest->mNumVertices );
|
||||||
|
@ -1105,7 +1104,7 @@ void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
|
||||||
aiAnimMesh* dest = *_dest = new aiAnimMesh();
|
aiAnimMesh* dest = *_dest = new aiAnimMesh();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest, src, sizeof(aiAnimMesh));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays
|
// and reallocate all arrays
|
||||||
GetArrayCopy(dest->mVertices, dest->mNumVertices);
|
GetArrayCopy(dest->mVertices, dest->mNumVertices);
|
||||||
|
@ -1162,7 +1161,7 @@ void SceneCombiner::Copy(aiTexture** _dest, const aiTexture* src) {
|
||||||
aiTexture* dest = *_dest = new aiTexture();
|
aiTexture* dest = *_dest = new aiTexture();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiTexture));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays. We must do it manually here
|
// and reallocate all arrays. We must do it manually here
|
||||||
const char* old = (const char*)dest->pcData;
|
const char* old = (const char*)dest->pcData;
|
||||||
|
@ -1192,7 +1191,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
|
||||||
aiAnimation* dest = *_dest = new aiAnimation();
|
aiAnimation* dest = *_dest = new aiAnimation();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiAnimation));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays
|
// and reallocate all arrays
|
||||||
CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
|
CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
|
||||||
|
@ -1208,7 +1207,7 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
|
||||||
aiNodeAnim* dest = *_dest = new aiNodeAnim();
|
aiNodeAnim* dest = *_dest = new aiNodeAnim();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiNodeAnim));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays
|
// and reallocate all arrays
|
||||||
GetArrayCopy( dest->mPositionKeys, dest->mNumPositionKeys );
|
GetArrayCopy( dest->mPositionKeys, dest->mNumPositionKeys );
|
||||||
|
@ -1224,7 +1223,7 @@ void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) {
|
||||||
aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
|
aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiMeshMorphAnim));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays
|
// and reallocate all arrays
|
||||||
GetArrayCopy( dest->mKeys, dest->mNumKeys );
|
GetArrayCopy( dest->mKeys, dest->mNumKeys );
|
||||||
|
@ -1245,7 +1244,7 @@ void SceneCombiner::Copy( aiCamera** _dest,const aiCamera* src) {
|
||||||
aiCamera* dest = *_dest = new aiCamera();
|
aiCamera* dest = *_dest = new aiCamera();
|
||||||
|
|
||||||
// get a flat copy, that's already OK
|
// get a flat copy, that's already OK
|
||||||
::memcpy(dest,src,sizeof(aiCamera));
|
*dest = *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1257,7 +1256,7 @@ void SceneCombiner::Copy(aiLight** _dest, const aiLight* src) {
|
||||||
aiLight* dest = *_dest = new aiLight();
|
aiLight* dest = *_dest = new aiLight();
|
||||||
|
|
||||||
// get a flat copy, that's already OK
|
// get a flat copy, that's already OK
|
||||||
::memcpy(dest,src,sizeof(aiLight));
|
*dest = *src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -1269,7 +1268,7 @@ void SceneCombiner::Copy(aiBone** _dest, const aiBone* src) {
|
||||||
aiBone* dest = *_dest = new aiBone();
|
aiBone* dest = *_dest = new aiBone();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiBone));
|
*dest = *src;
|
||||||
|
|
||||||
// and reallocate all arrays
|
// and reallocate all arrays
|
||||||
GetArrayCopy( dest->mWeights, dest->mNumWeights );
|
GetArrayCopy( dest->mWeights, dest->mNumWeights );
|
||||||
|
@ -1283,7 +1282,7 @@ void SceneCombiner::Copy (aiNode** _dest, const aiNode* src)
|
||||||
aiNode* dest = *_dest = new aiNode();
|
aiNode* dest = *_dest = new aiNode();
|
||||||
|
|
||||||
// get a flat copy
|
// get a flat copy
|
||||||
::memcpy(dest,src,sizeof(aiNode));
|
*dest = *src;
|
||||||
|
|
||||||
if (src->mMetaData) {
|
if (src->mMetaData) {
|
||||||
Copy(&dest->mMetaData, src->mMetaData);
|
Copy(&dest->mMetaData, src->mMetaData);
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -50,71 +48,60 @@ using namespace Assimp;
|
||||||
|
|
||||||
// CHAR_BIT seems to be defined under MVSC, but not under GCC. Pray that the correct value is 8.
|
// CHAR_BIT seems to be defined under MVSC, but not under GCC. Pray that the correct value is 8.
|
||||||
#ifndef CHAR_BIT
|
#ifndef CHAR_BIT
|
||||||
# define CHAR_BIT 8
|
#define CHAR_BIT 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
const aiVector3D PlaneInit(0.8523f, 0.34321f, 0.5736f);
|
||||||
# pragma warning(disable : 4127)
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructs a spatially sorted representation from the given position array.
|
// Constructs a spatially sorted representation from the given position array.
|
||||||
SpatialSort::SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
|
// define the reference plane. We choose some arbitrary vector away from all basic axises
|
||||||
unsigned int pElementOffset)
|
// in the hope that no model spreads all its vertices along this plane.
|
||||||
|
SpatialSort::SpatialSort(const aiVector3D *pPositions, unsigned int pNumPositions, unsigned int pElementOffset) :
|
||||||
// define the reference plane. We choose some arbitrary vector away from all basic axises
|
mPlaneNormal(PlaneInit) {
|
||||||
// in the hope that no model spreads all its vertices along this plane.
|
|
||||||
: mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
|
|
||||||
{
|
|
||||||
mPlaneNormal.Normalize();
|
mPlaneNormal.Normalize();
|
||||||
Fill(pPositions,pNumPositions,pElementOffset);
|
Fill(pPositions, pNumPositions, pElementOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
SpatialSort :: SpatialSort()
|
SpatialSort::SpatialSort() :
|
||||||
: mPlaneNormal(0.8523f, 0.34321f, 0.5736f)
|
mPlaneNormal(PlaneInit) {
|
||||||
{
|
|
||||||
mPlaneNormal.Normalize();
|
mPlaneNormal.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor
|
// Destructor
|
||||||
SpatialSort::~SpatialSort()
|
SpatialSort::~SpatialSort() {
|
||||||
{
|
// empty
|
||||||
// nothing to do here, everything destructs automatically
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SpatialSort::Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
|
void SpatialSort::Fill(const aiVector3D *pPositions, unsigned int pNumPositions,
|
||||||
unsigned int pElementOffset,
|
unsigned int pElementOffset,
|
||||||
bool pFinalize /*= true */)
|
bool pFinalize /*= true */) {
|
||||||
{
|
|
||||||
mPositions.clear();
|
mPositions.clear();
|
||||||
Append(pPositions,pNumPositions,pElementOffset,pFinalize);
|
Append(pPositions, pNumPositions, pElementOffset, pFinalize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SpatialSort :: Finalize()
|
void SpatialSort::Finalize() {
|
||||||
{
|
std::sort(mPositions.begin(), mPositions.end());
|
||||||
std::sort( mPositions.begin(), mPositions.end());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositions,
|
void SpatialSort::Append(const aiVector3D *pPositions, unsigned int pNumPositions,
|
||||||
unsigned int pElementOffset,
|
unsigned int pElementOffset,
|
||||||
bool pFinalize /*= true */)
|
bool pFinalize /*= true */) {
|
||||||
{
|
|
||||||
// store references to all given positions along with their distance to the reference plane
|
// store references to all given positions along with their distance to the reference plane
|
||||||
const size_t initial = mPositions.size();
|
const size_t initial = mPositions.size();
|
||||||
mPositions.reserve(initial + (pFinalize?pNumPositions:pNumPositions*2));
|
mPositions.reserve(initial + (pFinalize ? pNumPositions : pNumPositions * 2));
|
||||||
for( unsigned int a = 0; a < pNumPositions; a++)
|
for (unsigned int a = 0; a < pNumPositions; a++) {
|
||||||
{
|
const char *tempPointer = reinterpret_cast<const char *>(pPositions);
|
||||||
const char* tempPointer = reinterpret_cast<const char*> (pPositions);
|
const aiVector3D *vec = reinterpret_cast<const aiVector3D *>(tempPointer + a * pElementOffset);
|
||||||
const aiVector3D* vec = reinterpret_cast<const aiVector3D*> (tempPointer + a * pElementOffset);
|
|
||||||
|
|
||||||
// store position by index and distance
|
// store position by index and distance
|
||||||
ai_real distance = *vec * mPlaneNormal;
|
ai_real distance = *vec * mPlaneNormal;
|
||||||
mPositions.push_back( Entry( static_cast<unsigned int>(a+initial), *vec, distance));
|
mPositions.push_back(Entry(static_cast<unsigned int>(a + initial), *vec, distance));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pFinalize) {
|
if (pFinalize) {
|
||||||
|
@ -125,9 +112,8 @@ void SpatialSort::Append( const aiVector3D* pPositions, unsigned int pNumPositio
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns an iterator for all positions close to the given position.
|
// Returns an iterator for all positions close to the given position.
|
||||||
void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
void SpatialSort::FindPositions(const aiVector3D &pPosition,
|
||||||
ai_real pRadius, std::vector<unsigned int>& poResults) const
|
ai_real pRadius, std::vector<unsigned int> &poResults) const {
|
||||||
{
|
|
||||||
const ai_real dist = pPosition * mPlaneNormal;
|
const ai_real dist = pPosition * mPlaneNormal;
|
||||||
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
|
const ai_real minDist = dist - pRadius, maxDist = dist + pRadius;
|
||||||
|
|
||||||
|
@ -135,19 +121,18 @@ void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
||||||
poResults.clear();
|
poResults.clear();
|
||||||
|
|
||||||
// quick check for positions outside the range
|
// quick check for positions outside the range
|
||||||
if( mPositions.size() == 0)
|
if (mPositions.size() == 0)
|
||||||
return;
|
return;
|
||||||
if( maxDist < mPositions.front().mDistance)
|
if (maxDist < mPositions.front().mDistance)
|
||||||
return;
|
return;
|
||||||
if( minDist > mPositions.back().mDistance)
|
if (minDist > mPositions.back().mDistance)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// do a binary search for the minimal distance to start the iteration there
|
// do a binary search for the minimal distance to start the iteration there
|
||||||
unsigned int index = (unsigned int)mPositions.size() / 2;
|
unsigned int index = (unsigned int)mPositions.size() / 2;
|
||||||
unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
|
unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
|
||||||
while( binaryStepSize > 1)
|
while (binaryStepSize > 1) {
|
||||||
{
|
if (mPositions[index].mDistance < minDist)
|
||||||
if( mPositions[index].mDistance < minDist)
|
|
||||||
index += binaryStepSize;
|
index += binaryStepSize;
|
||||||
else
|
else
|
||||||
index -= binaryStepSize;
|
index -= binaryStepSize;
|
||||||
|
@ -157,21 +142,20 @@ void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
||||||
|
|
||||||
// depending on the direction of the last step we need to single step a bit back or forth
|
// depending on the direction of the last step we need to single step a bit back or forth
|
||||||
// to find the actual beginning element of the range
|
// to find the actual beginning element of the range
|
||||||
while( index > 0 && mPositions[index].mDistance > minDist)
|
while (index > 0 && mPositions[index].mDistance > minDist)
|
||||||
index--;
|
index--;
|
||||||
while( index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
|
while (index < (mPositions.size() - 1) && mPositions[index].mDistance < minDist)
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
// Mow start iterating from there until the first position lays outside of the distance range.
|
// Mow start iterating from there until the first position lays outside of the distance range.
|
||||||
// Add all positions inside the distance range within the given radius to the result aray
|
// Add all positions inside the distance range within the given radius to the result aray
|
||||||
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
||||||
const ai_real pSquared = pRadius*pRadius;
|
const ai_real pSquared = pRadius * pRadius;
|
||||||
while( it->mDistance < maxDist)
|
while (it->mDistance < maxDist) {
|
||||||
{
|
if ((it->mPosition - pPosition).SquareLength() < pSquared)
|
||||||
if( (it->mPosition - pPosition).SquareLength() < pSquared)
|
poResults.push_back(it->mIndex);
|
||||||
poResults.push_back( it->mIndex);
|
|
||||||
++it;
|
++it;
|
||||||
if( it == mPositions.end())
|
if (it == mPositions.end())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,70 +164,74 @@ void SpatialSort::FindPositions( const aiVector3D& pPosition,
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// Binary, signed-integer representation of a single-precision floating-point value.
|
// Binary, signed-integer representation of a single-precision floating-point value.
|
||||||
// IEEE 754 says: "If two floating-point numbers in the same format are ordered then they are
|
// IEEE 754 says: "If two floating-point numbers in the same format are ordered then they are
|
||||||
// ordered the same way when their bits are reinterpreted as sign-magnitude integers."
|
// ordered the same way when their bits are reinterpreted as sign-magnitude integers."
|
||||||
// This allows us to convert all floating-point numbers to signed integers of arbitrary size
|
// This allows us to convert all floating-point numbers to signed integers of arbitrary size
|
||||||
// and then use them to work with ULPs (Units in the Last Place, for high-precision
|
// and then use them to work with ULPs (Units in the Last Place, for high-precision
|
||||||
// computations) or to compare them (integer comparisons are faster than floating-point
|
// computations) or to compare them (integer comparisons are faster than floating-point
|
||||||
// comparisons on many platforms).
|
// comparisons on many platforms).
|
||||||
typedef ai_int BinFloat;
|
typedef ai_int BinFloat;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
// Converts the bit pattern of a floating-point number to its signed integer representation.
|
// Converts the bit pattern of a floating-point number to its signed integer representation.
|
||||||
BinFloat ToBinary( const ai_real & pValue) {
|
BinFloat ToBinary(const ai_real &pValue) {
|
||||||
|
|
||||||
// If this assertion fails, signed int is not big enough to store a float on your platform.
|
// If this assertion fails, signed int is not big enough to store a float on your platform.
|
||||||
// Please correct the declaration of BinFloat a few lines above - but do it in a portable,
|
// Please correct the declaration of BinFloat a few lines above - but do it in a portable,
|
||||||
// #ifdef'd manner!
|
// #ifdef'd manner!
|
||||||
static_assert( sizeof(BinFloat) >= sizeof(ai_real), "sizeof(BinFloat) >= sizeof(ai_real)");
|
static_assert(sizeof(BinFloat) >= sizeof(ai_real), "sizeof(BinFloat) >= sizeof(ai_real)");
|
||||||
|
|
||||||
#if defined( _MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
// If this assertion fails, Visual C++ has finally moved to ILP64. This means that this
|
// If this assertion fails, Visual C++ has finally moved to ILP64. This means that this
|
||||||
// code has just become legacy code! Find out the current value of _MSC_VER and modify
|
// code has just become legacy code! Find out the current value of _MSC_VER and modify
|
||||||
// the #if above so it evaluates false on the current and all upcoming VC versions (or
|
// the #if above so it evaluates false on the current and all upcoming VC versions (or
|
||||||
// on the current platform, if LP64 or LLP64 are still used on other platforms).
|
// on the current platform, if LP64 or LLP64 are still used on other platforms).
|
||||||
static_assert( sizeof(BinFloat) == sizeof(ai_real), "sizeof(BinFloat) == sizeof(ai_real)");
|
static_assert(sizeof(BinFloat) == sizeof(ai_real), "sizeof(BinFloat) == sizeof(ai_real)");
|
||||||
|
|
||||||
// This works best on Visual C++, but other compilers have their problems with it.
|
// This works best on Visual C++, but other compilers have their problems with it.
|
||||||
const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue);
|
const BinFloat binValue = reinterpret_cast<BinFloat const &>(pValue);
|
||||||
#else
|
//::memcpy(&binValue, &pValue, sizeof(pValue));
|
||||||
// On many compilers, reinterpreting a float address as an integer causes aliasing
|
//return binValue;
|
||||||
// problems. This is an ugly but more or less safe way of doing it.
|
#else
|
||||||
union {
|
// On many compilers, reinterpreting a float address as an integer causes aliasing
|
||||||
ai_real asFloat;
|
// problems. This is an ugly but more or less safe way of doing it.
|
||||||
BinFloat asBin;
|
union {
|
||||||
} conversion;
|
ai_real asFloat;
|
||||||
conversion.asBin = 0; // zero empty space in case sizeof(BinFloat) > sizeof(float)
|
BinFloat asBin;
|
||||||
conversion.asFloat = pValue;
|
} conversion;
|
||||||
const BinFloat binValue = conversion.asBin;
|
conversion.asBin = 0; // zero empty space in case sizeof(BinFloat) > sizeof(float)
|
||||||
#endif
|
conversion.asFloat = pValue;
|
||||||
|
const BinFloat binValue = conversion.asBin;
|
||||||
|
#endif
|
||||||
|
|
||||||
// floating-point numbers are of sign-magnitude format, so find out what signed number
|
// floating-point numbers are of sign-magnitude format, so find out what signed number
|
||||||
// representation we must convert negative values to.
|
// representation we must convert negative values to.
|
||||||
// See http://en.wikipedia.org/wiki/Signed_number_representations.
|
// See http://en.wikipedia.org/wiki/Signed_number_representations.
|
||||||
|
|
||||||
// Two's complement?
|
// Two's complement?
|
||||||
if( (-42 == (~42 + 1)) && (binValue & 0x80000000))
|
bool DefaultValue = ((-42 == (~42 + 1)) && (binValue & 0x80000000));
|
||||||
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
|
bool OneComplement = ((-42 == ~42) && (binValue & 0x80000000));
|
||||||
// One's complement?
|
bool SignedMagnitude = ((-42 == (42 | (-0))) && (binValue & 0x80000000));
|
||||||
else if ( (-42 == ~42) && (binValue & 0x80000000))
|
|
||||||
return BinFloat(-0) - binValue;
|
if (DefaultValue)
|
||||||
// Sign-magnitude?
|
return BinFloat(1 << (CHAR_BIT * sizeof(BinFloat) - 1)) - binValue;
|
||||||
else if( (-42 == (42 | (-0))) && (binValue & 0x80000000)) // -0 = 1000... binary
|
// One's complement?
|
||||||
return binValue;
|
else if (OneComplement)
|
||||||
else
|
return BinFloat(-0) - binValue;
|
||||||
return binValue;
|
// Sign-magnitude?
|
||||||
}
|
else if (SignedMagnitude) // -0 = 1000... binary
|
||||||
|
return binValue;
|
||||||
|
else
|
||||||
|
return binValue;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Fills an array with indices of all positions identical to the given position. In opposite to
|
// Fills an array with indices of all positions identical to the given position. In opposite to
|
||||||
// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units.
|
// FindPositions(), not an epsilon is used but a (very low) tolerance of four floating-point units.
|
||||||
void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
|
void SpatialSort::FindIdenticalPositions(const aiVector3D &pPosition, std::vector<unsigned int> &poResults) const {
|
||||||
std::vector<unsigned int>& poResults) const
|
|
||||||
{
|
|
||||||
// Epsilons have a huge disadvantage: they are of constant precision, while floating-point
|
// Epsilons have a huge disadvantage: they are of constant precision, while floating-point
|
||||||
// values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but
|
// values are of log2 precision. If you apply e=0.01 to 100, the epsilon is rather small, but
|
||||||
// if you apply it to 0.001, it is enormous.
|
// if you apply it to 0.001, it is enormous.
|
||||||
|
@ -269,20 +257,19 @@ void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
|
||||||
|
|
||||||
// Convert the plane distance to its signed integer representation so the ULPs tolerance can be
|
// Convert the plane distance to its signed integer representation so the ULPs tolerance can be
|
||||||
// applied. For some reason, VC won't optimize two calls of the bit pattern conversion.
|
// applied. For some reason, VC won't optimize two calls of the bit pattern conversion.
|
||||||
const BinFloat minDistBinary = ToBinary( pPosition * mPlaneNormal) - distanceToleranceInULPs;
|
const BinFloat minDistBinary = ToBinary(pPosition * mPlaneNormal) - distanceToleranceInULPs;
|
||||||
const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs;
|
const BinFloat maxDistBinary = minDistBinary + 2 * distanceToleranceInULPs;
|
||||||
|
|
||||||
// clear the array in this strange fashion because a simple clear() would also deallocate
|
// clear the array in this strange fashion because a simple clear() would also deallocate
|
||||||
// the array which we want to avoid
|
// the array which we want to avoid
|
||||||
poResults.resize( 0 );
|
poResults.resize(0);
|
||||||
|
|
||||||
// do a binary search for the minimal distance to start the iteration there
|
// do a binary search for the minimal distance to start the iteration there
|
||||||
unsigned int index = (unsigned int)mPositions.size() / 2;
|
unsigned int index = (unsigned int)mPositions.size() / 2;
|
||||||
unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
|
unsigned int binaryStepSize = (unsigned int)mPositions.size() / 4;
|
||||||
while( binaryStepSize > 1)
|
while (binaryStepSize > 1) {
|
||||||
{
|
|
||||||
// Ugly, but conditional jumps are faster with integers than with floats
|
// Ugly, but conditional jumps are faster with integers than with floats
|
||||||
if( minDistBinary > ToBinary(mPositions[index].mDistance))
|
if (minDistBinary > ToBinary(mPositions[index].mDistance))
|
||||||
index += binaryStepSize;
|
index += binaryStepSize;
|
||||||
else
|
else
|
||||||
index -= binaryStepSize;
|
index -= binaryStepSize;
|
||||||
|
@ -292,20 +279,19 @@ void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
|
||||||
|
|
||||||
// depending on the direction of the last step we need to single step a bit back or forth
|
// depending on the direction of the last step we need to single step a bit back or forth
|
||||||
// to find the actual beginning element of the range
|
// to find the actual beginning element of the range
|
||||||
while( index > 0 && minDistBinary < ToBinary(mPositions[index].mDistance) )
|
while (index > 0 && minDistBinary < ToBinary(mPositions[index].mDistance))
|
||||||
index--;
|
index--;
|
||||||
while( index < (mPositions.size() - 1) && minDistBinary > ToBinary(mPositions[index].mDistance))
|
while (index < (mPositions.size() - 1) && minDistBinary > ToBinary(mPositions[index].mDistance))
|
||||||
index++;
|
index++;
|
||||||
|
|
||||||
// Now start iterating from there until the first position lays outside of the distance range.
|
// Now start iterating from there until the first position lays outside of the distance range.
|
||||||
// Add all positions inside the distance range within the tolerance to the result array
|
// Add all positions inside the distance range within the tolerance to the result array
|
||||||
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
std::vector<Entry>::const_iterator it = mPositions.begin() + index;
|
||||||
while( ToBinary(it->mDistance) < maxDistBinary)
|
while (ToBinary(it->mDistance) < maxDistBinary) {
|
||||||
{
|
if (distance3DToleranceInULPs >= ToBinary((it->mPosition - pPosition).SquareLength()))
|
||||||
if( distance3DToleranceInULPs >= ToBinary((it->mPosition - pPosition).SquareLength()))
|
|
||||||
poResults.push_back(it->mIndex);
|
poResults.push_back(it->mIndex);
|
||||||
++it;
|
++it;
|
||||||
if( it == mPositions.end())
|
if (it == mPositions.end())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,22 +299,19 @@ void SpatialSort::FindIdenticalPositions( const aiVector3D& pPosition,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill, ai_real pRadius) const
|
unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int> &fill, ai_real pRadius) const {
|
||||||
{
|
fill.resize(mPositions.size(), UINT_MAX);
|
||||||
fill.resize(mPositions.size(),UINT_MAX);
|
|
||||||
ai_real dist, maxDist;
|
ai_real dist, maxDist;
|
||||||
|
|
||||||
unsigned int t=0;
|
unsigned int t = 0;
|
||||||
const ai_real pSquared = pRadius*pRadius;
|
const ai_real pSquared = pRadius * pRadius;
|
||||||
for (size_t i = 0; i < mPositions.size();) {
|
for (size_t i = 0; i < mPositions.size();) {
|
||||||
dist = mPositions[i].mPosition * mPlaneNormal;
|
dist = mPositions[i].mPosition * mPlaneNormal;
|
||||||
maxDist = dist + pRadius;
|
maxDist = dist + pRadius;
|
||||||
|
|
||||||
fill[mPositions[i].mIndex] = t;
|
fill[mPositions[i].mIndex] = t;
|
||||||
const aiVector3D& oldpos = mPositions[i].mPosition;
|
const aiVector3D &oldpos = mPositions[i].mPosition;
|
||||||
for (++i; i < fill.size() && mPositions[i].mDistance < maxDist
|
for (++i; i < fill.size() && mPositions[i].mDistance < maxDist && (mPositions[i].mPosition - oldpos).SquareLength() < pSquared; ++i) {
|
||||||
&& (mPositions[i].mPosition - oldpos).SquareLength() < pSquared; ++i)
|
|
||||||
{
|
|
||||||
fill[mPositions[i].mIndex] = t;
|
fill[mPositions[i].mIndex] = t;
|
||||||
}
|
}
|
||||||
++t;
|
++t;
|
||||||
|
@ -338,7 +321,7 @@ unsigned int SpatialSort::GenerateMappingTable(std::vector<unsigned int>& fill,
|
||||||
|
|
||||||
// debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1
|
// debug invariant: mPositions[i].mIndex values must range from 0 to mPositions.size()-1
|
||||||
for (size_t i = 0; i < fill.size(); ++i) {
|
for (size_t i = 0; i < fill.size(); ++i) {
|
||||||
ai_assert(fill[i]<mPositions.size());
|
ai_assert(fill[i] < mPositions.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -655,7 +655,8 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
||||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||||
|
|
||||||
if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation) {
|
if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation ||
|
||||||
|
comp == TransformationComp_PreRotation || comp == TransformationComp_PostRotation) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2739,15 +2740,12 @@ void FBXConverter::GenerateNodeAnimations(std::vector<aiNodeAnim *> &node_anims,
|
||||||
// be invoked _later_ (animations come first). If this node has only rotation,
|
// be invoked _later_ (animations come first). If this node has only rotation,
|
||||||
// scaling and translation _and_ there are no animated other components either,
|
// scaling and translation _and_ there are no animated other components either,
|
||||||
// we can use a single node and also a single node animation channel.
|
// we can use a single node and also a single node animation channel.
|
||||||
if (!has_complex && !NeedsComplexTransformationChain(target)) {
|
if( !has_complex && !NeedsComplexTransformationChain(target)) {
|
||||||
|
aiNodeAnim* const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
||||||
aiNodeAnim *const nd = GenerateSimpleNodeAnim(fixed_name, target, chain,
|
|
||||||
node_property_map.end(),
|
node_property_map.end(),
|
||||||
layer_map,
|
|
||||||
start, stop,
|
start, stop,
|
||||||
max_time,
|
max_time,
|
||||||
min_time,
|
min_time
|
||||||
true // input is TRS order, assimp is SRT
|
|
||||||
);
|
);
|
||||||
|
|
||||||
ai_assert(nd);
|
ai_assert(nd);
|
||||||
|
@ -3021,133 +3019,121 @@ aiNodeAnim *FBXConverter::GenerateTranslationNodeAnim(const std::string &name,
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
aiNodeAnim *FBXConverter::GenerateSimpleNodeAnim(const std::string &name,
|
aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||||
const Model &target,
|
const Model& target,
|
||||||
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||||
NodeMap::const_iterator iter_end,
|
NodeMap::const_iterator iterEnd,
|
||||||
const LayerMap &layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double &max_time,
|
double& maxTime,
|
||||||
double &min_time,
|
double& minTime)
|
||||||
bool reverse_order)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<aiNodeAnim> na(new aiNodeAnim());
|
std::unique_ptr<aiNodeAnim> na(new aiNodeAnim());
|
||||||
na->mNodeName.Set(name);
|
na->mNodeName.Set(name);
|
||||||
|
|
||||||
const PropertyTable &props = target.Props();
|
const PropertyTable &props = target.Props();
|
||||||
|
|
||||||
// need to convert from TRS order to SRT?
|
// collect unique times and keyframe lists
|
||||||
if (reverse_order) {
|
KeyFrameListList keyframeLists[TransformationComp_MAXIMUM];
|
||||||
|
KeyTimeList keytimes;
|
||||||
|
|
||||||
aiVector3D def_scale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
|
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||||
aiVector3D def_translate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
|
if (chain[i] == iterEnd)
|
||||||
aiVector3D def_rot = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
|
continue;
|
||||||
|
|
||||||
KeyFrameListList scaling;
|
keyframeLists[i] = GetKeyframeList((*chain[i]).second, start, stop);
|
||||||
KeyFrameListList translation;
|
|
||||||
KeyFrameListList rotation;
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Scaling] != iter_end) {
|
for (KeyFrameListList::const_iterator it = keyframeLists[i].begin(); it != keyframeLists[i].end(); ++it) {
|
||||||
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
|
const KeyTimeList& times = *std::get<0>(*it);
|
||||||
|
keytimes.insert(keytimes.end(), times.begin(), times.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chain[TransformationComp_Translation] != iter_end) {
|
// remove duplicates
|
||||||
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
|
std::sort(keytimes.begin(), keytimes.end());
|
||||||
}
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Rotation] != iter_end) {
|
auto last = std::unique(keytimes.begin(), keytimes.end());
|
||||||
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
|
keytimes.erase(last, keytimes.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyFrameListList joined;
|
const Model::RotOrder rotOrder = target.RotationOrder();
|
||||||
joined.insert(joined.end(), scaling.begin(), scaling.end());
|
const size_t keyCount = keytimes.size();
|
||||||
joined.insert(joined.end(), translation.begin(), translation.end());
|
|
||||||
joined.insert(joined.end(), rotation.begin(), rotation.end());
|
|
||||||
|
|
||||||
const KeyTimeList × = GetKeyTimeList(joined);
|
aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
|
||||||
|
aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
|
||||||
|
aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
|
||||||
|
aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
|
||||||
|
|
||||||
aiQuatKey *out_quat = new aiQuatKey[times.size()];
|
aiVectorKey* outTranslations = new aiVectorKey[keyCount];
|
||||||
aiVectorKey *out_scale = new aiVectorKey[times.size()];
|
aiQuatKey* outRotations = new aiQuatKey[keyCount];
|
||||||
aiVectorKey *out_translation = new aiVectorKey[times.size()];
|
aiVectorKey* outScales = new aiVectorKey[keyCount];
|
||||||
|
|
||||||
if (times.size()) {
|
if (keyframeLists[TransformationComp_Translation].size() > 0) {
|
||||||
ConvertTransformOrder_TRStoSRT(out_quat, out_scale, out_translation,
|
InterpolateKeys(outTranslations, keytimes, keyframeLists[TransformationComp_Translation], defTranslate, maxTime, minTime);
|
||||||
scaling,
|
|
||||||
translation,
|
|
||||||
rotation,
|
|
||||||
times,
|
|
||||||
max_time,
|
|
||||||
min_time,
|
|
||||||
target.RotationOrder(),
|
|
||||||
def_scale,
|
|
||||||
def_translate,
|
|
||||||
def_rot);
|
|
||||||
}
|
|
||||||
|
|
||||||
// XXX remove duplicates / redundant keys which this operation did
|
|
||||||
// likely produce if not all three channels were equally dense.
|
|
||||||
|
|
||||||
na->mNumScalingKeys = static_cast<unsigned int>(times.size());
|
|
||||||
na->mNumRotationKeys = na->mNumScalingKeys;
|
|
||||||
na->mNumPositionKeys = na->mNumScalingKeys;
|
|
||||||
|
|
||||||
na->mScalingKeys = out_scale;
|
|
||||||
na->mRotationKeys = out_quat;
|
|
||||||
na->mPositionKeys = out_translation;
|
|
||||||
} else {
|
} else {
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
// if a particular transformation is not given, grab it from
|
outTranslations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
// the corresponding node to meet the semantics of aiNodeAnim,
|
outTranslations[i].mValue = defTranslate;
|
||||||
// which requires all of rotation, scaling and translation
|
|
||||||
// to be set.
|
|
||||||
if (chain[TransformationComp_Scaling] != iter_end) {
|
|
||||||
ConvertScaleKeys(na.get(), (*chain[TransformationComp_Scaling]).second,
|
|
||||||
layer_map,
|
|
||||||
start, stop,
|
|
||||||
max_time,
|
|
||||||
min_time);
|
|
||||||
} else {
|
|
||||||
na->mScalingKeys = new aiVectorKey[1];
|
|
||||||
na->mNumScalingKeys = 1;
|
|
||||||
|
|
||||||
na->mScalingKeys[0].mTime = 0.;
|
|
||||||
na->mScalingKeys[0].mValue = PropertyGet(props, "Lcl Scaling",
|
|
||||||
aiVector3D(1.f, 1.f, 1.f));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Rotation] != iter_end) {
|
|
||||||
ConvertRotationKeys(na.get(), (*chain[TransformationComp_Rotation]).second,
|
|
||||||
layer_map,
|
|
||||||
start, stop,
|
|
||||||
max_time,
|
|
||||||
min_time,
|
|
||||||
target.RotationOrder());
|
|
||||||
} else {
|
|
||||||
na->mRotationKeys = new aiQuatKey[1];
|
|
||||||
na->mNumRotationKeys = 1;
|
|
||||||
|
|
||||||
na->mRotationKeys[0].mTime = 0.;
|
|
||||||
na->mRotationKeys[0].mValue = EulerToQuaternion(
|
|
||||||
PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f)),
|
|
||||||
target.RotationOrder());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain[TransformationComp_Translation] != iter_end) {
|
|
||||||
ConvertTranslationKeys(na.get(), (*chain[TransformationComp_Translation]).second,
|
|
||||||
layer_map,
|
|
||||||
start, stop,
|
|
||||||
max_time,
|
|
||||||
min_time);
|
|
||||||
} else {
|
|
||||||
na->mPositionKeys = new aiVectorKey[1];
|
|
||||||
na->mNumPositionKeys = 1;
|
|
||||||
|
|
||||||
na->mPositionKeys[0].mTime = 0.;
|
|
||||||
na->mPositionKeys[0].mValue = PropertyGet(props, "Lcl Translation",
|
|
||||||
aiVector3D(0.f, 0.f, 0.f));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyframeLists[TransformationComp_Rotation].size() > 0) {
|
||||||
|
InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
|
outRotations[i].mValue = defQuat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyframeLists[TransformationComp_Scaling].size() > 0) {
|
||||||
|
InterpolateKeys(outScales, keytimes, keyframeLists[TransformationComp_Scaling], defScale, maxTime, minTime);
|
||||||
|
} else {
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outScales[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
|
||||||
|
outScales[i].mValue = defScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ok = false;
|
||||||
|
const float zero_epsilon = 1e-6f;
|
||||||
|
|
||||||
|
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||||
|
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
||||||
|
const aiQuaternion preQuat = EulerToQuaternion(preRotation, Model::RotOrder_EulerXYZ);
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outRotations[i].mValue = preQuat * outRotations[i].mValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiVector3D& postRotation = PropertyGet<aiVector3D>(props, "PostRotation", ok);
|
||||||
|
if (ok && postRotation.SquareLength() > zero_epsilon) {
|
||||||
|
const aiQuaternion postQuat = EulerToQuaternion(postRotation, Model::RotOrder_EulerXYZ);
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
outRotations[i].mValue = outRotations[i].mValue * postQuat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert TRS to SRT
|
||||||
|
for (size_t i = 0; i < keyCount; ++i) {
|
||||||
|
aiQuaternion& r = outRotations[i].mValue;
|
||||||
|
aiVector3D& s = outScales[i].mValue;
|
||||||
|
aiVector3D& t = outTranslations[i].mValue;
|
||||||
|
|
||||||
|
aiMatrix4x4 mat, temp;
|
||||||
|
aiMatrix4x4::Translation(t, mat);
|
||||||
|
mat *= aiMatrix4x4(r.GetMatrix());
|
||||||
|
mat *= aiMatrix4x4::Scaling(s, temp);
|
||||||
|
|
||||||
|
mat.Decompose(s, r, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
na->mNumScalingKeys = static_cast<unsigned int>(keyCount);
|
||||||
|
na->mNumRotationKeys = na->mNumScalingKeys;
|
||||||
|
na->mNumPositionKeys = na->mNumScalingKeys;
|
||||||
|
|
||||||
|
na->mScalingKeys = outScales;
|
||||||
|
na->mRotationKeys = outRotations;
|
||||||
|
na->mPositionKeys = outTranslations;
|
||||||
|
|
||||||
return na.release();
|
return na.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3328,10 +3314,7 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
|
||||||
// take shortest path by checking the inner product
|
// take shortest path by checking the inner product
|
||||||
// http://www.3dkingdoms.com/weekly/weekly.php?a=36
|
// http://www.3dkingdoms.com/weekly/weekly.php?a=36
|
||||||
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
|
if (quat.x * lastq.x + quat.y * lastq.y + quat.z * lastq.z + quat.w * lastq.w < 0) {
|
||||||
quat.x = -quat.x;
|
quat.Conjugate();
|
||||||
quat.y = -quat.y;
|
|
||||||
quat.z = -quat.z;
|
|
||||||
quat.w = -quat.w;
|
|
||||||
}
|
}
|
||||||
lastq = quat;
|
lastq = quat;
|
||||||
|
|
||||||
|
@ -3339,60 +3322,6 @@ void FBXConverter::InterpolateKeys(aiQuatKey *valOut, const KeyTimeList &keys, c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FBXConverter::ConvertTransformOrder_TRStoSRT(aiQuatKey *out_quat, aiVectorKey *out_scale,
|
|
||||||
aiVectorKey *out_translation,
|
|
||||||
const KeyFrameListList &scaling,
|
|
||||||
const KeyFrameListList &translation,
|
|
||||||
const KeyFrameListList &rotation,
|
|
||||||
const KeyTimeList ×,
|
|
||||||
double &maxTime,
|
|
||||||
double &minTime,
|
|
||||||
Model::RotOrder order,
|
|
||||||
const aiVector3D &def_scale,
|
|
||||||
const aiVector3D &def_translate,
|
|
||||||
const aiVector3D &def_rotation) {
|
|
||||||
if (rotation.size()) {
|
|
||||||
InterpolateKeys(out_quat, times, rotation, def_rotation, maxTime, minTime, order);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < times.size(); ++i) {
|
|
||||||
out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
||||||
out_quat[i].mValue = EulerToQuaternion(def_rotation, order);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (scaling.size()) {
|
|
||||||
InterpolateKeys(out_scale, times, scaling, def_scale, maxTime, minTime);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < times.size(); ++i) {
|
|
||||||
out_scale[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
||||||
out_scale[i].mValue = def_scale;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (translation.size()) {
|
|
||||||
InterpolateKeys(out_translation, times, translation, def_translate, maxTime, minTime);
|
|
||||||
} else {
|
|
||||||
for (size_t i = 0; i < times.size(); ++i) {
|
|
||||||
out_translation[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
||||||
out_translation[i].mValue = def_translate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const size_t count = times.size();
|
|
||||||
for (size_t i = 0; i < count; ++i) {
|
|
||||||
aiQuaternion &r = out_quat[i].mValue;
|
|
||||||
aiVector3D &s = out_scale[i].mValue;
|
|
||||||
aiVector3D &t = out_translation[i].mValue;
|
|
||||||
|
|
||||||
aiMatrix4x4 mat, temp;
|
|
||||||
aiMatrix4x4::Translation(t, mat);
|
|
||||||
mat *= aiMatrix4x4(r.GetMatrix());
|
|
||||||
mat *= aiMatrix4x4::Scaling(s, temp);
|
|
||||||
|
|
||||||
mat.Decompose(s, r, t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
aiQuaternion FBXConverter::EulerToQuaternion(const aiVector3D &rot, Model::RotOrder order) {
|
aiQuaternion FBXConverter::EulerToQuaternion(const aiVector3D &rot, Model::RotOrder order) {
|
||||||
aiMatrix4x4 m;
|
aiMatrix4x4 m;
|
||||||
GetRotationMatrix(order, rot, m);
|
GetRotationMatrix(order, rot, m);
|
||||||
|
|
|
@ -349,12 +349,10 @@ private:
|
||||||
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
aiNodeAnim* GenerateSimpleNodeAnim(const std::string& name,
|
||||||
const Model& target,
|
const Model& target,
|
||||||
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
NodeMap::const_iterator chain[TransformationComp_MAXIMUM],
|
||||||
NodeMap::const_iterator iter_end,
|
NodeMap::const_iterator iterEnd,
|
||||||
const LayerMap& layer_map,
|
|
||||||
int64_t start, int64_t stop,
|
int64_t start, int64_t stop,
|
||||||
double& max_time,
|
double& maxTime,
|
||||||
double& min_time,
|
double& minTime);
|
||||||
bool reverse_order = false);
|
|
||||||
|
|
||||||
// key (time), value, mapto (component index)
|
// key (time), value, mapto (component index)
|
||||||
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
typedef std::tuple<std::shared_ptr<KeyTimeList>, std::shared_ptr<KeyValueList>, unsigned int > KeyFrameList;
|
||||||
|
@ -379,20 +377,6 @@ private:
|
||||||
double& minTime,
|
double& minTime,
|
||||||
Model::RotOrder order);
|
Model::RotOrder order);
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void ConvertTransformOrder_TRStoSRT(aiQuatKey* out_quat, aiVectorKey* out_scale,
|
|
||||||
aiVectorKey* out_translation,
|
|
||||||
const KeyFrameListList& scaling,
|
|
||||||
const KeyFrameListList& translation,
|
|
||||||
const KeyFrameListList& rotation,
|
|
||||||
const KeyTimeList& times,
|
|
||||||
double& maxTime,
|
|
||||||
double& minTime,
|
|
||||||
Model::RotOrder order,
|
|
||||||
const aiVector3D& def_scale,
|
|
||||||
const aiVector3D& def_translate,
|
|
||||||
const aiVector3D& def_rotation);
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// euler xyz -> quat
|
// euler xyz -> quat
|
||||||
aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order);
|
aiQuaternion EulerToQuaternion(const aiVector3D& rot, Model::RotOrder order);
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -50,27 +49,25 @@ namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
|
||||||
/** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */
|
/** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */
|
||||||
struct ImportSettings
|
struct ImportSettings {
|
||||||
{
|
ImportSettings() :
|
||||||
ImportSettings()
|
strictMode(true),
|
||||||
: strictMode(true)
|
readAllLayers(true),
|
||||||
, readAllLayers(true)
|
readAllMaterials(false),
|
||||||
, readAllMaterials(false)
|
readMaterials(true),
|
||||||
, readMaterials(true)
|
readTextures(true),
|
||||||
, readTextures(true)
|
readCameras(true),
|
||||||
, readCameras(true)
|
readLights(true),
|
||||||
, readLights(true)
|
readAnimations(true),
|
||||||
, readAnimations(true)
|
readWeights(true),
|
||||||
, readWeights(true)
|
preservePivots(true),
|
||||||
, preservePivots(true)
|
optimizeEmptyAnimationCurves(true),
|
||||||
, optimizeEmptyAnimationCurves(true)
|
useLegacyEmbeddedTextureNaming(false),
|
||||||
, useLegacyEmbeddedTextureNaming(false)
|
removeEmptyBones(true),
|
||||||
, removeEmptyBones( true )
|
convertToMeters(false) {
|
||||||
, convertToMeters( false ) {
|
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** enable strict mode:
|
/** enable strict mode:
|
||||||
* - only accept fbx 2012, 2013 files
|
* - only accept fbx 2012, 2013 files
|
||||||
* - on the slightest error, give up.
|
* - on the slightest error, give up.
|
||||||
|
@ -94,7 +91,6 @@ struct ImportSettings
|
||||||
* This bit is ignored unless readMaterials=true*/
|
* This bit is ignored unless readMaterials=true*/
|
||||||
bool readAllMaterials;
|
bool readAllMaterials;
|
||||||
|
|
||||||
|
|
||||||
/** import materials (true) or skip them and assign a default
|
/** import materials (true) or skip them and assign a default
|
||||||
* material. The default value is true.*/
|
* material. The default value is true.*/
|
||||||
bool readMaterials;
|
bool readMaterials;
|
||||||
|
@ -156,9 +152,7 @@ struct ImportSettings
|
||||||
bool convertToMeters;
|
bool convertToMeters;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // namespace FBX
|
||||||
} // !FBX
|
} // namespace Assimp
|
||||||
} // !Assimp
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, 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,
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -51,45 +50,44 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "FBXImportSettings.h"
|
#include "FBXImportSettings.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// TinyFormatter.h
|
// TinyFormatter.h
|
||||||
namespace Formatter {
|
namespace Formatter {
|
||||||
template <typename T,typename TR, typename A> class basic_formatter;
|
|
||||||
typedef class basic_formatter< char, std::char_traits<char>, std::allocator<char> > format;
|
template <typename T, typename TR, typename A>
|
||||||
}
|
class basic_formatter;
|
||||||
|
|
||||||
|
typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
|
||||||
|
|
||||||
|
} // namespace Formatter
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Load the Autodesk FBX file format.
|
/// Loads the Autodesk FBX file format.
|
||||||
|
///
|
||||||
See http://en.wikipedia.org/wiki/FBX
|
/// See http://en.wikipedia.org/wiki/FBX
|
||||||
*/
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter>
|
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
FBXImporter();
|
FBXImporter();
|
||||||
virtual ~FBXImporter();
|
virtual ~FBXImporter();
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
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 SetupProperties(const Importer *pImp);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void SetupProperties(const Importer* pImp);
|
void InternReadFile(const std::string &pFile,
|
||||||
|
aiScene *pScene,
|
||||||
// --------------------
|
IOSystem *pIOHandler);
|
||||||
void InternReadFile( const std::string& pFile,
|
|
||||||
aiScene* pScene,
|
|
||||||
IOSystem* pIOHandler
|
|
||||||
);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FBX::ImportSettings settings;
|
FBX::ImportSettings settings;
|
||||||
|
@ -97,4 +95,3 @@ private:
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
#endif // !INCLUDED_AI_FBX_IMPORTER_H
|
#endif // !INCLUDED_AI_FBX_IMPORTER_H
|
||||||
|
|
||||||
|
|
|
@ -1483,6 +1483,7 @@ void IRRImporter::InternReadFile( const std::string& pFile,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
delete root;
|
delete root;
|
||||||
|
delete reader;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER
|
||||||
|
|
|
@ -189,42 +189,42 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
||||||
continue;
|
continue;
|
||||||
if (aiProps[k].pKey) {
|
if (aiProps[k].pKey) {
|
||||||
switch (m3d_propertytypes[k].format) {
|
switch (m3d_propertytypes[k].format) {
|
||||||
case m3dpf_color:
|
case m3dpf_color:
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
aiProps[k].index, c) == AI_SUCCESS)
|
aiProps[k].index, c) == AI_SUCCESS)
|
||||||
addProp(&m3d->material[mi],
|
addProp(&m3d->material[mi],
|
||||||
m3d_propertytypes[k].id, mkColor(&c));
|
m3d_propertytypes[k].id, mkColor(&c));
|
||||||
break;
|
break;
|
||||||
case m3dpf_float:
|
case m3dpf_float:
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
aiProps[k].index, f) == AI_SUCCESS)
|
aiProps[k].index, f) == AI_SUCCESS)
|
||||||
addProp(&m3d->material[mi],
|
addProp(&m3d->material[mi],
|
||||||
m3d_propertytypes[k].id,
|
m3d_propertytypes[k].id,
|
||||||
/* not (uint32_t)f, because we don't want to convert
|
/* not (uint32_t)f, because we don't want to convert
|
||||||
* it, we want to see it as 32 bits of memory */
|
* it, we want to see it as 32 bits of memory */
|
||||||
*((uint32_t *)&f));
|
*((uint32_t *)&f));
|
||||||
break;
|
break;
|
||||||
case m3dpf_uint8:
|
case m3dpf_uint8:
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
aiProps[k].index, j) == AI_SUCCESS) {
|
aiProps[k].index, j) == AI_SUCCESS) {
|
||||||
// special conversion for illumination model property
|
// special conversion for illumination model property
|
||||||
if (m3d_propertytypes[k].id == m3dp_il) {
|
if (m3d_propertytypes[k].id == m3dp_il) {
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case aiShadingMode_NoShading: j = 0; break;
|
case aiShadingMode_NoShading: j = 0; break;
|
||||||
case aiShadingMode_Phong: j = 2; break;
|
case aiShadingMode_Phong: j = 2; break;
|
||||||
default: j = 1; break;
|
default: j = 1; break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
addProp(&m3d->material[mi],
|
|
||||||
m3d_propertytypes[k].id, j);
|
|
||||||
}
|
}
|
||||||
break;
|
addProp(&m3d->material[mi],
|
||||||
default:
|
m3d_propertytypes[k].id, j);
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
}
|
||||||
aiProps[k].index, j) == AI_SUCCESS)
|
break;
|
||||||
addProp(&m3d->material[mi],
|
default:
|
||||||
m3d_propertytypes[k].id, j);
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
break;
|
aiProps[k].index, j) == AI_SUCCESS)
|
||||||
|
addProp(&m3d->material[mi],
|
||||||
|
m3d_propertytypes[k].id, j);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aiTxProps[k].pKey &&
|
if (aiTxProps[k].pKey &&
|
||||||
|
@ -292,8 +292,8 @@ void ExportSceneM3D(
|
||||||
// Prototyped and registered in Exporter.cpp
|
// Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneM3DA(
|
void ExportSceneM3DA(
|
||||||
const char *,
|
const char *,
|
||||||
IOSystem*,
|
IOSystem *,
|
||||||
const aiScene*,
|
const aiScene *,
|
||||||
const ExportProperties *
|
const ExportProperties *
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
@ -312,7 +312,9 @@ void ExportSceneM3DA(
|
||||||
M3DExporter::M3DExporter(const aiScene *pScene, const ExportProperties *pProperties) :
|
M3DExporter::M3DExporter(const aiScene *pScene, const ExportProperties *pProperties) :
|
||||||
mScene(pScene),
|
mScene(pScene),
|
||||||
mProperties(pProperties),
|
mProperties(pProperties),
|
||||||
outfile() {}
|
outfile() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void M3DExporter::doExport(
|
void M3DExporter::doExport(
|
||||||
|
@ -352,6 +354,9 @@ void M3DExporter::doExport(
|
||||||
// explicitly release file pointer,
|
// explicitly release file pointer,
|
||||||
// so we don't have to rely on class destruction.
|
// so we don't have to rely on class destruction.
|
||||||
outfile.reset();
|
outfile.reset();
|
||||||
|
|
||||||
|
M3D_FREE(m3d->name);
|
||||||
|
m3d->name = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -50,15 +50,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef ASSIMP_USE_M3D_READFILECB
|
#ifdef ASSIMP_USE_M3D_READFILECB
|
||||||
|
|
||||||
# if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
|
#if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
|
||||||
# define threadlocal thread_local
|
#define threadlocal thread_local
|
||||||
# else
|
#else
|
||||||
# if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
|
#if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
|
||||||
# define threadlocal __declspec(thread)
|
#define threadlocal __declspec(thread)
|
||||||
# else
|
#else
|
||||||
# define threadlocal
|
#define threadlocal
|
||||||
# endif
|
#endif
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -66,37 +66,37 @@ extern "C" {
|
||||||
threadlocal void *m3dimporter_pIOHandler;
|
threadlocal void *m3dimporter_pIOHandler;
|
||||||
|
|
||||||
unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
|
unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
|
||||||
ai_assert(nullptr != fn);
|
ai_assert(nullptr != fn);
|
||||||
ai_assert(nullptr != size);
|
ai_assert(nullptr != size);
|
||||||
std::string file(fn);
|
std::string file(fn);
|
||||||
std::unique_ptr<Assimp::IOStream> pStream(
|
std::unique_ptr<Assimp::IOStream> pStream(
|
||||||
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
|
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
|
||||||
size_t fileSize = 0;
|
size_t fileSize = 0;
|
||||||
unsigned char *data = NULL;
|
unsigned char *data = NULL;
|
||||||
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
|
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
|
||||||
// (should be an empty object returning nothing I guess)
|
// (should be an empty object returning nothing I guess)
|
||||||
if (pStream) {
|
if (pStream) {
|
||||||
fileSize = pStream->FileSize();
|
fileSize = pStream->FileSize();
|
||||||
// should be allocated with malloc(), because the library will call free() to deallocate
|
// should be allocated with malloc(), because the library will call free() to deallocate
|
||||||
data = (unsigned char *)malloc(fileSize);
|
data = (unsigned char *)malloc(fileSize);
|
||||||
if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
|
if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
|
||||||
pStream.reset();
|
pStream.reset();
|
||||||
*size = 0;
|
*size = 0;
|
||||||
// don't throw a deadly exception, it's not fatal if we can't read an external asset
|
// don't throw a deadly exception, it's not fatal if we can't read an external asset
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
pStream.reset();
|
pStream.reset();
|
||||||
}
|
}
|
||||||
*size = (int)fileSize;
|
*size = (int)fileSize;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
M3DWrapper::M3DWrapper() {
|
M3DWrapper::M3DWrapper() {
|
||||||
// use malloc() here because m3d_free() will call free()
|
// use malloc() here because m3d_free() will call free()
|
||||||
m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
|
m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
|
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
|
||||||
|
@ -105,41 +105,42 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSIMP_USE_M3D_READFILECB
|
#ifdef ASSIMP_USE_M3D_READFILECB
|
||||||
// pass this IOHandler to the C callback in a thread-local pointer
|
// pass this IOHandler to the C callback in a thread-local pointer
|
||||||
m3dimporter_pIOHandler = pIOHandler;
|
m3dimporter_pIOHandler = pIOHandler;
|
||||||
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
|
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
|
||||||
// Clear the C callback
|
// Clear the C callback
|
||||||
m3dimporter_pIOHandler = nullptr;
|
m3dimporter_pIOHandler = nullptr;
|
||||||
#else
|
#else
|
||||||
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
|
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
M3DWrapper::~M3DWrapper() {
|
M3DWrapper::~M3DWrapper() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void M3DWrapper::reset() {
|
void M3DWrapper::reset() {
|
||||||
ClearSave();
|
ClearSave();
|
||||||
if (m3d_)
|
if (m3d_) {
|
||||||
m3d_free(m3d_);
|
m3d_free(m3d_);
|
||||||
m3d_ = nullptr;
|
}
|
||||||
|
m3d_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
|
unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
|
||||||
#if (!(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER))
|
#if (!(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER))
|
||||||
ClearSave();
|
ClearSave();
|
||||||
saved_output_ = m3d_save(m3d_, quality, flags, &size);
|
saved_output_ = m3d_save(m3d_, quality, flags, &size);
|
||||||
return saved_output_;
|
return saved_output_;
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void M3DWrapper::ClearSave() {
|
void M3DWrapper::ClearSave() {
|
||||||
if (saved_output_)
|
if (saved_output_)
|
||||||
M3D_FREE(saved_output_);
|
M3D_FREE(saved_output_);
|
||||||
saved_output_ = nullptr;
|
saved_output_ = nullptr;
|
||||||
}
|
}
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -1556,7 +1556,7 @@ static int _m3dstbi__create_png_image(_m3dstbi__png *a, unsigned char *image_dat
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _m3dstbi__compute_transparency(_m3dstbi__png *z, unsigned char tc[3], int out_n) {
|
static int _m3dstbi__compute_transparency(_m3dstbi__png *z, unsigned char* tc, int out_n) {
|
||||||
_m3dstbi__context *s = z->s;
|
_m3dstbi__context *s = z->s;
|
||||||
_m3dstbi__uint32 i, pixel_count = s->img_x * s->img_y;
|
_m3dstbi__uint32 i, pixel_count = s->img_x * s->img_y;
|
||||||
unsigned char *p = z->out;
|
unsigned char *p = z->out;
|
||||||
|
@ -1639,7 +1639,7 @@ static int _m3dstbi__expand_png_palette(_m3dstbi__png *a, unsigned char *palette
|
||||||
|
|
||||||
static int _m3dstbi__parse_png_file(_m3dstbi__png *z, int scan, int req_comp) {
|
static int _m3dstbi__parse_png_file(_m3dstbi__png *z, int scan, int req_comp) {
|
||||||
unsigned char palette[1024], pal_img_n = 0;
|
unsigned char palette[1024], pal_img_n = 0;
|
||||||
unsigned char has_trans = 0, tc[3];
|
unsigned char has_trans = 0, tc[3] = {};
|
||||||
_m3dstbi__uint16 tc16[3];
|
_m3dstbi__uint16 tc16[3];
|
||||||
_m3dstbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0;
|
_m3dstbi__uint32 ioff = 0, idata_limit = 0, i, pal_len = 0;
|
||||||
int first = 1, k, interlace = 0, color = 0;
|
int first = 1, k, interlace = 0, color = 0;
|
||||||
|
@ -4350,7 +4350,7 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
M3D_INDEX last, *vrtxidx = NULL, *mtrlidx = NULL, *tmapidx = NULL, *skinidx = NULL;
|
M3D_INDEX last, *vrtxidx = NULL, *mtrlidx = NULL, *tmapidx = NULL, *skinidx = NULL;
|
||||||
uint32_t idx, numcmap = 0, *cmap = NULL, numvrtx = 0, maxvrtx = 0, numtmap = 0, maxtmap = 0, numproc = 0;
|
uint32_t idx, numcmap = 0, *cmap = NULL, numvrtx = 0, maxvrtx = 0, numtmap = 0, maxtmap = 0, numproc = 0;
|
||||||
uint32_t numskin = 0, maxskin = 0, numstr = 0, maxt = 0, maxbone = 0, numgrp = 0, maxgrp = 0, *grpidx = NULL;
|
uint32_t numskin = 0, maxskin = 0, numstr = 0, maxt = 0, maxbone = 0, numgrp = 0, maxgrp = 0, *grpidx = NULL;
|
||||||
uint8_t *opa;
|
uint8_t *opa = nullptr;
|
||||||
m3dcd_t *cd;
|
m3dcd_t *cd;
|
||||||
m3dc_t *cmd;
|
m3dc_t *cmd;
|
||||||
m3dstr_t *str = NULL;
|
m3dstr_t *str = NULL;
|
||||||
|
@ -5440,13 +5440,13 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
out += 2;
|
out += 2;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
*((float *)out) = vrtx[i].data.x;
|
memcpy(out, &vrtx[i].data.x, sizeof(float));
|
||||||
out += 4;
|
out += 4;
|
||||||
*((float *)out) = vrtx[i].data.y;
|
memcpy(out, &vrtx[i].data.y, sizeof(float));
|
||||||
out += 4;
|
out += 4;
|
||||||
*((float *)out) = vrtx[i].data.z;
|
memcpy(out, &vrtx[i].data.z, sizeof(float));
|
||||||
out += 4;
|
out += 4;
|
||||||
*((float *)out) = vrtx[i].data.w;
|
memcpy(out, &vrtx[i].data.w, sizeof(float));
|
||||||
out += 4;
|
out += 4;
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
|
@ -5474,9 +5474,11 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
}
|
}
|
||||||
out = _m3d_addidx(out, sk_s, vrtx[i].data.skinid);
|
out = _m3d_addidx(out, sk_s, vrtx[i].data.skinid);
|
||||||
}
|
}
|
||||||
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
||||||
|
memcpy(length, &v, sizeof(uint32_t));
|
||||||
|
//*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
||||||
out = NULL;
|
out = NULL;
|
||||||
len += *length;
|
len += v;
|
||||||
}
|
}
|
||||||
/* bones chunk */
|
/* bones chunk */
|
||||||
if (model->numbone && model->bone && !(flags & M3D_EXP_NOBONE)) {
|
if (model->numbone && model->bone && !(flags & M3D_EXP_NOBONE)) {
|
||||||
|
@ -5660,8 +5662,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
out = _m3d_addidx(out, vi_s, vrtxidx[face[i].data.normal[j]]);
|
out = _m3d_addidx(out, vi_s, vrtxidx[face[i].data.normal[j]]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
||||||
len += *length;
|
memcpy(length, &v, sizeof(uint32_t));
|
||||||
|
len += v;
|
||||||
out = NULL;
|
out = NULL;
|
||||||
}
|
}
|
||||||
/* mathematical shapes face */
|
/* mathematical shapes face */
|
||||||
|
@ -5721,8 +5724,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
||||||
len += *length;
|
memcpy( length, &v, sizeof(uint32_t));
|
||||||
|
len += v;
|
||||||
out = NULL;
|
out = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5765,8 +5769,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
out = _m3d_addidx(out, si_s, _m3d_stridx(str, numstr, model->label[l].text));
|
out = _m3d_addidx(out, si_s, _m3d_stridx(str, numstr, model->label[l].text));
|
||||||
}
|
}
|
||||||
if (length) {
|
if (length) {
|
||||||
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
||||||
len += *length;
|
memcpy( length, &v, sizeof(uint32_t));
|
||||||
|
len += v;
|
||||||
}
|
}
|
||||||
out = NULL;
|
out = NULL;
|
||||||
sn = sl = NULL;
|
sn = sl = NULL;
|
||||||
|
@ -5796,8 +5801,9 @@ unsigned char *m3d_save(m3d_t *model, int quality, int flags, unsigned int *size
|
||||||
out = _m3d_addidx(out, vi_s, vrtxidx[a->frame[i].transform[k].ori]);
|
out = _m3d_addidx(out, vi_s, vrtxidx[a->frame[i].transform[k].ori]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*length = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
uint32_t v = (uint32_t)((uintptr_t)out - (uintptr_t)((uint8_t *)h + len));
|
||||||
len += *length;
|
memcpy( length, &v, sizeof(uint32_t));
|
||||||
|
len += v;
|
||||||
out = NULL;
|
out = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -503,7 +503,7 @@ aiReturn aiMaterial::AddBinaryProperty (const void* pInput,
|
||||||
pcNew->mData = new char[pSizeInBytes];
|
pcNew->mData = new char[pSizeInBytes];
|
||||||
memcpy (pcNew->mData,pInput,pSizeInBytes);
|
memcpy (pcNew->mData,pInput,pSizeInBytes);
|
||||||
|
|
||||||
pcNew->mKey.length = (ai_uint32)::strlen(pKey);
|
pcNew->mKey.length = static_cast<ai_uint32>( ::strlen(pKey) );
|
||||||
ai_assert ( MAXLEN > pcNew->mKey.length);
|
ai_assert ( MAXLEN > pcNew->mKey.length);
|
||||||
strcpy( pcNew->mKey.data, pKey );
|
strcpy( pcNew->mKey.data, pKey );
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
#include "LimitBoneWeightsProcess.h"
|
#include "LimitBoneWeightsProcess.h"
|
||||||
|
#include <assimp/SmallVector.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
@ -52,7 +53,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
LimitBoneWeightsProcess::LimitBoneWeightsProcess()
|
LimitBoneWeightsProcess::LimitBoneWeightsProcess()
|
||||||
|
@ -76,10 +76,12 @@ bool LimitBoneWeightsProcess::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.
|
||||||
void LimitBoneWeightsProcess::Execute( aiScene* pScene) {
|
void LimitBoneWeightsProcess::Execute( aiScene* pScene)
|
||||||
|
{
|
||||||
ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
|
ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess begin");
|
||||||
for (unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
|
|
||||||
ProcessMesh(pScene->mMeshes[a]);
|
for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
|
||||||
|
ProcessMesh(pScene->mMeshes[m]);
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess end");
|
ASSIMP_LOG_DEBUG("LimitBoneWeightsProcess end");
|
||||||
|
@ -95,107 +97,96 @@ void LimitBoneWeightsProcess::SetupProperties(const Importer* pImp)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Unites identical vertices in the given mesh
|
// Unites identical vertices in the given mesh
|
||||||
void LimitBoneWeightsProcess::ProcessMesh( aiMesh* pMesh)
|
void LimitBoneWeightsProcess::ProcessMesh(aiMesh* pMesh)
|
||||||
{
|
{
|
||||||
if( !pMesh->HasBones())
|
if (!pMesh->HasBones())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// collect all bone weights per vertex
|
// collect all bone weights per vertex
|
||||||
typedef std::vector< std::vector< Weight > > WeightsPerVertex;
|
typedef SmallVector<Weight,8> VertexWeightArray;
|
||||||
WeightsPerVertex vertexWeights( pMesh->mNumVertices);
|
typedef std::vector<VertexWeightArray> WeightsPerVertex;
|
||||||
|
WeightsPerVertex vertexWeights(pMesh->mNumVertices);
|
||||||
|
size_t maxVertexWeights = 0;
|
||||||
|
|
||||||
// collect all weights per vertex
|
for (unsigned int b = 0; b < pMesh->mNumBones; ++b)
|
||||||
for( unsigned int a = 0; a < pMesh->mNumBones; a++)
|
|
||||||
{
|
{
|
||||||
const aiBone* bone = pMesh->mBones[a];
|
const aiBone* bone = pMesh->mBones[b];
|
||||||
for( unsigned int b = 0; b < bone->mNumWeights; b++)
|
for (unsigned int w = 0; w < bone->mNumWeights; ++w)
|
||||||
{
|
{
|
||||||
const aiVertexWeight& w = bone->mWeights[b];
|
const aiVertexWeight& vw = bone->mWeights[w];
|
||||||
vertexWeights[w.mVertexId].push_back( Weight( a, w.mWeight));
|
vertexWeights[vw.mVertexId].push_back(Weight(b, vw.mWeight));
|
||||||
|
maxVertexWeights = std::max(maxVertexWeights, vertexWeights[vw.mVertexId].size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (maxVertexWeights <= mMaxWeights)
|
||||||
|
return;
|
||||||
|
|
||||||
unsigned int removed = 0, old_bones = pMesh->mNumBones;
|
unsigned int removed = 0, old_bones = pMesh->mNumBones;
|
||||||
|
|
||||||
// now cut the weight count if it exceeds the maximum
|
// now cut the weight count if it exceeds the maximum
|
||||||
bool bChanged = false;
|
for (WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
|
||||||
for( WeightsPerVertex::iterator vit = vertexWeights.begin(); vit != vertexWeights.end(); ++vit)
|
|
||||||
{
|
{
|
||||||
if( vit->size() <= mMaxWeights)
|
if (vit->size() <= mMaxWeights)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bChanged = true;
|
|
||||||
|
|
||||||
// more than the defined maximum -> first sort by weight in descending order. That's
|
// more than the defined maximum -> first sort by weight in descending order. That's
|
||||||
// why we defined the < operator in such a weird way.
|
// why we defined the < operator in such a weird way.
|
||||||
std::sort( vit->begin(), vit->end());
|
std::sort(vit->begin(), vit->end());
|
||||||
|
|
||||||
// now kill everything beyond the maximum count
|
// now kill everything beyond the maximum count
|
||||||
unsigned int m = static_cast<unsigned int>(vit->size());
|
unsigned int m = static_cast<unsigned int>(vit->size());
|
||||||
vit->erase( vit->begin() + mMaxWeights, vit->end());
|
vit->resize(mMaxWeights);
|
||||||
removed += static_cast<unsigned int>(m-vit->size());
|
removed += static_cast<unsigned int>(m - vit->size());
|
||||||
|
|
||||||
// and renormalize the weights
|
// and renormalize the weights
|
||||||
float sum = 0.0f;
|
float sum = 0.0f;
|
||||||
for( std::vector<Weight>::const_iterator it = vit->begin(); it != vit->end(); ++it ) {
|
for(const Weight* it = vit->begin(); it != vit->end(); ++it) {
|
||||||
sum += it->mWeight;
|
sum += it->mWeight;
|
||||||
}
|
}
|
||||||
if( 0.0f != sum ) {
|
if (0.0f != sum) {
|
||||||
const float invSum = 1.0f / sum;
|
const float invSum = 1.0f / sum;
|
||||||
for( std::vector<Weight>::iterator it = vit->begin(); it != vit->end(); ++it ) {
|
for(Weight* it = vit->begin(); it != vit->end(); ++it) {
|
||||||
it->mWeight *= invSum;
|
it->mWeight *= invSum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bChanged) {
|
// clear weight count for all bone
|
||||||
// rebuild the vertex weight array for all bones
|
for (unsigned int a = 0; a < pMesh->mNumBones; ++a)
|
||||||
typedef std::vector< std::vector< aiVertexWeight > > WeightsPerBone;
|
{
|
||||||
WeightsPerBone boneWeights( pMesh->mNumBones);
|
pMesh->mBones[a]->mNumWeights = 0;
|
||||||
for( unsigned int a = 0; a < vertexWeights.size(); a++)
|
}
|
||||||
|
|
||||||
|
// rebuild the vertex weight array for all bones
|
||||||
|
for (unsigned int a = 0; a < vertexWeights.size(); ++a)
|
||||||
|
{
|
||||||
|
const VertexWeightArray& vw = vertexWeights[a];
|
||||||
|
for (const Weight* it = vw.begin(); it != vw.end(); ++it)
|
||||||
{
|
{
|
||||||
const std::vector<Weight>& vw = vertexWeights[a];
|
aiBone* bone = pMesh->mBones[it->mBone];
|
||||||
for( std::vector<Weight>::const_iterator it = vw.begin(); it != vw.end(); ++it)
|
bone->mWeights[bone->mNumWeights++] = aiVertexWeight(a, it->mWeight);
|
||||||
boneWeights[it->mBone].push_back( aiVertexWeight( a, it->mWeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
// and finally copy the vertex weight list over to the mesh's bones
|
|
||||||
std::vector<bool> abNoNeed(pMesh->mNumBones,false);
|
|
||||||
bChanged = false;
|
|
||||||
|
|
||||||
for( unsigned int a = 0; a < pMesh->mNumBones; a++)
|
|
||||||
{
|
|
||||||
const std::vector<aiVertexWeight>& bw = boneWeights[a];
|
|
||||||
aiBone* bone = pMesh->mBones[a];
|
|
||||||
|
|
||||||
if ( bw.empty() )
|
|
||||||
{
|
|
||||||
abNoNeed[a] = bChanged = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy the weight list. should always be less weights than before, so we don't need a new allocation
|
|
||||||
ai_assert( bw.size() <= bone->mNumWeights);
|
|
||||||
bone->mNumWeights = static_cast<unsigned int>( bw.size() );
|
|
||||||
::memcpy( bone->mWeights, &bw[0], bw.size() * sizeof( aiVertexWeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bChanged) {
|
|
||||||
// the number of new bones is smaller than before, so we can reuse the old array
|
|
||||||
aiBone** ppcCur = pMesh->mBones;aiBone** ppcSrc = ppcCur;
|
|
||||||
|
|
||||||
for (std::vector<bool>::const_iterator iter = abNoNeed.begin();iter != abNoNeed.end() ;++iter) {
|
|
||||||
if (*iter) {
|
|
||||||
delete *ppcSrc;
|
|
||||||
--pMesh->mNumBones;
|
|
||||||
}
|
|
||||||
else *ppcCur++ = *ppcSrc;
|
|
||||||
++ppcSrc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
|
||||||
ASSIMP_LOG_INFO_F("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove empty bones
|
||||||
|
unsigned int writeBone = 0;
|
||||||
|
|
||||||
|
for (unsigned int readBone = 0; readBone< pMesh->mNumBones; ++readBone)
|
||||||
|
{
|
||||||
|
aiBone* bone = pMesh->mBones[readBone];
|
||||||
|
if (bone->mNumWeights > 0)
|
||||||
|
{
|
||||||
|
pMesh->mBones[writeBone++] = bone;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete bone;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pMesh->mNumBones = writeBone;
|
||||||
|
|
||||||
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
|
ASSIMP_LOG_INFO_F("Removed ", removed, " weights. Input bones: ", old_bones, ". Output bones: ", pMesh->mNumBones);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,7 +617,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *model
|
||||||
// We'll leave it up to the user to figure out which extension the file has.
|
// We'll leave it up to the user to figure out which extension the file has.
|
||||||
aiString name;
|
aiString name;
|
||||||
strncpy( name.data, pTexture->strName, sizeof name.data );
|
strncpy( name.data, pTexture->strName, sizeof name.data );
|
||||||
name.length = (ai_uint32)strlen( name.data );
|
name.length = static_cast<ai_uint32>(strlen( name.data ));
|
||||||
pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
|
pMatHelper->AddProperty( &name, AI_MATKEY_TEXTURE_DIFFUSE( 0 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -616,7 +616,7 @@ void SMDImporter::CreateOutputMaterials() {
|
||||||
if (aszTextures[iMat].length())
|
if (aszTextures[iMat].length())
|
||||||
{
|
{
|
||||||
::strncpy(szName.data, aszTextures[iMat].c_str(),MAXLEN-1);
|
::strncpy(szName.data, aszTextures[iMat].c_str(),MAXLEN-1);
|
||||||
szName.length = (ai_uint32)aszTextures[iMat].length();
|
szName.length = static_cast<ai_uint32>( aszTextures[iMat].length() );
|
||||||
pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
pcMat->AddProperty(&szName,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, 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,
|
||||||
|
@ -43,17 +41,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file Implementation of the Terragen importer class */
|
/** @file Implementation of the Terragen importer class */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_TERRAGEN_IMPORTER
|
||||||
|
|
||||||
#include "TerragenLoader.h"
|
#include "TerragenLoader.h"
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/importerdesc.h>
|
||||||
#include <assimp/IOSystem.hpp>
|
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -72,78 +68,72 @@ static const aiImporterDesc desc = {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
TerragenImporter::TerragenImporter()
|
TerragenImporter::TerragenImporter() :
|
||||||
: configComputeUVs (false)
|
configComputeUVs(false) {}
|
||||||
{}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
TerragenImporter::~TerragenImporter()
|
TerragenImporter::~TerragenImporter() {}
|
||||||
{}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 TerragenImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
bool TerragenImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
|
||||||
{
|
|
||||||
// check file extension
|
// check file extension
|
||||||
std::string extension = GetExtension(pFile);
|
std::string extension = GetExtension(pFile);
|
||||||
|
|
||||||
if( extension == "ter")
|
if (extension == "ter")
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( !extension.length() || checkSig) {
|
if (!extension.length() || checkSig) {
|
||||||
/* If CanRead() is called in order to check whether we
|
/* If CanRead() is called in order to check whether we
|
||||||
* support a specific file extension in general pIOHandler
|
* support a specific file extension in general pIOHandler
|
||||||
* might be NULL and it's our duty to return true here.
|
* might be NULL and it's our duty to return true here.
|
||||||
*/
|
*/
|
||||||
if (!pIOHandler)return true;
|
if (!pIOHandler) return true;
|
||||||
const char* tokens[] = {"terragen"};
|
const char *tokens[] = { "terragen" };
|
||||||
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* TerragenImporter::GetInfo () const
|
const aiImporterDesc *TerragenImporter::GetInfo() const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup import properties
|
// Setup import properties
|
||||||
void TerragenImporter::SetupProperties(const Importer* pImp)
|
void TerragenImporter::SetupProperties(const Importer *pImp) {
|
||||||
{
|
|
||||||
// AI_CONFIG_IMPORT_TER_MAKE_UVS
|
// AI_CONFIG_IMPORT_TER_MAKE_UVS
|
||||||
configComputeUVs = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS,0) );
|
configComputeUVs = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_TER_MAKE_UVS, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void TerragenImporter::InternReadFile( const std::string& pFile,
|
void TerragenImporter::InternReadFile(const std::string &pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
{
|
IOStream *file = pIOHandler->Open(pFile, "rb");
|
||||||
IOStream* file = pIOHandler->Open( pFile, "rb");
|
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file == NULL)
|
if (file == NULL)
|
||||||
throw DeadlyImportError( "Failed to open TERRAGEN TERRAIN file " + pFile + ".");
|
throw DeadlyImportError("Failed to open TERRAGEN TERRAIN file " + pFile + ".");
|
||||||
|
|
||||||
// Construct a stream reader to read all data in the correct endianness
|
// Construct a stream reader to read all data in the correct endianness
|
||||||
StreamReaderLE reader(file);
|
StreamReaderLE reader(file);
|
||||||
if(reader.GetRemainingSize() < 16)
|
if (reader.GetRemainingSize() < 16)
|
||||||
throw DeadlyImportError( "TER: file is too small" );
|
throw DeadlyImportError("TER: file is too small");
|
||||||
|
|
||||||
// Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN '
|
// Check for the existence of the two magic strings 'TERRAGEN' and 'TERRAIN '
|
||||||
if (::strncmp((const char*)reader.GetPtr(),AI_TERR_BASE_STRING,8))
|
if (::strncmp((const char *)reader.GetPtr(), AI_TERR_BASE_STRING, 8))
|
||||||
throw DeadlyImportError( "TER: Magic string \'TERRAGEN\' not found" );
|
throw DeadlyImportError("TER: Magic string \'TERRAGEN\' not found");
|
||||||
|
|
||||||
if (::strncmp((const char*)reader.GetPtr()+8,AI_TERR_TERRAIN_STRING,8))
|
if (::strncmp((const char *)reader.GetPtr() + 8, AI_TERR_TERRAIN_STRING, 8))
|
||||||
throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
|
throw DeadlyImportError("TER: Magic string \'TERRAIN\' not found");
|
||||||
|
|
||||||
unsigned int x = 0,y = 0,mode = 0;
|
unsigned int x = 0, y = 0, mode = 0;
|
||||||
|
|
||||||
aiNode* root = pScene->mRootNode = new aiNode();
|
aiNode *root = pScene->mRootNode = new aiNode();
|
||||||
root->mName.Set("<TERRAGEN.TERRAIN>");
|
root->mName.Set("<TERRAGEN.TERRAIN>");
|
||||||
|
|
||||||
// Default scaling is 30
|
// Default scaling is 30
|
||||||
|
@ -151,104 +141,98 @@ void TerragenImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// Now read all chunks until we're finished or an EOF marker is encountered
|
// Now read all chunks until we're finished or an EOF marker is encountered
|
||||||
reader.IncPtr(16);
|
reader.IncPtr(16);
|
||||||
while (reader.GetRemainingSize() >= 4)
|
while (reader.GetRemainingSize() >= 4) {
|
||||||
{
|
const char *head = (const char *)reader.GetPtr();
|
||||||
const char* head = (const char*)reader.GetPtr();
|
|
||||||
reader.IncPtr(4);
|
reader.IncPtr(4);
|
||||||
|
|
||||||
// EOF, break in every case
|
// EOF, break in every case
|
||||||
if (!::strncmp(head,AI_TERR_EOF_STRING,4))
|
if (!::strncmp(head, AI_TERR_EOF_STRING, 4))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Number of x-data points
|
// Number of x-data points
|
||||||
if (!::strncmp(head,AI_TERR_CHUNK_XPTS,4))
|
if (!::strncmp(head, AI_TERR_CHUNK_XPTS, 4)) {
|
||||||
{
|
|
||||||
x = (uint16_t)reader.GetI2();
|
x = (uint16_t)reader.GetI2();
|
||||||
}
|
}
|
||||||
// Number of y-data points
|
// Number of y-data points
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_YPTS,4))
|
else if (!::strncmp(head, AI_TERR_CHUNK_YPTS, 4)) {
|
||||||
{
|
|
||||||
y = (uint16_t)reader.GetI2();
|
y = (uint16_t)reader.GetI2();
|
||||||
}
|
}
|
||||||
// Squared terrains width-1.
|
// Squared terrains width-1.
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_SIZE,4))
|
else if (!::strncmp(head, AI_TERR_CHUNK_SIZE, 4)) {
|
||||||
{
|
x = y = (uint16_t)reader.GetI2() + 1;
|
||||||
x = y = (uint16_t)reader.GetI2()+1;
|
|
||||||
}
|
}
|
||||||
// terrain scaling
|
// terrain scaling
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_SCAL,4))
|
else if (!::strncmp(head, AI_TERR_CHUNK_SCAL, 4)) {
|
||||||
{
|
|
||||||
root->mTransformation.a1 = reader.GetF4();
|
root->mTransformation.a1 = reader.GetF4();
|
||||||
root->mTransformation.b2 = reader.GetF4();
|
root->mTransformation.b2 = reader.GetF4();
|
||||||
root->mTransformation.c3 = reader.GetF4();
|
root->mTransformation.c3 = reader.GetF4();
|
||||||
}
|
}
|
||||||
// mapping == 1: earth radius
|
// mapping == 1: earth radius
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
|
else if (!::strncmp(head, AI_TERR_CHUNK_CRAD, 4)) {
|
||||||
{
|
|
||||||
reader.GetF4();
|
reader.GetF4();
|
||||||
}
|
}
|
||||||
// mapping mode
|
// mapping mode
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))
|
else if (!::strncmp(head, AI_TERR_CHUNK_CRVM, 4)) {
|
||||||
{
|
|
||||||
mode = reader.GetI1();
|
mode = reader.GetI1();
|
||||||
if (0 != mode)
|
if (0 != mode)
|
||||||
ASSIMP_LOG_ERROR("TER: Unsupported mapping mode, a flat terrain is returned");
|
ASSIMP_LOG_ERROR("TER: Unsupported mapping mode, a flat terrain is returned");
|
||||||
}
|
}
|
||||||
// actual terrain data
|
// actual terrain data
|
||||||
else if (!::strncmp(head,AI_TERR_CHUNK_ALTW,4))
|
else if (!::strncmp(head, AI_TERR_CHUNK_ALTW, 4)) {
|
||||||
{
|
float hscale = (float)reader.GetI2() / 65536;
|
||||||
float hscale = (float)reader.GetI2() / 65536;
|
|
||||||
float bheight = (float)reader.GetI2();
|
float bheight = (float)reader.GetI2();
|
||||||
|
|
||||||
if (!hscale)hscale = 1;
|
if (!hscale) hscale = 1;
|
||||||
|
|
||||||
// Ensure we have enough data
|
// Ensure we have enough data
|
||||||
if (reader.GetRemainingSize() < x*y*2)
|
if (reader.GetRemainingSize() < x * y * 2)
|
||||||
throw DeadlyImportError("TER: ALTW chunk is too small");
|
throw DeadlyImportError("TER: ALTW chunk is too small");
|
||||||
|
|
||||||
if (x <= 1 || y <= 1)
|
if (x <= 1 || y <= 1)
|
||||||
throw DeadlyImportError("TER: Invalid terrain size");
|
throw DeadlyImportError("TER: Invalid terrain size");
|
||||||
|
|
||||||
// Allocate the output mesh
|
// Allocate the output mesh
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes = 1];
|
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes = 1];
|
||||||
aiMesh* m = pScene->mMeshes[0] = new aiMesh();
|
aiMesh *m = pScene->mMeshes[0] = new aiMesh();
|
||||||
|
|
||||||
// We return quads
|
// We return quads
|
||||||
aiFace* f = m->mFaces = new aiFace[m->mNumFaces = (x-1)*(y-1)];
|
aiFace *f = m->mFaces = new aiFace[m->mNumFaces = (x - 1) * (y - 1)];
|
||||||
aiVector3D* pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces*4];
|
aiVector3D *pv = m->mVertices = new aiVector3D[m->mNumVertices = m->mNumFaces * 4];
|
||||||
|
|
||||||
aiVector3D *uv( NULL );
|
aiVector3D *uv(NULL);
|
||||||
float step_y( 0.0f ), step_x( 0.0f );
|
float step_y(0.0f), step_x(0.0f);
|
||||||
if (configComputeUVs) {
|
if (configComputeUVs) {
|
||||||
uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
|
uv = m->mTextureCoords[0] = new aiVector3D[m->mNumVertices];
|
||||||
step_y = 1.f/y;
|
step_y = 1.f / y;
|
||||||
step_x = 1.f/x;
|
step_x = 1.f / x;
|
||||||
}
|
}
|
||||||
const int16_t* data = (const int16_t*)reader.GetPtr();
|
const int16_t *data = (const int16_t *)reader.GetPtr();
|
||||||
|
|
||||||
for (unsigned int yy = 0, t = 0; yy < y-1;++yy) {
|
for (unsigned int yy = 0, t = 0; yy < y - 1; ++yy) {
|
||||||
for (unsigned int xx = 0; xx < x-1;++xx,++f) {
|
for (unsigned int xx = 0; xx < x - 1; ++xx, ++f) {
|
||||||
|
|
||||||
// make verts
|
// make verts
|
||||||
const float fy = (float)yy, fx = (float)xx;
|
const float fy = (float)yy, fx = (float)xx;
|
||||||
unsigned tmp,tmp2;
|
unsigned tmp, tmp2;
|
||||||
*pv++ = aiVector3D(fx,fy, (float)data[(tmp2=x*yy) + xx] * hscale + bheight);
|
*pv++ = aiVector3D(fx, fy, (float)data[(tmp2 = x * yy) + xx] * hscale + bheight);
|
||||||
*pv++ = aiVector3D(fx,fy+1, (float)data[(tmp=x*(yy+1)) + xx] * hscale + bheight);
|
*pv++ = aiVector3D(fx, fy + 1, (float)data[(tmp = x * (yy + 1)) + xx] * hscale + bheight);
|
||||||
*pv++ = aiVector3D(fx+1,fy+1,(float)data[tmp + xx+1] * hscale + bheight);
|
*pv++ = aiVector3D(fx + 1, fy + 1, (float)data[tmp + xx + 1] * hscale + bheight);
|
||||||
*pv++ = aiVector3D(fx+1,fy, (float)data[tmp2 + xx+1] * hscale + bheight);
|
*pv++ = aiVector3D(fx + 1, fy, (float)data[tmp2 + xx + 1] * hscale + bheight);
|
||||||
|
|
||||||
// also make texture coordinates, if necessary
|
// also make texture coordinates, if necessary
|
||||||
if (configComputeUVs) {
|
if (configComputeUVs) {
|
||||||
*uv++ = aiVector3D( step_x*xx, step_y*yy, 0.f );
|
*uv++ = aiVector3D(step_x * xx, step_y * yy, 0.f);
|
||||||
*uv++ = aiVector3D( step_x*xx, step_y*(yy+1), 0.f );
|
*uv++ = aiVector3D(step_x * xx, step_y * (yy + 1), 0.f);
|
||||||
*uv++ = aiVector3D( step_x*(xx+1), step_y*(yy+1), 0.f );
|
*uv++ = aiVector3D(step_x * (xx + 1), step_y * (yy + 1), 0.f);
|
||||||
*uv++ = aiVector3D( step_x*(xx+1), step_y*yy, 0.f );
|
*uv++ = aiVector3D(step_x * (xx + 1), step_y * yy, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// make indices
|
// make indices
|
||||||
f->mIndices = new unsigned int[f->mNumIndices = 4];
|
f->mIndices = new unsigned int[f->mNumIndices = 4];
|
||||||
for (unsigned int i = 0; i < 4;++i)
|
for (unsigned int i = 0; i < 4; ++i) {
|
||||||
f->mIndices[i] = t++;
|
f->mIndices[i] = t;
|
||||||
|
t++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -47,21 +46,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
|
#define INCLUDED_AI_TERRAGEN_TERRAIN_LOADER_H
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// Magic strings
|
// Magic strings
|
||||||
#define AI_TERR_BASE_STRING "TERRAGEN"
|
#define AI_TERR_BASE_STRING "TERRAGEN"
|
||||||
#define AI_TERR_TERRAIN_STRING "TERRAIN "
|
#define AI_TERR_TERRAIN_STRING "TERRAIN "
|
||||||
#define AI_TERR_EOF_STRING "EOF "
|
#define AI_TERR_EOF_STRING "EOF "
|
||||||
|
|
||||||
// Chunka
|
// Chunka
|
||||||
#define AI_TERR_CHUNK_XPTS "XPTS"
|
#define AI_TERR_CHUNK_XPTS "XPTS"
|
||||||
#define AI_TERR_CHUNK_YPTS "YPTS"
|
#define AI_TERR_CHUNK_YPTS "YPTS"
|
||||||
#define AI_TERR_CHUNK_SIZE "SIZE"
|
#define AI_TERR_CHUNK_SIZE "SIZE"
|
||||||
#define AI_TERR_CHUNK_SCAL "SCAL"
|
#define AI_TERR_CHUNK_SCAL "SCAL"
|
||||||
#define AI_TERR_CHUNK_CRAD "CRAD"
|
#define AI_TERR_CHUNK_CRAD "CRAD"
|
||||||
#define AI_TERR_CHUNK_CRVM "CRVM"
|
#define AI_TERR_CHUNK_CRVM "CRVM"
|
||||||
#define AI_TERR_CHUNK_ALTW "ALTW"
|
#define AI_TERR_CHUNK_ALTW "ALTW"
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief Importer class to load Terragen (0.9) terrain files.
|
/** @brief Importer class to load Terragen (0.9) terrain files.
|
||||||
|
@ -69,33 +68,28 @@ namespace Assimp {
|
||||||
* The loader is basing on the information found here:
|
* The loader is basing on the information found here:
|
||||||
* http://www.planetside.co.uk/terragen/dev/tgterrain.html#chunks
|
* http://www.planetside.co.uk/terragen/dev/tgterrain.html#chunks
|
||||||
*/
|
*/
|
||||||
class TerragenImporter : public BaseImporter
|
class TerragenImporter : public BaseImporter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
TerragenImporter();
|
TerragenImporter();
|
||||||
~TerragenImporter();
|
~TerragenImporter();
|
||||||
|
|
||||||
|
|
||||||
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 InternReadFile(const std::string &pFile, aiScene *pScene,
|
||||||
|
IOSystem *pIOHandler);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void SetupProperties(const Importer *pImp);
|
||||||
IOSystem* pIOHandler);
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
|
||||||
void SetupProperties(const Importer* pImp);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool configComputeUVs;
|
bool configComputeUVs;
|
||||||
|
|
||||||
}; //! class TerragenImporter
|
}; //! class TerragenImporter
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, 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,
|
||||||
|
@ -48,26 +46,112 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* http://local.wasp.uwa.edu.au/~pbourke/dataformats/unreal/
|
* http://local.wasp.uwa.edu.au/~pbourke/dataformats/unreal/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3D_IMPORTER
|
||||||
|
|
||||||
#include "Unreal/UnrealLoader.h"
|
#include "Unreal/UnrealLoader.h"
|
||||||
#include "PostProcessing/ConvertToLHProcess.h"
|
#include "PostProcessing/ConvertToLHProcess.h"
|
||||||
|
|
||||||
#include <assimp/StreamReader.h>
|
|
||||||
#include <assimp/ParsingUtils.h>
|
#include <assimp/ParsingUtils.h>
|
||||||
|
#include <assimp/StreamReader.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/importerdesc.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/importerdesc.h>
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
namespace Unreal {
|
||||||
|
|
||||||
|
/*
|
||||||
|
0 = Normal one-sided
|
||||||
|
1 = Normal two-sided
|
||||||
|
2 = Translucent two-sided
|
||||||
|
3 = Masked two-sided
|
||||||
|
4 = Modulation blended two-sided
|
||||||
|
8 = Placeholder triangle for weapon positioning (invisible)
|
||||||
|
*/
|
||||||
|
enum MeshFlags {
|
||||||
|
MF_NORMAL_OS = 0,
|
||||||
|
MF_NORMAL_TS = 1,
|
||||||
|
MF_NORMAL_TRANS_TS = 2,
|
||||||
|
MF_NORMAL_MASKED_TS = 3,
|
||||||
|
MF_NORMAL_MOD_TS = 4,
|
||||||
|
MF_WEAPON_PLACEHOLDER = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
// a single triangle
|
||||||
|
struct Triangle {
|
||||||
|
uint16_t mVertex[3]; // Vertex indices
|
||||||
|
char mType; // James' Mesh Type
|
||||||
|
char mColor; // Color for flat and Gourand Shaded
|
||||||
|
unsigned char mTex[3][2]; // Texture UV coordinates
|
||||||
|
unsigned char mTextureNum; // Source texture offset
|
||||||
|
char mFlags; // Unreal Mesh Flags (unused)
|
||||||
|
unsigned int matIndex;
|
||||||
|
};
|
||||||
|
|
||||||
|
// temporary representation for a material
|
||||||
|
struct TempMat {
|
||||||
|
TempMat() :
|
||||||
|
type(MF_NORMAL_OS), tex(), numFaces(0) {}
|
||||||
|
|
||||||
|
explicit TempMat(const Triangle &in) :
|
||||||
|
type((Unreal::MeshFlags)in.mType), tex(in.mTextureNum), numFaces(0) {}
|
||||||
|
|
||||||
|
// type of mesh
|
||||||
|
Unreal::MeshFlags type;
|
||||||
|
|
||||||
|
// index of texture
|
||||||
|
unsigned int tex;
|
||||||
|
|
||||||
|
// number of faces using us
|
||||||
|
unsigned int numFaces;
|
||||||
|
|
||||||
|
// for std::find
|
||||||
|
bool operator==(const TempMat &o) {
|
||||||
|
return (tex == o.tex && type == o.type);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Vertex {
|
||||||
|
int32_t X : 11;
|
||||||
|
int32_t Y : 11;
|
||||||
|
int32_t Z : 10;
|
||||||
|
};
|
||||||
|
|
||||||
|
// UNREAL vertex compression
|
||||||
|
inline void CompressVertex(const aiVector3D &v, uint32_t &out) {
|
||||||
|
union {
|
||||||
|
Vertex n;
|
||||||
|
int32_t t;
|
||||||
|
};
|
||||||
|
t = 0;
|
||||||
|
n.X = (int32_t)v.x;
|
||||||
|
n.Y = (int32_t)v.y;
|
||||||
|
n.Z = (int32_t)v.z;
|
||||||
|
::memcpy(&out, &t, sizeof(int32_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
// UNREAL vertex decompression
|
||||||
|
inline void DecompressVertex(aiVector3D &v, int32_t in) {
|
||||||
|
union {
|
||||||
|
Vertex n;
|
||||||
|
int32_t i;
|
||||||
|
};
|
||||||
|
i = in;
|
||||||
|
|
||||||
|
v.x = (float)n.X;
|
||||||
|
v.y = (float)n.Y;
|
||||||
|
v.z = (float)n.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace Unreal
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"Unreal Mesh Importer",
|
"Unreal Mesh Importer",
|
||||||
"",
|
"",
|
||||||
|
@ -81,79 +165,70 @@ static const aiImporterDesc desc = {
|
||||||
"3d uc"
|
"3d uc"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
UnrealImporter::UnrealImporter()
|
UnrealImporter::UnrealImporter() :
|
||||||
: configFrameID (0)
|
mConfigFrameID(0), mConfigHandleFlags(true) {}
|
||||||
, configHandleFlags (true)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
UnrealImporter::~UnrealImporter()
|
UnrealImporter::~UnrealImporter() {}
|
||||||
{}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 UnrealImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const
|
bool UnrealImporter::CanRead(const std::string &pFile, IOSystem * /*pIOHandler*/, bool /*checkSig*/) const {
|
||||||
{
|
return SimpleExtensionCheck(pFile, "3d", "uc");
|
||||||
return SimpleExtensionCheck(pFile,"3d","uc");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Build a string of all file extensions supported
|
// Build a string of all file extensions supported
|
||||||
const aiImporterDesc* UnrealImporter::GetInfo () const
|
const aiImporterDesc *UnrealImporter::GetInfo() const {
|
||||||
{
|
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Setup configuration properties for the loader
|
// Setup configuration properties for the loader
|
||||||
void UnrealImporter::SetupProperties(const Importer* pImp)
|
void UnrealImporter::SetupProperties(const Importer *pImp) {
|
||||||
{
|
|
||||||
// The
|
// The
|
||||||
// AI_CONFIG_IMPORT_UNREAL_KEYFRAME option overrides the
|
// AI_CONFIG_IMPORT_UNREAL_KEYFRAME option overrides the
|
||||||
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
|
// AI_CONFIG_IMPORT_GLOBAL_KEYFRAME option.
|
||||||
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME,-1);
|
mConfigFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_KEYFRAME, -1);
|
||||||
if(static_cast<unsigned int>(-1) == configFrameID) {
|
if (static_cast<unsigned int>(-1) == mConfigFrameID) {
|
||||||
configFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME,0);
|
mConfigFrameID = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_GLOBAL_KEYFRAME, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, default is true
|
// AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, default is true
|
||||||
configHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS,1));
|
mConfigHandleFlags = (0 != pImp->GetPropertyInteger(AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void UnrealImporter::InternReadFile( const std::string& pFile,
|
void UnrealImporter::InternReadFile(const std::string &pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
{
|
|
||||||
// For any of the 3 files being passed get the three correct paths
|
// For any of the 3 files being passed get the three correct paths
|
||||||
// First of all, determine file extension
|
// First of all, determine file extension
|
||||||
std::string::size_type pos = pFile.find_last_of('.');
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
std::string extension = GetExtension(pFile);
|
std::string extension = GetExtension(pFile);
|
||||||
|
|
||||||
std::string d_path,a_path,uc_path;
|
std::string d_path, a_path, uc_path;
|
||||||
if (extension == "3d") {
|
if (extension == "3d") {
|
||||||
// jjjj_d.3d
|
// jjjj_d.3d
|
||||||
// jjjj_a.3d
|
// jjjj_a.3d
|
||||||
pos = pFile.find_last_of('_');
|
pos = pFile.find_last_of('_');
|
||||||
if (std::string::npos == pos) {
|
if (std::string::npos == pos) {
|
||||||
throw DeadlyImportError("UNREAL: Unexpected naming scheme");
|
throw DeadlyImportError("UNREAL: Unexpected naming scheme");
|
||||||
}
|
}
|
||||||
extension = pFile.substr(0,pos);
|
extension = pFile.substr(0, pos);
|
||||||
}
|
} else {
|
||||||
else {
|
extension = pFile.substr(0, pos);
|
||||||
extension = pFile.substr(0,pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// build proper paths
|
// build proper paths
|
||||||
d_path = extension+"_d.3d";
|
d_path = extension + "_d.3d";
|
||||||
a_path = extension+"_a.3d";
|
a_path = extension + "_a.3d";
|
||||||
uc_path = extension+".uc";
|
uc_path = extension + ".uc";
|
||||||
|
|
||||||
ASSIMP_LOG_DEBUG_F( "UNREAL: data file is ", d_path);
|
ASSIMP_LOG_DEBUG_F("UNREAL: data file is ", d_path);
|
||||||
ASSIMP_LOG_DEBUG_F("UNREAL: aniv file is ", a_path);
|
ASSIMP_LOG_DEBUG_F("UNREAL: aniv file is ", a_path);
|
||||||
ASSIMP_LOG_DEBUG_F("UNREAL: uc file is ", uc_path);
|
ASSIMP_LOG_DEBUG_F("UNREAL: uc file is ", uc_path);
|
||||||
|
|
||||||
|
@ -174,11 +249,11 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// collect triangles
|
// collect triangles
|
||||||
std::vector<Unreal::Triangle> triangles(numTris);
|
std::vector<Unreal::Triangle> triangles(numTris);
|
||||||
for (auto & tri : triangles) {
|
for (auto &tri : triangles) {
|
||||||
for (unsigned int i = 0; i < 3;++i) {
|
for (unsigned int i = 0; i < 3; ++i) {
|
||||||
|
|
||||||
tri.mVertex[i] = d_reader.GetI2();
|
tri.mVertex[i] = d_reader.GetI2();
|
||||||
if (tri.mVertex[i] >= numTris) {
|
if (tri.mVertex[i] >= numTris) {
|
||||||
ASSIMP_LOG_WARN("UNREAL: vertex index out of range");
|
ASSIMP_LOG_WARN("UNREAL: vertex index out of range");
|
||||||
tri.mVertex[i] = 0;
|
tri.mVertex[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -186,7 +261,7 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
tri.mType = d_reader.GetI1();
|
tri.mType = d_reader.GetI1();
|
||||||
|
|
||||||
// handle mesh flagss?
|
// handle mesh flagss?
|
||||||
if (configHandleFlags)
|
if (mConfigHandleFlags)
|
||||||
tri.mType = Unreal::MF_NORMAL_OS;
|
tri.mType = Unreal::MF_NORMAL_OS;
|
||||||
else {
|
else {
|
||||||
// ignore MOD and MASKED for the moment, treat them as two-sided
|
// ignore MOD and MASKED for the moment, treat them as two-sided
|
||||||
|
@ -195,12 +270,12 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
d_reader.IncPtr(1);
|
d_reader.IncPtr(1);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3;++i)
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
for (unsigned int i2 = 0; i2 < 2;++i2)
|
for (unsigned int i2 = 0; i2 < 2; ++i2)
|
||||||
tri.mTex[i][i2] = d_reader.GetI1();
|
tri.mTex[i][i2] = d_reader.GetI1();
|
||||||
|
|
||||||
tri.mTextureNum = d_reader.GetI1();
|
tri.mTextureNum = d_reader.GetI1();
|
||||||
maxTexIdx = std::max(maxTexIdx,(unsigned int)tri.mTextureNum);
|
maxTexIdx = std::max(maxTexIdx, (unsigned int)tri.mTextureNum);
|
||||||
d_reader.IncPtr(1);
|
d_reader.IncPtr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,63 +286,64 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// read number of frames
|
// read number of frames
|
||||||
const uint32_t numFrames = a_reader.GetI2();
|
const uint32_t numFrames = a_reader.GetI2();
|
||||||
if (configFrameID >= numFrames) {
|
if (mConfigFrameID >= numFrames) {
|
||||||
throw DeadlyImportError("UNREAL: The requested frame does not exist");
|
throw DeadlyImportError("UNREAL: The requested frame does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t st = a_reader.GetI2();
|
uint32_t st = a_reader.GetI2();
|
||||||
if (st != numVert*4u)
|
if (st != numVert * 4u)
|
||||||
throw DeadlyImportError("UNREAL: Unexpected aniv file length");
|
throw DeadlyImportError("UNREAL: Unexpected aniv file length");
|
||||||
|
|
||||||
// skip to our frame
|
// skip to our frame
|
||||||
a_reader.IncPtr(configFrameID *numVert*4);
|
a_reader.IncPtr(mConfigFrameID * numVert * 4);
|
||||||
|
|
||||||
// collect vertices
|
// collect vertices
|
||||||
std::vector<aiVector3D> vertices(numVert);
|
std::vector<aiVector3D> vertices(numVert);
|
||||||
for (auto &vertex : vertices) {
|
for (auto &vertex : vertices) {
|
||||||
int32_t val = a_reader.GetI4();
|
int32_t val = a_reader.GetI4();
|
||||||
Unreal::DecompressVertex(vertex ,val);
|
Unreal::DecompressVertex(vertex, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// list of textures.
|
// list of textures.
|
||||||
std::vector< std::pair<unsigned int, std::string> > textures;
|
std::vector<std::pair<unsigned int, std::string>> textures;
|
||||||
|
|
||||||
// allocate the output scene
|
// allocate the output scene
|
||||||
aiNode* nd = pScene->mRootNode = new aiNode();
|
aiNode *nd = pScene->mRootNode = new aiNode();
|
||||||
nd->mName.Set("<UnrealRoot>");
|
nd->mName.Set("<UnrealRoot>");
|
||||||
|
|
||||||
// we can live without the uc file if necessary
|
// we can live without the uc file if necessary
|
||||||
std::unique_ptr<IOStream> pb (pIOHandler->Open(uc_path));
|
std::unique_ptr<IOStream> pb(pIOHandler->Open(uc_path));
|
||||||
if (pb.get()) {
|
if (pb.get()) {
|
||||||
|
|
||||||
std::vector<char> _data;
|
std::vector<char> _data;
|
||||||
TextFileToBuffer(pb.get(),_data);
|
TextFileToBuffer(pb.get(), _data);
|
||||||
const char* data = &_data[0];
|
const char *data = &_data[0];
|
||||||
|
|
||||||
std::vector< std::pair< std::string,std::string > > tempTextures;
|
std::vector<std::pair<std::string, std::string>> tempTextures;
|
||||||
|
|
||||||
// do a quick search in the UC file for some known, usually texture-related, tags
|
// do a quick search in the UC file for some known, usually texture-related, tags
|
||||||
for (;*data;++data) {
|
for (; *data; ++data) {
|
||||||
if (TokenMatchI(data,"#exec",5)) {
|
if (TokenMatchI(data, "#exec", 5)) {
|
||||||
SkipSpacesAndLineEnd(&data);
|
SkipSpacesAndLineEnd(&data);
|
||||||
|
|
||||||
// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
|
// #exec TEXTURE IMPORT [...] NAME=jjjjj [...] FILE=jjjj.pcx [...]
|
||||||
if (TokenMatchI(data,"TEXTURE",7)) {
|
if (TokenMatchI(data, "TEXTURE", 7)) {
|
||||||
SkipSpacesAndLineEnd(&data);
|
SkipSpacesAndLineEnd(&data);
|
||||||
|
|
||||||
if (TokenMatchI(data,"IMPORT",6)) {
|
if (TokenMatchI(data, "IMPORT", 6)) {
|
||||||
tempTextures.push_back(std::pair< std::string,std::string >());
|
tempTextures.push_back(std::pair<std::string, std::string>());
|
||||||
std::pair< std::string,std::string >& me = tempTextures.back();
|
std::pair<std::string, std::string> &me = tempTextures.back();
|
||||||
for (;!IsLineEnd(*data);++data) {
|
for (; !IsLineEnd(*data); ++data) {
|
||||||
if (!::ASSIMP_strincmp(data,"NAME=",5)) {
|
if (!::ASSIMP_strincmp(data, "NAME=", 5)) {
|
||||||
const char *d = data+=5;
|
const char *d = data += 5;
|
||||||
for (;!IsSpaceOrNewLine(*data);++data);
|
for (; !IsSpaceOrNewLine(*data); ++data)
|
||||||
me.first = std::string(d,(size_t)(data-d));
|
;
|
||||||
}
|
me.first = std::string(d, (size_t)(data - d));
|
||||||
else if (!::ASSIMP_strincmp(data,"FILE=",5)) {
|
} else if (!::ASSIMP_strincmp(data, "FILE=", 5)) {
|
||||||
const char *d = data+=5;
|
const char *d = data += 5;
|
||||||
for (;!IsSpaceOrNewLine(*data);++data);
|
for (; !IsSpaceOrNewLine(*data); ++data)
|
||||||
me.second = std::string(d,(size_t)(data-d));
|
;
|
||||||
|
me.second = std::string(d, (size_t)(data - d));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!me.first.length() || !me.second.length())
|
if (!me.first.length() || !me.second.length())
|
||||||
|
@ -276,65 +352,61 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
|
// #exec MESHMAP SETTEXTURE MESHMAP=box NUM=1 TEXTURE=Jtex1
|
||||||
// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
|
// #exec MESHMAP SCALE MESHMAP=box X=0.1 Y=0.1 Z=0.2
|
||||||
else if (TokenMatchI(data,"MESHMAP",7)) {
|
else if (TokenMatchI(data, "MESHMAP", 7)) {
|
||||||
SkipSpacesAndLineEnd(&data);
|
SkipSpacesAndLineEnd(&data);
|
||||||
|
|
||||||
if (TokenMatchI(data,"SETTEXTURE",10)) {
|
if (TokenMatchI(data, "SETTEXTURE", 10)) {
|
||||||
|
|
||||||
textures.push_back(std::pair<unsigned int, std::string>());
|
textures.push_back(std::pair<unsigned int, std::string>());
|
||||||
std::pair<unsigned int, std::string>& me = textures.back();
|
std::pair<unsigned int, std::string> &me = textures.back();
|
||||||
|
|
||||||
for (;!IsLineEnd(*data);++data) {
|
for (; !IsLineEnd(*data); ++data) {
|
||||||
if (!::ASSIMP_strincmp(data,"NUM=",4)) {
|
if (!::ASSIMP_strincmp(data, "NUM=", 4)) {
|
||||||
data += 4;
|
data += 4;
|
||||||
me.first = strtoul10(data,&data);
|
me.first = strtoul10(data, &data);
|
||||||
}
|
} else if (!::ASSIMP_strincmp(data, "TEXTURE=", 8)) {
|
||||||
else if (!::ASSIMP_strincmp(data,"TEXTURE=",8)) {
|
|
||||||
data += 8;
|
data += 8;
|
||||||
const char *d = data;
|
const char *d = data;
|
||||||
for (;!IsSpaceOrNewLine(*data);++data);
|
for (; !IsSpaceOrNewLine(*data); ++data)
|
||||||
me.second = std::string(d,(size_t)(data-d));
|
;
|
||||||
|
me.second = std::string(d, (size_t)(data - d));
|
||||||
|
|
||||||
// try to find matching path names, doesn't care if we don't find them
|
// try to find matching path names, doesn't care if we don't find them
|
||||||
for (std::vector< std::pair< std::string,std::string > >::const_iterator it = tempTextures.begin();
|
for (std::vector<std::pair<std::string, std::string>>::const_iterator it = tempTextures.begin();
|
||||||
it != tempTextures.end(); ++it) {
|
it != tempTextures.end(); ++it) {
|
||||||
if ((*it).first == me.second) {
|
if ((*it).first == me.second) {
|
||||||
me.second = (*it).second;
|
me.second = (*it).second;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (TokenMatchI(data, "SCALE", 5)) {
|
||||||
else if (TokenMatchI(data,"SCALE",5)) {
|
|
||||||
|
|
||||||
for (;!IsLineEnd(*data);++data) {
|
for (; !IsLineEnd(*data); ++data) {
|
||||||
if (data[0] == 'X' && data[1] == '=') {
|
if (data[0] == 'X' && data[1] == '=') {
|
||||||
data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.a1);
|
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.a1);
|
||||||
}
|
} else if (data[0] == 'Y' && data[1] == '=') {
|
||||||
else if (data[0] == 'Y' && data[1] == '=') {
|
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.b2);
|
||||||
data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.b2);
|
} else if (data[0] == 'Z' && data[1] == '=') {
|
||||||
}
|
data = fast_atoreal_move<float>(data + 2, (float &)nd->mTransformation.c3);
|
||||||
else if (data[0] == 'Z' && data[1] == '=') {
|
|
||||||
data = fast_atoreal_move<float>(data+2,(float&)nd->mTransformation.c3);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
ASSIMP_LOG_ERROR("Unable to open .uc file");
|
ASSIMP_LOG_ERROR("Unable to open .uc file");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Unreal::TempMat> materials;
|
std::vector<Unreal::TempMat> materials;
|
||||||
materials.reserve(textures.size()*2+5);
|
materials.reserve(textures.size() * 2 + 5);
|
||||||
|
|
||||||
// find out how many output meshes and materials we'll have and build material indices
|
// find out how many output meshes and materials we'll have and build material indices
|
||||||
for (Unreal::Triangle &tri : triangles) {
|
for (Unreal::Triangle &tri : triangles) {
|
||||||
Unreal::TempMat mat(tri);
|
Unreal::TempMat mat(tri);
|
||||||
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
|
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(), materials.end(), mat);
|
||||||
if (nt == materials.end()) {
|
if (nt == materials.end()) {
|
||||||
// add material
|
// add material
|
||||||
tri.matIndex = static_cast<unsigned int>(materials.size());
|
tri.matIndex = static_cast<unsigned int>(materials.size());
|
||||||
|
@ -342,9 +414,8 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
materials.push_back(mat);
|
materials.push_back(mat);
|
||||||
|
|
||||||
++pScene->mNumMeshes;
|
++pScene->mNumMeshes;
|
||||||
}
|
} else {
|
||||||
else {
|
tri.matIndex = static_cast<unsigned int>(nt - materials.begin());
|
||||||
tri.matIndex = static_cast<unsigned int>(nt-materials.begin());
|
|
||||||
++nt->numFaces;
|
++nt->numFaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,65 +425,65 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate meshes and bind them to the node graph
|
// allocate meshes and bind them to the node graph
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
|
||||||
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
|
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials = pScene->mNumMeshes];
|
||||||
|
|
||||||
nd->mNumMeshes = pScene->mNumMeshes;
|
nd->mNumMeshes = pScene->mNumMeshes;
|
||||||
nd->mMeshes = new unsigned int[nd->mNumMeshes];
|
nd->mMeshes = new unsigned int[nd->mNumMeshes];
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes;++i) {
|
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
aiMesh* m = pScene->mMeshes[i] = new aiMesh();
|
aiMesh *m = pScene->mMeshes[i] = new aiMesh();
|
||||||
m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
m->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||||
|
|
||||||
const unsigned int num = materials[i].numFaces;
|
const unsigned int num = materials[i].numFaces;
|
||||||
m->mFaces = new aiFace [num];
|
m->mFaces = new aiFace[num];
|
||||||
m->mVertices = new aiVector3D [num*3];
|
m->mVertices = new aiVector3D[num * 3];
|
||||||
m->mTextureCoords[0] = new aiVector3D [num*3];
|
m->mTextureCoords[0] = new aiVector3D[num * 3];
|
||||||
|
|
||||||
nd->mMeshes[i] = i;
|
nd->mMeshes[i] = i;
|
||||||
|
|
||||||
// create materials, too
|
// create materials, too
|
||||||
aiMaterial* mat = new aiMaterial();
|
aiMaterial *mat = new aiMaterial();
|
||||||
pScene->mMaterials[i] = mat;
|
pScene->mMaterials[i] = mat;
|
||||||
|
|
||||||
// all white by default - texture rulez
|
// all white by default - texture rulez
|
||||||
aiColor3D color(1.f,1.f,1.f);
|
aiColor3D color(1.f, 1.f, 1.f);
|
||||||
|
|
||||||
aiString s;
|
aiString s;
|
||||||
::ai_snprintf( s.data, MAXLEN, "mat%u_tx%u_",i,materials[i].tex );
|
::ai_snprintf(s.data, MAXLEN, "mat%u_tx%u_", i, materials[i].tex);
|
||||||
|
|
||||||
// set the two-sided flag
|
// set the two-sided flag
|
||||||
if (materials[i].type == Unreal::MF_NORMAL_TS) {
|
if (materials[i].type == Unreal::MF_NORMAL_TS) {
|
||||||
const int twosided = 1;
|
const int twosided = 1;
|
||||||
mat->AddProperty(&twosided,1,AI_MATKEY_TWOSIDED);
|
mat->AddProperty(&twosided, 1, AI_MATKEY_TWOSIDED);
|
||||||
::strcat(s.data,"ts_");
|
::strcat(s.data, "ts_");
|
||||||
}
|
} else
|
||||||
else ::strcat(s.data,"os_");
|
::strcat(s.data, "os_");
|
||||||
|
|
||||||
// make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
|
// make TRANS faces 90% opaque that RemRedundantMaterials won't catch us
|
||||||
if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
|
if (materials[i].type == Unreal::MF_NORMAL_TRANS_TS) {
|
||||||
const float opac = 0.9f;
|
const float opac = 0.9f;
|
||||||
mat->AddProperty(&opac,1,AI_MATKEY_OPACITY);
|
mat->AddProperty(&opac, 1, AI_MATKEY_OPACITY);
|
||||||
::strcat(s.data,"tran_");
|
::strcat(s.data, "tran_");
|
||||||
}
|
} else
|
||||||
else ::strcat(s.data,"opaq_");
|
::strcat(s.data, "opaq_");
|
||||||
|
|
||||||
// a special name for the weapon attachment point
|
// a special name for the weapon attachment point
|
||||||
if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
|
if (materials[i].type == Unreal::MF_WEAPON_PLACEHOLDER) {
|
||||||
s.length = ::ai_snprintf( s.data, MAXLEN, "$WeaponTag$" );
|
s.length = ::ai_snprintf(s.data, MAXLEN, "$WeaponTag$");
|
||||||
color = aiColor3D(0.f,0.f,0.f);
|
color = aiColor3D(0.f, 0.f, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set color and name
|
// set color and name
|
||||||
mat->AddProperty(&color,1,AI_MATKEY_COLOR_DIFFUSE);
|
mat->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
s.length = (ai_uint32)::strlen(s.data);
|
s.length = static_cast<ai_uint32>(::strlen(s.data));
|
||||||
mat->AddProperty(&s,AI_MATKEY_NAME);
|
mat->AddProperty(&s, AI_MATKEY_NAME);
|
||||||
|
|
||||||
// set texture, if any
|
// set texture, if any
|
||||||
const unsigned int tex = materials[i].tex;
|
const unsigned int tex = materials[i].tex;
|
||||||
for (std::vector< std::pair< unsigned int, std::string > >::const_iterator it = textures.begin();it != textures.end();++it) {
|
for (std::vector<std::pair<unsigned int, std::string>>::const_iterator it = textures.begin(); it != textures.end(); ++it) {
|
||||||
if ((*it).first == tex) {
|
if ((*it).first == tex) {
|
||||||
s.Set((*it).second);
|
s.Set((*it).second);
|
||||||
mat->AddProperty(&s,AI_MATKEY_TEXTURE_DIFFUSE(0));
|
mat->AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,17 +492,17 @@ void UnrealImporter::InternReadFile( const std::string& pFile,
|
||||||
// fill them.
|
// fill them.
|
||||||
for (const Unreal::Triangle &tri : triangles) {
|
for (const Unreal::Triangle &tri : triangles) {
|
||||||
Unreal::TempMat mat(tri);
|
Unreal::TempMat mat(tri);
|
||||||
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(),materials.end(),mat);
|
std::vector<Unreal::TempMat>::iterator nt = std::find(materials.begin(), materials.end(), mat);
|
||||||
|
|
||||||
aiMesh* mesh = pScene->mMeshes[nt-materials.begin()];
|
aiMesh *mesh = pScene->mMeshes[nt - materials.begin()];
|
||||||
aiFace& f = mesh->mFaces[mesh->mNumFaces++];
|
aiFace &f = mesh->mFaces[mesh->mNumFaces++];
|
||||||
f.mIndices = new unsigned int[f.mNumIndices = 3];
|
f.mIndices = new unsigned int[f.mNumIndices = 3];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < 3;++i,mesh->mNumVertices++) {
|
for (unsigned int i = 0; i < 3; ++i, mesh->mNumVertices++) {
|
||||||
f.mIndices[i] = mesh->mNumVertices;
|
f.mIndices[i] = mesh->mNumVertices;
|
||||||
|
|
||||||
mesh->mVertices[mesh->mNumVertices] = vertices[ tri.mVertex[i] ];
|
mesh->mVertices[mesh->mNumVertices] = vertices[tri.mVertex[i]];
|
||||||
mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D( tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
|
mesh->mTextureCoords[0][mesh->mNumVertices] = aiVector3D(tri.mTex[i][0] / 255.f, 1.f - tri.mTex[i][1] / 255.f, 0.f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -47,161 +46,57 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_3D_LOADER_H
|
#define INCLUDED_AI_3D_LOADER_H
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Unreal {
|
|
||||||
|
|
||||||
/*
|
|
||||||
0 = Normal one-sided
|
|
||||||
1 = Normal two-sided
|
|
||||||
2 = Translucent two-sided
|
|
||||||
3 = Masked two-sided
|
|
||||||
4 = Modulation blended two-sided
|
|
||||||
8 = Placeholder triangle for weapon positioning (invisible)
|
|
||||||
*/
|
|
||||||
enum MeshFlags {
|
|
||||||
MF_NORMAL_OS = 0,
|
|
||||||
MF_NORMAL_TS = 1,
|
|
||||||
MF_NORMAL_TRANS_TS = 2,
|
|
||||||
MF_NORMAL_MASKED_TS = 3,
|
|
||||||
MF_NORMAL_MOD_TS = 4,
|
|
||||||
MF_WEAPON_PLACEHOLDER = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
// a single triangle
|
|
||||||
struct Triangle {
|
|
||||||
uint16_t mVertex[3]; // Vertex indices
|
|
||||||
char mType; // James' Mesh Type
|
|
||||||
char mColor; // Color for flat and Gourand Shaded
|
|
||||||
unsigned char mTex[3][2]; // Texture UV coordinates
|
|
||||||
unsigned char mTextureNum; // Source texture offset
|
|
||||||
char mFlags; // Unreal Mesh Flags (unused)
|
|
||||||
|
|
||||||
unsigned int matIndex;
|
|
||||||
};
|
|
||||||
|
|
||||||
// temporary representation for a material
|
|
||||||
struct TempMat {
|
|
||||||
TempMat()
|
|
||||||
: type()
|
|
||||||
, tex()
|
|
||||||
, numFaces (0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
explicit TempMat(const Triangle& in)
|
|
||||||
: type ((Unreal::MeshFlags)in.mType)
|
|
||||||
, tex (in.mTextureNum)
|
|
||||||
, numFaces (0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
// type of mesh
|
|
||||||
Unreal::MeshFlags type;
|
|
||||||
|
|
||||||
// index of texture
|
|
||||||
unsigned int tex;
|
|
||||||
|
|
||||||
// number of faces using us
|
|
||||||
unsigned int numFaces;
|
|
||||||
|
|
||||||
// for std::find
|
|
||||||
bool operator == (const TempMat& o ) {
|
|
||||||
return (tex == o.tex && type == o.type);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Vertex
|
|
||||||
{
|
|
||||||
int32_t X : 11;
|
|
||||||
int32_t Y : 11;
|
|
||||||
int32_t Z : 10;
|
|
||||||
};
|
|
||||||
|
|
||||||
// UNREAL vertex compression
|
|
||||||
inline void CompressVertex(const aiVector3D& v, uint32_t& out)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
Vertex n;
|
|
||||||
int32_t t;
|
|
||||||
};
|
|
||||||
n.X = (int32_t)v.x;
|
|
||||||
n.Y = (int32_t)v.y;
|
|
||||||
n.Z = (int32_t)v.z;
|
|
||||||
::memcpy( &out, &t, sizeof(int32_t));
|
|
||||||
//out = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UNREAL vertex decompression
|
|
||||||
inline void DecompressVertex(aiVector3D& v, int32_t in)
|
|
||||||
{
|
|
||||||
union {
|
|
||||||
Vertex n;
|
|
||||||
int32_t i;
|
|
||||||
};
|
|
||||||
i = in;
|
|
||||||
|
|
||||||
v.x = (float)n.X;
|
|
||||||
v.y = (float)n.Y;
|
|
||||||
v.z = (float)n.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end namespace Unreal
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** @brief Importer class to load UNREAL files (*.3d)
|
/** @brief Importer class to load UNREAL files (*.3d)
|
||||||
*/
|
*/
|
||||||
class UnrealImporter : public BaseImporter
|
class UnrealImporter : public BaseImporter {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
UnrealImporter();
|
UnrealImporter();
|
||||||
~UnrealImporter();
|
~UnrealImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Returns whether we can handle the format of the given file
|
/** @brief Returns whether we 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:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Called by Importer::GetExtensionList()
|
/** @brief Called by Importer::GetExtensionList()
|
||||||
*
|
*
|
||||||
* See #BaseImporter::GetInfo for the details
|
* See #BaseImporter::GetInfo for the details
|
||||||
*/
|
*/
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc *GetInfo() const;
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Setup properties for the importer
|
/** @brief Setup properties for the importer
|
||||||
*
|
*
|
||||||
* See BaseImporter::SetupProperties() for details
|
* See BaseImporter::SetupProperties() for details
|
||||||
*/
|
*/
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer *pImp);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Imports the given file into the given scene structure.
|
/** @brief 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);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! frame to be loaded
|
//! frame to be loaded
|
||||||
uint32_t configFrameID;
|
uint32_t mConfigFrameID;
|
||||||
|
|
||||||
//! process surface flags
|
//! process surface flags
|
||||||
bool configHandleFlags;
|
bool mConfigHandleFlags;
|
||||||
|
|
||||||
}; // !class UnrealImporter
|
}; // !class UnrealImporter
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
#endif // AI_UNREALIMPORTER_H_INC
|
#endif // AI_UNREALIMPORTER_H_INC
|
||||||
|
|
|
@ -176,7 +176,7 @@ void XGLImporter::InternReadFile( const std::string& pFile,
|
||||||
raw_reader->IncPtr(2);
|
raw_reader->IncPtr(2);
|
||||||
|
|
||||||
zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
|
zstream.next_in = reinterpret_cast<Bytef*>( raw_reader->GetPtr() );
|
||||||
zstream.avail_in = raw_reader->GetRemainingSize();
|
zstream.avail_in = (uInt) raw_reader->GetRemainingSize();
|
||||||
|
|
||||||
size_t total = 0l;
|
size_t total = 0l;
|
||||||
|
|
||||||
|
|
|
@ -382,7 +382,12 @@ namespace glTF
|
||||||
{
|
{
|
||||||
friend struct Accessor;
|
friend struct Accessor;
|
||||||
|
|
||||||
Accessor& accessor;
|
// This field is reported as not used, making it protectd is the easiest way to work around it without going to the bottom of what the problem is:
|
||||||
|
// ../code/glTF2/glTF2Asset.h:392:19: error: private field 'accessor' is not used [-Werror,-Wunused-private-field]
|
||||||
|
protected:
|
||||||
|
Accessor &accessor;
|
||||||
|
|
||||||
|
private:
|
||||||
uint8_t* data;
|
uint8_t* data;
|
||||||
size_t elemSize, stride;
|
size_t elemSize, stride;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <set>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -81,14 +82,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
#define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||||
#else
|
#else
|
||||||
#define gltf_unordered_map map
|
#define gltf_unordered_map map
|
||||||
|
#define gltf_unordered_set set
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#if _MSC_VER > 1600
|
#if _MSC_VER > 1600
|
||||||
#define gltf_unordered_map unordered_map
|
#define gltf_unordered_map unordered_map
|
||||||
|
#define gltf_unordered_set unordered_set
|
||||||
#else
|
#else
|
||||||
#define gltf_unordered_map tr1::unordered_map
|
#define gltf_unordered_map tr1::unordered_map
|
||||||
|
#define gltf_unordered_set tr1::unordered_set
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -375,8 +380,8 @@ struct Accessor : public Object {
|
||||||
|
|
||||||
inline uint8_t *GetPointer();
|
inline uint8_t *GetPointer();
|
||||||
|
|
||||||
template <class T>
|
template<class T>
|
||||||
bool ExtractData(T *&outData);
|
void ExtractData(T *&outData);
|
||||||
|
|
||||||
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
|
void WriteData(size_t count, const void *src_buffer, size_t src_stride);
|
||||||
|
|
||||||
|
@ -384,12 +389,18 @@ struct Accessor : public Object {
|
||||||
class Indexer {
|
class Indexer {
|
||||||
friend struct Accessor;
|
friend struct Accessor;
|
||||||
|
|
||||||
|
// This field is reported as not used, making it protectd is the easiest way to work around it without going to the bottom of what the problem is:
|
||||||
|
// ../code/glTF2/glTF2Asset.h:392:19: error: private field 'accessor' is not used [-Werror,-Wunused-private-field]
|
||||||
|
protected:
|
||||||
Accessor &accessor;
|
Accessor &accessor;
|
||||||
|
|
||||||
|
private:
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
size_t elemSize, stride;
|
size_t elemSize, stride;
|
||||||
|
|
||||||
Indexer(Accessor &acc);
|
Indexer(Accessor &acc);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Accesses the i-th value as defined by the accessor
|
//! Accesses the i-th value as defined by the accessor
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -720,6 +731,7 @@ struct Mesh : public Object {
|
||||||
std::vector<Primitive> primitives;
|
std::vector<Primitive> primitives;
|
||||||
|
|
||||||
std::vector<float> weights;
|
std::vector<float> weights;
|
||||||
|
std::vector<std::string> targetNames;
|
||||||
|
|
||||||
Mesh() {}
|
Mesh() {}
|
||||||
|
|
||||||
|
@ -874,6 +886,8 @@ class LazyDict : public LazyDictBase {
|
||||||
Value *mDict; //! JSON dictionary object
|
Value *mDict; //! JSON dictionary object
|
||||||
Asset &mAsset; //! The asset instance
|
Asset &mAsset; //! The asset instance
|
||||||
|
|
||||||
|
std::gltf_unordered_set<unsigned int> mRecursiveReferenceCheck; //! Used by Retrieve to prevent recursive lookups
|
||||||
|
|
||||||
void AttachToDocument(Document &doc);
|
void AttachToDocument(Document &doc);
|
||||||
void DetachFromDocument();
|
void DetachFromDocument();
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,11 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
|
||||||
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
|
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mRecursiveReferenceCheck.find(i) != mRecursiveReferenceCheck.end()) {
|
||||||
|
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" has recursive reference to itself");
|
||||||
|
}
|
||||||
|
mRecursiveReferenceCheck.insert(i);
|
||||||
|
|
||||||
// Unique ptr prevents memory leak in case of Read throws an exception
|
// Unique ptr prevents memory leak in case of Read throws an exception
|
||||||
auto inst = std::unique_ptr<T>(new T());
|
auto inst = std::unique_ptr<T>(new T());
|
||||||
inst->id = std::string(mDictId) + "_" + to_string(i);
|
inst->id = std::string(mDictId) + "_" + to_string(i);
|
||||||
|
@ -287,7 +292,9 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
|
||||||
ReadMember(obj, "name", inst->name);
|
ReadMember(obj, "name", inst->name);
|
||||||
inst->Read(obj, mAsset);
|
inst->Read(obj, mAsset);
|
||||||
|
|
||||||
return Add(inst.release());
|
Ref<T> result = Add(inst.release());
|
||||||
|
mRecursiveReferenceCheck.erase(i);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -508,18 +515,23 @@ inline size_t Buffer::AppendData(uint8_t *data, size_t length) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Buffer::Grow(size_t amount) {
|
inline void Buffer::Grow(size_t amount) {
|
||||||
if (amount <= 0) return;
|
if (amount <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Capacity is big enough
|
||||||
if (capacity >= byteLength + amount) {
|
if (capacity >= byteLength + amount) {
|
||||||
byteLength += amount;
|
byteLength += amount;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shift operation is standard way to divide integer by 2, it doesn't cast it to float back and forth, also works for odd numbers,
|
// Just allocate data which we need
|
||||||
// originally it would look like: static_cast<size_t>(capacity * 1.5f)
|
capacity = byteLength + amount;
|
||||||
capacity = std::max(capacity + (capacity >> 1), byteLength + amount);
|
|
||||||
|
|
||||||
uint8_t *b = new uint8_t[capacity];
|
uint8_t *b = new uint8_t[capacity];
|
||||||
if (mData) memcpy(b, mData.get(), byteLength);
|
if (nullptr != mData) {
|
||||||
|
memcpy(b, mData.get(), byteLength);
|
||||||
|
}
|
||||||
mData.reset(b, std::default_delete<uint8_t[]>());
|
mData.reset(b, std::default_delete<uint8_t[]>());
|
||||||
byteLength += amount;
|
byteLength += amount;
|
||||||
}
|
}
|
||||||
|
@ -608,10 +620,13 @@ inline void CopyData(size_t count,
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
template <class T>
|
template<class T>
|
||||||
bool Accessor::ExtractData(T *&outData) {
|
void Accessor::ExtractData(T *&outData)
|
||||||
uint8_t *data = GetPointer();
|
{
|
||||||
if (!data) return false;
|
uint8_t* data = GetPointer();
|
||||||
|
if (!data) {
|
||||||
|
throw DeadlyImportError("GLTF: data is NULL");
|
||||||
|
}
|
||||||
|
|
||||||
const size_t elemSize = GetElementSize();
|
const size_t elemSize = GetElementSize();
|
||||||
const size_t totalSize = elemSize * count;
|
const size_t totalSize = elemSize * count;
|
||||||
|
@ -631,8 +646,6 @@ bool Accessor::ExtractData(T *&outData) {
|
||||||
memcpy(outData + i, data + i * stride, elemSize);
|
memcpy(outData + i, data + i * stride, elemSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {
|
inline void Accessor::WriteData(size_t _count, const void *src_buffer, size_t src_stride) {
|
||||||
|
@ -1021,6 +1034,19 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Value *extras = FindObject(pJSON_Object, "extras");
|
||||||
|
if (nullptr != extras ) {
|
||||||
|
if (Value* curTargetNames = FindArray(*extras, "targetNames")) {
|
||||||
|
this->targetNames.resize(curTargetNames->Size());
|
||||||
|
for (unsigned int i = 0; i < curTargetNames->Size(); ++i) {
|
||||||
|
Value& targetNameValue = (*curTargetNames)[i];
|
||||||
|
if (targetNameValue.IsString()) {
|
||||||
|
this->targetNames[i] = targetNameValue.GetString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Camera::Read(Value &obj, Asset & /*r*/) {
|
inline void Camera::Read(Value &obj, Asset & /*r*/) {
|
||||||
|
|
|
@ -472,6 +472,9 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
if (mesh.weights.size() > i) {
|
if (mesh.weights.size() > i) {
|
||||||
aiAnimMesh.mWeight = mesh.weights[i];
|
aiAnimMesh.mWeight = mesh.weights[i];
|
||||||
}
|
}
|
||||||
|
if (mesh.targetNames.size() > i) {
|
||||||
|
aiAnimMesh.mName = mesh.targetNames[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -680,6 +683,7 @@ void glTF2Importer::ImportCameras(glTF2::Asset &r) {
|
||||||
aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
|
aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
|
||||||
aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
|
aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
|
||||||
aicam->mHorizontalFOV = 0.0;
|
aicam->mHorizontalFOV = 0.0;
|
||||||
|
aicam->mOrthographicWidth = cam.cameraProperties.ortographic.xmag;
|
||||||
aicam->mAspect = 1.0f;
|
aicam->mAspect = 1.0f;
|
||||||
if (0.f != cam.cameraProperties.ortographic.ymag) {
|
if (0.f != cam.cameraProperties.ortographic.ymag) {
|
||||||
aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
|
aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
|
||||||
|
|
|
@ -15,7 +15,11 @@ if ( MSVC )
|
||||||
endif ( MSVC )
|
endif ( MSVC )
|
||||||
|
|
||||||
IF(CMAKE_SYSTEM_NAME MATCHES "(Darwin|FreeBSD)")
|
IF(CMAKE_SYSTEM_NAME MATCHES "(Darwin|FreeBSD)")
|
||||||
add_library(IrrXML ${IrrXML_SRCS})
|
IF(APPLE)
|
||||||
|
add_library(IrrXML STATIC ${IrrXML_SRCS})
|
||||||
|
ELSE()
|
||||||
|
add_library(IrrXML ${IrrXML_SRCS})
|
||||||
|
ENDIF()
|
||||||
ELSE()
|
ELSE()
|
||||||
add_library(IrrXML STATIC ${IrrXML_SRCS})
|
add_library(IrrXML STATIC ${IrrXML_SRCS})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
|
@ -8,16 +8,7 @@
|
||||||
#include "irrXML.h"
|
#include "irrXML.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
|
#include "fast_atof.h"
|
||||||
#include <cassert>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <cctype>
|
|
||||||
#include <cstdint>
|
|
||||||
//using namespace Assimp;
|
|
||||||
|
|
||||||
// For locale independent number conversion
|
|
||||||
#include <sstream>
|
|
||||||
#include <locale>
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define IRR_DEBUGPRINT(x) printf((x));
|
#define IRR_DEBUGPRINT(x) printf((x));
|
||||||
|
@ -37,14 +28,23 @@ template<class char_type, class superclass>
|
||||||
class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
|
class CXMLReaderImpl : public IIrrXMLReader<char_type, superclass>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
|
CXMLReaderImpl(IFileReadCallBack* callback, bool deleteCallBack = true)
|
||||||
: TextData(0), P(0), TextBegin(0), TextSize(0), CurrentNodeType(EXN_NONE),
|
: TextData(0)
|
||||||
SourceFormat(ETF_ASCII), TargetFormat(ETF_ASCII)
|
, P(0)
|
||||||
{
|
, TextBegin(0)
|
||||||
if (!callback)
|
, TextSize(0)
|
||||||
|
, CurrentNodeType(EXN_NONE)
|
||||||
|
, SourceFormat(ETF_ASCII)
|
||||||
|
, TargetFormat(ETF_ASCII)
|
||||||
|
, NodeName ()
|
||||||
|
, EmptyString()
|
||||||
|
, IsEmptyElement(false)
|
||||||
|
, SpecialCharacters()
|
||||||
|
, Attributes() {
|
||||||
|
if (!callback) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
storeTargetFormat();
|
storeTargetFormat();
|
||||||
|
|
||||||
|
@ -168,8 +168,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
core::stringc c = attr->Value.c_str();
|
core::stringc c = attr->Value.c_str();
|
||||||
return static_cast<float>(atof(c.c_str()));
|
return core::fast_atof(c.c_str());
|
||||||
//return fast_atof(c.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -181,11 +180,7 @@ public:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
core::stringc c = attrvalue;
|
core::stringc c = attrvalue;
|
||||||
std::istringstream sstr(c.c_str());
|
return core::fast_atof(c.c_str());
|
||||||
sstr.imbue(std::locale("C")); // Locale free number convert
|
|
||||||
float fNum;
|
|
||||||
sstr >> fNum;
|
|
||||||
return fNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,7 +223,7 @@ private:
|
||||||
{
|
{
|
||||||
char_type* start = P;
|
char_type* start = P;
|
||||||
|
|
||||||
// move forward until '<' found
|
// more forward until '<' found
|
||||||
while(*P != L'<' && *P)
|
while(*P != L'<' && *P)
|
||||||
++P;
|
++P;
|
||||||
|
|
||||||
|
@ -438,10 +433,6 @@ private:
|
||||||
while(*P != L'>')
|
while(*P != L'>')
|
||||||
++P;
|
++P;
|
||||||
|
|
||||||
// remove trailing whitespace, if any
|
|
||||||
while( std::isspace( P[-1]))
|
|
||||||
--P;
|
|
||||||
|
|
||||||
NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
|
NodeName = core::string<char_type>(pBeginClose, (int)(P - pBeginClose));
|
||||||
++P;
|
++P;
|
||||||
}
|
}
|
||||||
|
@ -676,12 +667,8 @@ private:
|
||||||
|
|
||||||
TextData = new char_type[sizeWithoutHeader];
|
TextData = new char_type[sizeWithoutHeader];
|
||||||
|
|
||||||
// MSVC debugger complains here about loss of data ...
|
|
||||||
size_t numShift = sizeof( char_type) * 8;
|
|
||||||
assert(numShift < 64);
|
|
||||||
const src_char_type cc = (src_char_type)(((uint64_t(1u) << numShift) - 1));
|
|
||||||
for (int i=0; i<sizeWithoutHeader; ++i)
|
for (int i=0; i<sizeWithoutHeader; ++i)
|
||||||
TextData[i] = char_type( source[i] & cc);
|
TextData[i] = (char_type)source[i];
|
||||||
|
|
||||||
TextBegin = TextData;
|
TextBegin = TextData;
|
||||||
TextSize = sizeWithoutHeader;
|
TextSize = sizeWithoutHeader;
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
// Copyright (C) 2002-2005 Nikolaus Gebhardt
|
||||||
|
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
||||||
|
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
|
||||||
|
|
||||||
|
#ifndef __FAST_A_TO_F_H_INCLUDED__
|
||||||
|
#define __FAST_A_TO_F_H_INCLUDED__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
namespace irr
|
||||||
|
{
|
||||||
|
namespace core
|
||||||
|
{
|
||||||
|
|
||||||
|
const float fast_atof_table[] = {
|
||||||
|
0.f,
|
||||||
|
0.1f,
|
||||||
|
0.01f,
|
||||||
|
0.001f,
|
||||||
|
0.0001f,
|
||||||
|
0.00001f,
|
||||||
|
0.000001f,
|
||||||
|
0.0000001f,
|
||||||
|
0.00000001f,
|
||||||
|
0.000000001f,
|
||||||
|
0.0000000001f,
|
||||||
|
0.00000000001f,
|
||||||
|
0.000000000001f,
|
||||||
|
0.0000000000001f,
|
||||||
|
0.00000000000001f,
|
||||||
|
0.000000000000001f
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Provides a fast function for converting a string into a float,
|
||||||
|
//! about 6 times faster than atof in win32.
|
||||||
|
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
|
||||||
|
inline char* fast_atof_move(char* c, float& out)
|
||||||
|
{
|
||||||
|
bool inv = false;
|
||||||
|
char *t;
|
||||||
|
float f;
|
||||||
|
|
||||||
|
if (*c=='-')
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
inv = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = (float)strtol(c, &t, 10);
|
||||||
|
|
||||||
|
c = t;
|
||||||
|
|
||||||
|
if (*c == '.')
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
|
||||||
|
float pl = (float)strtol(c, &t, 10);
|
||||||
|
pl *= fast_atof_table[t-c];
|
||||||
|
|
||||||
|
f += pl;
|
||||||
|
|
||||||
|
c = t;
|
||||||
|
|
||||||
|
if (*c == 'e')
|
||||||
|
{
|
||||||
|
++c;
|
||||||
|
float exp = (float)strtol(c, &t, 10);
|
||||||
|
f *= (float)pow(10.0f, exp);
|
||||||
|
c = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inv)
|
||||||
|
f *= -1.0f;
|
||||||
|
|
||||||
|
out = f;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Provides a fast function for converting a string into a float,
|
||||||
|
//! about 6 times faster than atof in win32.
|
||||||
|
// If you find any bugs, please send them to me, niko (at) irrlicht3d.org.
|
||||||
|
inline const char* fast_atof_move_const(const char* c, float& out)
|
||||||
|
{
|
||||||
|
bool inv = false;
|
||||||
|
char *t;
|
||||||
|
float f;
|
||||||
|
|
||||||
|
if (*c=='-')
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
inv = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = (float)strtol(c, &t, 10);
|
||||||
|
|
||||||
|
c = t;
|
||||||
|
|
||||||
|
if (*c == '.')
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
|
||||||
|
float pl = (float)strtol(c, &t, 10);
|
||||||
|
pl *= fast_atof_table[t-c];
|
||||||
|
|
||||||
|
f += pl;
|
||||||
|
|
||||||
|
c = t;
|
||||||
|
|
||||||
|
if (*c == 'e')
|
||||||
|
{
|
||||||
|
++c;
|
||||||
|
f32 exp = (f32)strtol(c, &t, 10);
|
||||||
|
f *= (f32)powf(10.0f, exp);
|
||||||
|
c = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inv)
|
||||||
|
f *= -1.0f;
|
||||||
|
|
||||||
|
out = f;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline float fast_atof(const char* c)
|
||||||
|
{
|
||||||
|
float ret;
|
||||||
|
fast_atof_move_const(c, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace core
|
||||||
|
}// end namespace irr
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@ class array
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
array()
|
array()
|
||||||
: data(0), allocated(0), used(0),
|
: data(0), allocated(0), used(0),
|
||||||
free_when_destroyed(true), is_sorted(true)
|
free_when_destroyed(true), is_sorted(true)
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
|
|
||||||
//! Constructor
|
//! Constructor
|
||||||
string(const string<T>& other)
|
string(const string<T>& other)
|
||||||
: array(0), allocated(0), used(0)
|
: array(0), allocated(0), used(0)
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
|
@ -117,7 +117,7 @@ public:
|
||||||
//! Constructor for unicode and ascii strings
|
//! Constructor for unicode and ascii strings
|
||||||
template <class B>
|
template <class B>
|
||||||
string(const B* c)
|
string(const B* c)
|
||||||
: array(0),allocated(0), used(0)
|
: array(0), allocated(0), used(0)
|
||||||
{
|
{
|
||||||
*this = c;
|
*this = c;
|
||||||
}
|
}
|
||||||
|
@ -636,9 +636,6 @@ private:
|
||||||
for (s32 i=0; i<amount; ++i)
|
for (s32 i=0; i<amount; ++i)
|
||||||
array[i] = old_array[i];
|
array[i] = old_array[i];
|
||||||
|
|
||||||
if (allocated < used)
|
|
||||||
used = allocated;
|
|
||||||
|
|
||||||
delete [] old_array;
|
delete [] old_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,13 +79,8 @@ typedef unsigned short wchar_t;
|
||||||
#endif // microsoft compiler
|
#endif // microsoft compiler
|
||||||
|
|
||||||
//! define a break macro for debugging only in Win32 mode.
|
//! define a break macro for debugging only in Win32 mode.
|
||||||
// WORKAROUND (assimp): remove __asm
|
#if !defined(_WIN64) && defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
|
||||||
#if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
|
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) if (_CONDITION_) {_asm int 3}
|
||||||
#if defined(_M_IX86)
|
|
||||||
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ ) /*if (_CONDITION_) {_asm int 3}*/
|
|
||||||
#else
|
|
||||||
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
|
#define _IRR_DEBUG_BREAK_IF( _CONDITION_ )
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,10 +91,8 @@ When you call unmanaged code that returns a bool type value of false from manage
|
||||||
the return value may appear as true. See
|
the return value may appear as true. See
|
||||||
http://support.microsoft.com/default.aspx?kbid=823071 for details.
|
http://support.microsoft.com/default.aspx?kbid=823071 for details.
|
||||||
Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/
|
Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400*/
|
||||||
|
#if !defined(_WIN64) && defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
|
||||||
// WORKAROUND (assimp): remove __asm
|
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX __asm mov eax,100
|
||||||
#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER > 1299) && (_MSC_VER < 1400)
|
|
||||||
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX /*__asm mov eax,100*/
|
|
||||||
#else
|
#else
|
||||||
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
|
#define _IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX
|
||||||
#endif // _IRR_MANAGED_MARSHALLING_BUGFIX
|
#endif // _IRR_MANAGED_MARSHALLING_BUGFIX
|
||||||
|
|
|
@ -2,14 +2,10 @@
|
||||||
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
// This file is part of the "Irrlicht Engine" and the "irrXML" project.
|
||||||
// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
|
// For conditions of distribution and use, see copyright notice in irrlicht.h and/or irrXML.h
|
||||||
|
|
||||||
// Need to include Assimp, too. We're using Assimp's version of fast_atof
|
|
||||||
// so we need stdint.h. But no PCH.
|
|
||||||
|
|
||||||
|
|
||||||
#include "irrXML.h"
|
#include "irrXML.h"
|
||||||
#include "irrString.h"
|
#include "irrString.h"
|
||||||
#include "irrArray.h"
|
#include "irrArray.h"
|
||||||
//#include <assimp/fast_atof.h>
|
#include "fast_atof.h"
|
||||||
#include "CXMLReaderImpl.h"
|
#include "CXMLReaderImpl.h"
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
|
@ -18,7 +14,7 @@ namespace io
|
||||||
{
|
{
|
||||||
|
|
||||||
//! Implementation of the file read callback for ordinary files
|
//! Implementation of the file read callback for ordinary files
|
||||||
class IRRXML_API CFileReadCallBack : public IFileReadCallBack
|
class CFileReadCallBack : public IFileReadCallBack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,6 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
# define IRRXML_API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
# define IRRXML_API __attribute__ ((visibility("default")))
|
|
||||||
#endif // _WIN32
|
|
||||||
|
|
||||||
/** \mainpage irrXML 1.2 API documentation
|
/** \mainpage irrXML 1.2 API documentation
|
||||||
<div align="center"><img src="logobig.png" ></div>
|
<div align="center"><img src="logobig.png" ></div>
|
||||||
|
|
||||||
|
@ -178,7 +172,7 @@ namespace io
|
||||||
ETF_UTF32_BE,
|
ETF_UTF32_BE,
|
||||||
|
|
||||||
//! UTF-32 format, little endian
|
//! UTF-32 format, little endian
|
||||||
ETF_UTF32_LE
|
ETF_UTF32_LE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -215,7 +209,7 @@ namespace io
|
||||||
two methods to read your data and give a pointer to an instance of
|
two methods to read your data and give a pointer to an instance of
|
||||||
your implementation when calling createIrrXMLReader(),
|
your implementation when calling createIrrXMLReader(),
|
||||||
createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
|
createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
|
||||||
class IRRXML_API IFileReadCallBack
|
class IFileReadCallBack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -415,7 +409,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReader* createIrrXMLReader(const char* filename);
|
IrrXMLReader* createIrrXMLReader(const char* filename);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-8 or ASCII character xml parser.
|
//! Creates an instance of an UFT-8 or ASCII character xml parser.
|
||||||
/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
|
/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
|
||||||
|
@ -427,7 +421,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReader* createIrrXMLReader(FILE* file);
|
IrrXMLReader* createIrrXMLReader(FILE* file);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-8 or ASCII character xml parser.
|
//! Creates an instance of an UFT-8 or ASCII character xml parser.
|
||||||
/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
|
/** This means that all character data will be returned in 8 bit ASCII or UTF-8. The file to read can
|
||||||
|
@ -440,7 +434,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback);
|
IrrXMLReader* createIrrXMLReader(IFileReadCallBack* callback);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-16 xml parser.
|
//! Creates an instance of an UFT-16 xml parser.
|
||||||
/** This means that
|
/** This means that
|
||||||
|
@ -452,7 +446,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename);
|
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(const char* filename);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-16 xml parser.
|
//! Creates an instance of an UFT-16 xml parser.
|
||||||
/** This means that all character data will be returned in UTF-16. The file to read can
|
/** This means that all character data will be returned in UTF-16. The file to read can
|
||||||
|
@ -464,7 +458,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file);
|
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(FILE* file);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-16 xml parser.
|
//! Creates an instance of an UFT-16 xml parser.
|
||||||
/** This means that all character data will be returned in UTF-16. The file to read can
|
/** This means that all character data will be returned in UTF-16. The file to read can
|
||||||
|
@ -477,7 +471,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback);
|
IrrXMLReaderUTF16* createIrrXMLReaderUTF16(IFileReadCallBack* callback);
|
||||||
|
|
||||||
|
|
||||||
//! Creates an instance of an UFT-32 xml parser.
|
//! Creates an instance of an UFT-32 xml parser.
|
||||||
|
@ -489,7 +483,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename);
|
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(const char* filename);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-32 xml parser.
|
//! Creates an instance of an UFT-32 xml parser.
|
||||||
/** This means that all character data will be returned in UTF-32. The file to read can
|
/** This means that all character data will be returned in UTF-32. The file to read can
|
||||||
|
@ -501,7 +495,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file);
|
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(FILE* file);
|
||||||
|
|
||||||
//! Creates an instance of an UFT-32 xml parser.
|
//! Creates an instance of an UFT-32 xml parser.
|
||||||
/** This means that
|
/** This means that
|
||||||
|
@ -515,7 +509,7 @@ namespace io
|
||||||
\return Returns a pointer to the created xml parser. This pointer should be
|
\return Returns a pointer to the created xml parser. This pointer should be
|
||||||
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
deleted using 'delete' after no longer needed. Returns 0 if an error occured
|
||||||
and the file could not be opened. */
|
and the file could not be opened. */
|
||||||
IRRXML_API IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback);
|
IrrXMLReaderUTF32* createIrrXMLReaderUTF32(IFileReadCallBack* callback);
|
||||||
|
|
||||||
|
|
||||||
/*! \file irrxml.h
|
/*! \file irrxml.h
|
||||||
|
|
|
@ -55,36 +55,51 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Math {
|
namespace Math {
|
||||||
|
|
||||||
// TODO: use binary GCD for unsigned integers ....
|
/// @brief Will return the greatest common divisor.
|
||||||
template < typename IntegerType >
|
/// @param a [in] Value a.
|
||||||
inline
|
/// @param b [in] Value b.
|
||||||
IntegerType gcd( IntegerType a, IntegerType b ) {
|
/// @return The greatest common divisor.
|
||||||
|
template <typename IntegerType>
|
||||||
|
inline IntegerType gcd( IntegerType a, IntegerType b ) {
|
||||||
const IntegerType zero = (IntegerType)0;
|
const IntegerType zero = (IntegerType)0;
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
if ( a == zero )
|
if ( a == zero ) {
|
||||||
return b;
|
return b;
|
||||||
|
}
|
||||||
b %= a;
|
b %= a;
|
||||||
|
|
||||||
if ( b == zero )
|
if ( b == zero ) {
|
||||||
return a;
|
return a;
|
||||||
|
}
|
||||||
a %= b;
|
a %= b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Will return the greatest common divisor.
|
||||||
|
/// @param a [in] Value a.
|
||||||
|
/// @param b [in] Value b.
|
||||||
|
/// @return The greatest common divisor.
|
||||||
template < typename IntegerType >
|
template < typename IntegerType >
|
||||||
inline
|
inline IntegerType lcm( IntegerType a, IntegerType b ) {
|
||||||
IntegerType lcm( IntegerType a, IntegerType b ) {
|
|
||||||
const IntegerType t = gcd (a,b);
|
const IntegerType t = gcd (a,b);
|
||||||
if (!t)
|
if (!t) {
|
||||||
return t;
|
return t;
|
||||||
|
}
|
||||||
return a / t * b;
|
return a / t * b;
|
||||||
}
|
}
|
||||||
|
/// @brief Will return the smallest epsilon-value for the requested type.
|
||||||
|
/// @return The numercical limit epsilon depending on its type.
|
||||||
template<class T>
|
template<class T>
|
||||||
inline
|
inline T getEpsilon() {
|
||||||
T getEpsilon() {
|
|
||||||
return std::numeric_limits<T>::epsilon();
|
return std::numeric_limits<T>::epsilon();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Will return the constant PI for the requested type.
|
||||||
|
/// @return Pi
|
||||||
|
template<class T>
|
||||||
|
inline T PI() {
|
||||||
|
return static_cast<T>(3.14159265358979323846);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // namespace Math
|
||||||
|
} // namespace Assimp
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file Defines small vector with inplace storage.
|
||||||
|
Based on CppCon 2016: Chandler Carruth "High Performance Code 201: Hybrid Data Structures" */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef AI_SMALLVECTOR_H_INC
|
||||||
|
#define AI_SMALLVECTOR_H_INC
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# pragma GCC system_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
/// @brief Small vector with inplace storage.
|
||||||
|
///
|
||||||
|
/// Reduces heap allocations when list is shorter. It uses a small array for a dedicated size.
|
||||||
|
/// When the growing gets bigger than this small cache a dynamic growing algorithm will be
|
||||||
|
/// used.
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
template<typename T, unsigned int Capacity>
|
||||||
|
class SmallVector {
|
||||||
|
public:
|
||||||
|
/// @brief The default class constructor.
|
||||||
|
SmallVector() :
|
||||||
|
mStorage(mInplaceStorage),
|
||||||
|
mSize(0),
|
||||||
|
mCapacity(Capacity) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief The class destructor.
|
||||||
|
~SmallVector() {
|
||||||
|
if (mStorage != mInplaceStorage) {
|
||||||
|
delete [] mStorage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Will push a new item. The capacity will grow in case of a too small capacity.
|
||||||
|
/// @param item [in] The item to push at the end of the vector.
|
||||||
|
void push_back(const T& item) {
|
||||||
|
if (mSize < mCapacity) {
|
||||||
|
mStorage[mSize++] = item;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
push_back_and_grow(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Will resize the vector.
|
||||||
|
/// @param newSize [in] The new size.
|
||||||
|
void resize(size_t newSize) {
|
||||||
|
if (newSize > mCapacity) {
|
||||||
|
grow(newSize);
|
||||||
|
}
|
||||||
|
mSize = newSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns the current size of the vector.
|
||||||
|
/// @return The current size.
|
||||||
|
size_t size() const {
|
||||||
|
return mSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns a pointer to the first item.
|
||||||
|
/// @return The first item as a pointer.
|
||||||
|
T* begin() {
|
||||||
|
return mStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns a pointer to the end.
|
||||||
|
/// @return The end as a pointer.
|
||||||
|
T* end() {
|
||||||
|
return &mStorage[mSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns a const pointer to the first item.
|
||||||
|
/// @return The first item as a const pointer.
|
||||||
|
T* begin() const {
|
||||||
|
return mStorage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @brief Returns a const pointer to the end.
|
||||||
|
/// @return The end as a const pointer.
|
||||||
|
T* end() const {
|
||||||
|
return &mStorage[mSize];
|
||||||
|
}
|
||||||
|
|
||||||
|
SmallVector(const SmallVector &) = delete;
|
||||||
|
SmallVector(SmallVector &&) = delete;
|
||||||
|
SmallVector &operator = (const SmallVector &) = delete;
|
||||||
|
SmallVector &operator = (SmallVector &&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void grow( size_t newCapacity) {
|
||||||
|
T* oldStorage = mStorage;
|
||||||
|
T* newStorage = new T[newCapacity];
|
||||||
|
|
||||||
|
std::memcpy(newStorage, oldStorage, mSize * sizeof(T));
|
||||||
|
|
||||||
|
mStorage = newStorage;
|
||||||
|
mCapacity = newCapacity;
|
||||||
|
|
||||||
|
if (oldStorage != mInplaceStorage) {
|
||||||
|
delete [] oldStorage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back_and_grow(const T& item) {
|
||||||
|
grow(mCapacity + Capacity);
|
||||||
|
|
||||||
|
mStorage[mSize++] = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* mStorage;
|
||||||
|
size_t mSize;
|
||||||
|
size_t mCapacity;
|
||||||
|
T mInplaceStorage[Capacity];
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace Assimp
|
||||||
|
|
||||||
|
#endif // !! AI_SMALLVECTOR_H_INC
|
|
@ -46,11 +46,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_SPATIALSORT_H_INC
|
#define AI_SPATIALSORT_H_INC
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# pragma GCC system_header
|
#pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -62,10 +62,8 @@ namespace Assimp {
|
||||||
* time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen
|
* time, with O(n) worst case complexity when all vertices lay on the plane. The plane is chosen
|
||||||
* so that it avoids common planes in usual data sets. */
|
* so that it avoids common planes in usual data sets. */
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
class ASSIMP_API SpatialSort
|
class ASSIMP_API SpatialSort {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SpatialSort();
|
SpatialSort();
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
|
@ -76,14 +74,12 @@ public:
|
||||||
* @param pNumPositions Number of vectors to expect in that array.
|
* @param pNumPositions Number of vectors to expect in that array.
|
||||||
* @param pElementOffset Offset in bytes from the beginning of one vector in memory
|
* @param pElementOffset Offset in bytes from the beginning of one vector in memory
|
||||||
* to the beginning of the next vector. */
|
* to the beginning of the next vector. */
|
||||||
SpatialSort( const aiVector3D* pPositions, unsigned int pNumPositions,
|
SpatialSort(const aiVector3D *pPositions, unsigned int pNumPositions,
|
||||||
unsigned int pElementOffset);
|
unsigned int pElementOffset);
|
||||||
|
|
||||||
/** Destructor */
|
/** Destructor */
|
||||||
~SpatialSort();
|
~SpatialSort();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
/** Sets the input data for the SpatialSort. This replaces existing data, if any.
|
/** Sets the input data for the SpatialSort. This replaces existing data, if any.
|
||||||
* The new data receives new indices in ascending order.
|
* The new data receives new indices in ascending order.
|
||||||
|
@ -97,17 +93,15 @@ public:
|
||||||
* required in order to use #FindPosition() or #GenerateMappingTable().
|
* required in order to use #FindPosition() or #GenerateMappingTable().
|
||||||
* If you don't finalize yet, you can use #Append() to add data from
|
* If you don't finalize yet, you can use #Append() to add data from
|
||||||
* other sources.*/
|
* other sources.*/
|
||||||
void Fill( const aiVector3D* pPositions, unsigned int pNumPositions,
|
void Fill(const aiVector3D *pPositions, unsigned int pNumPositions,
|
||||||
unsigned int pElementOffset,
|
unsigned int pElementOffset,
|
||||||
bool pFinalize = true);
|
bool pFinalize = true);
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
/** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */
|
/** Same as #Fill(), except the method appends to existing data in the #SpatialSort. */
|
||||||
void Append( const aiVector3D* pPositions, unsigned int pNumPositions,
|
void Append(const aiVector3D *pPositions, unsigned int pNumPositions,
|
||||||
unsigned int pElementOffset,
|
unsigned int pElementOffset,
|
||||||
bool pFinalize = true);
|
bool pFinalize = true);
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
/** Finalize the spatial hash data structure. This can be useful after
|
/** Finalize the spatial hash data structure. This can be useful after
|
||||||
|
@ -123,8 +117,8 @@ public:
|
||||||
* @param poResults The container to store the indices of the found positions.
|
* @param poResults The container to store the indices of the found positions.
|
||||||
* Will be emptied by the call so it may contain anything.
|
* Will be emptied by the call so it may contain anything.
|
||||||
* @return An iterator to iterate over all vertices in the given area.*/
|
* @return An iterator to iterate over all vertices in the given area.*/
|
||||||
void FindPositions( const aiVector3D& pPosition, ai_real pRadius,
|
void FindPositions(const aiVector3D &pPosition, ai_real pRadius,
|
||||||
std::vector<unsigned int>& poResults) const;
|
std::vector<unsigned int> &poResults) const;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
/** Fills an array with indices of all positions identical to the given position. In
|
/** Fills an array with indices of all positions identical to the given position. In
|
||||||
|
@ -133,8 +127,8 @@ public:
|
||||||
* @param pPosition The position to look for vertices.
|
* @param pPosition The position to look for vertices.
|
||||||
* @param poResults The container to store the indices of the found positions.
|
* @param poResults The container to store the indices of the found positions.
|
||||||
* Will be emptied by the call so it may contain anything.*/
|
* Will be emptied by the call so it may contain anything.*/
|
||||||
void FindIdenticalPositions( const aiVector3D& pPosition,
|
void FindIdenticalPositions(const aiVector3D &pPosition,
|
||||||
std::vector<unsigned int>& poResults) const;
|
std::vector<unsigned int> &poResults) const;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
/** Compute a table that maps each vertex ID referring to a spatially close
|
/** Compute a table that maps each vertex ID referring to a spatially close
|
||||||
|
@ -144,8 +138,8 @@ public:
|
||||||
* @param pRadius Maximal distance from the position a vertex may have to
|
* @param pRadius Maximal distance from the position a vertex may have to
|
||||||
* be counted in.
|
* be counted in.
|
||||||
* @return Number of unique vertices (n). */
|
* @return Number of unique vertices (n). */
|
||||||
unsigned int GenerateMappingTable(std::vector<unsigned int>& fill,
|
unsigned int GenerateMappingTable(std::vector<unsigned int> &fill,
|
||||||
ai_real pRadius) const;
|
ai_real pRadius) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
|
/** Normal of the sorting plane, normalized. The center is always at (0, 0, 0) */
|
||||||
|
@ -159,15 +153,17 @@ protected:
|
||||||
ai_real mDistance; ///< Distance of this vertex to the sorting plane
|
ai_real mDistance; ///< Distance of this vertex to the sorting plane
|
||||||
|
|
||||||
Entry() AI_NO_EXCEPT
|
Entry() AI_NO_EXCEPT
|
||||||
: mIndex( 999999999 ), mPosition(), mDistance( 99999. ) {
|
: mIndex(999999999),
|
||||||
|
mPosition(),
|
||||||
|
mDistance(99999.) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
Entry( unsigned int pIndex, const aiVector3D& pPosition, ai_real pDistance)
|
Entry(unsigned int pIndex, const aiVector3D &pPosition, ai_real pDistance) :
|
||||||
: mIndex( pIndex), mPosition( pPosition), mDistance( pDistance) {
|
mIndex(pIndex), mPosition(pPosition), mDistance(pDistance) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator < (const Entry& e) const { return mDistance < e.mDistance; }
|
bool operator<(const Entry &e) const { return mDistance < e.mDistance; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// all positions, sorted by distance to the sorting plane
|
// all positions, sorted by distance to the sorting plane
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -49,13 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_STREAMREADER_H_INCLUDED
|
#define AI_STREAMREADER_H_INCLUDED
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# pragma GCC system_header
|
#pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <assimp/IOStream.hpp>
|
|
||||||
#include <assimp/Defines.h>
|
|
||||||
#include <assimp/ByteSwapper.h>
|
#include <assimp/ByteSwapper.h>
|
||||||
|
#include <assimp/Defines.h>
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -74,10 +72,8 @@ namespace Assimp {
|
||||||
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
|
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
|
||||||
class StreamReader {
|
class StreamReader {
|
||||||
public:
|
public:
|
||||||
// FIXME: use these data types throughout the whole library,
|
using diff = size_t;
|
||||||
// then change them to 64 bit values :-)
|
using pos = size_t;
|
||||||
using diff = int;
|
|
||||||
using pos = unsigned int;
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Construction from a given stream with a well-defined endianness.
|
/** Construction from a given stream with a well-defined endianness.
|
||||||
|
@ -91,40 +87,45 @@ public:
|
||||||
* stream is in little endian byte order. Otherwise the
|
* stream is in little endian byte order. Otherwise the
|
||||||
* endianness information is contained in the @c SwapEndianess
|
* endianness information is contained in the @c SwapEndianess
|
||||||
* template parameter and this parameter is meaningless. */
|
* template parameter and this parameter is meaningless. */
|
||||||
StreamReader(std::shared_ptr<IOStream> stream, bool le = false)
|
StreamReader(std::shared_ptr<IOStream> stream, bool le = false) :
|
||||||
: stream(stream)
|
mStream(stream),
|
||||||
, le(le)
|
mBuffer(nullptr),
|
||||||
{
|
mCurrent(nullptr),
|
||||||
|
mEnd(nullptr),
|
||||||
|
mLimit(nullptr),
|
||||||
|
mLe(le) {
|
||||||
ai_assert(stream);
|
ai_assert(stream);
|
||||||
InternBegin();
|
InternBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
StreamReader(IOStream* stream, bool le = false)
|
StreamReader(IOStream *stream, bool le = false) :
|
||||||
: stream(std::shared_ptr<IOStream>(stream))
|
mStream(std::shared_ptr<IOStream>(stream)),
|
||||||
, le(le)
|
mBuffer(nullptr),
|
||||||
{
|
mCurrent(nullptr),
|
||||||
ai_assert(stream);
|
mEnd(nullptr),
|
||||||
|
mLimit(nullptr),
|
||||||
|
mLe(le) {
|
||||||
|
ai_assert(nullptr != stream);
|
||||||
InternBegin();
|
InternBegin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
~StreamReader() {
|
~StreamReader() {
|
||||||
delete[] buffer;
|
delete[] mBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated, use overloaded operator>> instead
|
// deprecated, use overloaded operator>> instead
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read a float from the stream */
|
/// Read a float from the stream.
|
||||||
float GetF4()
|
float GetF4() {
|
||||||
{
|
|
||||||
return Get<float>();
|
return Get<float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read a double from the stream */
|
/// Read a double from the stream.
|
||||||
double GetF8() {
|
double GetF8() {
|
||||||
return Get<double>();
|
return Get<double>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,7 +137,7 @@ public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read a signed 8 bit integer from the stream */
|
/** Read a signed 8 bit integer from the stream */
|
||||||
int8_t GetI1() {
|
int8_t GetI1() {
|
||||||
return Get<int8_t>();
|
return Get<int8_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,55 +155,55 @@ public:
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read a unsigned 16 bit integer from the stream */
|
/** Read a unsigned 16 bit integer from the stream */
|
||||||
uint16_t GetU2() {
|
uint16_t GetU2() {
|
||||||
return Get<uint16_t>();
|
return Get<uint16_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read a unsigned 8 bit integer from the stream */
|
/// Read a unsigned 8 bit integer from the stream
|
||||||
uint8_t GetU1() {
|
uint8_t GetU1() {
|
||||||
return Get<uint8_t>();
|
return Get<uint8_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read an unsigned 32 bit integer from the stream */
|
/// Read an unsigned 32 bit integer from the stream
|
||||||
uint32_t GetU4() {
|
uint32_t GetU4() {
|
||||||
return Get<uint32_t>();
|
return Get<uint32_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Read a unsigned 64 bit integer from the stream */
|
/// Read a unsigned 64 bit integer from the stream
|
||||||
uint64_t GetU8() {
|
uint64_t GetU8() {
|
||||||
return Get<uint64_t>();
|
return Get<uint64_t>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Get the remaining stream size (to the end of the stream) */
|
/// Get the remaining stream size (to the end of the stream)
|
||||||
unsigned int GetRemainingSize() const {
|
size_t GetRemainingSize() const {
|
||||||
return (unsigned int)(end - current);
|
return (unsigned int)(mEnd - mCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Get the remaining stream size (to the current read limit). The
|
/** Get the remaining stream size (to the current read limit). The
|
||||||
* return value is the remaining size of the stream if no custom
|
* return value is the remaining size of the stream if no custom
|
||||||
* read limit has been set. */
|
* read limit has been set. */
|
||||||
unsigned int GetRemainingSizeToLimit() const {
|
size_t GetRemainingSizeToLimit() const {
|
||||||
return (unsigned int)(limit - current);
|
return (unsigned int)(mLimit - mCurrent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Increase the file pointer (relative seeking) */
|
/** Increase the file pointer (relative seeking) */
|
||||||
void IncPtr(intptr_t plus) {
|
void IncPtr(intptr_t plus) {
|
||||||
current += plus;
|
mCurrent += plus;
|
||||||
if (current > limit) {
|
if (mCurrent > mLimit) {
|
||||||
throw DeadlyImportError("End of file or read limit was reached");
|
throw DeadlyImportError("End of file or read limit was reached");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Get the current file pointer */
|
/** Get the current file pointer */
|
||||||
int8_t* GetPtr() const {
|
int8_t *GetPtr() const {
|
||||||
return current;
|
return mCurrent;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
@ -211,9 +212,9 @@ public:
|
||||||
* large chunks of data at once.
|
* large chunks of data at once.
|
||||||
* @param p The new pointer, which is validated against the size
|
* @param p The new pointer, which is validated against the size
|
||||||
* limit and buffer boundaries. */
|
* limit and buffer boundaries. */
|
||||||
void SetPtr(int8_t* p) {
|
void SetPtr(int8_t *p) {
|
||||||
current = p;
|
mCurrent = p;
|
||||||
if (current > limit || current < buffer) {
|
if (mCurrent > mLimit || mCurrent < mBuffer) {
|
||||||
throw DeadlyImportError("End of file or read limit was reached");
|
throw DeadlyImportError("End of file or read limit was reached");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -222,21 +223,20 @@ public:
|
||||||
/** Copy n bytes to an external buffer
|
/** Copy n bytes to an external buffer
|
||||||
* @param out Destination for copying
|
* @param out Destination for copying
|
||||||
* @param bytes Number of bytes to copy */
|
* @param bytes Number of bytes to copy */
|
||||||
void CopyAndAdvance(void* out, size_t bytes) {
|
void CopyAndAdvance(void *out, size_t bytes) {
|
||||||
int8_t* ur = GetPtr();
|
int8_t *ur = GetPtr();
|
||||||
SetPtr(ur+bytes); // fire exception if eof
|
SetPtr(ur + bytes); // fire exception if eof
|
||||||
|
|
||||||
::memcpy(out,ur,bytes);
|
::memcpy(out, ur, bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
/// @brief Get the current offset from the beginning of the file
|
||||||
/** Get the current offset from the beginning of the file */
|
int GetCurrentPos() const {
|
||||||
int GetCurrentPos() const {
|
return (unsigned int)(mCurrent - mBuffer);
|
||||||
return (unsigned int)(current - buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetCurrentPos(size_t pos) {
|
void SetCurrentPos(size_t pos) {
|
||||||
SetPtr(buffer + pos);
|
SetPtr(mBuffer + pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
@ -246,15 +246,15 @@ public:
|
||||||
* the beginning of the file. Specifying UINT_MAX
|
* the beginning of the file. Specifying UINT_MAX
|
||||||
* resets the limit to the original end of the stream.
|
* resets the limit to the original end of the stream.
|
||||||
* Returns the previously set limit. */
|
* Returns the previously set limit. */
|
||||||
unsigned int SetReadLimit(unsigned int _limit) {
|
unsigned int SetReadLimit(unsigned int _limit) {
|
||||||
unsigned int prev = GetReadLimit();
|
unsigned int prev = GetReadLimit();
|
||||||
if (UINT_MAX == _limit) {
|
if (UINT_MAX == _limit) {
|
||||||
limit = end;
|
mLimit = mEnd;
|
||||||
return prev;
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
limit = buffer + _limit;
|
mLimit = mBuffer + _limit;
|
||||||
if (limit > end) {
|
if (mLimit > mEnd) {
|
||||||
throw DeadlyImportError("StreamReader: Invalid read limit");
|
throw DeadlyImportError("StreamReader: Invalid read limit");
|
||||||
}
|
}
|
||||||
return prev;
|
return prev;
|
||||||
|
@ -263,21 +263,21 @@ public:
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Get the current read limit in bytes. Reading over this limit
|
/** Get the current read limit in bytes. Reading over this limit
|
||||||
* accidentally raises an exception. */
|
* accidentally raises an exception. */
|
||||||
unsigned int GetReadLimit() const {
|
unsigned int GetReadLimit() const {
|
||||||
return (unsigned int)(limit - buffer);
|
return (unsigned int)(mLimit - mBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** Skip to the read limit in bytes. Reading over this limit
|
/** Skip to the read limit in bytes. Reading over this limit
|
||||||
* accidentally raises an exception. */
|
* accidentally raises an exception. */
|
||||||
void SkipToReadLimit() {
|
void SkipToReadLimit() {
|
||||||
current = limit;
|
mCurrent = mLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
/** overload operator>> and allow chaining of >> ops. */
|
/** overload operator>> and allow chaining of >> ops. */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
StreamReader& operator >> (T& f) {
|
StreamReader &operator>>(T &f) {
|
||||||
f = Get<T>();
|
f = Get<T>();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -286,14 +286,14 @@ public:
|
||||||
/** Generic read method. ByteSwap::Swap(T*) *must* be defined */
|
/** Generic read method. ByteSwap::Swap(T*) *must* be defined */
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T Get() {
|
T Get() {
|
||||||
if ( current + sizeof(T) > limit) {
|
if (mCurrent + sizeof(T) > mLimit) {
|
||||||
throw DeadlyImportError("End of file or stream limit was reached");
|
throw DeadlyImportError("End of file or stream limit was reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
T f;
|
T f;
|
||||||
::memcpy (&f, current, sizeof(T));
|
::memcpy(&f, mCurrent, sizeof(T));
|
||||||
Intern::Getter<SwapEndianess,T,RuntimeSwitch>() (&f,le);
|
Intern::Getter<SwapEndianess, T, RuntimeSwitch>()(&f, mLe);
|
||||||
current += sizeof(T);
|
mCurrent += sizeof(T);
|
||||||
|
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
@ -301,46 +301,44 @@ public:
|
||||||
private:
|
private:
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
void InternBegin() {
|
void InternBegin() {
|
||||||
if (!stream) {
|
if (nullptr == mStream) {
|
||||||
// in case someone wonders: StreamReader is frequently invoked with
|
|
||||||
// no prior validation whether the input stream is valid. Since
|
|
||||||
// no one bothers changing the error message, this message here
|
|
||||||
// is passed down to the caller and 'unable to open file'
|
|
||||||
// simply describes best what happened.
|
|
||||||
throw DeadlyImportError("StreamReader: Unable to open file");
|
throw DeadlyImportError("StreamReader: Unable to open file");
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t s = stream->FileSize() - stream->Tell();
|
const size_t filesize = mStream->FileSize() - mStream->Tell();
|
||||||
if (!s) {
|
if (0 == filesize) {
|
||||||
throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
|
throw DeadlyImportError("StreamReader: File is empty or EOF is already reached");
|
||||||
}
|
}
|
||||||
|
|
||||||
current = buffer = new int8_t[s];
|
mCurrent = mBuffer = new int8_t[filesize];
|
||||||
const size_t read = stream->Read(current,1,s);
|
const size_t read = mStream->Read(mCurrent, 1, filesize);
|
||||||
// (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable
|
// (read < s) can only happen if the stream was opened in text mode, in which case FileSize() is not reliable
|
||||||
ai_assert(read <= s);
|
ai_assert(read <= filesize);
|
||||||
end = limit = &buffer[read-1] + 1;
|
mEnd = mLimit = &mBuffer[read - 1] + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<IOStream> stream;
|
std::shared_ptr<IOStream> mStream;
|
||||||
int8_t *buffer, *current, *end, *limit;
|
int8_t *mBuffer;
|
||||||
bool le;
|
int8_t *mCurrent;
|
||||||
|
int8_t *mEnd;
|
||||||
|
int8_t *mLimit;
|
||||||
|
bool mLe;
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
|
// `static` StreamReaders. Their byte order is fixed and they might be a little bit faster.
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
typedef StreamReader<true> StreamReaderLE;
|
typedef StreamReader<true> StreamReaderLE;
|
||||||
typedef StreamReader<false> StreamReaderBE;
|
typedef StreamReader<false> StreamReaderBE;
|
||||||
#else
|
#else
|
||||||
typedef StreamReader<true> StreamReaderBE;
|
typedef StreamReader<true> StreamReaderBE;
|
||||||
typedef StreamReader<false> StreamReaderLE;
|
typedef StreamReader<false> StreamReaderLE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// `dynamic` StreamReader. The byte order of the input data is specified in the
|
// `dynamic` StreamReader. The byte order of the input data is specified in the
|
||||||
// c'tor. This involves runtime branching and might be a little bit slower.
|
// c'tor. This involves runtime branching and might be a little bit slower.
|
||||||
typedef StreamReader<true,true> StreamReaderAny;
|
typedef StreamReader<true, true> StreamReaderAny;
|
||||||
|
|
||||||
} // end namespace Assimp
|
} // end namespace Assimp
|
||||||
|
|
||||||
|
|
|
@ -145,4 +145,21 @@ std::string DecimalToHexa( T toConvert ) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief translate RGBA to String
|
||||||
|
/// @param r aiColor.r
|
||||||
|
/// @param g aiColor.g
|
||||||
|
/// @param b aiColor.b
|
||||||
|
/// @param a aiColor.a
|
||||||
|
/// @param with_head #
|
||||||
|
/// @return The hexadecimal string, is empty in case of an error.
|
||||||
|
AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head) {
|
||||||
|
std::stringstream ss;
|
||||||
|
if (with_head) {
|
||||||
|
ss << "#";
|
||||||
|
}
|
||||||
|
ss << std::hex << (r << 24 | g << 16 | b << 8 | a);
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // INCLUDED_AI_STRINGUTILS_H
|
#endif // INCLUDED_AI_STRINGUTILS_H
|
||||||
|
|
|
@ -171,15 +171,26 @@ struct aiCamera
|
||||||
*/
|
*/
|
||||||
float mAspect;
|
float mAspect;
|
||||||
|
|
||||||
|
/** Half horizontal orthographic width, in scene units.
|
||||||
|
*
|
||||||
|
* The orthographic width specifies the half width of the
|
||||||
|
* orthographic view box. If non-zero the camera is
|
||||||
|
* orthographic and the mAspect should define to the
|
||||||
|
* ratio between the orthographic width and height
|
||||||
|
* and mHorizontalFOV should be set to 0.
|
||||||
|
* The default value is 0 (not orthographic).
|
||||||
|
*/
|
||||||
|
float mOrthographicWidth;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
aiCamera() AI_NO_EXCEPT
|
aiCamera() AI_NO_EXCEPT
|
||||||
: mUp (0.f,1.f,0.f)
|
: mUp (0.f,1.f,0.f)
|
||||||
, mLookAt (0.f,0.f,1.f)
|
, mLookAt (0.f,0.f,1.f)
|
||||||
, mHorizontalFOV (0.25f * (float)AI_MATH_PI)
|
, mHorizontalFOV (0.25f * (float)AI_MATH_PI)
|
||||||
, mClipPlaneNear (0.1f)
|
, mClipPlaneNear (0.1f)
|
||||||
, mClipPlaneFar (1000.f)
|
, mClipPlaneFar (1000.f)
|
||||||
, mAspect (0.f)
|
, mAspect (0.f)
|
||||||
|
, mOrthographicWidth (0.f)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/** @brief Get a *right-handed* camera matrix from me
|
/** @brief Get a *right-handed* camera matrix from me
|
||||||
|
|
|
@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -49,29 +47,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_METADATA_H_INC
|
#define AI_METADATA_H_INC
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
# pragma GCC system_header
|
#pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (_MSC_VER <= 1500)
|
#if defined(_MSC_VER) && (_MSC_VER <= 1500)
|
||||||
# include "Compiler/pstdint.h"
|
#include "Compiler/pstdint.h"
|
||||||
#else
|
#else
|
||||||
# include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Enum used to distinguish data types
|
* Enum used to distinguish data types
|
||||||
*/
|
*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
typedef enum aiMetadataType {
|
typedef enum aiMetadataType {
|
||||||
AI_BOOL = 0,
|
AI_BOOL = 0,
|
||||||
AI_INT32 = 1,
|
AI_INT32 = 1,
|
||||||
AI_UINT64 = 2,
|
AI_UINT64 = 2,
|
||||||
AI_FLOAT = 3,
|
AI_FLOAT = 3,
|
||||||
AI_DOUBLE = 4,
|
AI_DOUBLE = 4,
|
||||||
AI_AISTRING = 5,
|
AI_AISTRING = 5,
|
||||||
AI_AIVECTOR3D = 6,
|
AI_AIVECTOR3D = 6,
|
||||||
AI_META_MAX = 7,
|
AI_META_MAX = 7,
|
||||||
|
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
FORCE_32BIT = INT_MAX
|
FORCE_32BIT = INT_MAX
|
||||||
|
@ -84,10 +82,10 @@ typedef enum aiMetadataType {
|
||||||
*
|
*
|
||||||
* The type field uniquely identifies the underlying type of the data field
|
* The type field uniquely identifies the underlying type of the data field
|
||||||
*/
|
*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct aiMetadataEntry {
|
struct aiMetadataEntry {
|
||||||
aiMetadataType mType;
|
aiMetadataType mType;
|
||||||
void* mData;
|
void *mData;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -98,15 +96,29 @@ struct aiMetadataEntry {
|
||||||
/**
|
/**
|
||||||
* Helper functions to get the aiType enum entry for a type
|
* Helper functions to get the aiType enum entry for a type
|
||||||
*/
|
*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
|
||||||
inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
|
inline aiMetadataType GetAiType(bool) {
|
||||||
inline aiMetadataType GetAiType( int32_t ) { return AI_INT32; }
|
return AI_BOOL;
|
||||||
inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
|
}
|
||||||
inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
|
inline aiMetadataType GetAiType(int32_t) {
|
||||||
inline aiMetadataType GetAiType( double ) { return AI_DOUBLE; }
|
return AI_INT32;
|
||||||
inline aiMetadataType GetAiType( const aiString & ) { return AI_AISTRING; }
|
}
|
||||||
inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; }
|
inline aiMetadataType GetAiType(uint64_t) {
|
||||||
|
return AI_UINT64;
|
||||||
|
}
|
||||||
|
inline aiMetadataType GetAiType(float) {
|
||||||
|
return AI_FLOAT;
|
||||||
|
}
|
||||||
|
inline aiMetadataType GetAiType(double) {
|
||||||
|
return AI_DOUBLE;
|
||||||
|
}
|
||||||
|
inline aiMetadataType GetAiType(const aiString &) {
|
||||||
|
return AI_AISTRING;
|
||||||
|
}
|
||||||
|
inline aiMetadataType GetAiType(const aiVector3D &) {
|
||||||
|
return AI_AIVECTOR3D;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
@ -116,17 +128,17 @@ inline aiMetadataType GetAiType( const aiVector3D & ) { return AI_AIVECTOR3D; }
|
||||||
*
|
*
|
||||||
* Metadata is a key-value store using string keys and values.
|
* Metadata is a key-value store using string keys and values.
|
||||||
*/
|
*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct aiMetadata {
|
struct aiMetadata {
|
||||||
/** Length of the mKeys and mValues arrays, respectively */
|
/** Length of the mKeys and mValues arrays, respectively */
|
||||||
unsigned int mNumProperties;
|
unsigned int mNumProperties;
|
||||||
|
|
||||||
/** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
|
/** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
|
||||||
C_STRUCT aiString* mKeys;
|
C_STRUCT aiString *mKeys;
|
||||||
|
|
||||||
/** Arrays of values, may not be NULL. Entries in this array may be NULL if the
|
/** Arrays of values, may not be NULL. Entries in this array may be NULL if the
|
||||||
* corresponding property key has no assigned value. */
|
* corresponding property key has no assigned value. */
|
||||||
C_STRUCT aiMetadataEntry* mValues;
|
C_STRUCT aiMetadataEntry *mValues;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
@ -134,71 +146,62 @@ struct aiMetadata {
|
||||||
* @brief The default constructor, set all members to zero by default.
|
* @brief The default constructor, set all members to zero by default.
|
||||||
*/
|
*/
|
||||||
aiMetadata() AI_NO_EXCEPT
|
aiMetadata() AI_NO_EXCEPT
|
||||||
: mNumProperties(0)
|
: mNumProperties(0),
|
||||||
, mKeys(nullptr)
|
mKeys(nullptr),
|
||||||
, mValues(nullptr) {
|
mValues(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMetadata( const aiMetadata &rhs )
|
aiMetadata(const aiMetadata &rhs) :
|
||||||
: mNumProperties( rhs.mNumProperties )
|
mNumProperties(rhs.mNumProperties), mKeys(nullptr), mValues(nullptr) {
|
||||||
, mKeys( nullptr )
|
mKeys = new aiString[mNumProperties];
|
||||||
, mValues( nullptr ) {
|
for (size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i) {
|
||||||
mKeys = new aiString[ mNumProperties ];
|
mKeys[i] = rhs.mKeys[i];
|
||||||
for ( size_t i = 0; i < static_cast<size_t>( mNumProperties ); ++i ) {
|
|
||||||
mKeys[ i ] = rhs.mKeys[ i ];
|
|
||||||
}
|
}
|
||||||
mValues = new aiMetadataEntry[ mNumProperties ];
|
mValues = new aiMetadataEntry[mNumProperties];
|
||||||
for ( size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i ) {
|
for (size_t i = 0; i < static_cast<size_t>(mNumProperties); ++i) {
|
||||||
mValues[ i ].mType = rhs.mValues[ i ].mType;
|
mValues[i].mType = rhs.mValues[i].mType;
|
||||||
switch ( rhs.mValues[ i ].mType ) {
|
switch (rhs.mValues[i].mType) {
|
||||||
case AI_BOOL:
|
case AI_BOOL:
|
||||||
mValues[ i ].mData = new bool;
|
mValues[i].mData = new bool;
|
||||||
::memcpy( mValues[ i ].mData, rhs.mValues[ i ].mData, sizeof(bool) );
|
::memcpy(mValues[i].mData, rhs.mValues[i].mData, sizeof(bool));
|
||||||
break;
|
break;
|
||||||
case AI_INT32: {
|
case AI_INT32: {
|
||||||
int32_t v;
|
int32_t v;
|
||||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( int32_t ) );
|
::memcpy(&v, rhs.mValues[i].mData, sizeof(int32_t));
|
||||||
mValues[ i ].mData = new int32_t( v );
|
mValues[i].mData = new int32_t(v);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case AI_UINT64: {
|
case AI_UINT64: {
|
||||||
uint64_t v;
|
uint64_t v;
|
||||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( uint64_t ) );
|
::memcpy(&v, rhs.mValues[i].mData, sizeof(uint64_t));
|
||||||
mValues[ i ].mData = new uint64_t( v );
|
mValues[i].mData = new uint64_t(v);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case AI_FLOAT: {
|
case AI_FLOAT: {
|
||||||
float v;
|
float v;
|
||||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( float ) );
|
::memcpy(&v, rhs.mValues[i].mData, sizeof(float));
|
||||||
mValues[ i ].mData = new float( v );
|
mValues[i].mData = new float(v);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case AI_DOUBLE: {
|
case AI_DOUBLE: {
|
||||||
double v;
|
double v;
|
||||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( double ) );
|
::memcpy(&v, rhs.mValues[i].mData, sizeof(double));
|
||||||
mValues[ i ].mData = new double( v );
|
mValues[i].mData = new double(v);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case AI_AISTRING: {
|
case AI_AISTRING: {
|
||||||
aiString v;
|
aiString v;
|
||||||
rhs.Get<aiString>( mKeys[ i ], v );
|
rhs.Get<aiString>(mKeys[i], v);
|
||||||
mValues[ i ].mData = new aiString( v );
|
mValues[i].mData = new aiString(v);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
case AI_AIVECTOR3D: {
|
case AI_AIVECTOR3D: {
|
||||||
aiVector3D v;
|
aiVector3D v;
|
||||||
rhs.Get<aiVector3D>( mKeys[ i ], v );
|
rhs.Get<aiVector3D>(mKeys[i], v);
|
||||||
mValues[ i ].mData = new aiVector3D( v );
|
mValues[i].mData = new aiVector3D(v);
|
||||||
}
|
} break;
|
||||||
break;
|
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
case FORCE_32BIT:
|
case FORCE_32BIT:
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,33 +209,33 @@ struct aiMetadata {
|
||||||
* @brief The destructor.
|
* @brief The destructor.
|
||||||
*/
|
*/
|
||||||
~aiMetadata() {
|
~aiMetadata() {
|
||||||
delete [] mKeys;
|
delete[] mKeys;
|
||||||
mKeys = nullptr;
|
mKeys = nullptr;
|
||||||
if (mValues) {
|
if (mValues) {
|
||||||
// Delete each metadata entry
|
// Delete each metadata entry
|
||||||
for (unsigned i=0; i<mNumProperties; ++i) {
|
for (unsigned i = 0; i < mNumProperties; ++i) {
|
||||||
void* data = mValues[i].mData;
|
void *data = mValues[i].mData;
|
||||||
switch (mValues[i].mType) {
|
switch (mValues[i].mType) {
|
||||||
case AI_BOOL:
|
case AI_BOOL:
|
||||||
delete static_cast< bool* >( data );
|
delete static_cast<bool *>(data);
|
||||||
break;
|
break;
|
||||||
case AI_INT32:
|
case AI_INT32:
|
||||||
delete static_cast< int32_t* >( data );
|
delete static_cast<int32_t *>(data);
|
||||||
break;
|
break;
|
||||||
case AI_UINT64:
|
case AI_UINT64:
|
||||||
delete static_cast< uint64_t* >( data );
|
delete static_cast<uint64_t *>(data);
|
||||||
break;
|
break;
|
||||||
case AI_FLOAT:
|
case AI_FLOAT:
|
||||||
delete static_cast< float* >( data );
|
delete static_cast<float *>(data);
|
||||||
break;
|
break;
|
||||||
case AI_DOUBLE:
|
case AI_DOUBLE:
|
||||||
delete static_cast< double* >( data );
|
delete static_cast<double *>(data);
|
||||||
break;
|
break;
|
||||||
case AI_AISTRING:
|
case AI_AISTRING:
|
||||||
delete static_cast< aiString* >( data );
|
delete static_cast<aiString *>(data);
|
||||||
break;
|
break;
|
||||||
case AI_AIVECTOR3D:
|
case AI_AIVECTOR3D:
|
||||||
delete static_cast< aiVector3D* >( data );
|
delete static_cast<aiVector3D *>(data);
|
||||||
break;
|
break;
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
case FORCE_32BIT:
|
case FORCE_32BIT:
|
||||||
|
@ -243,7 +246,7 @@ struct aiMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the metadata array
|
// Delete the metadata array
|
||||||
delete [] mValues;
|
delete[] mValues;
|
||||||
mValues = nullptr;
|
mValues = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,16 +255,15 @@ struct aiMetadata {
|
||||||
* @brief Allocates property fields + keys.
|
* @brief Allocates property fields + keys.
|
||||||
* @param numProperties Number of requested properties.
|
* @param numProperties Number of requested properties.
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline aiMetadata *Alloc(unsigned int numProperties) {
|
||||||
aiMetadata *Alloc( unsigned int numProperties ) {
|
if (0 == numProperties) {
|
||||||
if ( 0 == numProperties ) {
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMetadata *data = new aiMetadata;
|
aiMetadata *data = new aiMetadata;
|
||||||
data->mNumProperties = numProperties;
|
data->mNumProperties = numProperties;
|
||||||
data->mKeys = new aiString[ data->mNumProperties ]();
|
data->mKeys = new aiString[data->mNumProperties]();
|
||||||
data->mValues = new aiMetadataEntry[ data->mNumProperties ]();
|
data->mValues = new aiMetadataEntry[data->mNumProperties]();
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -269,44 +271,40 @@ struct aiMetadata {
|
||||||
/**
|
/**
|
||||||
* @brief Deallocates property fields + keys.
|
* @brief Deallocates property fields + keys.
|
||||||
*/
|
*/
|
||||||
static inline
|
static inline void Dealloc(aiMetadata *metadata) {
|
||||||
void Dealloc( aiMetadata *metadata ) {
|
|
||||||
delete metadata;
|
delete metadata;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline
|
inline void Add(const std::string &key, const T &value) {
|
||||||
void Add(const std::string& key, const T& value) {
|
aiString *new_keys = new aiString[mNumProperties + 1];
|
||||||
aiString* new_keys = new aiString[mNumProperties + 1];
|
aiMetadataEntry *new_values = new aiMetadataEntry[mNumProperties + 1];
|
||||||
aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
|
|
||||||
|
|
||||||
for(unsigned int i = 0; i < mNumProperties; ++i)
|
for (unsigned int i = 0; i < mNumProperties; ++i) {
|
||||||
{
|
new_keys[i] = mKeys[i];
|
||||||
new_keys[i] = mKeys[i];
|
new_values[i] = mValues[i];
|
||||||
new_values[i] = mValues[i];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
delete[] mKeys;
|
delete[] mKeys;
|
||||||
delete[] mValues;
|
delete[] mValues;
|
||||||
|
|
||||||
mKeys = new_keys;
|
mKeys = new_keys;
|
||||||
mValues = new_values;
|
mValues = new_values;
|
||||||
|
|
||||||
mNumProperties++;
|
mNumProperties++;
|
||||||
|
|
||||||
Set(mNumProperties - 1, key, value);
|
Set(mNumProperties - 1, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline
|
inline bool Set(unsigned index, const std::string &key, const T &value) {
|
||||||
bool Set( unsigned index, const std::string& key, const T& value ) {
|
|
||||||
// In range assertion
|
// In range assertion
|
||||||
if ( index >= mNumProperties ) {
|
if (index >= mNumProperties) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that we have a valid key.
|
// Ensure that we have a valid key.
|
||||||
if ( key.empty() ) {
|
if (key.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,73 +319,86 @@ struct aiMetadata {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline
|
inline bool Set( const std::string &key, const T &value ) {
|
||||||
bool Get( unsigned index, T& value ) const {
|
if (key.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
for (unsigned int i = 0; i < mNumProperties; ++i) {
|
||||||
|
if (key == mKeys[i].C_Str()) {
|
||||||
|
Set(i, key, value);
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline bool Get(unsigned index, T &value) const {
|
||||||
// In range assertion
|
// In range assertion
|
||||||
if ( index >= mNumProperties ) {
|
if (index >= mNumProperties) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return false if the output data type does
|
// Return false if the output data type does
|
||||||
// not match the found value's data type
|
// not match the found value's data type
|
||||||
if ( GetAiType( value ) != mValues[ index ].mType ) {
|
if (GetAiType(value) != mValues[index].mType) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, output the found value and
|
// Otherwise, output the found value and
|
||||||
// return true
|
// return true
|
||||||
value = *static_cast<T*>(mValues[index].mData);
|
value = *static_cast<T *>(mValues[index].mData);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline
|
inline bool Get(const aiString &key, T &value) const {
|
||||||
bool Get( const aiString& key, T& value ) const {
|
|
||||||
// Search for the given key
|
// Search for the given key
|
||||||
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
for (unsigned int i = 0; i < mNumProperties; ++i) {
|
||||||
if ( mKeys[ i ] == key ) {
|
if (mKeys[i] == key) {
|
||||||
return Get( i, value );
|
return Get(i, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline
|
inline bool Get(const std::string &key, T &value) const {
|
||||||
bool Get( const std::string& key, T& value ) const {
|
|
||||||
return Get(aiString(key), value);
|
return Get(aiString(key), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return metadata entry for analyzing it by user.
|
/// Return metadata entry for analyzing it by user.
|
||||||
/// \param [in] pIndex - index of the entry.
|
/// \param [in] pIndex - index of the entry.
|
||||||
/// \param [out] pKey - pointer to the key value.
|
/// \param [out] pKey - pointer to the key value.
|
||||||
/// \param [out] pEntry - pointer to the entry: type and value.
|
/// \param [out] pEntry - pointer to the entry: type and value.
|
||||||
/// \return false - if pIndex is out of range, else - true.
|
/// \return false - if pIndex is out of range, else - true.
|
||||||
inline
|
inline bool Get(size_t index, const aiString *&key, const aiMetadataEntry *&entry) const {
|
||||||
bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) const {
|
if (index >= mNumProperties) {
|
||||||
if ( index >= mNumProperties ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
key = &mKeys[index];
|
key = &mKeys[index];
|
||||||
entry = &mValues[index];
|
entry = &mValues[index];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether there is a metadata entry for the given key.
|
/// Check whether there is a metadata entry for the given key.
|
||||||
/// \param [in] Key - the key value value to check for.
|
/// \param [in] Key - the key value value to check for.
|
||||||
inline
|
inline bool HasKey(const char *key) {
|
||||||
bool HasKey(const char* key) {
|
if (nullptr == key) {
|
||||||
if ( nullptr == key ) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for the given key
|
// Search for the given key
|
||||||
for (unsigned int i = 0; i < mNumProperties; ++i) {
|
for (unsigned int i = 0; i < mNumProperties; ++i) {
|
||||||
if ( 0 == strncmp(mKeys[i].C_Str(), key, mKeys[i].length ) ) {
|
if (0 == strncmp(mKeys[i].C_Str(), key, mKeys[i].length)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -395,7 +406,6 @@ struct aiMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AI_METADATA_H_INC
|
#endif // AI_METADATA_H_INC
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName=Open Asset Import Library - SDK
|
AppName=Open Asset Import Library - SDK
|
||||||
AppVerName=Open Asset Import Library - SDK (v5.0.0)
|
AppVerName=Open Asset Import Library - SDK (v5.0.1)
|
||||||
DefaultDirName={pf}\Assimp
|
DefaultDirName={pf}\Assimp
|
||||||
DefaultGroupName=Assimp
|
DefaultGroupName=Assimp
|
||||||
UninstallDisplayIcon={app}\bin\x64\assimp.exe
|
UninstallDisplayIcon={app}\bin\x64\assimp.exe
|
||||||
|
@ -12,9 +12,9 @@ SetupIconFile=..\..\tools\shared\assimp_tools_icon.ico
|
||||||
WizardImageFile=compiler:WizModernImage-IS.BMP
|
WizardImageFile=compiler:WizModernImage-IS.BMP
|
||||||
WizardSmallImageFile=compiler:WizModernSmallImage-IS.BMP
|
WizardSmallImageFile=compiler:WizModernSmallImage-IS.BMP
|
||||||
LicenseFile=License.rtf
|
LicenseFile=License.rtf
|
||||||
OutputBaseFileName=assimp-sdk-5.0.0-setup
|
OutputBaseFileName=assimp-sdk-5.0.1-setup
|
||||||
VersionInfoVersion=5.0.0.0
|
VersionInfoVersion=5.0.1.0
|
||||||
VersionInfoTextVersion=5.0.0
|
VersionInfoTextVersion=5.0.1
|
||||||
VersionInfoCompany=Assimp Development Team
|
VersionInfoCompany=Assimp Development Team
|
||||||
ArchitecturesInstallIn64BitMode=x64
|
ArchitecturesInstallIn64BitMode=x64
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
AppName=Open Asset Import Library - SDK
|
AppName=Open Asset Import Library - SDK
|
||||||
AppVerName=Open Asset Import Library - SDK (v5.0.0)
|
AppVerName=Open Asset Import Library - SDK (v5.0.1)
|
||||||
DefaultDirName={pf}\Assimp
|
DefaultDirName={pf}\Assimp
|
||||||
DefaultGroupName=Assimp
|
DefaultGroupName=Assimp
|
||||||
UninstallDisplayIcon={app}\bin\x86\assimp.exe
|
UninstallDisplayIcon={app}\bin\x86\assimp.exe
|
||||||
|
@ -12,9 +12,9 @@ SetupIconFile=..\..\tools\shared\assimp_tools_icon.ico
|
||||||
WizardImageFile=compiler:WizModernImage-IS.BMP
|
WizardImageFile=compiler:WizModernImage-IS.BMP
|
||||||
WizardSmallImageFile=compiler:WizModernSmallImage-IS.BMP
|
WizardSmallImageFile=compiler:WizModernSmallImage-IS.BMP
|
||||||
LicenseFile=License.rtf
|
LicenseFile=License.rtf
|
||||||
OutputBaseFileName=assimp-sdk-5.0.0-setup
|
OutputBaseFileName=assimp-sdk-5.0.1-setup
|
||||||
VersionInfoVersion=4.1.0.0
|
VersionInfoVersion=5.0.1.0
|
||||||
VersionInfoTextVersion=4.1.0
|
VersionInfoTextVersion=5.0.1
|
||||||
VersionInfoCompany=Assimp Development Team
|
VersionInfoCompany=Assimp Development Team
|
||||||
;ArchitecturesInstallIn64BitMode=x64
|
;ArchitecturesInstallIn64BitMode=x64
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
SET(SAMPLE_PROJECT_NAME assimp_simpleogl)
|
||||||
|
|
||||||
FIND_PACKAGE(OpenGL)
|
FIND_PACKAGE(OpenGL)
|
||||||
FIND_PACKAGE(GLUT)
|
FIND_PACKAGE(GLUT)
|
||||||
IF ( MSVC )
|
IF ( MSVC )
|
||||||
|
@ -16,6 +18,10 @@ IF ( NOT GLUT_FOUND )
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
||||||
|
# Used for usage and error messages in the program.
|
||||||
|
ADD_COMPILE_DEFINITIONS(ASSIMP_VERSION="${ASSIMP_VERSION}")
|
||||||
|
ADD_COMPILE_DEFINITIONS(PROJECT_NAME="${SAMPLE_PROJECT_NAME}")
|
||||||
|
|
||||||
if ( MSVC )
|
if ( MSVC )
|
||||||
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
|
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
|
||||||
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
|
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
|
||||||
|
@ -34,17 +40,17 @@ LINK_DIRECTORIES(
|
||||||
${Assimp_BINARY_DIR}/lib
|
${Assimp_BINARY_DIR}/lib
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE( assimp_simpleogl
|
ADD_EXECUTABLE( ${SAMPLE_PROJECT_NAME}
|
||||||
Sample_SimpleOpenGL.c
|
Sample_SimpleOpenGL.c
|
||||||
)
|
)
|
||||||
|
|
||||||
SET_PROPERTY(TARGET assimp_simpleogl PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
SET_PROPERTY(TARGET ${SAMPLE_PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||||
|
|
||||||
TARGET_LINK_LIBRARIES( assimp_simpleogl assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
|
TARGET_LINK_LIBRARIES( ${SAMPLE_PROJECT_NAME} assimp ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES} ${M_LIB} )
|
||||||
SET_TARGET_PROPERTIES( assimp_simpleogl PROPERTIES
|
SET_TARGET_PROPERTIES( ${SAMPLE_PROJECT_NAME} PROPERTIES
|
||||||
OUTPUT_NAME assimp_simpleogl
|
OUTPUT_NAME ${SAMPLE_PROJECT_NAME}
|
||||||
)
|
)
|
||||||
|
|
||||||
INSTALL( TARGETS assimp_simpleogl
|
INSTALL( TARGETS ${SAMPLE_PROJECT_NAME}
|
||||||
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
|
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
|
||||||
)
|
)
|
||||||
|
|
|
@ -15,9 +15,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <glut.h>
|
#include <freeglut.h>
|
||||||
#else
|
#else
|
||||||
#include <GL/glut.h>
|
#include <GL/freeglut.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* assimp include files. These three are usually needed. */
|
/* assimp include files. These three are usually needed. */
|
||||||
|
@ -25,6 +25,39 @@
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
||||||
|
#define COMMAND_USAGE "--usage"
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------- */
|
||||||
|
inline static void print_run_command(const char* command_name) {
|
||||||
|
printf("Run '%s %s' for more information.\n",
|
||||||
|
PROJECT_NAME, command_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------- */
|
||||||
|
inline static void print_error(const char* msg) {
|
||||||
|
printf("ERROR: %s\n", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_LINE "\n"
|
||||||
|
#define DOUBLE_NEW_LINE NEW_LINE NEW_LINE
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------------- */
|
||||||
|
inline static void print_usage() {
|
||||||
|
static const char* usage_format =
|
||||||
|
"Usage: "
|
||||||
|
PROJECT_NAME
|
||||||
|
" <file>" DOUBLE_NEW_LINE
|
||||||
|
"where:" DOUBLE_NEW_LINE
|
||||||
|
" %-10s %s" DOUBLE_NEW_LINE
|
||||||
|
"options:" DOUBLE_NEW_LINE
|
||||||
|
" %-10s %s" DOUBLE_NEW_LINE;
|
||||||
|
printf(usage_format,
|
||||||
|
// where
|
||||||
|
"file", "The input model file to load.",
|
||||||
|
// options
|
||||||
|
COMMAND_USAGE, "Display usage.");
|
||||||
|
}
|
||||||
|
|
||||||
/* the global Assimp scene object */
|
/* the global Assimp scene object */
|
||||||
const C_STRUCT aiScene* scene = NULL;
|
const C_STRUCT aiScene* scene = NULL;
|
||||||
GLuint scene_list = 0;
|
GLuint scene_list = 0;
|
||||||
|
@ -245,7 +278,7 @@ void do_motion (void)
|
||||||
static int frames = 0;
|
static int frames = 0;
|
||||||
|
|
||||||
int time = glutGet(GLUT_ELAPSED_TIME);
|
int time = glutGet(GLUT_ELAPSED_TIME);
|
||||||
angle += (time-prev_time)*0.01;
|
angle += static_cast<float>((time-prev_time)*0.01);
|
||||||
prev_time = time;
|
prev_time = time;
|
||||||
|
|
||||||
frames += 1;
|
frames += 1;
|
||||||
|
@ -324,12 +357,42 @@ int loadasset (const char* path)
|
||||||
/* ---------------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------------- */
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
const char* model_file = NULL;
|
||||||
C_STRUCT aiLogStream stream;
|
C_STRUCT aiLogStream stream;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
print_error("No input model file specifed.");
|
||||||
|
print_run_command(COMMAND_USAGE);
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find and execute available commands entered by the user.
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
if (!strncmp(argv[i], COMMAND_USAGE, strlen(COMMAND_USAGE))) {
|
||||||
|
print_usage();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check and validate the specified model file extension.
|
||||||
|
model_file = argv[1];
|
||||||
|
const char* extension = strchr(model_file, '.');
|
||||||
|
if (!extension) {
|
||||||
|
print_error("Please provide a file with a valid extension.");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AI_FALSE == aiIsExtensionSupported(extension)) {
|
||||||
|
print_error("The specified model file extension is currently "
|
||||||
|
"unsupported in Assimp " ASSIMP_VERSION ".");
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
glutInitWindowSize(900,600);
|
glutInitWindowSize(900,600);
|
||||||
glutInitWindowPosition(100,100);
|
glutInitWindowPosition(100,100);
|
||||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||||
glutInit(&argc, argv);
|
glutInit(&argc, argv);
|
||||||
|
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
||||||
|
|
||||||
glutCreateWindow("Assimp - Very simple OpenGL sample");
|
glutCreateWindow("Assimp - Very simple OpenGL sample");
|
||||||
glutDisplayFunc(display);
|
glutDisplayFunc(display);
|
||||||
|
@ -346,14 +409,11 @@ int main(int argc, char **argv)
|
||||||
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
|
stream = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"assimp_log.txt");
|
||||||
aiAttachLogStream(&stream);
|
aiAttachLogStream(&stream);
|
||||||
|
|
||||||
/* the model name can be specified on the command line. If none
|
// Load the model file.
|
||||||
is specified, we try to locate one of the more expressive test
|
if(0 != loadasset(model_file)) {
|
||||||
models from the repository (/models-nonbsd may be missing in
|
print_error("Failed to load model. Please ensure that the specified file exists.");
|
||||||
some distributions so we need a fallback from /models!). */
|
aiDetachAllLogStreams();
|
||||||
if( 0 != loadasset( argc >= 2 ? argv[1] : "../../test/models-nonbsd/X/dwarf.x")) {
|
return EXIT_FAILURE;
|
||||||
if( argc != 1 || (0 != loadasset( "../../../../test/models-nonbsd/X/dwarf.x") && 0 != loadasset( "../../test/models/X/Testwuson.X"))) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glClearColor(0.1f,0.1f,0.1f,1.f);
|
glClearColor(0.1f,0.1f,0.1f,1.f);
|
||||||
|
@ -384,5 +444,5 @@ int main(int argc, char **argv)
|
||||||
again. This will definitely release the last resources allocated
|
again. This will definitely release the last resources allocated
|
||||||
by Assimp.*/
|
by Assimp.*/
|
||||||
aiDetachAllLogStreams();
|
aiDetachAllLogStreams();
|
||||||
return 0;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,40 +31,40 @@ struct Texture {
|
||||||
|
|
||||||
class Mesh {
|
class Mesh {
|
||||||
public:
|
public:
|
||||||
std::vector<VERTEX> vertices;
|
std::vector<VERTEX> vertices_;
|
||||||
std::vector<UINT> indices;
|
std::vector<UINT> indices_;
|
||||||
std::vector<Texture> textures;
|
std::vector<Texture> textures_;
|
||||||
ID3D11Device *dev;
|
ID3D11Device *dev_;
|
||||||
|
|
||||||
Mesh(ID3D11Device *dev, const std::vector<VERTEX>& vertices, const std::vector<UINT>& indices, const std::vector<Texture>& textures) :
|
Mesh(ID3D11Device *dev, const std::vector<VERTEX>& vertices, const std::vector<UINT>& indices, const std::vector<Texture>& textures) :
|
||||||
vertices(vertices),
|
vertices_(vertices),
|
||||||
indices(indices),
|
indices_(indices),
|
||||||
textures(textures),
|
textures_(textures),
|
||||||
dev(dev),
|
dev_(dev),
|
||||||
VertexBuffer(nullptr),
|
VertexBuffer_(nullptr),
|
||||||
IndexBuffer(nullptr) {
|
IndexBuffer_(nullptr) {
|
||||||
this->setupMesh(this->dev);
|
this->setupMesh(this->dev_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(ID3D11DeviceContext *devcon) {
|
void Draw(ID3D11DeviceContext *devcon) {
|
||||||
UINT stride = sizeof(VERTEX);
|
UINT stride = sizeof(VERTEX);
|
||||||
UINT offset = 0;
|
UINT offset = 0;
|
||||||
|
|
||||||
devcon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
|
devcon->IASetVertexBuffers(0, 1, &VertexBuffer_, &stride, &offset);
|
||||||
devcon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
|
devcon->IASetIndexBuffer(IndexBuffer_, DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
|
||||||
devcon->PSSetShaderResources(0, 1, &textures[0].texture);
|
devcon->PSSetShaderResources(0, 1, &textures_[0].texture);
|
||||||
|
|
||||||
devcon->DrawIndexed(static_cast<UINT>(indices.size()), 0, 0);
|
devcon->DrawIndexed(static_cast<UINT>(indices_.size()), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
SafeRelease(VertexBuffer);
|
SafeRelease(VertexBuffer_);
|
||||||
SafeRelease(IndexBuffer);
|
SafeRelease(IndexBuffer_);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
// Render data
|
// Render data
|
||||||
ID3D11Buffer *VertexBuffer, *IndexBuffer;
|
ID3D11Buffer *VertexBuffer_, *IndexBuffer_;
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
// Initializes all the buffer objects/arrays
|
// Initializes all the buffer objects/arrays
|
||||||
|
@ -73,15 +73,15 @@ private:
|
||||||
|
|
||||||
D3D11_BUFFER_DESC vbd;
|
D3D11_BUFFER_DESC vbd;
|
||||||
vbd.Usage = D3D11_USAGE_IMMUTABLE;
|
vbd.Usage = D3D11_USAGE_IMMUTABLE;
|
||||||
vbd.ByteWidth = static_cast<UINT>(sizeof(VERTEX) * vertices.size());
|
vbd.ByteWidth = static_cast<UINT>(sizeof(VERTEX) * vertices_.size());
|
||||||
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
vbd.CPUAccessFlags = 0;
|
vbd.CPUAccessFlags = 0;
|
||||||
vbd.MiscFlags = 0;
|
vbd.MiscFlags = 0;
|
||||||
|
|
||||||
D3D11_SUBRESOURCE_DATA initData;
|
D3D11_SUBRESOURCE_DATA initData;
|
||||||
initData.pSysMem = &vertices[0];
|
initData.pSysMem = &vertices_[0];
|
||||||
|
|
||||||
hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer);
|
hr = dev->CreateBuffer(&vbd, &initData, &VertexBuffer_);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
Close();
|
Close();
|
||||||
throw std::runtime_error("Failed to create vertex buffer.");
|
throw std::runtime_error("Failed to create vertex buffer.");
|
||||||
|
@ -89,14 +89,14 @@ private:
|
||||||
|
|
||||||
D3D11_BUFFER_DESC ibd;
|
D3D11_BUFFER_DESC ibd;
|
||||||
ibd.Usage = D3D11_USAGE_IMMUTABLE;
|
ibd.Usage = D3D11_USAGE_IMMUTABLE;
|
||||||
ibd.ByteWidth = static_cast<UINT>(sizeof(UINT) * indices.size());
|
ibd.ByteWidth = static_cast<UINT>(sizeof(UINT) * indices_.size());
|
||||||
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
ibd.CPUAccessFlags = 0;
|
ibd.CPUAccessFlags = 0;
|
||||||
ibd.MiscFlags = 0;
|
ibd.MiscFlags = 0;
|
||||||
|
|
||||||
initData.pSysMem = &indices[0];
|
initData.pSysMem = &indices_[0];
|
||||||
|
|
||||||
hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer);
|
hr = dev->CreateBuffer(&ibd, &initData, &IndexBuffer_);
|
||||||
if (FAILED(hr)) {
|
if (FAILED(hr)) {
|
||||||
Close();
|
Close();
|
||||||
throw std::runtime_error("Failed to create index buffer.");
|
throw std::runtime_error("Failed to create index buffer.");
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
#include "ModelLoader.h"
|
#include "ModelLoader.h"
|
||||||
|
|
||||||
ModelLoader::ModelLoader() :
|
ModelLoader::ModelLoader() :
|
||||||
dev(nullptr),
|
dev_(nullptr),
|
||||||
devcon(nullptr),
|
devcon_(nullptr),
|
||||||
meshes(),
|
meshes_(),
|
||||||
directory(),
|
directory_(),
|
||||||
textures_loaded(),
|
textures_loaded_(),
|
||||||
hwnd(nullptr) {
|
hwnd_(nullptr) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,14 @@ bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devc
|
||||||
aiProcess_Triangulate |
|
aiProcess_Triangulate |
|
||||||
aiProcess_ConvertToLeftHanded);
|
aiProcess_ConvertToLeftHanded);
|
||||||
|
|
||||||
if (pScene == NULL)
|
if (pScene == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
this->directory = filename.substr(0, filename.find_last_of("/\\"));
|
this->directory_ = filename.substr(0, filename.find_last_of("/\\"));
|
||||||
|
|
||||||
this->dev = dev;
|
this->dev_ = dev;
|
||||||
this->devcon = devcon;
|
this->devcon_ = devcon;
|
||||||
this->hwnd = hwnd;
|
this->hwnd_ = hwnd;
|
||||||
|
|
||||||
processNode(pScene->mRootNode, pScene);
|
processNode(pScene->mRootNode, pScene);
|
||||||
|
|
||||||
|
@ -37,8 +37,8 @@ bool ModelLoader::Load(HWND hwnd, ID3D11Device * dev, ID3D11DeviceContext * devc
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
|
void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
|
||||||
for (int i = 0; i < meshes.size(); ++i ) {
|
for (size_t i = 0; i < meshes_.size(); ++i ) {
|
||||||
meshes[i].Draw(devcon);
|
meshes_[i].Draw(devcon);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
|
||||||
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mesh(dev, vertices, indices, textures);
|
return Mesh(dev_, vertices, indices, textures);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, std::string typeName, const aiScene * scene) {
|
std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextureType type, std::string typeName, const aiScene * scene) {
|
||||||
|
@ -98,9 +98,9 @@ std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextu
|
||||||
mat->GetTexture(type, i, &str);
|
mat->GetTexture(type, i, &str);
|
||||||
// Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
|
// Check if texture was loaded before and if so, continue to next iteration: skip loading a new texture
|
||||||
bool skip = false;
|
bool skip = false;
|
||||||
for (UINT j = 0; j < textures_loaded.size(); j++) {
|
for (UINT j = 0; j < textures_loaded_.size(); j++) {
|
||||||
if (std::strcmp(textures_loaded[j].path.c_str(), str.C_Str()) == 0) {
|
if (std::strcmp(textures_loaded_[j].path.c_str(), str.C_Str()) == 0) {
|
||||||
textures.push_back(textures_loaded[j]);
|
textures.push_back(textures_loaded_[j]);
|
||||||
skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)
|
skip = true; // A texture with the same filepath has already been loaded, continue to next one. (optimization)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -113,34 +113,34 @@ std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextu
|
||||||
texture.texture = getTextureFromModel(scene, textureindex);
|
texture.texture = getTextureFromModel(scene, textureindex);
|
||||||
} else {
|
} else {
|
||||||
std::string filename = std::string(str.C_Str());
|
std::string filename = std::string(str.C_Str());
|
||||||
filename = directory + '/' + filename;
|
filename = directory_ + '/' + filename;
|
||||||
std::wstring filenamews = std::wstring(filename.begin(), filename.end());
|
std::wstring filenamews = std::wstring(filename.begin(), filename.end());
|
||||||
hr = CreateWICTextureFromFile(dev, devcon, filenamews.c_str(), nullptr, &texture.texture);
|
hr = CreateWICTextureFromFile(dev_, devcon_, filenamews.c_str(), nullptr, &texture.texture);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
MessageBox(hwnd, "Texture couldn't be loaded", "Error!", MB_ICONERROR | MB_OK);
|
MessageBox(hwnd_, "Texture couldn't be loaded", "Error!", MB_ICONERROR | MB_OK);
|
||||||
}
|
}
|
||||||
texture.type = typeName;
|
texture.type = typeName;
|
||||||
texture.path = str.C_Str();
|
texture.path = str.C_Str();
|
||||||
textures.push_back(texture);
|
textures.push_back(texture);
|
||||||
this->textures_loaded.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
|
this->textures_loaded_.push_back(texture); // Store it as texture loaded for entire model, to ensure we won't unnecesery load duplicate textures.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return textures;
|
return textures;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelLoader::Close() {
|
void ModelLoader::Close() {
|
||||||
for (auto& t : textures_loaded)
|
for (auto& t : textures_loaded_)
|
||||||
t.Release();
|
t.Release();
|
||||||
|
|
||||||
for (int i = 0; i < meshes.size(); i++) {
|
for (size_t i = 0; i < meshes_.size(); i++) {
|
||||||
meshes[i].Close();
|
meshes_[i].Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
|
void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
|
||||||
for (UINT i = 0; i < node->mNumMeshes; i++) {
|
for (UINT i = 0; i < node->mNumMeshes; i++) {
|
||||||
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
|
||||||
meshes.push_back(this->processMesh(mesh, scene));
|
meshes_.push_back(this->processMesh(mesh, scene));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (UINT i = 0; i < node->mNumChildren; i++) {
|
for (UINT i = 0; i < node->mNumChildren; i++) {
|
||||||
|
@ -179,9 +179,9 @@ ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scen
|
||||||
|
|
||||||
int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth);
|
int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth);
|
||||||
|
|
||||||
hr = CreateWICTextureFromMemory(dev, devcon, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture);
|
hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
MessageBox(hwnd, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);
|
MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,12 @@ public:
|
||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
private:
|
private:
|
||||||
ID3D11Device *dev;
|
ID3D11Device *dev_;
|
||||||
ID3D11DeviceContext *devcon;
|
ID3D11DeviceContext *devcon_;
|
||||||
std::vector<Mesh> meshes;
|
std::vector<Mesh> meshes_;
|
||||||
std::string directory;
|
std::string directory_;
|
||||||
std::vector<Texture> textures_loaded;
|
std::vector<Texture> textures_loaded_;
|
||||||
HWND hwnd;
|
HWND hwnd_;
|
||||||
|
|
||||||
void processNode(aiNode* node, const aiScene* scene);
|
void processNode(aiNode* node, const aiScene* scene);
|
||||||
Mesh processMesh(aiMesh* mesh, const aiScene* scene);
|
Mesh processMesh(aiMesh* mesh, const aiScene* scene);
|
||||||
|
|
|
@ -56,7 +56,7 @@ const char g_szClassName[] = "directxWindowClass";
|
||||||
static std::string g_ModelPath;
|
static std::string g_ModelPath;
|
||||||
|
|
||||||
UINT width, height;
|
UINT width, height;
|
||||||
HWND hwnd = nullptr;
|
HWND g_hwnd = nullptr;
|
||||||
|
|
||||||
// ------------------------------------------------------------
|
// ------------------------------------------------------------
|
||||||
// DirectX Variables
|
// DirectX Variables
|
||||||
|
@ -120,13 +120,13 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/,
|
||||||
LPWSTR lpCmdLine, int nCmdShow)
|
LPWSTR /*lpCmdLine*/, int nCmdShow)
|
||||||
{
|
{
|
||||||
int argc;
|
int argc;
|
||||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||||
if (!argv) {
|
if (!argv) {
|
||||||
MessageBox(NULL,
|
MessageBox(nullptr,
|
||||||
TEXT("An error occured while reading command line arguments."),
|
TEXT("An error occured while reading command line arguments."),
|
||||||
TEXT("Error!"),
|
TEXT("Error!"),
|
||||||
MB_ICONERROR | MB_OK);
|
MB_ICONERROR | MB_OK);
|
||||||
|
@ -143,7 +143,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
|
|
||||||
// Ensure that a model file has been specified.
|
// Ensure that a model file has been specified.
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
MessageBox(NULL,
|
MessageBox(nullptr,
|
||||||
TEXT("No model file specified. The program will now close."),
|
TEXT("No model file specified. The program will now close."),
|
||||||
TEXT("Error!"),
|
TEXT("Error!"),
|
||||||
MB_ICONERROR | MB_OK);
|
MB_ICONERROR | MB_OK);
|
||||||
|
@ -165,16 +165,16 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
wc.cbClsExtra = 0;
|
wc.cbClsExtra = 0;
|
||||||
wc.cbWndExtra = 0;
|
wc.cbWndExtra = 0;
|
||||||
wc.hInstance = hInstance;
|
wc.hInstance = hInstance;
|
||||||
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||||
wc.hbrBackground = NULL;
|
wc.hbrBackground = nullptr;
|
||||||
wc.lpszMenuName = NULL;
|
wc.lpszMenuName = nullptr;
|
||||||
wc.lpszClassName = g_szClassName;
|
wc.lpszClassName = g_szClassName;
|
||||||
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
|
||||||
|
|
||||||
if (!RegisterClassEx(&wc))
|
if (!RegisterClassEx(&wc))
|
||||||
{
|
{
|
||||||
MessageBox(NULL, "Window Registration Failed!", "Error!",
|
MessageBox(nullptr, "Window Registration Failed!", "Error!",
|
||||||
MB_ICONEXCLAMATION | MB_OK);
|
MB_ICONEXCLAMATION | MB_OK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -182,35 +182,35 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
RECT wr = { 0,0, SCREEN_WIDTH, SCREEN_HEIGHT };
|
RECT wr = { 0,0, SCREEN_WIDTH, SCREEN_HEIGHT };
|
||||||
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
|
AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, FALSE);
|
||||||
|
|
||||||
hwnd = CreateWindowEx(
|
g_hwnd = CreateWindowEx(
|
||||||
WS_EX_CLIENTEDGE,
|
WS_EX_CLIENTEDGE,
|
||||||
g_szClassName,
|
g_szClassName,
|
||||||
" Simple Textured Directx11 Sample ",
|
" Simple Textured Directx11 Sample ",
|
||||||
WS_OVERLAPPEDWINDOW,
|
WS_OVERLAPPEDWINDOW,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,
|
CW_USEDEFAULT, CW_USEDEFAULT, wr.right - wr.left, wr.bottom - wr.top,
|
||||||
NULL, NULL, hInstance, NULL
|
nullptr, nullptr, hInstance, nullptr
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hwnd == NULL)
|
if (g_hwnd == nullptr)
|
||||||
{
|
{
|
||||||
MessageBox(NULL, "Window Creation Failed!", "Error!",
|
MessageBox(nullptr, "Window Creation Failed!", "Error!",
|
||||||
MB_ICONEXCLAMATION | MB_OK);
|
MB_ICONEXCLAMATION | MB_OK);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowWindow(hwnd, nCmdShow);
|
ShowWindow(g_hwnd, nCmdShow);
|
||||||
UpdateWindow(hwnd);
|
UpdateWindow(g_hwnd);
|
||||||
|
|
||||||
width = wr.right - wr.left;
|
width = wr.right - wr.left;
|
||||||
height = wr.bottom - wr.top;
|
height = wr.bottom - wr.top;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
InitD3D(hInstance, hwnd);
|
InitD3D(hInstance, g_hwnd);
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
|
@ -225,17 +225,17 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
CleanD3D();
|
CleanD3D();
|
||||||
return static_cast<int>(msg.wParam);
|
return static_cast<int>(msg.wParam);
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
MessageBox(hwnd, e.what(), TEXT("Error!"), MB_ICONERROR | MB_OK);
|
MessageBox(g_hwnd, e.what(), TEXT("Error!"), MB_ICONERROR | MB_OK);
|
||||||
CleanD3D();
|
CleanD3D();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
MessageBox(hwnd, TEXT("Caught an unknown exception."), TEXT("Error!"), MB_ICONERROR | MB_OK);
|
MessageBox(g_hwnd, TEXT("Caught an unknown exception."), TEXT("Error!"), MB_ICONERROR | MB_OK);
|
||||||
CleanD3D();
|
CleanD3D();
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
void InitD3D(HINSTANCE /*hinstance*/, HWND hWnd)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
|
@ -362,7 +362,7 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
|
// Note this tutorial doesn't handle full-screen swapchains so we block the ALT+ENTER shortcut
|
||||||
dxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER);
|
dxgiFactory->MakeWindowAssociation(g_hwnd, DXGI_MWA_NO_ALT_ENTER);
|
||||||
|
|
||||||
dxgiFactory->Release();
|
dxgiFactory->Release();
|
||||||
|
|
||||||
|
@ -372,7 +372,7 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
||||||
ID3D11Texture2D *pBackBuffer;
|
ID3D11Texture2D *pBackBuffer;
|
||||||
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
|
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
|
||||||
|
|
||||||
dev->CreateRenderTargetView(pBackBuffer, NULL, &backbuffer);
|
dev->CreateRenderTargetView(pBackBuffer, nullptr, &backbuffer);
|
||||||
pBackBuffer->Release();
|
pBackBuffer->Release();
|
||||||
|
|
||||||
D3D11_TEXTURE2D_DESC descDepth;
|
D3D11_TEXTURE2D_DESC descDepth;
|
||||||
|
@ -440,7 +440,7 @@ void InitD3D(HINSTANCE hinstance, HWND hWnd)
|
||||||
void CleanD3D(void)
|
void CleanD3D(void)
|
||||||
{
|
{
|
||||||
if (swapchain)
|
if (swapchain)
|
||||||
swapchain->SetFullscreenState(FALSE, NULL);
|
swapchain->SetFullscreenState(FALSE, nullptr);
|
||||||
|
|
||||||
if (ourModel) {
|
if (ourModel) {
|
||||||
ourModel->Close();
|
ourModel->Close();
|
||||||
|
@ -513,8 +513,8 @@ void InitPipeline()
|
||||||
if(FAILED(CompileShaderFromFile(SHADER_PATH PIXEL_SHADER_FILE, 0, "main", "ps_4_0", &PS)))
|
if(FAILED(CompileShaderFromFile(SHADER_PATH PIXEL_SHADER_FILE, 0, "main", "ps_4_0", &PS)))
|
||||||
Throwanerror(UTFConverter(L"Failed to compile shader from file " PIXEL_SHADER_FILE).c_str());
|
Throwanerror(UTFConverter(L"Failed to compile shader from file " PIXEL_SHADER_FILE).c_str());
|
||||||
|
|
||||||
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
|
dev->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), nullptr, &pVS);
|
||||||
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
|
dev->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), nullptr, &pPS);
|
||||||
|
|
||||||
D3D11_INPUT_ELEMENT_DESC ied[] =
|
D3D11_INPUT_ELEMENT_DESC ied[] =
|
||||||
{
|
{
|
||||||
|
@ -564,7 +564,7 @@ void InitGraphics()
|
||||||
m_View = XMMatrixLookAtLH(Eye, At, Up);
|
m_View = XMMatrixLookAtLH(Eye, At, Up);
|
||||||
|
|
||||||
ourModel = new ModelLoader;
|
ourModel = new ModelLoader;
|
||||||
if (!ourModel->Load(hwnd, dev, devcon, g_ModelPath))
|
if (!ourModel->Load(g_hwnd, dev, devcon, g_ModelPath))
|
||||||
Throwanerror("Model couldn't be loaded");
|
Throwanerror("Model couldn't be loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,16 +576,16 @@ HRESULT CompileShaderFromFile(LPCWSTR pFileName, const D3D_SHADER_MACRO* pDefine
|
||||||
compileFlags |= D3DCOMPILE_DEBUG;
|
compileFlags |= D3DCOMPILE_DEBUG;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ID3DBlob* pErrorBlob = NULL;
|
ID3DBlob* pErrorBlob = nullptr;
|
||||||
|
|
||||||
HRESULT result = D3DCompileFromFile(pFileName, pDefines, D3D_COMPILE_STANDARD_FILE_INCLUDE, pEntryPoint, pShaderModel, compileFlags, 0, ppBytecodeBlob, &pErrorBlob);
|
HRESULT result = D3DCompileFromFile(pFileName, pDefines, D3D_COMPILE_STANDARD_FILE_INCLUDE, pEntryPoint, pShaderModel, compileFlags, 0, ppBytecodeBlob, &pErrorBlob);
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
{
|
{
|
||||||
if (pErrorBlob != NULL)
|
if (pErrorBlob != nullptr)
|
||||||
OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer());
|
OutputDebugStringA((LPCSTR)pErrorBlob->GetBufferPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pErrorBlob != NULL)
|
if (pErrorBlob != nullptr)
|
||||||
pErrorBlob->Release();
|
pErrorBlob->Release();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -17,7 +17,6 @@ if ( MSVC )
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(
|
INCLUDE_DIRECTORIES(
|
||||||
${Assimp_SOURCE_DIR}/include
|
|
||||||
${Assimp_SOURCE_DIR}/code
|
${Assimp_SOURCE_DIR}/code
|
||||||
${OPENGL_INCLUDE_DIR}
|
${OPENGL_INCLUDE_DIR}
|
||||||
${GLUT_INCLUDE_DIR}
|
${GLUT_INCLUDE_DIR}
|
||||||
|
@ -30,7 +29,6 @@ LINK_DIRECTORIES(
|
||||||
)
|
)
|
||||||
|
|
||||||
ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
|
ADD_EXECUTABLE( assimp_simpletexturedogl WIN32
|
||||||
SimpleTexturedOpenGL/include/boost_includes.h
|
|
||||||
SimpleTexturedOpenGL/src/model_loading.cpp
|
SimpleTexturedOpenGL/src/model_loading.cpp
|
||||||
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.cpp
|
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.cpp
|
||||||
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.h
|
${SAMPLES_SHARED_CODE_DIR}/UTFConverter.h
|
||||||
|
@ -47,3 +45,4 @@ SET_TARGET_PROPERTIES( assimp_simpletexturedogl PROPERTIES
|
||||||
INSTALL( TARGETS assimp_simpletexturedogl
|
INSTALL( TARGETS assimp_simpletexturedogl
|
||||||
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
|
DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-dev
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
#include <boost/lexical_cast.hpp>
|
|
|
@ -18,8 +18,10 @@
|
||||||
#include <GL/gl.h>
|
#include <GL/gl.h>
|
||||||
#include <GL/glu.h>
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
#pragma warning(disable: 4100) // Disable warning 'unreferenced formal parameter'
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include "contrib/stb_image/stb_image.h"
|
#include "contrib/stb_image/stb_image.h"
|
||||||
|
#pragma warning(default: 4100) // Enable warning 'unreferenced formal parameter'
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
@ -38,10 +40,10 @@
|
||||||
// The default hard-coded path. Can be overridden by supplying a path through the command line.
|
// The default hard-coded path. Can be overridden by supplying a path through the command line.
|
||||||
static std::string modelpath = "../../test/models/OBJ/spider.obj";
|
static std::string modelpath = "../../test/models/OBJ/spider.obj";
|
||||||
|
|
||||||
HGLRC hRC=NULL; // Permanent Rendering Context
|
HGLRC hRC=nullptr; // Permanent Rendering Context
|
||||||
HDC hDC=NULL; // Private GDI Device Context
|
HDC hDC=nullptr; // Private GDI Device Context
|
||||||
HWND hWnd=NULL; // Holds Window Handle
|
HWND g_hWnd=nullptr; // Holds Window Handle
|
||||||
HINSTANCE hInstance; // Holds The Instance Of The Application
|
HINSTANCE g_hInstance=nullptr; // Holds The Instance Of The Application
|
||||||
|
|
||||||
bool keys[256]; // Array used for Keyboard Routine;
|
bool keys[256]; // Array used for Keyboard Routine;
|
||||||
bool active=TRUE; // Window Active Flag Set To TRUE by Default
|
bool active=TRUE; // Window Active Flag Set To TRUE by Default
|
||||||
|
@ -64,7 +66,7 @@ GLfloat LightPosition[]= { 0.0f, 0.0f, 15.0f, 1.0f };
|
||||||
|
|
||||||
|
|
||||||
// the global Assimp scene object
|
// the global Assimp scene object
|
||||||
const aiScene* scene = NULL;
|
const aiScene* g_scene = nullptr;
|
||||||
GLuint scene_list = 0;
|
GLuint scene_list = 0;
|
||||||
aiVector3D scene_min, scene_max, scene_center;
|
aiVector3D scene_min, scene_max, scene_center;
|
||||||
|
|
||||||
|
@ -122,15 +124,15 @@ bool Import3DFromFile( const std::string& pFile)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MessageBox(NULL, UTFConverter("Couldn't open file: " + pFile).c_wstr() , TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
|
MessageBox(nullptr, UTFConverter("Couldn't open file: " + pFile).c_wstr() , TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
|
||||||
logInfo( importer.GetErrorString());
|
logInfo( importer.GetErrorString());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene = importer.ReadFile( pFile, aiProcessPreset_TargetRealtime_Quality);
|
g_scene = importer.ReadFile(pFile, aiProcessPreset_TargetRealtime_Quality);
|
||||||
|
|
||||||
// If the import failed, report it
|
// If the import failed, report it
|
||||||
if( !scene)
|
if(!g_scene)
|
||||||
{
|
{
|
||||||
logInfo( importer.GetErrorString());
|
logInfo( importer.GetErrorString());
|
||||||
return false;
|
return false;
|
||||||
|
@ -179,7 +181,7 @@ void freeTextureIds()
|
||||||
if (textureIds)
|
if (textureIds)
|
||||||
{
|
{
|
||||||
delete[] textureIds;
|
delete[] textureIds;
|
||||||
textureIds = NULL;
|
textureIds = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +217,7 @@ int LoadGLTextures(const aiScene* scene)
|
||||||
while (texFound == AI_SUCCESS)
|
while (texFound == AI_SUCCESS)
|
||||||
{
|
{
|
||||||
texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
|
texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
|
||||||
textureIdMap[path.data] = NULL; //fill map with textures, pointers still NULL yet
|
textureIdMap[path.data] = nullptr; //fill map with textures, pointers still NULL yet
|
||||||
texIndex++;
|
texIndex++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +285,7 @@ int LoadGLTextures(const aiScene* scene)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Error occurred */
|
/* Error occurred */
|
||||||
MessageBox(NULL, UTFConverter("Couldn't load Image: " + fileloc).c_wstr(), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
|
MessageBox(nullptr, UTFConverter("Couldn't load Image: " + fileloc).c_wstr(), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Because we have already copied image data into texture data we can release memory used by image.
|
// Because we have already copied image data into texture data we can release memory used by image.
|
||||||
|
@ -299,7 +301,7 @@ int LoadGLTextures(const aiScene* scene)
|
||||||
// All Setup For OpenGL goes here
|
// All Setup For OpenGL goes here
|
||||||
int InitGL()
|
int InitGL()
|
||||||
{
|
{
|
||||||
if (!LoadGLTextures(scene))
|
if (!LoadGLTextures(g_scene))
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -440,12 +442,12 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float
|
||||||
// draw all meshes assigned to this node
|
// draw all meshes assigned to this node
|
||||||
for (; n < nd->mNumMeshes; ++n)
|
for (; n < nd->mNumMeshes; ++n)
|
||||||
{
|
{
|
||||||
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]];
|
||||||
|
|
||||||
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
|
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
|
||||||
|
|
||||||
|
|
||||||
if(mesh->mNormals == NULL)
|
if(mesh->mNormals == nullptr)
|
||||||
{
|
{
|
||||||
glDisable(GL_LIGHTING);
|
glDisable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
@ -454,7 +456,7 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mesh->mColors[0] != NULL)
|
if(mesh->mColors[0] != nullptr)
|
||||||
{
|
{
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
}
|
}
|
||||||
|
@ -480,9 +482,9 @@ void recursive_render (const struct aiScene *sc, const struct aiNode* nd, float
|
||||||
for(i = 0; i < face->mNumIndices; i++) // go through all vertices in face
|
for(i = 0; i < face->mNumIndices; i++) // go through all vertices in face
|
||||||
{
|
{
|
||||||
int vertexIndex = face->mIndices[i]; // get group index for current index
|
int vertexIndex = face->mIndices[i]; // get group index for current index
|
||||||
if(mesh->mColors[0] != NULL)
|
if(mesh->mColors[0] != nullptr)
|
||||||
Color4f(&mesh->mColors[0][vertexIndex]);
|
Color4f(&mesh->mColors[0][vertexIndex]);
|
||||||
if(mesh->mNormals != NULL)
|
if(mesh->mNormals != nullptr)
|
||||||
|
|
||||||
if(mesh->HasTextureCoords(0)) //HasTextureCoords(texture_coordinates_set)
|
if(mesh->HasTextureCoords(0)) //HasTextureCoords(texture_coordinates_set)
|
||||||
{
|
{
|
||||||
|
@ -527,7 +529,7 @@ int DrawGLScene() //Here's where we do all the drawing
|
||||||
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
|
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
|
||||||
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
|
glRotatef(zrot, 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
drawAiScene(scene);
|
drawAiScene(g_scene);
|
||||||
|
|
||||||
//xrot+=0.3f;
|
//xrot+=0.3f;
|
||||||
yrot+=0.2f;
|
yrot+=0.2f;
|
||||||
|
@ -541,50 +543,50 @@ void KillGLWindow() // Properly Kill The Window
|
||||||
{
|
{
|
||||||
if (fullscreen) // Are We In Fullscreen Mode?
|
if (fullscreen) // Are We In Fullscreen Mode?
|
||||||
{
|
{
|
||||||
ChangeDisplaySettings(NULL, 0); // If So Switch Back To The Desktop
|
ChangeDisplaySettings(nullptr, 0); // If So Switch Back To The Desktop
|
||||||
ShowCursor(TRUE); // Show Mouse Pointer
|
ShowCursor(TRUE); // Show Mouse Pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hRC) // Do We Have A Rendering Context?
|
if (hRC) // Do We Have A Rendering Context?
|
||||||
{
|
{
|
||||||
if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts?
|
if (!wglMakeCurrent(nullptr, nullptr)) // Are We Able To Release The DC And RC Contexts?
|
||||||
{
|
{
|
||||||
MessageBox(NULL, TEXT("Release Of DC And RC Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
MessageBox(nullptr, TEXT("Release Of DC And RC Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
|
if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC?
|
||||||
{
|
{
|
||||||
MessageBox(NULL, TEXT("Release Rendering Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
MessageBox(nullptr, TEXT("Release Rendering Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
||||||
}
|
}
|
||||||
hRC = NULL;
|
hRC = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hDC)
|
if (hDC)
|
||||||
{
|
{
|
||||||
if (!ReleaseDC(hWnd, hDC)) // Are We able to Release The DC?
|
if (!ReleaseDC(g_hWnd, hDC)) // Are We able to Release The DC?
|
||||||
MessageBox(NULL, TEXT("Release Device Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
MessageBox(nullptr, TEXT("Release Device Context Failed."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
||||||
hDC = NULL;
|
hDC = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hWnd)
|
if (g_hWnd)
|
||||||
{
|
{
|
||||||
if (!DestroyWindow(hWnd)) // Are We Able To Destroy The Window
|
if (!DestroyWindow(g_hWnd)) // Are We Able To Destroy The Window
|
||||||
MessageBox(NULL, TEXT("Could Not Release hWnd."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
MessageBox(nullptr, TEXT("Could Not Release hWnd."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
||||||
hWnd = NULL;
|
g_hWnd = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hInstance)
|
if (g_hInstance)
|
||||||
{
|
{
|
||||||
if (!UnregisterClass(TEXT("OpenGL"), hInstance)) // Are We Able To Unregister Class
|
if (!UnregisterClass(TEXT("OpenGL"), g_hInstance)) // Are We Able To Unregister Class
|
||||||
MessageBox(NULL, TEXT("Could Not Unregister Class."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
MessageBox(nullptr, TEXT("Could Not Unregister Class."), TEXT("SHUTDOWN ERROR"), MB_OK | MB_ICONINFORMATION);
|
||||||
hInstance = NULL;
|
g_hInstance = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLboolean abortGLInit(const char* abortMessage)
|
GLboolean abortGLInit(const char* abortMessage)
|
||||||
{
|
{
|
||||||
KillGLWindow(); // Reset Display
|
KillGLWindow(); // Reset Display
|
||||||
MessageBox(NULL, UTFConverter(abortMessage).c_wstr(), TEXT("ERROR"), MB_OK|MB_ICONEXCLAMATION);
|
MessageBox(nullptr, UTFConverter(abortMessage).c_wstr(), TEXT("ERROR"), MB_OK|MB_ICONEXCLAMATION);
|
||||||
return FALSE; // quit and return False
|
return FALSE; // quit and return False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,21 +604,21 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
|
|
||||||
fullscreen = fullscreenflag;
|
fullscreen = fullscreenflag;
|
||||||
|
|
||||||
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
|
g_hInstance = GetModuleHandle(nullptr); // Grab An Instance For Our Window
|
||||||
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window
|
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Move, And Own DC For Window
|
||||||
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles Messages
|
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc handles Messages
|
||||||
wc.cbClsExtra = 0; // No Extra Window Data
|
wc.cbClsExtra = 0; // No Extra Window Data
|
||||||
wc.cbWndExtra = 0; // No Extra Window Data
|
wc.cbWndExtra = 0; // No Extra Window Data
|
||||||
wc.hInstance = hInstance;
|
wc.hInstance = g_hInstance;
|
||||||
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
|
wc.hIcon = LoadIcon(nullptr, IDI_WINLOGO); // Load The Default Icon
|
||||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load the default arrow
|
wc.hCursor = LoadCursor(nullptr, IDC_ARROW); // Load the default arrow
|
||||||
wc.hbrBackground= NULL; // No Background required for OpenGL
|
wc.hbrBackground= nullptr; // No Background required for OpenGL
|
||||||
wc.lpszMenuName = NULL; // No Menu
|
wc.lpszMenuName = nullptr; // No Menu
|
||||||
wc.lpszClassName= TEXT("OpenGL"); // Class Name
|
wc.lpszClassName= TEXT("OpenGL"); // Class Name
|
||||||
|
|
||||||
if (!RegisterClass(&wc))
|
if (!RegisterClass(&wc))
|
||||||
{
|
{
|
||||||
MessageBox(NULL, TEXT("Failed to register the window class"), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
|
MessageBox(nullptr, TEXT("Failed to register the window class"), TEXT("ERROR"), MB_OK | MB_ICONEXCLAMATION);
|
||||||
return FALSE; //exit and return false
|
return FALSE; //exit and return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,14 +636,14 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
|
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
|
||||||
{
|
{
|
||||||
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
|
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
|
||||||
if (MessageBox(NULL,TEXT("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),TEXT("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
|
if (MessageBox(nullptr,TEXT("The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?"),TEXT("NeHe GL"),MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
|
||||||
{
|
{
|
||||||
fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE)
|
fullscreen = FALSE; // Select Windowed Mode (Fullscreen = FALSE)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//Popup Messagebox: Closing
|
//Popup Messagebox: Closing
|
||||||
MessageBox(NULL, TEXT("Program will close now."), TEXT("ERROR"), MB_OK|MB_ICONSTOP);
|
MessageBox(nullptr, TEXT("Program will close now."), TEXT("ERROR"), MB_OK|MB_ICONSTOP);
|
||||||
return FALSE; //exit, return false
|
return FALSE; //exit, return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -661,7 +663,7 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
|
|
||||||
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requestes Size
|
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requestes Size
|
||||||
|
|
||||||
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
|
if (nullptr == (g_hWnd=CreateWindowEx(dwExStyle, // Extended Style For The Window
|
||||||
TEXT("OpenGL"), // Class Name
|
TEXT("OpenGL"), // Class Name
|
||||||
UTFConverter(title).c_wstr(), // Window Title
|
UTFConverter(title).c_wstr(), // Window Title
|
||||||
WS_CLIPSIBLINGS | // Required Window Style
|
WS_CLIPSIBLINGS | // Required Window Style
|
||||||
|
@ -670,10 +672,10 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
0, 0, // Window Position
|
0, 0, // Window Position
|
||||||
WindowRect.right-WindowRect.left, // Calc adjusted Window Width
|
WindowRect.right-WindowRect.left, // Calc adjusted Window Width
|
||||||
WindowRect.bottom-WindowRect.top, // Calc adjustes Window Height
|
WindowRect.bottom-WindowRect.top, // Calc adjustes Window Height
|
||||||
NULL, // No Parent Window
|
nullptr, // No Parent Window
|
||||||
NULL, // No Menu
|
nullptr, // No Menu
|
||||||
hInstance, // Instance
|
g_hInstance, // Instance
|
||||||
NULL ))) // Don't pass anything To WM_CREATE
|
nullptr ))) // Don't pass anything To WM_CREATE
|
||||||
{
|
{
|
||||||
abortGLInit("Window Creation Error.");
|
abortGLInit("Window Creation Error.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -701,13 +703,13 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
0, 0, 0 // Layer Masks Ignored
|
0, 0, 0 // Layer Masks Ignored
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!(hDC=GetDC(hWnd))) // Did we get the Device Context?
|
if (nullptr == (hDC=GetDC(g_hWnd))) // Did we get the Device Context?
|
||||||
{
|
{
|
||||||
abortGLInit("Can't Create A GL Device Context.");
|
abortGLInit("Can't Create A GL Device Context.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(PixelFormat=ChoosePixelFormat(hDC, &pfd))) // Did We Find a matching pixel Format?
|
if (0 == (PixelFormat=ChoosePixelFormat(hDC, &pfd))) // Did We Find a matching pixel Format?
|
||||||
{
|
{
|
||||||
abortGLInit("Can't Find Suitable PixelFormat");
|
abortGLInit("Can't Find Suitable PixelFormat");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -719,7 +721,7 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(hRC=wglCreateContext(hDC)))
|
if (nullptr == (hRC=wglCreateContext(hDC)))
|
||||||
{
|
{
|
||||||
abortGLInit("Can't Create A GL Rendering Context.");
|
abortGLInit("Can't Create A GL Rendering Context.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -733,9 +735,9 @@ BOOL CreateGLWindow(const char* title, int width, int height, int bits, bool ful
|
||||||
|
|
||||||
//// *** everything okay ***
|
//// *** everything okay ***
|
||||||
|
|
||||||
ShowWindow(hWnd, SW_SHOW); // Show The Window
|
ShowWindow(g_hWnd, SW_SHOW); // Show The Window
|
||||||
SetForegroundWindow(hWnd); // Slightly Higher Prio
|
SetForegroundWindow(g_hWnd); // Slightly Higher Prio
|
||||||
SetFocus(hWnd); // Sets Keyboard Focus To The Window
|
SetFocus(g_hWnd); // Sets Keyboard Focus To The Window
|
||||||
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
|
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
|
||||||
|
|
||||||
if (!InitGL())
|
if (!InitGL())
|
||||||
|
@ -753,7 +755,7 @@ void cleanup()
|
||||||
|
|
||||||
destroyAILogger();
|
destroyAILogger();
|
||||||
|
|
||||||
if (hWnd)
|
if (g_hWnd)
|
||||||
KillGLWindow();
|
KillGLWindow();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -818,12 +820,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, // Handles for this Window
|
||||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI WinMain( HINSTANCE hInstance, // The instance
|
int WINAPI WinMain( HINSTANCE /*hInstance*/, // The instance
|
||||||
HINSTANCE hPrevInstance, // Previous instance
|
HINSTANCE /*hPrevInstance*/, // Previous instance
|
||||||
LPSTR lpCmdLine, // Command Line Parameters
|
LPSTR /*lpCmdLine*/, // Command Line Parameters
|
||||||
int nShowCmd ) // Window Show State
|
int /*nShowCmd*/ ) // Window Show State
|
||||||
{
|
{
|
||||||
MSG msg;
|
MSG msg = {};
|
||||||
BOOL done=FALSE;
|
BOOL done=FALSE;
|
||||||
|
|
||||||
createAILogger();
|
createAILogger();
|
||||||
|
@ -832,7 +834,7 @@ int WINAPI WinMain( HINSTANCE hInstance, // The instance
|
||||||
// Check the command line for an override file path.
|
// Check the command line for an override file path.
|
||||||
int argc;
|
int argc;
|
||||||
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||||
if (argv != NULL && argc > 1)
|
if (argv != nullptr && argc > 1)
|
||||||
{
|
{
|
||||||
std::wstring modelpathW(argv[1]);
|
std::wstring modelpathW(argv[1]);
|
||||||
modelpath = UTFConverter(modelpathW).str();
|
modelpath = UTFConverter(modelpathW).str();
|
||||||
|
@ -846,7 +848,7 @@ int WINAPI WinMain( HINSTANCE hInstance, // The instance
|
||||||
|
|
||||||
logInfo("=============== Post Import ====================");
|
logInfo("=============== Post Import ====================");
|
||||||
|
|
||||||
if (MessageBox(NULL, TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start Fullscreen?"), MB_YESNO|MB_ICONEXCLAMATION)==IDNO)
|
if (MessageBox(nullptr, TEXT("Would You Like To Run In Fullscreen Mode?"), TEXT("Start Fullscreen?"), MB_YESNO|MB_ICONEXCLAMATION)==IDNO)
|
||||||
{
|
{
|
||||||
fullscreen=FALSE;
|
fullscreen=FALSE;
|
||||||
}
|
}
|
||||||
|
@ -859,7 +861,7 @@ int WINAPI WinMain( HINSTANCE hInstance, // The instance
|
||||||
|
|
||||||
while(!done) // Game Loop
|
while(!done) // Game Loop
|
||||||
{
|
{
|
||||||
if (PeekMessage(&msg, NULL, 0,0, PM_REMOVE))
|
if (PeekMessage(&msg, nullptr, 0,0, PM_REMOVE))
|
||||||
{
|
{
|
||||||
if (msg.message==WM_QUIT)
|
if (msg.message==WM_QUIT)
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,14 @@ SET( COMMON
|
||||||
unit/utIssues.cpp
|
unit/utIssues.cpp
|
||||||
unit/utAnim.cpp
|
unit/utAnim.cpp
|
||||||
unit/AssimpAPITest.cpp
|
unit/AssimpAPITest.cpp
|
||||||
|
unit/AssimpAPITest_aiMatrix3x3.cpp
|
||||||
|
unit/AssimpAPITest_aiMatrix4x4.cpp
|
||||||
|
unit/AssimpAPITest_aiQuaternion.cpp
|
||||||
|
unit/AssimpAPITest_aiVector2D.cpp
|
||||||
|
unit/AssimpAPITest_aiVector3D.cpp
|
||||||
|
unit/MathTest.cpp
|
||||||
|
unit/MathTest.h
|
||||||
|
unit/RandomNumberGeneration.h
|
||||||
unit/utBatchLoader.cpp
|
unit/utBatchLoader.cpp
|
||||||
unit/utDefaultIOStream.cpp
|
unit/utDefaultIOStream.cpp
|
||||||
unit/utFastAtof.cpp
|
unit/utFastAtof.cpp
|
||||||
|
@ -76,10 +84,13 @@ SET( COMMON
|
||||||
unit/utProfiler.cpp
|
unit/utProfiler.cpp
|
||||||
unit/utSharedPPData.cpp
|
unit/utSharedPPData.cpp
|
||||||
unit/utStringUtils.cpp
|
unit/utStringUtils.cpp
|
||||||
|
unit/Common/uiScene.cpp
|
||||||
unit/Common/utLineSplitter.cpp
|
unit/Common/utLineSplitter.cpp
|
||||||
|
unit/Common/utSpatialSort.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( IMPORTERS
|
SET( IMPORTERS
|
||||||
|
unit/ImportExport/Assxml/utAssxmlImportExport.cpp
|
||||||
unit/utLWSImportExport.cpp
|
unit/utLWSImportExport.cpp
|
||||||
unit/utLWOImportExport.cpp
|
unit/utLWOImportExport.cpp
|
||||||
unit/utSMDImportExport.cpp
|
unit/utSMDImportExport.cpp
|
||||||
|
@ -136,6 +147,9 @@ SET( IMPORTERS
|
||||||
unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
|
unit/ImportExport/MDL/utMDLImporter_HL1_ImportSettings.cpp
|
||||||
unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp
|
unit/ImportExport/MDL/utMDLImporter_HL1_Materials.cpp
|
||||||
unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
|
unit/ImportExport/MDL/utMDLImporter_HL1_Nodes.cpp
|
||||||
|
#unit/ImportExport/IRR/utIrrImportExport.cpp
|
||||||
|
unit/ImportExport/RAW/utRAWImportExport.cpp
|
||||||
|
unit/ImportExport/Terragen/utTerragenImportExport.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
SET( MATERIAL
|
SET( MATERIAL
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"asset": {
|
||||||
|
"version": "2.0"
|
||||||
|
},
|
||||||
|
"scene": 0,
|
||||||
|
"scenes": [
|
||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"children": [
|
||||||
|
1
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"children": [
|
||||||
|
0
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "MathTest.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class AssimpAPITest_aiMatrix3x3 : public AssimpMathTest {
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
result_c = result_cpp = aiMatrix3x3();
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMatrix3x3 result_c, result_cpp;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiIdentityMatrix3Test) {
|
||||||
|
// Force a non-identity matrix.
|
||||||
|
result_c = aiMatrix3x3(0,0,0,0,0,0,0,0,0);
|
||||||
|
aiIdentityMatrix3(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromMatrix4Test) {
|
||||||
|
const auto m = random_mat4();
|
||||||
|
result_cpp = aiMatrix3x3(m);
|
||||||
|
aiMatrix3FromMatrix4(&result_c, &m);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromQuaternionTest) {
|
||||||
|
const auto q = random_quat();
|
||||||
|
result_cpp = q.GetMatrix();
|
||||||
|
aiMatrix3FromQuaternion(&result_c, &q);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3AreEqualTest) {
|
||||||
|
result_c = result_cpp = random_mat3();
|
||||||
|
EXPECT_EQ(result_cpp == result_c,
|
||||||
|
(bool)aiMatrix3AreEqual(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3AreEqualEpsilonTest) {
|
||||||
|
result_c = result_cpp = random_mat3();
|
||||||
|
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
|
||||||
|
(bool)aiMatrix3AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMultiplyMatrix3Test) {
|
||||||
|
const auto m = random_mat3();
|
||||||
|
result_c = result_cpp = random_mat3();
|
||||||
|
result_cpp *= m;
|
||||||
|
aiMultiplyMatrix3(&result_c, &m);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiTransposeMatrix3Test) {
|
||||||
|
result_c = result_cpp = random_mat3();
|
||||||
|
result_cpp.Transpose();
|
||||||
|
aiTransposeMatrix3(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3InverseTest) {
|
||||||
|
// Use a predetermined matrix to prevent arbitrary
|
||||||
|
// cases where it could have a null determinant.
|
||||||
|
result_c = result_cpp = aiMatrix3x3(
|
||||||
|
5, 2, 7,
|
||||||
|
4, 6, 9,
|
||||||
|
1, 8, 3);
|
||||||
|
result_cpp.Inverse();
|
||||||
|
aiMatrix3Inverse(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3DeterminantTest) {
|
||||||
|
result_c = result_cpp = random_mat3();
|
||||||
|
EXPECT_EQ(result_cpp.Determinant(),
|
||||||
|
aiMatrix3Determinant(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3RotationZTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
aiMatrix3x3::RotationZ(angle, result_cpp);
|
||||||
|
aiMatrix3RotationZ(&result_c, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromRotationAroundAxisTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
const auto axis = random_unit_vec3();
|
||||||
|
aiMatrix3x3::Rotation(angle, axis, result_cpp);
|
||||||
|
aiMatrix3FromRotationAroundAxis(&result_c, &axis, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3TranslationTest) {
|
||||||
|
const auto axis = random_vec2();
|
||||||
|
aiMatrix3x3::Translation(axis, result_cpp);
|
||||||
|
aiMatrix3Translation(&result_c, &axis);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix3x3, aiMatrix3FromToTest) {
|
||||||
|
// Use predetermined vectors to prevent running into division by zero.
|
||||||
|
const auto from = aiVector3D(1,2,1).Normalize(), to = aiVector3D(-1,1,1).Normalize();
|
||||||
|
aiMatrix3x3::FromToMatrix(from, to, result_cpp);
|
||||||
|
aiMatrix3FromTo(&result_c, &from, &to);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "MathTest.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class AssimpAPITest_aiMatrix4x4 : public AssimpMathTest {
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
result_c = result_cpp = aiMatrix4x4();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generates a predetermined transformation matrix to use
|
||||||
|
for the aiDecompose functions to prevent running into
|
||||||
|
division by zero. */
|
||||||
|
aiMatrix4x4 get_predetermined_transformation_matrix_for_decomposition() const {
|
||||||
|
aiMatrix4x4 t, r;
|
||||||
|
aiMatrix4x4::Translation(aiVector3D(14,-25,-8), t);
|
||||||
|
aiMatrix4x4::Rotation(Math::PI<float>() / 4.0f, aiVector3D(1).Normalize(), r);
|
||||||
|
return t * r;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiMatrix4x4 result_c, result_cpp;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiIdentityMatrix4Test) {
|
||||||
|
// Force a non-identity matrix.
|
||||||
|
result_c = aiMatrix4x4(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
|
||||||
|
aiIdentityMatrix4(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromMatrix3Test) {
|
||||||
|
aiMatrix3x3 m = random_mat3();
|
||||||
|
result_cpp = aiMatrix4x4(m);
|
||||||
|
aiMatrix4FromMatrix3(&result_c, &m);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromScalingQuaternionPositionTest) {
|
||||||
|
const aiVector3D s = random_vec3();
|
||||||
|
const aiQuaternion q = random_quat();
|
||||||
|
const aiVector3D t = random_vec3();
|
||||||
|
result_cpp = aiMatrix4x4(s, q, t);
|
||||||
|
aiMatrix4FromScalingQuaternionPosition(&result_c, &s, &q, &t);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4AddTest) {
|
||||||
|
const aiMatrix4x4 temp = random_mat4();
|
||||||
|
result_c = result_cpp = random_mat4();
|
||||||
|
result_cpp = result_cpp + temp;
|
||||||
|
aiMatrix4Add(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4AreEqualTest) {
|
||||||
|
result_c = result_cpp = random_mat4();
|
||||||
|
EXPECT_EQ(result_cpp == result_c,
|
||||||
|
(bool)aiMatrix4AreEqual(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4AreEqualEpsilonTest) {
|
||||||
|
result_c = result_cpp = random_mat4();
|
||||||
|
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
|
||||||
|
(bool)aiMatrix4AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMultiplyMatrix4Test) {
|
||||||
|
const auto m = random_mat4();
|
||||||
|
result_c = result_cpp = random_mat4();
|
||||||
|
result_cpp *= m;
|
||||||
|
aiMultiplyMatrix4(&result_c, &m);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiTransposeMatrix4Test) {
|
||||||
|
result_c = result_cpp = random_mat4();
|
||||||
|
result_cpp.Transpose();
|
||||||
|
aiTransposeMatrix4(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4InverseTest) {
|
||||||
|
// Use a predetermined matrix to prevent arbitrary
|
||||||
|
// cases where it could have a null determinant.
|
||||||
|
result_c = result_cpp = aiMatrix4x4(
|
||||||
|
6, 10, 15, 3,
|
||||||
|
14, 2, 12, 8,
|
||||||
|
9, 13, 5, 16,
|
||||||
|
4, 7, 11, 1);
|
||||||
|
result_cpp.Inverse();
|
||||||
|
aiMatrix4Inverse(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DeterminantTest) {
|
||||||
|
result_c = result_cpp = random_mat4();
|
||||||
|
EXPECT_EQ(result_cpp.Determinant(),
|
||||||
|
aiMatrix4Determinant(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4IsIdentityTest) {
|
||||||
|
EXPECT_EQ(result_cpp.IsIdentity(),
|
||||||
|
(bool)aiMatrix4IsIdentity(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiDecomposeMatrixTest) {
|
||||||
|
aiVector3D scaling_c, scaling_cpp,
|
||||||
|
position_c, position_cpp;
|
||||||
|
aiQuaternion rotation_c, rotation_cpp;
|
||||||
|
|
||||||
|
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
|
||||||
|
result_cpp.Decompose(scaling_cpp, rotation_cpp, position_cpp);
|
||||||
|
aiDecomposeMatrix(&result_c, &scaling_c, &rotation_c, &position_c);
|
||||||
|
EXPECT_EQ(scaling_cpp, scaling_c);
|
||||||
|
EXPECT_EQ(position_cpp, position_c);
|
||||||
|
EXPECT_EQ(rotation_cpp, rotation_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeIntoScalingEulerAnglesPositionTest) {
|
||||||
|
aiVector3D scaling_c, scaling_cpp,
|
||||||
|
rotation_c, rotation_cpp,
|
||||||
|
position_c, position_cpp;
|
||||||
|
|
||||||
|
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
|
||||||
|
result_cpp.Decompose(scaling_cpp, rotation_cpp, position_cpp);
|
||||||
|
aiMatrix4DecomposeIntoScalingEulerAnglesPosition(&result_c, &scaling_c, &rotation_c, &position_c);
|
||||||
|
EXPECT_EQ(scaling_cpp, scaling_c);
|
||||||
|
EXPECT_EQ(position_cpp, position_c);
|
||||||
|
EXPECT_EQ(rotation_cpp, rotation_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeIntoScalingAxisAnglePositionTest) {
|
||||||
|
aiVector3D scaling_c, scaling_cpp,
|
||||||
|
axis_c, axis_cpp,
|
||||||
|
position_c, position_cpp;
|
||||||
|
float angle_c, angle_cpp;
|
||||||
|
|
||||||
|
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
|
||||||
|
result_cpp.Decompose(scaling_cpp, axis_cpp, angle_cpp, position_cpp);
|
||||||
|
aiMatrix4DecomposeIntoScalingAxisAnglePosition(&result_c, &scaling_c, &axis_c, &angle_c, &position_c);
|
||||||
|
EXPECT_EQ(scaling_cpp, scaling_c);
|
||||||
|
EXPECT_EQ(axis_cpp, axis_c);
|
||||||
|
EXPECT_EQ(angle_cpp, angle_c);
|
||||||
|
EXPECT_EQ(position_cpp, position_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4DecomposeNoScalingTest) {
|
||||||
|
aiVector3D position_c, position_cpp;
|
||||||
|
aiQuaternion rotation_c, rotation_cpp;
|
||||||
|
|
||||||
|
result_c = result_cpp = get_predetermined_transformation_matrix_for_decomposition();
|
||||||
|
result_cpp.DecomposeNoScaling(rotation_cpp, position_cpp);
|
||||||
|
aiMatrix4DecomposeNoScaling(&result_c, &rotation_c, &position_c);
|
||||||
|
EXPECT_EQ(position_cpp, position_c);
|
||||||
|
EXPECT_EQ(rotation_cpp, rotation_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromEulerAnglesTest) {
|
||||||
|
const float x(RandPI.next()),
|
||||||
|
y(RandPI.next()),
|
||||||
|
z(RandPI.next());
|
||||||
|
result_cpp.FromEulerAnglesXYZ(x, y, z);
|
||||||
|
aiMatrix4FromEulerAngles(&result_c, x, y, z);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4RotationXTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
aiMatrix4x4::RotationX(angle, result_cpp);
|
||||||
|
aiMatrix4RotationX(&result_c, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4RotationYTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
aiMatrix4x4::RotationY(angle, result_cpp);
|
||||||
|
aiMatrix4RotationY(&result_c, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4RotationZTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
aiMatrix4x4::RotationZ(angle, result_cpp);
|
||||||
|
aiMatrix4RotationZ(&result_c, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromRotationAroundAxisTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
const auto axis = random_unit_vec3();
|
||||||
|
aiMatrix4x4::Rotation(angle, axis, result_cpp);
|
||||||
|
aiMatrix4FromRotationAroundAxis(&result_c, &axis, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4TranslationTest) {
|
||||||
|
const auto axis = random_vec3();
|
||||||
|
aiMatrix4x4::Translation(axis, result_cpp);
|
||||||
|
aiMatrix4Translation(&result_c, &axis);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4ScalingTest) {
|
||||||
|
const auto scaling = random_vec3();
|
||||||
|
aiMatrix4x4::Scaling(scaling, result_cpp);
|
||||||
|
aiMatrix4Scaling(&result_c, &scaling);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiMatrix4x4, aiMatrix4FromToTest) {
|
||||||
|
// Use predetermined vectors to prevent running into division by zero.
|
||||||
|
const auto from = aiVector3D(1,2,1).Normalize(), to = aiVector3D(-1,1,1).Normalize();
|
||||||
|
aiMatrix4x4::FromToMatrix(from, to, result_cpp);
|
||||||
|
aiMatrix4FromTo(&result_c, &from, &to);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "MathTest.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class AssimpAPITest_aiQuaternion : public AssimpMathTest {
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
result_c = result_cpp = aiQuaternion();
|
||||||
|
}
|
||||||
|
|
||||||
|
aiQuaternion result_c, result_cpp;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiCreateQuaternionFromMatrixTest) {
|
||||||
|
// Use a predetermined transformation matrix
|
||||||
|
// to prevent running into division by zero.
|
||||||
|
aiMatrix3x3 m, r;
|
||||||
|
aiMatrix3x3::Translation(aiVector2D(14,-25), m);
|
||||||
|
aiMatrix3x3::RotationZ(Math::PI<float>() / 4.0f, r);
|
||||||
|
m = m * r;
|
||||||
|
|
||||||
|
result_cpp = aiQuaternion(m);
|
||||||
|
aiCreateQuaternionFromMatrix(&result_c, &m);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromEulerAnglesTest) {
|
||||||
|
const float x(RandPI.next()),
|
||||||
|
y(RandPI.next()),
|
||||||
|
z(RandPI.next());
|
||||||
|
result_cpp = aiQuaternion(x, y, z);
|
||||||
|
aiQuaternionFromEulerAngles(&result_c, x, y, z);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromAxisAngleTest) {
|
||||||
|
const float angle(RandPI.next());
|
||||||
|
const aiVector3D axis(random_unit_vec3());
|
||||||
|
result_cpp = aiQuaternion(axis, angle);
|
||||||
|
aiQuaternionFromAxisAngle(&result_c, &axis, angle);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionFromNormalizedQuaternionTest) {
|
||||||
|
const auto qvec3 = random_unit_vec3();
|
||||||
|
result_cpp = aiQuaternion(qvec3);
|
||||||
|
aiQuaternionFromNormalizedQuaternion(&result_c, &qvec3);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionAreEqualTest) {
|
||||||
|
result_c = result_cpp = random_quat();
|
||||||
|
EXPECT_EQ(result_cpp == result_c,
|
||||||
|
(bool)aiQuaternionAreEqual(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionAreEqualEpsilonTest) {
|
||||||
|
result_c = result_cpp = random_quat();
|
||||||
|
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
|
||||||
|
(bool)aiQuaternionAreEqualEpsilon(&result_cpp, &result_c, Epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionNormalizeTest) {
|
||||||
|
result_c = result_cpp = random_quat();
|
||||||
|
aiQuaternionNormalize(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp.Normalize(), result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionConjugateTest) {
|
||||||
|
result_c = result_cpp = random_quat();
|
||||||
|
aiQuaternionConjugate(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp.Conjugate(), result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionMultiplyTest) {
|
||||||
|
const aiQuaternion temp = random_quat();
|
||||||
|
result_c = result_cpp = random_quat();
|
||||||
|
result_cpp = result_cpp * temp;
|
||||||
|
aiQuaternionMultiply(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiQuaternion, aiQuaternionInterpolateTest) {
|
||||||
|
// Use predetermined quaternions to prevent division by zero
|
||||||
|
// during slerp calculations.
|
||||||
|
const float INTERPOLATION(0.5f);
|
||||||
|
const auto q1 = aiQuaternion(aiVector3D(-1,1,1).Normalize(), Math::PI<float>() / 4.0f);
|
||||||
|
const auto q2 = aiQuaternion(aiVector3D(1,2,1).Normalize(), Math::PI<float>() / 2.0f);
|
||||||
|
aiQuaternion::Interpolate(result_cpp, q1, q2, INTERPOLATION);
|
||||||
|
aiQuaternionInterpolate(&result_c, &q1, &q2, INTERPOLATION);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "MathTest.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class AssimpAPITest_aiVector2D : public AssimpMathTest {
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
result_c = result_cpp = aiVector2D();
|
||||||
|
temp = random_vec2(); // Generates a random 2D vector != null vector.
|
||||||
|
}
|
||||||
|
|
||||||
|
aiVector2D result_c, result_cpp, temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2AreEqualTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
EXPECT_EQ(result_cpp == result_c,
|
||||||
|
(bool)aiVector2AreEqual(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2AreEqualEpsilonTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
|
||||||
|
(bool)aiVector2AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2AddTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
result_cpp += temp;
|
||||||
|
aiVector2Add(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2SubtractTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
result_cpp -= temp;
|
||||||
|
aiVector2Subtract(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2ScaleTest) {
|
||||||
|
const float FACTOR = RandNonZero.next();
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
result_cpp *= FACTOR;
|
||||||
|
aiVector2Scale(&result_c, FACTOR);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2SymMulTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
result_cpp = result_cpp.SymMul(temp);
|
||||||
|
aiVector2SymMul(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2DivideByScalarTest) {
|
||||||
|
const float DIVISOR = RandNonZero.next();
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
result_cpp /= DIVISOR;
|
||||||
|
aiVector2DivideByScalar(&result_c, DIVISOR);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2DivideByVectorTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
result_cpp = result_cpp / temp;
|
||||||
|
aiVector2DivideByVector(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2LengthTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
EXPECT_EQ(result_cpp.Length(), aiVector2Length(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2SquareLengthTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
EXPECT_EQ(result_cpp.SquareLength(), aiVector2SquareLength(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2NegateTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
aiVector2Negate(&result_c);
|
||||||
|
EXPECT_EQ(-result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2DotProductTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
EXPECT_EQ(result_cpp * result_c,
|
||||||
|
aiVector2DotProduct(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector2D, aiVector2NormalizeTest) {
|
||||||
|
result_c = result_cpp = random_vec2();
|
||||||
|
aiVector2Normalize(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp.Normalize(), result_c);
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include "MathTest.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class AssimpAPITest_aiVector3D : public AssimpMathTest {
|
||||||
|
protected:
|
||||||
|
virtual void SetUp() {
|
||||||
|
result_c = result_cpp = aiVector3D();
|
||||||
|
temp = random_vec3(); // Generates a random 3D vector != null vector.
|
||||||
|
}
|
||||||
|
|
||||||
|
aiVector3D result_c, result_cpp, temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3AreEqualTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
EXPECT_EQ(result_cpp == result_c,
|
||||||
|
(bool)aiVector3AreEqual(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3AreEqualEpsilonTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
EXPECT_EQ(result_cpp.Equal(result_c, Epsilon),
|
||||||
|
(bool)aiVector3AreEqualEpsilon(&result_cpp, &result_c, Epsilon));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3LessThanTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
EXPECT_EQ(result_cpp < temp,
|
||||||
|
(bool)aiVector3LessThan(&result_c, &temp));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3AddTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp += temp;
|
||||||
|
aiVector3Add(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3SubtractTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp -= temp;
|
||||||
|
aiVector3Subtract(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3ScaleTest) {
|
||||||
|
const float FACTOR = RandNonZero.next();
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp *= FACTOR;
|
||||||
|
aiVector3Scale(&result_c, FACTOR);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3SymMulTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp = result_cpp.SymMul(temp);
|
||||||
|
aiVector3SymMul(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3DivideByScalarTest) {
|
||||||
|
const float DIVISOR = RandNonZero.next();
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp /= DIVISOR;
|
||||||
|
aiVector3DivideByScalar(&result_c, DIVISOR);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3DivideByVectorTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp = result_cpp / temp;
|
||||||
|
aiVector3DivideByVector(&result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3LengthTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
EXPECT_EQ(result_cpp.Length(), aiVector3Length(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3SquareLengthTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
EXPECT_EQ(result_cpp.SquareLength(), aiVector3SquareLength(&result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3NegateTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
aiVector3Negate(&result_c);
|
||||||
|
EXPECT_EQ(-result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3DotProductTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
EXPECT_EQ(result_cpp * result_c,
|
||||||
|
aiVector3DotProduct(&result_cpp, &result_c));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3CrossProductTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
result_cpp = result_cpp ^ temp;
|
||||||
|
aiVector3CrossProduct(&result_c, &result_c, &temp);
|
||||||
|
EXPECT_EQ(result_cpp, result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3NormalizeTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
aiVector3Normalize(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp.Normalize(), result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3NormalizeSafeTest) {
|
||||||
|
result_c = result_cpp = random_vec3();
|
||||||
|
aiVector3NormalizeSafe(&result_c);
|
||||||
|
EXPECT_EQ(result_cpp.NormalizeSafe(), result_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiVector3RotateByQuaternionTest) {
|
||||||
|
aiVector3D v_c, v_cpp;
|
||||||
|
v_c = v_cpp = random_vec3();
|
||||||
|
const auto q = random_quat();
|
||||||
|
aiVector3RotateByQuaternion(&v_c, &q);
|
||||||
|
EXPECT_EQ(q.Rotate(v_cpp), v_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiTransformVecByMatrix3Test) {
|
||||||
|
const auto m = random_mat3();
|
||||||
|
aiVector3D v_c, v_cpp;
|
||||||
|
v_c = v_cpp = random_vec3();
|
||||||
|
v_cpp *= m;
|
||||||
|
aiTransformVecByMatrix3(&v_c, &m);
|
||||||
|
EXPECT_EQ(v_cpp, v_c);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(AssimpAPITest_aiVector3D, aiTransformVecByMatrix4Test) {
|
||||||
|
const auto m = random_mat4();
|
||||||
|
aiVector3D v_c, v_cpp;
|
||||||
|
v_c = v_cpp = random_vec3();
|
||||||
|
v_cpp *= m;
|
||||||
|
aiTransformVecByMatrix4(&v_c, &m);
|
||||||
|
EXPECT_EQ(v_cpp, v_c);
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utScene : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
aiScene *scene;
|
||||||
|
|
||||||
|
void SetUp() override {
|
||||||
|
scene = new aiScene;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
delete scene;
|
||||||
|
scene = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(utScene, findNodeTest) {
|
||||||
|
scene->mRootNode = new aiNode();
|
||||||
|
scene->mRootNode->mName.Set("test");
|
||||||
|
aiNode *child = new aiNode;
|
||||||
|
child->mName.Set("child");
|
||||||
|
scene->mRootNode->addChildren(1, &child);
|
||||||
|
aiNode *found = scene->mRootNode->FindNode("child");
|
||||||
|
EXPECT_EQ(child, found);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utScene, sceneHasContentTest) {
|
||||||
|
EXPECT_FALSE(scene->HasAnimations());
|
||||||
|
EXPECT_FALSE(scene->HasMaterials());
|
||||||
|
EXPECT_FALSE(scene->HasMeshes());
|
||||||
|
EXPECT_FALSE(scene->HasCameras());
|
||||||
|
EXPECT_FALSE(scene->HasLights());
|
||||||
|
EXPECT_FALSE(scene->HasTextures());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utScene, getShortFilenameTest) {
|
||||||
|
std::string long_filename1 = "foo_bar/name";
|
||||||
|
const char *name1 = scene->GetShortFilename(long_filename1.c_str());
|
||||||
|
EXPECT_NE(nullptr, name1);
|
||||||
|
|
||||||
|
std::string long_filename2 = "foo_bar\\name";
|
||||||
|
const char *name2 = scene->GetShortFilename(long_filename2.c_str());
|
||||||
|
EXPECT_NE(nullptr, name2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utScene, getEmbeddedTextureTest) {
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
|
#include <assimp/SpatialSort.h>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utSpatialSort : public ::testing::Test {
|
||||||
|
public
|
||||||
|
:
|
||||||
|
aiVector3D *vecs;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
::srand(static_cast<unsigned>(time(0)));
|
||||||
|
vecs = new aiVector3D[100];
|
||||||
|
for (size_t i = 0; i < 100; ++i) {
|
||||||
|
vecs[i].x = static_cast<float>(rand()) / (static_cast<float>(RAND_MAX / 100));
|
||||||
|
vecs[i].y = static_cast<float>(rand()) / (static_cast<float>(RAND_MAX / 100));
|
||||||
|
vecs[i].z = static_cast<float>(rand()) / (static_cast<float>(RAND_MAX / 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override {
|
||||||
|
delete[] vecs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F( utSpatialSort, findIdenticalsTest ) {
|
||||||
|
SpatialSort sSort;
|
||||||
|
sSort.Fill(vecs, 100, sizeof(aiVector3D));
|
||||||
|
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
|
sSort.FindIdenticalPositions(vecs[0], indices);
|
||||||
|
EXPECT_EQ(1u, indices.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utSpatialSort, findPositionsTest) {
|
||||||
|
SpatialSort sSort;
|
||||||
|
sSort.Fill(vecs, 100, sizeof(aiVector3D));
|
||||||
|
|
||||||
|
std::vector<unsigned int> indices;
|
||||||
|
sSort.FindPositions(vecs[0], 0.01f, indices);
|
||||||
|
EXPECT_EQ(1u, indices.size());
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2019, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AbstractImportExportBase.h"
|
||||||
|
#include "SceneDiffer.h"
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utAssxmlImportExport : public AbstractImportExportBase {
|
||||||
|
public:
|
||||||
|
bool importerTest() override {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
bool exporterTest() override {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/OBJ/spider.obj", aiProcess_ValidateDataStructure);
|
||||||
|
EXPECT_NE(scene, nullptr );
|
||||||
|
|
||||||
|
::Assimp::Exporter exporter;
|
||||||
|
return AI_SUCCESS == exporter.Export(scene, "assxml", ASSIMP_TEST_MODELS_DIR "/OBJ/spider_out.assxml");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
|
TEST_F(utAssxmlImportExport, exportAssxmlTest) {
|
||||||
|
EXPECT_TRUE(exporterTest());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "AbstractImportExportBase.h"
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utIrrImportExport : public AbstractImportExportBase {
|
||||||
|
public:
|
||||||
|
virtual bool importerTest() {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/IRR/box.irr", aiProcess_ValidateDataStructure);
|
||||||
|
return nullptr != scene;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(utIrrImportExport, importSimpleIrrTest) {
|
||||||
|
EXPECT_TRUE(importerTest());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(utIrrImportExport, importSGIrrTest) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/IRR/dawfInCellar_SameHierarchy.irr", aiProcess_ValidateDataStructure);
|
||||||
|
EXPECT_NE( nullptr,scene);
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "AbstractImportExportBase.h"
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
class utRAWImportExport : public AbstractImportExportBase {
|
||||||
|
public:
|
||||||
|
virtual bool importerTest() {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/RAW/Wuson.raw", aiProcess_ValidateDataStructure);
|
||||||
|
#ifndef ASSIMP_BUILD_NO_RAW_IMPORTER
|
||||||
|
return nullptr != scene;
|
||||||
|
#else
|
||||||
|
return nullptr == scene;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(utRAWImportExport, importSimpleRAWTest) {
|
||||||
|
EXPECT_TRUE(importerTest());
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AbstractImportExportBase.h"
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
|
class utTerragenImportExport : public AbstractImportExportBase {
|
||||||
|
public:
|
||||||
|
virtual bool importerTest() {
|
||||||
|
/*Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/TER/RealisticTerrain.ter", aiProcess_ValidateDataStructure);
|
||||||
|
return nullptr != scene;*/
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(utTerragenImportExport, importX3DFromFileTest) {
|
||||||
|
EXPECT_TRUE(importerTest());
|
||||||
|
}
|
|
@ -39,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#include "MathTest.h"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
// Initialize epsilon value.
|
||||||
|
const float AssimpMathTest::Epsilon = Math::getEpsilon<float>();
|
||||||
|
|
||||||
|
// Initialize with an interval of [1,100].
|
||||||
|
RandomUniformFloatGenerator AssimpMathTest::RandNonZero(1.0f, 100.0f);
|
||||||
|
|
||||||
|
// Initialize with an interval of [-PI,PI] inclusively.
|
||||||
|
RandomUniformFloatGenerator AssimpMathTest::RandPI(-Math::PI<float>(), Math::PI<float>());
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSIMP_MATH_TEST_H
|
||||||
|
#define ASSIMP_MATH_TEST_H
|
||||||
|
|
||||||
|
#include "UnitTestPCH.h"
|
||||||
|
#include <assimp/types.h>
|
||||||
|
#include "RandomNumberGeneration.h"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
/** Custom test class providing several math related utilities. */
|
||||||
|
class AssimpMathTest : public ::testing::Test {
|
||||||
|
public:
|
||||||
|
/** Return a random non-null 2D vector. */
|
||||||
|
inline static aiVector2D random_vec2() {
|
||||||
|
return aiVector2D(RandNonZero.next(), RandNonZero.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a random non-null 3D vector. */
|
||||||
|
inline static aiVector3D random_vec3() {
|
||||||
|
return aiVector3D(RandNonZero.next(), RandNonZero.next(),RandNonZero.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a random unit 3D vector. */
|
||||||
|
inline static aiVector3D random_unit_vec3() {
|
||||||
|
return random_vec3().NormalizeSafe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a quaternion with random orientation and
|
||||||
|
* rotation angle around axis. */
|
||||||
|
inline static aiQuaternion random_quat() {
|
||||||
|
return aiQuaternion(random_unit_vec3(), RandPI.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a random non-null 3x3 matrix. */
|
||||||
|
inline static aiMatrix3x3 random_mat3() {
|
||||||
|
return aiMatrix3x3(
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(),
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(),
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Return a random non-null 4x4 matrix. */
|
||||||
|
inline static aiMatrix4x4 random_mat4() {
|
||||||
|
return aiMatrix4x4(
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next(),
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next(),
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next(),
|
||||||
|
RandNonZero.next(), RandNonZero.next(),RandNonZero.next(), RandNonZero.next());
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Epsilon value to use in tests. */
|
||||||
|
static const float Epsilon;
|
||||||
|
|
||||||
|
/** Random number generators. */
|
||||||
|
static RandomUniformFloatGenerator RandNonZero, RandPI;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_MATH_TEST_H
|
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2020, assimp team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ASSIMP_RANDOM_NUMBER_GENERATION_H
|
||||||
|
#define ASSIMP_RANDOM_NUMBER_GENERATION_H
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
/** Helper class to use for generating pseudo-random
|
||||||
|
* real numbers, with a uniform distribution. */
|
||||||
|
template<typename T>
|
||||||
|
class RandomUniformRealGenerator {
|
||||||
|
public:
|
||||||
|
RandomUniformRealGenerator() :
|
||||||
|
dist_(),
|
||||||
|
rd_(),
|
||||||
|
re_(rd_()) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
RandomUniformRealGenerator(T min, T max) :
|
||||||
|
dist_(min, max),
|
||||||
|
rd_(),
|
||||||
|
re_(rd_()) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
inline T next() {
|
||||||
|
return dist_(re_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::uniform_real_distribution<T> dist_;
|
||||||
|
std::random_device rd_;
|
||||||
|
std::default_random_engine re_;
|
||||||
|
};
|
||||||
|
|
||||||
|
using RandomUniformFloatGenerator = RandomUniformRealGenerator<float>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_RANDOM_NUMBER_GENERATION_H
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
|
|
||||||
#include <assimp/material.h>
|
#include <assimp/material.h>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -39,7 +39,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
#include <assimp/Exporter.hpp>
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
|
@ -40,7 +40,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AbstractImportExportBase.h"
|
#include "AbstractImportExportBase.h"
|
||||||
#include "SceneDiffer.h"
|
|
||||||
#include "UnitTestPCH.h"
|
#include "UnitTestPCH.h"
|
||||||
|
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue