Merge remote-tracking branch 'upstream/master'
commit
d73a64b061
|
@ -0,0 +1,2 @@
|
||||||
|
service_name: travis-pro
|
||||||
|
repo_token: GZXuNlublKFy7HAewHAZLk5ZwgipTFAOA
|
|
@ -0,0 +1,22 @@
|
||||||
|
# See <http://EditorConfig.org> for details
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[CMakeLists.txt,*.cmake{,.in}]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.h.in]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.txt]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Declare files that will always have LF line endings on checkout.
|
||||||
|
*.cpp text eol=lf
|
||||||
|
*.h text eol=lf
|
||||||
|
*.c text eol=lf
|
||||||
|
*.hpp text eol=lf
|
||||||
|
*.txt text eol=lf
|
||||||
|
*.cmake text eol=lf
|
||||||
|
*.sh text eol=lf
|
|
@ -1,3 +1,4 @@
|
||||||
|
.idea
|
||||||
build
|
build
|
||||||
.project
|
.project
|
||||||
*.kdev4*
|
*.kdev4*
|
||||||
|
@ -10,13 +11,14 @@ build
|
||||||
# Output
|
# Output
|
||||||
bin/
|
bin/
|
||||||
lib/
|
lib/
|
||||||
contrib/
|
|
||||||
|
|
||||||
# Generated
|
# Generated
|
||||||
assimp.pc
|
assimp.pc
|
||||||
revision.h
|
revision.h
|
||||||
contrib/zlib/zconf.h
|
contrib/zlib/zconf.h
|
||||||
contrib/zlib/zlib.pc
|
contrib/zlib/zlib.pc
|
||||||
|
include/assimp/config.h
|
||||||
|
|
||||||
# CMake
|
# CMake
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
|
@ -27,8 +29,55 @@ cmake_uninstall.cmake
|
||||||
assimp-config.cmake
|
assimp-config.cmake
|
||||||
assimp-config-version.cmake
|
assimp-config-version.cmake
|
||||||
|
|
||||||
|
# MakeFile
|
||||||
|
Makefile
|
||||||
|
code/Makefile
|
||||||
|
test/Makefile
|
||||||
|
test/headercheck/Makefile
|
||||||
|
tools/assimp_cmd/Makefile
|
||||||
|
|
||||||
# Tests
|
# Tests
|
||||||
test/results
|
test/results
|
||||||
|
|
||||||
# Python
|
# Python
|
||||||
__pycache__
|
__pycache__
|
||||||
|
*.log
|
||||||
|
*.vcxproj
|
||||||
|
*.filters
|
||||||
|
*.tlog
|
||||||
|
Assimp.sdf
|
||||||
|
test/gtest/tmp/gtest-gitupdate.cmake
|
||||||
|
test/gtest/tmp/gtest-gitclone.cmake
|
||||||
|
test/gtest/tmp/gtest-cfgcmd.txt.in
|
||||||
|
test/gtest/tmp/gtest-cfgcmd.txt
|
||||||
|
test/gtest/src/gtest-stamp/gtest-download.cmake
|
||||||
|
test/gtest/src/gtest-stamp/gtest-configure.cmake
|
||||||
|
test/gtest/src/gtest-stamp/gtest-build.cmake
|
||||||
|
test/gtest/src/gtest-stamp/Debug/gtest-patch
|
||||||
|
*.cache
|
||||||
|
test/gtest/src/gtest-stamp/Debug/gtest-build
|
||||||
|
*.suo
|
||||||
|
*.lib
|
||||||
|
test/gtest/src/gtest-stamp/Debug/
|
||||||
|
tools/assimp_view/assimp_viewer.vcxproj.user
|
||||||
|
|
||||||
|
# Unix editor backups
|
||||||
|
*~
|
||||||
|
test/gtest/src/gtest-stamp/gtest-gitinfo.txt
|
||||||
|
test/gtest/src/gtest-stamp/gtest-gitclone-lastrun.txt
|
||||||
|
Assimp.opensdf
|
||||||
|
contrib/zlib/CTestTestfile.cmake
|
||||||
|
ipch/assimp_viewer-44bbbcd1/assimp_viewerd-ccc45335.ipch
|
||||||
|
bin64/assimp-vc140-mt.dll
|
||||||
|
bin64/assimp-vc140-mtd.dll
|
||||||
|
lib64/assimp-vc140-mt.exp
|
||||||
|
lib64/assimp-vc140-mtd.exp
|
||||||
|
lib64/assimp-vc140-mtd.ilk
|
||||||
|
lib64/assimp-vc140-mtd.pdb
|
||||||
|
bin64/assimp-vc120-mt.dll
|
||||||
|
bin64/assimp-vc120-mtd.dll
|
||||||
|
lib64/assimp-vc120-mtd.pdb
|
||||||
|
lib64/assimp-vc120-mtd.ilk
|
||||||
|
lib64/assimp-vc120-mtd.exp
|
||||||
|
lib64/assimp-vc120-mt.exp
|
||||||
|
xcuserdata
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
function generate()
|
||||||
|
{
|
||||||
|
cmake -G "Unix Makefiles" -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD -DASSIMP_COVERALLS=$ENABLE_COVERALLS
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ $ANDROID ]; then
|
||||||
|
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
|
||||||
|
else
|
||||||
|
generate \
|
||||||
|
&& make -j4 \
|
||||||
|
&& sudo make install \
|
||||||
|
&& sudo ldconfig \
|
||||||
|
&& (cd test/unit; ../../bin/unit) \
|
||||||
|
#&& (cd test/regression; chmod 755 run.py; ./run.py ../../bin/assimp; \
|
||||||
|
# chmod 755 result_checker.py; ./result_checker.py)
|
||||||
|
fi
|
69
.travis.yml
69
.travis.yml
|
@ -1,11 +1,32 @@
|
||||||
before_install:
|
before_install:
|
||||||
|
- sudo apt-get update -qq
|
||||||
|
- sudo apt-get install cmake
|
||||||
- sudo apt-get install cmake python3
|
- sudo apt-get install cmake python3
|
||||||
|
- if [ $LINUX ]; then sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; fi
|
||||||
|
- echo -e "#ifndef A_R_H_INC\n#define A_R_H_INC\n#define GitVersion ${TRAVIS_JOB_ID}\n#define GitBranch \"${TRAVIS_BRANCH}\"\n#endif // A_R_H_INC" > revision.h
|
||||||
|
# install latest LCOV (1.9 was failing)
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
- wget http://ftp.de.debian.org/debian/pool/main/l/lcov/lcov_1.11.orig.tar.gz
|
||||||
|
- tar xf lcov_1.11.orig.tar.gz
|
||||||
|
- sudo make -C lcov-1.11/ install
|
||||||
|
- gem install coveralls-lcov
|
||||||
|
- lcov --version
|
||||||
|
- g++ --version
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- TRAVIS_NO_EXPORT=YES
|
global:
|
||||||
- TRAVIS_NO_EXPORT=NO
|
- secure: "lZ7pHQvl5dpZWzBQAaIMf0wqrvtcZ4wiZKeIZjf83TEsflW8+z0uTpIuN30ZV6Glth/Sq1OhLnTP5+N57fZU/1ebA5twHdvP4bS5CIUUg71/CXQZNl36xeaqvxsG/xRrdpKOsPdjAOsQ9KPTQulsX43XDLS7CasMiLvYOpqKcPc="
|
||||||
- TRAVIS_STATIC_BUILD=ON
|
- PV=r8e PLATF=linux-x86_64 NDK_HOME=${TRAVIS_BUILD_DIR}/android-ndk-${PV} PATH=${PATH}:${NDK_HOME}
|
||||||
- TRAVIS_STATIC_BUILD=OFF
|
matrix:
|
||||||
|
- LINUX=1 TRAVIS_NO_EXPORT=YES ENABLE_COVERALLS=ON
|
||||||
|
- LINUX=1 TRAVIS_NO_EXPORT=NO ENABLE_COVERALLS=OFF
|
||||||
|
- LINUX=1 SHARED_BUILD=ON ENABLE_COVERALLS=OFF
|
||||||
|
- LINUX=1 SHARED_BUILD=OFF ENABLE_COVERALLS=OFF
|
||||||
|
- ANDROID=1
|
||||||
|
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
|
@ -13,17 +34,31 @@ compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang
|
||||||
|
|
||||||
script:
|
install:
|
||||||
- cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -STATIC_BUILD=$TRAVIS_STATIC_BUILD
|
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi
|
||||||
- make
|
|
||||||
- sudo make install
|
|
||||||
- sudo ldconfig
|
|
||||||
- cd test/unit
|
|
||||||
- ../../bin/unit
|
|
||||||
- cd ../regression
|
|
||||||
- chmod 755 run.py
|
|
||||||
- ./run.py
|
|
||||||
- echo "=========================================================="
|
|
||||||
- echo "REGRESSION TEST FAILS (results/run_regression_suite_failures.csv)"
|
|
||||||
- cat ../results/run_regression_suite_failures.csv
|
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
# init coverage to 0 (optional)
|
||||||
|
- lcov --directory . --zerocounters
|
||||||
|
|
||||||
|
script:
|
||||||
|
- export COVERALLS_SERVICE_NAME=travis-ci
|
||||||
|
- export COVERALLS_REPO_TOKEN=abc12345
|
||||||
|
- . ./.travis.sh
|
||||||
|
|
||||||
|
after_success:
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
- lcov --directory . --capture --output-file coverage.info
|
||||||
|
- lcov --remove coverage.info '/usr/*' 'contrib/*' 'test/*' --output-file coverage.info
|
||||||
|
- lcov --list coverage.info
|
||||||
|
- coveralls-lcov --source-encoding=ISO-8859-1 --repo-token=${COVERALLS_TOKEN} coverage.info
|
||||||
|
|
||||||
|
addons:
|
||||||
|
coverity_scan:
|
||||||
|
project:
|
||||||
|
name: "assimp/assimp"
|
||||||
|
notification_email: kim.kulling@googlemail.com
|
||||||
|
build_command_prepend: "cmake"
|
||||||
|
build_command: "make"
|
||||||
|
branch_pattern: coverity_scan
|
||||||
|
|
34
CHANGES
34
CHANGES
|
@ -2,6 +2,40 @@
|
||||||
CHANGELOG
|
CHANGELOG
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
3.2.1 (2016-10-01)
|
||||||
|
|
||||||
|
FEATURES:
|
||||||
|
- Updated glTF exporter to meet 1.0 specification.
|
||||||
|
|
||||||
|
FIXES/HOUSEKEEPING:
|
||||||
|
- Fixed glTF Validator errors for exported glTF format.
|
||||||
|
|
||||||
|
ISSUES:
|
||||||
|
- Hard coded sampler setting for
|
||||||
|
- magFilter
|
||||||
|
- minFilter
|
||||||
|
- void* in ExportData for accessor max and min.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
3.2.0 (2015-11-03)
|
||||||
|
|
||||||
|
FEATURES:
|
||||||
|
- OpenDDL-Parser is part of contrib-source.
|
||||||
|
- Experimental OpenGEX-support
|
||||||
|
- CI-check for linux and windows
|
||||||
|
- Coverity check added
|
||||||
|
- New regression testsuite.
|
||||||
|
|
||||||
|
FIXES/HOUSEKEEPING:
|
||||||
|
- Hundreds of bugfixes in all parts of the library
|
||||||
|
- Unified line endings
|
||||||
|
|
||||||
|
|
||||||
|
API COMPATIBILITY:
|
||||||
|
- Removed precompiled header to increase build speed for linux
|
||||||
|
|
||||||
|
|
||||||
3.1.1 (2014-06-15)
|
3.1.1 (2014-06-15)
|
||||||
|
|
||||||
FEATURES:
|
FEATURES:
|
||||||
|
|
482
CMakeLists.txt
482
CMakeLists.txt
|
@ -1,57 +1,188 @@
|
||||||
cmake_minimum_required( VERSION 2.6 )
|
# Open Asset Import Library (assimp)
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006-2016, 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.
|
||||||
|
#
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
SET(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required
|
||||||
|
cmake_minimum_required( VERSION 2.8 )
|
||||||
PROJECT( Assimp )
|
PROJECT( Assimp )
|
||||||
|
|
||||||
# Define here the needed parameters
|
# All supported options ###############################################
|
||||||
set (ASSIMP_VERSION_MAJOR 3)
|
OPTION( BUILD_SHARED_LIBS
|
||||||
set (ASSIMP_VERSION_MINOR 1)
|
"Build package with shared libraries."
|
||||||
set (ASSIMP_VERSION_PATCH 1) # subversion revision?
|
ON
|
||||||
set (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
)
|
||||||
set (ASSIMP_SOVERSION 3)
|
OPTION( ASSIMP_DOUBLE_PRECISION
|
||||||
set (PROJECT_VERSION "${ASSIMP_VERSION}")
|
"Set to ON to enable double precision processing"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION( ASSIMP_OPT_BUILD_PACKAGES
|
||||||
|
"Set to ON to generate CPack configuration files and packaging targets"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION( ASSIMP_ANDROID_JNIIOSYSTEM
|
||||||
|
"Android JNI IOSystem support is active"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION( ASSIMP_NO_EXPORT
|
||||||
|
"Disable Assimp's export functionality."
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION( ASSIMP_BUILD_ZLIB
|
||||||
|
"Build your own zlib"
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
option( ASSIMP_BUILD_ASSIMP_TOOLS
|
||||||
|
"If the supplementary tools for Assimp are built in addition to the library."
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
option ( ASSIMP_BUILD_SAMPLES
|
||||||
|
"If the official samples are built as well (needs Glut)."
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
OPTION ( ASSIMP_BUILD_TESTS
|
||||||
|
"If the test suite for Assimp is built in addition to the library."
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
OPTION ( ASSIMP_COVERALLS
|
||||||
|
"Eańable this to measure test coverage."
|
||||||
|
OFF
|
||||||
|
)
|
||||||
|
|
||||||
set(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
IF(MSVC)
|
||||||
|
set (CMAKE_PREFIX_PATH "D:\\libs\\devil")
|
||||||
|
OPTION( ASSIMP_INSTALL_PDB
|
||||||
|
"Install MSVC debug files."
|
||||||
|
ON
|
||||||
|
)
|
||||||
|
ENDIF(MSVC)
|
||||||
|
|
||||||
|
IF(NOT BUILD_SHARED_LIBS)
|
||||||
|
SET(LINK_SEARCH_START_STATIC TRUE)
|
||||||
|
ENDIF(NOT BUILD_SHARED_LIBS)
|
||||||
|
|
||||||
|
# Define here the needed parameters
|
||||||
|
SET (ASSIMP_VERSION_MAJOR 3)
|
||||||
|
SET (ASSIMP_VERSION_MINOR 3)
|
||||||
|
SET (ASSIMP_VERSION_PATCH 1) # subversion revision?
|
||||||
|
SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
|
||||||
|
SET (ASSIMP_SOVERSION 3)
|
||||||
|
SET (PROJECT_VERSION "${ASSIMP_VERSION}")
|
||||||
|
|
||||||
|
SET(ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources")
|
||||||
|
|
||||||
|
# Needed for openddl_parser config, no use of c++11 at this moment
|
||||||
|
add_definitions( -DOPENDDL_NO_USE_CPP11 )
|
||||||
|
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
|
||||||
|
|
||||||
# Get the current working branch
|
# Get the current working branch
|
||||||
execute_process(
|
EXECUTE_PROCESS(
|
||||||
COMMAND git rev-parse --abbrev-ref HEAD
|
COMMAND git rev-parse --abbrev-ref HEAD
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_BRANCH
|
OUTPUT_VARIABLE GIT_BRANCH
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
)
|
)
|
||||||
|
|
||||||
# Get the latest abbreviated commit hash of the working branch
|
# Get the latest abbreviated commit hash of the working branch
|
||||||
execute_process(
|
EXECUTE_PROCESS(
|
||||||
COMMAND git log -1 --format=%h
|
COMMAND git log -1 --format=%h
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
ERROR_QUIET
|
||||||
)
|
)
|
||||||
|
|
||||||
if(NOT GIT_COMMIT_HASH)
|
IF(NOT GIT_COMMIT_HASH)
|
||||||
set(GIT_COMMIT_HASH 0)
|
SET(GIT_COMMIT_HASH 0)
|
||||||
endif(NOT GIT_COMMIT_HASH)
|
ENDIF(NOT GIT_COMMIT_HASH)
|
||||||
|
|
||||||
|
IF(ASSIMP_DOUBLE_PRECISION)
|
||||||
|
ADD_DEFINITIONS(-DASSIMP_DOUBLE_PRECISION)
|
||||||
|
ENDIF(ASSIMP_DOUBLE_PRECISION)
|
||||||
|
|
||||||
configure_file(
|
configure_file(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/revision.h.in
|
${CMAKE_CURRENT_LIST_DIR}/revision.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
${CMAKE_CURRENT_BINARY_DIR}/revision.h
|
||||||
)
|
)
|
||||||
|
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
configure_file(
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/include/assimp/config.h.in
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/include/assimp/config.h
|
||||||
|
)
|
||||||
|
|
||||||
option(ASSIMP_OPT_BUILD_PACKAGES "Set to ON to generate CPack configuration files and packaging targets" OFF)
|
include_directories(
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
|
./
|
||||||
set(LIBASSIMP_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}" )
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
set(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev" )
|
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||||
set(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
)
|
||||||
set(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
|
||||||
|
|
||||||
if((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
|
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules" )
|
||||||
add_definitions(-fPIC) # this is a very important switch and some libraries seem now to have it....
|
SET(LIBASSIMP_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}" )
|
||||||
|
SET(LIBASSIMP-DEV_COMPONENT "libassimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH}-dev" )
|
||||||
|
SET(CPACK_COMPONENTS_ALL assimp-bin ${LIBASSIMP_COMPONENT} ${LIBASSIMP-DEV_COMPONENT} assimp-dev)
|
||||||
|
SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
|
||||||
|
|
||||||
|
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
|
||||||
|
IF( UNIX )
|
||||||
|
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
|
||||||
|
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
IF((CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) AND NOT CMAKE_COMPILER_IS_MINGW)
|
||||||
|
IF (BUILD_SHARED_LIBS AND CMAKE_SIZEOF_VOID_P EQUAL 8) # -fPIC is only required for shared libs on 64 bit
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||||
|
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
|
||||||
|
ENDIF()
|
||||||
# hide all not-exported symbols
|
# hide all not-exported symbols
|
||||||
add_definitions( -fvisibility=hidden -Wall )
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -Wall -std=c++0x" )
|
||||||
elseif(MSVC)
|
ELSEIF(MSVC)
|
||||||
# enable multi-core compilation with MSVC
|
# enable multi-core compilation with MSVC
|
||||||
add_definitions(/MP)
|
add_compile_options(/MP)
|
||||||
|
ELSEIF ( "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
|
||||||
|
ELSEIF( CMAKE_COMPILER_IS_MINGW )
|
||||||
|
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -Wno-long-long -pedantic -std=c++11" )
|
||||||
|
add_definitions( -U__STRICT_ANSI__ )
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
if (ASSIMP_COVERALLS)
|
||||||
|
include(Coveralls)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
INCLUDE (FindPkgConfig)
|
INCLUDE (FindPkgConfig)
|
||||||
|
@ -70,27 +201,18 @@ IF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||||
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
ENDIF ( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||||
|
|
||||||
# Cache these to allow the user to override them manually.
|
# Cache these to allow the user to override them manually.
|
||||||
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE PATH
|
SET( ASSIMP_LIB_INSTALL_DIR "lib" CACHE STRING
|
||||||
"Path the built library files are installed to." )
|
"Path the built library files are installed to." )
|
||||||
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
|
SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE STRING
|
||||||
"Path the header files are installed to." )
|
"Path the header files are installed to." )
|
||||||
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE STRING
|
||||||
"Path the tool executables are installed to." )
|
"Path the tool executables are installed to." )
|
||||||
option (ASSIMP_BUILD_STATIC_LIB "Build a static (.a) version of the library" OFF)
|
|
||||||
|
|
||||||
SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools")
|
||||||
# Allow the user to build a static library
|
ELSE()
|
||||||
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
|
SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
|
||||||
IF ( ASSIMP_BUILD_STATIC_LIB )
|
ENDIF()
|
||||||
option ( BUILD_SHARED_LIBS "Build a shared version of the library" OFF )
|
|
||||||
ELSE ( ASSIMP_BUILD_STATIC_LIB )
|
|
||||||
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
|
|
||||||
ENDIF ( ASSIMP_BUILD_STATIC_LIB )
|
|
||||||
|
|
||||||
# Generate a pkg-config .pc for the Assimp library.
|
|
||||||
CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assimp.pc" @ONLY )
|
|
||||||
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
|
||||||
|
|
||||||
# Only generate this target if no higher-level project already has
|
# Only generate this target if no higher-level project already has
|
||||||
IF (NOT TARGET uninstall)
|
IF (NOT TARGET uninstall)
|
||||||
|
@ -99,74 +221,49 @@ IF (NOT TARGET uninstall)
|
||||||
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
add_custom_target(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
# Globally enable Boost resp. the Boost workaround – it is also needed by the
|
|
||||||
# tools which include the Assimp headers.
|
|
||||||
option ( ASSIMP_ENABLE_BOOST_WORKAROUND
|
|
||||||
"If a simple implementation of the used Boost functions is used. Slightly reduces functionality, but enables builds without Boost available."
|
|
||||||
ON
|
|
||||||
)
|
|
||||||
IF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
|
||||||
INCLUDE_DIRECTORIES( code/BoostWorkaround )
|
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_BOOST_WORKAROUND )
|
|
||||||
MESSAGE( STATUS "Building a non-boost version of Assimp." )
|
|
||||||
ELSE ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
|
||||||
SET( Boost_DETAILED_FAILURE_MSG ON )
|
|
||||||
SET( Boost_ADDITIONAL_VERSIONS "1.47" "1.47.0" "1.48.0" "1.48" "1.49" "1.49.0" "1.50" "1.50.0" "1.51" "1.51.0" "1.52.0" "1.53.0" "1.54.0" "1.55" )
|
|
||||||
FIND_PACKAGE( Boost )
|
|
||||||
IF ( NOT Boost_FOUND )
|
|
||||||
MESSAGE( FATAL_ERROR
|
|
||||||
"Boost libraries (http://www.boost.org/) not found. "
|
|
||||||
"You can build a non-boost version of Assimp with slightly reduced "
|
|
||||||
"functionality by specifying -DASSIMP_ENABLE_BOOST_WORKAROUND=ON."
|
|
||||||
)
|
|
||||||
ENDIF ( NOT Boost_FOUND )
|
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} )
|
|
||||||
ENDIF ( ASSIMP_ENABLE_BOOST_WORKAROUND )
|
|
||||||
|
|
||||||
# cmake configuration files
|
# cmake configuration files
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" @ONLY IMMEDIATE)
|
||||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/assimp-config-version.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" @ONLY IMMEDIATE)
|
||||||
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/assimp-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/assimp-config-version.cmake" DESTINATION "${ASSIMP_LIB_INSTALL_DIR}/cmake/assimp-${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}" COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
|
|
||||||
option ( ASSIMP_NO_EXPORT
|
FIND_PACKAGE( DirectX )
|
||||||
"Disable Assimp's export functionality."
|
|
||||||
OFF
|
IF( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
)
|
SET(LIBSTDC++_LIBRARIES -lstdc++)
|
||||||
|
ENDIF( CMAKE_COMPILER_IS_GNUCXX )
|
||||||
|
|
||||||
# Search for external dependencies, and build them from source if not found
|
# Search for external dependencies, and build them from source if not found
|
||||||
# Search for zlib
|
# Search for zlib
|
||||||
find_package(ZLIB)
|
IF ( NOT ASSIMP_BUILD_ZLIB )
|
||||||
if( NOT ZLIB_FOUND )
|
find_package(ZLIB)
|
||||||
|
ENDIF( NOT ASSIMP_BUILD_ZLIB )
|
||||||
|
|
||||||
|
IF( NOT ZLIB_FOUND )
|
||||||
message(STATUS "compiling zlib from souces")
|
message(STATUS "compiling zlib from souces")
|
||||||
include(CheckIncludeFile)
|
include(CheckIncludeFile)
|
||||||
include(CheckTypeSize)
|
include(CheckTypeSize)
|
||||||
include(CheckFunctionExists)
|
include(CheckFunctionExists)
|
||||||
# compile from sources
|
# compile from sources
|
||||||
add_subdirectory(contrib/zlib)
|
add_subdirectory(contrib/zlib)
|
||||||
set(ZLIB_FOUND 1)
|
SET(ZLIB_FOUND 1)
|
||||||
set(ZLIB_LIBRARIES zlibstatic)
|
SET(ZLIB_LIBRARIES zlibstatic)
|
||||||
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
SET(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
|
||||||
else(NOT ZLIB_FOUND)
|
else(NOT ZLIB_FOUND)
|
||||||
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
|
||||||
endif(NOT ZLIB_FOUND)
|
SET(ZLIB_LIBRARIES_LINKED -lz)
|
||||||
|
ENDIF(NOT ZLIB_FOUND)
|
||||||
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
|
||||||
|
|
||||||
# Search for unzip
|
# Search for unzip
|
||||||
if (PKG_CONFIG_FOUND)
|
IF (PKG_CONFIG_FOUND)
|
||||||
PKG_CHECK_MODULES(UNZIP minizip)
|
PKG_CHECK_MODULES(UNZIP minizip)
|
||||||
endif (PKG_CONFIG_FOUND)
|
ENDIF (PKG_CONFIG_FOUND)
|
||||||
|
|
||||||
IF ( ASSIMP_NO_EXPORT )
|
IF ( ASSIMP_NO_EXPORT )
|
||||||
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_EXPORT)
|
||||||
MESSAGE( STATUS "Build an import-only version of Assimp." )
|
MESSAGE( STATUS "Build an import-only version of Assimp." )
|
||||||
ENDIF( ASSIMP_NO_EXPORT )
|
ENDIF( ASSIMP_NO_EXPORT )
|
||||||
|
|
||||||
# if(CMAKE_CL_64)
|
|
||||||
# set(ASSIMP_BUILD_ARCHITECTURE "amd64")
|
|
||||||
# else(CMAKE_CL_64)
|
|
||||||
# set(ASSIMP_BUILD_ARCHITECTURE "x86")
|
|
||||||
# endif(CMAKE_CL_64)
|
|
||||||
SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING
|
SET ( ASSIMP_BUILD_ARCHITECTURE "" CACHE STRING
|
||||||
"describe the current architecture."
|
"describe the current architecture."
|
||||||
)
|
)
|
||||||
|
@ -186,22 +283,88 @@ ENDIF ( ASSIMP_BUILD_COMPILER STREQUAL "")
|
||||||
|
|
||||||
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
||||||
|
|
||||||
ADD_SUBDIRECTORY( code/ )
|
SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
|
||||||
option ( ASSIMP_BUILD_ASSIMP_TOOLS
|
"Build the C4D importer, which relies on the non-free Melange SDK."
|
||||||
"If the supplementary tools for Assimp are built in addition to the library."
|
|
||||||
ON
|
|
||||||
)
|
)
|
||||||
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|
||||||
IF ( WIN32 )
|
|
||||||
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
|
||||||
ENDIF ( WIN32 )
|
|
||||||
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
|
||||||
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
|
||||||
|
|
||||||
option ( ASSIMP_BUILD_SAMPLES
|
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
"If the official samples are built as well (needs Glut)."
|
IF ( MSVC )
|
||||||
OFF
|
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes")
|
||||||
)
|
|
||||||
|
# pick the correct prebuilt library
|
||||||
|
IF(MSVC14)
|
||||||
|
SET(C4D_LIB_POSTFIX "_2015")
|
||||||
|
ELSEIF(MSVC12)
|
||||||
|
SET(C4D_LIB_POSTFIX "_2013")
|
||||||
|
ELSEIF(MSVC11)
|
||||||
|
SET(C4D_LIB_POSTFIX "_2012")
|
||||||
|
ELSEIF(MSVC10)
|
||||||
|
SET(C4D_LIB_POSTFIX "_2010")
|
||||||
|
ELSE()
|
||||||
|
MESSAGE( FATAL_ERROR
|
||||||
|
"C4D is currently only supported with MSVC 10, 11, 12, 14"
|
||||||
|
)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/libraries/win")
|
||||||
|
|
||||||
|
SET(C4D_DEBUG_LIBRARIES
|
||||||
|
"${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_debug.lib"
|
||||||
|
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_debug.lib"
|
||||||
|
)
|
||||||
|
SET(C4D_RELEASE_LIBRARIES
|
||||||
|
"${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_release.lib"
|
||||||
|
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_release.lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
# winsock and winmm are necessary dependencies of melange (this is undocumented, but true.)
|
||||||
|
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
|
||||||
|
ELSE ()
|
||||||
|
MESSAGE( FATAL_ERROR
|
||||||
|
"C4D is currently only available on Windows with melange SDK installed in contrib/Melange"
|
||||||
|
)
|
||||||
|
ENDIF ( MSVC )
|
||||||
|
ELSE (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
|
ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
|
||||||
|
ENDIF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY( code/ )
|
||||||
|
IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
|
IF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
||||||
|
option ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
|
||||||
|
IF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||||
|
ADD_SUBDIRECTORY( tools/assimp_view/ )
|
||||||
|
ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
|
||||||
|
ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
|
||||||
|
|
||||||
|
ADD_SUBDIRECTORY( tools/assimp_cmd/ )
|
||||||
|
|
||||||
|
# Check dependencies for assimp_qt_viewer.
|
||||||
|
# Why here? Maybe user do not want Qt viewer and have no Qt.
|
||||||
|
# Why assimp_qt_viewer/CMakeLists.txt still contain similar check?
|
||||||
|
# Because viewer can be build independently of Assimp.
|
||||||
|
FIND_PACKAGE(Qt5Widgets QUIET)
|
||||||
|
FIND_PACKAGE(DevIL QUIET)
|
||||||
|
FIND_PACKAGE(OpenGL QUIET)
|
||||||
|
IF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||||
|
ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
|
||||||
|
ELSE()
|
||||||
|
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
|
||||||
|
IF (NOT Qt5_FOUND)
|
||||||
|
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
|
||||||
|
ENDIF (NOT Qt5_FOUND)
|
||||||
|
|
||||||
|
IF (NOT IL_FOUND)
|
||||||
|
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} DevIL")
|
||||||
|
ENDIF (NOT IL_FOUND)
|
||||||
|
|
||||||
|
IF (NOT OPENGL_FOUND)
|
||||||
|
SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
|
||||||
|
ENDIF (NOT OPENGL_FOUND)
|
||||||
|
|
||||||
|
MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
|
||||||
|
ENDIF ( Qt5Widgets_FOUND AND IL_FOUND AND OPENGL_FOUND)
|
||||||
|
ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_SAMPLES)
|
IF ( ASSIMP_BUILD_SAMPLES)
|
||||||
IF ( WIN32 )
|
IF ( WIN32 )
|
||||||
|
@ -210,68 +373,87 @@ IF ( ASSIMP_BUILD_SAMPLES)
|
||||||
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
ADD_SUBDIRECTORY( samples/SimpleOpenGL/ )
|
||||||
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
ENDIF ( ASSIMP_BUILD_SAMPLES )
|
||||||
|
|
||||||
option ( ASSIMP_BUILD_TESTS
|
|
||||||
"If the test suite for Assimp is built in addition to the library."
|
|
||||||
ON
|
|
||||||
)
|
|
||||||
|
|
||||||
IF ( ASSIMP_BUILD_TESTS )
|
IF ( ASSIMP_BUILD_TESTS )
|
||||||
ADD_SUBDIRECTORY( test/ )
|
ADD_SUBDIRECTORY( test/ )
|
||||||
ENDIF ( ASSIMP_BUILD_TESTS )
|
ENDIF ( ASSIMP_BUILD_TESTS )
|
||||||
|
|
||||||
IF(MSVC)
|
# Generate a pkg-config .pc for the Assimp library.
|
||||||
option ( ASSIMP_INSTALL_PDB
|
CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assimp.pc" @ONLY )
|
||||||
"Install MSVC debug files."
|
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
|
||||||
ON
|
|
||||||
)
|
|
||||||
ENDIF(MSVC)
|
|
||||||
|
|
||||||
if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
|
IF(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
|
||||||
# Packing information
|
# Packing information
|
||||||
set(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}")
|
SET(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
|
SET(CPACK_PACKAGE_CONTACT "" CACHE STRING "Package maintainer and PGP signer.")
|
||||||
set(CPACK_PACKAGE_VENDOR "http://assimp.sourceforge.net/")
|
SET(CPACK_PACKAGE_VENDOR "https://github.com/assimp")
|
||||||
set(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
|
SET(CPACK_PACKAGE_DISPLAY_NAME "Assimp ${ASSIMP_VERSION}")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY " - Open Asset Import Library ${ASSIMP_VERSION}")
|
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY " - Open Asset Import Library ${ASSIMP_VERSION}")
|
||||||
set(CPACK_PACKAGE_VERSION "${ASSIMP_VERSION}.${ASSIMP_PACKAGE_VERSION}" )
|
SET(CPACK_PACKAGE_VERSION "${ASSIMP_VERSION}.${ASSIMP_PACKAGE_VERSION}" )
|
||||||
set(CPACK_PACKAGE_VERSION_MAJOR "${ASSIMP_VERSION_MAJOR}")
|
SET(CPACK_PACKAGE_VERSION_MAJOR "${ASSIMP_VERSION_MAJOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_MINOR "${ASSIMP_VERSION_MINOR}")
|
SET(CPACK_PACKAGE_VERSION_MINOR "${ASSIMP_VERSION_MINOR}")
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH "${ASSIMP_VERSION_PATCH}")
|
SET(CPACK_PACKAGE_VERSION_PATCH "${ASSIMP_VERSION_PATCH}")
|
||||||
set(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
|
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "assimp${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}")
|
||||||
#set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/description")
|
SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
||||||
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
|
|
||||||
|
|
||||||
string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER")
|
string(TOUPPER ${LIBASSIMP_COMPONENT} "LIBASSIMP_COMPONENT_UPPER")
|
||||||
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER")
|
string(TOUPPER ${LIBASSIMP-DEV_COMPONENT} "LIBASSIMP-DEV_COMPONENT_UPPER")
|
||||||
|
|
||||||
set(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
|
SET(CPACK_COMPONENT_ASSIMP-BIN_DISPLAY_NAME "tools")
|
||||||
set(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" )
|
SET(CPACK_COMPONENT_ASSIMP-BIN_DEPENDS "${LIBASSIMP_COMPONENT}" )
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP_COMPONENT_UPPER}_DISPLAY_NAME "libraries")
|
SET(CPACK_COMPONENT_${LIBASSIMP_COMPONENT_UPPER}_DISPLAY_NAME "libraries")
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DISPLAY_NAME "common headers and installs")
|
SET(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DISPLAY_NAME "common headers and installs")
|
||||||
set(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DEPENDS $ "{LIBASSIMP_COMPONENT}" )
|
SET(CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT_UPPER}_DEPENDS $ "{LIBASSIMP_COMPONENT}" )
|
||||||
set(CPACK_COMPONENT_ASSIMP-DEV_DISPLAY_NAME "${CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT}_DISPLAY_NAME}" )
|
SET(CPACK_COMPONENT_ASSIMP-DEV_DISPLAY_NAME "${CPACK_COMPONENT_${LIBASSIMP-DEV_COMPONENT}_DISPLAY_NAME}" )
|
||||||
set(CPACK_COMPONENT_ASSIMP-DEV_DEPENDS "${LIBASSIMP-DEV_COMPONENT}" )
|
SET(CPACK_COMPONENT_ASSIMP-DEV_DEPENDS "${LIBASSIMP-DEV_COMPONENT}" )
|
||||||
set(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake libboost-dev libboost-thread-dev libboost-math-dev zlib1g-dev pkg-config)
|
SET(CPACK_DEBIAN_BUILD_DEPENDS debhelper cmake zlib1g-dev pkg-config)
|
||||||
|
|
||||||
# debian
|
# debian
|
||||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
SET(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||||
set(CPACK_DEBIAN_CMAKE_OPTIONS "-DBUILD_ASSIMP_SAMPLES:BOOL=${ASSIMP_BUILD_SAMPLES}")
|
SET(CPACK_DEBIAN_CMAKE_OPTIONS "-DBUILD_ASSIMP_SAMPLES:BOOL=${ASSIMP_BUILD_SAMPLES}")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
SET(CPACK_DEBIAN_PACKAGE_SECTION "libs" )
|
||||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
SET(CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_COMPONENTS_ALL}")
|
||||||
set(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
|
||||||
set(CPACK_DEBIAN_PACKAGE_NAME "assimp")
|
SET(CPACK_DEBIAN_PACKAGE_NAME "assimp")
|
||||||
set(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging)
|
SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/cppunit-1.12.1 contrib/cppunit_note.txt contrib/zlib workspaces test doc obj samples packaging)
|
||||||
set(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
|
||||||
set(CPACK_DEBIAN_CHANGELOG)
|
SET(CPACK_DEBIAN_CHANGELOG)
|
||||||
execute_process(COMMAND lsb_release -is
|
execute_process(COMMAND lsb_release -is
|
||||||
OUTPUT_VARIABLE _lsb_distribution OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_VARIABLE _lsb_distribution OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
RESULT_VARIABLE _lsb_release_failed)
|
RESULT_VARIABLE _lsb_release_failed)
|
||||||
set(CPACK_DEBIAN_DISTRIBUTION_NAME ${_lsb_distribution} CACHE STRING "Name of the distrubiton")
|
SET(CPACK_DEBIAN_DISTRIBUTION_NAME ${_lsb_distribution} CACHE STRING "Name of the distrubiton")
|
||||||
string(TOLOWER ${CPACK_DEBIAN_DISTRIBUTION_NAME} CPACK_DEBIAN_DISTRIBUTION_NAME)
|
STRING(TOLOWER ${CPACK_DEBIAN_DISTRIBUTION_NAME} CPACK_DEBIAN_DISTRIBUTION_NAME)
|
||||||
if( ${CPACK_DEBIAN_DISTRIBUTION_NAME} STREQUAL "ubuntu" )
|
IF( ${CPACK_DEBIAN_DISTRIBUTION_NAME} STREQUAL "ubuntu" )
|
||||||
set(CPACK_DEBIAN_DISTRIBUTION_RELEASES lucid maverick natty oneiric precise CACHE STRING "Release code-names of the distrubiton release")
|
SET(CPACK_DEBIAN_DISTRIBUTION_RELEASES lucid maverick natty oneiric precise CACHE STRING "Release code-names of the distrubiton release")
|
||||||
endif()
|
ENDIF()
|
||||||
set(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources")
|
SET(DPUT_HOST "" CACHE STRING "PPA repository to upload the debian sources")
|
||||||
include(CPack)
|
include(CPack)
|
||||||
include(DebSourcePPA)
|
include(DebSourcePPA)
|
||||||
endif()
|
ENDIF()
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
SET(BIN_DIR "${PROJECT_SOURCE_DIR}/bin64/")
|
||||||
|
SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib64/")
|
||||||
|
elseif()
|
||||||
|
SET(BIN_DIR "${PROJECT_SOURCE_DIR}/bin32/")
|
||||||
|
SET(LIB_DIR "${PROJECT_SOURCE_DIR}/lib32/")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
if(MSVC12)
|
||||||
|
SET(ASSIMP_MSVC_VERSION "vc120")
|
||||||
|
elseif(MSVC14)
|
||||||
|
SET(ASSIMP_MSVC_VERSION "vc140")
|
||||||
|
ENDIF(MSVC12)
|
||||||
|
|
||||||
|
if(MSVC12 OR MSVC14)
|
||||||
|
add_custom_target(UpdateAssimpLibsDebugSymbolsAndDLLs COMMENT "Copying Assimp Libraries ..." VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.dll VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.exp VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mt.lib VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${BIN_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.dll VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.exp ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.exp VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.ilk VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.lib ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.lib VERBATIM)
|
||||||
|
add_custom_command(TARGET UpdateAssimpLibsDebugSymbolsAndDLLs COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/code/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb ${LIB_DIR}assimp-${ASSIMP_MSVC_VERSION}-mtd.pdb VERBATIM)
|
||||||
|
ENDIF(MSVC12 OR MSVC14)
|
||||||
|
ENDIF (WIN32)
|
||||||
|
|
18
CREDITS
18
CREDITS
|
@ -7,13 +7,13 @@ The following is a non-exhaustive list of all constributors over the years.
|
||||||
If you think your name should be listed here, drop us a line and we'll add you.
|
If you think your name should be listed here, drop us a line and we'll add you.
|
||||||
|
|
||||||
- Alexander Gessler,
|
- Alexander Gessler,
|
||||||
3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Admin and Design).
|
3DS-, BLEND-, ASE-, DXF-, HMP-, MDL-, MD2-, MD3-, MD5-, MDC-, NFF-, PLY-, STL-, RAW-, OFF-, MS3D-, Q3D- and LWO-Loader, Assimp-Viewer, assimp-cmd, -noboost, Website (Design).
|
||||||
|
|
||||||
- Thomas Schulze,
|
- Thomas Schulze,
|
||||||
X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation.
|
X-, Collada-, BVH-Loader, Postprocessing framework. Data structure & Interface design, documentation.
|
||||||
|
|
||||||
- Kim Kulling,
|
- Kim Kulling,
|
||||||
Obj-Loader, Logging system, Scons-build environment, CMake build environment, Linux build.
|
Obj-, Q3BSD-, OpenGEX-Loader, Logging system, CMake-build-environment, Linux-build, Website ( Admin ), Coverity ( Admin ), Glitter ( Admin ).
|
||||||
|
|
||||||
- R.Schmidt,
|
- R.Schmidt,
|
||||||
Linux build, eclipse support.
|
Linux build, eclipse support.
|
||||||
|
@ -30,7 +30,7 @@ Ogre Loader, VC2010 fixes and CMake fixes.
|
||||||
|
|
||||||
- Sebastian Hempel,
|
- Sebastian Hempel,
|
||||||
PyAssimp (first version)
|
PyAssimp (first version)
|
||||||
Compile-Bugfixes for mingw, add enviroment for static library support in make.
|
Compile-Bugfixes for mingw, add environment for static library support in make.
|
||||||
|
|
||||||
- Jonathan Pokrass
|
- Jonathan Pokrass
|
||||||
Supplied a bugfix concerning the scaling in the md3 loader.
|
Supplied a bugfix concerning the scaling in the md3 loader.
|
||||||
|
@ -114,7 +114,7 @@ Contributes a fix for the configure script environment.
|
||||||
Contributed AssimpDelphi (/port/AssimpDelphi).
|
Contributed AssimpDelphi (/port/AssimpDelphi).
|
||||||
|
|
||||||
- rdb
|
- rdb
|
||||||
Contributes a bundle of fixes and improvments for the bsp-importer.
|
Contributes a bundle of fixes and improvements for the bsp-importer.
|
||||||
|
|
||||||
- Mick P
|
- Mick P
|
||||||
For contributing the De-bone postprocessing step and filing various bug reports.
|
For contributing the De-bone postprocessing step and filing various bug reports.
|
||||||
|
@ -148,3 +148,13 @@ Bugfixes for uv-tanget calculation.
|
||||||
|
|
||||||
- Jonne Nauha
|
- Jonne Nauha
|
||||||
Ogre Binary format support
|
Ogre Binary format support
|
||||||
|
|
||||||
|
- Filip Wasil, Tieto Poland Sp. z o.o.
|
||||||
|
Android JNI asset extraction support
|
||||||
|
|
||||||
|
- Richard Steffen
|
||||||
|
Contributed ExportProperties interface
|
||||||
|
Contributed X File exporter
|
||||||
|
Contributed Step (stp) exporter
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
Open Asset Import Library Coding Conventions
|
||||||
|
==
|
||||||
|
|
||||||
|
If you want to participate as a developer in the **Open Asset Import Library** please read and respect the following coding conventions. This will ensure consistency throughout the codebase and help all the Open Asset Import Library users.
|
||||||
|
|
||||||
|
Spacing
|
||||||
|
==
|
||||||
|
|
||||||
|
* Use UNIX-style line endings (LF)
|
||||||
|
* Remove any trailing whitespace
|
||||||
|
* Expand tabs to 4 spaces
|
|
@ -1,14 +0,0 @@
|
||||||
===============================================
|
|
||||||
The Asset-Importer-Library Coding conventions
|
|
||||||
===============================================
|
|
||||||
|
|
||||||
If you want to participate to the Asset-Importer_Library please have a look
|
|
||||||
onto these coding conventions and try to follow them. They are more or less
|
|
||||||
some kind of guide line to help others coming into the code and help all
|
|
||||||
the Asset-Importer-Library users.
|
|
||||||
|
|
||||||
Tab width
|
|
||||||
===========
|
|
||||||
The tab width shall be 4 spaces.
|
|
||||||
|
|
||||||
|
|
15
INSTALL
15
INSTALL
|
@ -33,13 +33,12 @@ CMake is the preferred build system for Assimp. The minimum required version
|
||||||
is 2.6. If you don't have it yet, downloads for CMake can be found on
|
is 2.6. If you don't have it yet, downloads for CMake can be found on
|
||||||
http://www.cmake.org/.
|
http://www.cmake.org/.
|
||||||
|
|
||||||
Building Assimp with CMake is 'business as usual' if you've used CMake
|
For Unix:
|
||||||
before. All steps can be done either on the command line / shell or
|
|
||||||
by using the CMake GUI tool, the choice is up to you.
|
|
||||||
|
|
||||||
First, invoke CMake to generate build files for a particular
|
|
||||||
toolchain (for standard GNU makefiles: cmake -G 'Unix Makefiles').
|
|
||||||
Afterwards, use the generated build files to perform the actual
|
|
||||||
build.
|
|
||||||
|
|
||||||
|
1. cmake CMakeLists.txt -G 'Unix Makefiles'
|
||||||
|
2. make
|
||||||
|
|
||||||
|
For Windows:
|
||||||
|
1. Open a command prompt
|
||||||
|
2. cmake CMakeLists.txt
|
||||||
|
2. Open your default IDE and build it
|
||||||
|
|
8
LICENSE
8
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -76,9 +76,3 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
89
Readme.md
89
Readme.md
|
@ -1,18 +1,34 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
========
|
==================================
|
||||||
|
|
||||||
Open Asset Import Library is a Open Source library designed to load various __3d file formats and convert them into a shared, in-memory format__. It supports more than __40 file formats__ for import and a growing selection of file formats for export. Additionally, assimp features various __post processing tools__ to refine the imported data: _normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials_ and many more.
|
[![Linux Build Status](https://travis-ci.org/assimp/assimp.svg)](https://travis-ci.org/assimp/assimp)
|
||||||
|
[![Windows Build Status](https://ci.appveyor.com/api/projects/status/tmo433wax6u6cjp4?svg=true)](https://ci.appveyor.com/project/kimkulling/assimp)
|
||||||
|
<a href="https://scan.coverity.com/projects/5607">
|
||||||
|
<img alt="Coverity Scan Build Status"
|
||||||
|
src="https://scan.coverity.com/projects/5607/badge.svg"/>
|
||||||
|
</a>
|
||||||
|
[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
|
||||||
|
<br>
|
||||||
|
|
||||||
This is the development trunk of assimp containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories. According to [Travis-CI] (https://travis-ci.org/), the current build status of the trunk is [![Build Status](https://travis-ci.org/assimp/assimp.png)](https://travis-ci.org/assimp/assimp)
|
APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
|
||||||
|
|
||||||
[open3mod](https://github.com/acgessler/open3mod) is an Open Source 3D model viewer based off Assimp's import and export abilities.
|
Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
|
||||||
|
|
||||||
|
This is the development trunk containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [assimp.sf.net](http://assimp.sf.net) or from *nix package repositories.
|
||||||
|
The current build status is:
|
||||||
|
|
||||||
|
Gitter chat: [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||||
|
__[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.__
|
||||||
|
|
||||||
|
Please check our Wiki as well: https://github.com/assimp/assimp/wiki
|
||||||
|
|
||||||
#### Supported file formats ####
|
#### Supported file formats ####
|
||||||
|
|
||||||
The library provides importers for a lot of file formats, including:
|
A full list [is here](http://assimp.org/main_features_formats.html).
|
||||||
|
__Importers__:
|
||||||
|
|
||||||
- 3DS
|
- 3DS
|
||||||
- BLEND (Blender 3D)
|
- BLEND (Blender)
|
||||||
- DAE/Collada
|
- DAE/Collada
|
||||||
- FBX
|
- FBX
|
||||||
- IFC-STEP
|
- IFC-STEP
|
||||||
|
@ -29,6 +45,7 @@ The library provides importers for a lot of file formats, including:
|
||||||
- STL
|
- STL
|
||||||
- X
|
- X
|
||||||
- OBJ
|
- OBJ
|
||||||
|
- OpenGEX
|
||||||
- SMD
|
- SMD
|
||||||
- LWO
|
- LWO
|
||||||
- LXO
|
- LXO
|
||||||
|
@ -46,13 +63,15 @@ The library provides importers for a lot of file formats, including:
|
||||||
- Ogre Binary
|
- Ogre Binary
|
||||||
- Ogre XML
|
- Ogre XML
|
||||||
- Q3D
|
- Q3D
|
||||||
- ASSBIN (Assimp scene serialization)
|
- ASSBIN (Assimp custom format)
|
||||||
|
- glTF (partial)
|
||||||
|
- 3MF
|
||||||
|
|
||||||
Additionally, the following formats are also supported, but not part of the core library as they depend on proprietary libraries.
|
Additionally, some formats are supported by dependency on non-free code or external SDKs (not built by default):
|
||||||
|
|
||||||
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
- C4D (https://github.com/acgessler/assimp-cinema4d)
|
||||||
|
|
||||||
Exporters include:
|
__Exporters__:
|
||||||
|
|
||||||
- DAE (Collada)
|
- DAE (Collada)
|
||||||
- STL
|
- STL
|
||||||
|
@ -62,65 +81,63 @@ Exporters include:
|
||||||
- 3DS
|
- 3DS
|
||||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||||
- ASSBIN
|
- ASSBIN
|
||||||
|
- STEP
|
||||||
|
- glTF (partial)
|
||||||
|
|
||||||
See [the full list here](http://assimp.sourceforge.net/main_features_formats.html).
|
### Building ###
|
||||||
|
Take a look into the `INSTALL` file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
|
||||||
|
|
||||||
|
### Ports ###
|
||||||
|
* [Android](port/AndroidJNI/README.md)
|
||||||
|
* [Python](port/PyAssimp/README.md)
|
||||||
|
* [.NET](port/AssimpNET/Readme.md)
|
||||||
|
* [Pascal](port/AssimpPascal/Readme.md)
|
||||||
|
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
|
||||||
|
|
||||||
#### Repository structure ####
|
#### Repository structure ####
|
||||||
|
Open Asset Import Library is implemented in C++. The directory structure is:
|
||||||
|
|
||||||
|
|
||||||
Open Asset Import Library is implemented in C++ (but provides both a C and a
|
|
||||||
C++ish interface). The directory structure is:
|
|
||||||
|
|
||||||
/bin Folder for binaries, only used on Windows
|
|
||||||
/code Source code
|
/code Source code
|
||||||
/contrib Third-party libraries
|
/contrib Third-party libraries
|
||||||
/doc Documentation (doxysource and pre-compiled docs)
|
/doc Documentation (doxysource and pre-compiled docs)
|
||||||
/include Public header C and C++ header files
|
/include Public header C and C++ header files
|
||||||
/lib Static library location for Windows
|
|
||||||
/obj Object file location for Windows
|
|
||||||
/scripts Scripts used to generate the loading code for some formats
|
/scripts Scripts used to generate the loading code for some formats
|
||||||
/port Ports to other languages and scripts to maintain those.
|
/port Ports to other languages and scripts to maintain those.
|
||||||
/test Unit- and regression tests, test suite of models
|
/test Unit- and regression tests, test suite of models
|
||||||
/tools Tools (old assimp viewer, command line `assimp`)
|
/tools Tools (old assimp viewer, command line `assimp`)
|
||||||
/samples A small number of samples to illustrate possible
|
/samples A small number of samples to illustrate possible
|
||||||
use cases for Assimp
|
use cases for Assimp
|
||||||
/workspaces Build enviroments for vc,xcode,... (deprecated,
|
/workspaces Build environments for vc,xcode,... (deprecated,
|
||||||
CMake has superseeded all legacy build options!)
|
CMake has superseeded all legacy build options!)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Building ###
|
|
||||||
|
|
||||||
|
|
||||||
Take a look into the `INSTALL` file. Our build system is CMake, if you already used CMake before there is a good chance you know what to do.
|
|
||||||
|
|
||||||
|
|
||||||
### Where to get help ###
|
### Where to get help ###
|
||||||
|
For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
||||||
|
|
||||||
For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
|
|
||||||
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
(CHMs for Windows are included in some release packages and should be located right here in the root folder).
|
||||||
|
|
||||||
If the documentation doesn't solve your problems,
|
If the docs don't solve your problem, ask on [StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
|
||||||
[try our forums at SF.net](http://sourceforge.net/p/assimp/discussion/817654) or ask on
|
|
||||||
[StackOverflow](http://stackoverflow.com/questions/tagged/assimp?sort=newest).
|
|
||||||
|
|
||||||
For development discussions, there is also a mailing list, _assimp-discussions_
|
For development discussions, there is also a (very low-volume) mailing list, _assimp-discussions_
|
||||||
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
[(subscribe here)]( https://lists.sourceforge.net/lists/listinfo/assimp-discussions)
|
||||||
|
|
||||||
### Contributing ###
|
Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
|
||||||
|
|
||||||
|
And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
|
||||||
|
|
||||||
|
### Contributing ###
|
||||||
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
|
||||||
a pull request with your changes against the main repository's `master` branch.
|
a pull request with your changes against the main repository's `master` branch.
|
||||||
|
|
||||||
|
### Donate ###
|
||||||
|
If you like assimp, consider buying us a beer (or two):
|
||||||
|
[Donate](http://sourceforge.net/donate/index.php?group_id=226462)
|
||||||
|
|
||||||
### License ###
|
### License ###
|
||||||
|
Our license is based on the modified, __3-clause BSD__-License.
|
||||||
Our license is based on the modified, __3-clause BSD__-License, which is very liberal.
|
|
||||||
|
|
||||||
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
|
An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
|
||||||
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
|
and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
|
||||||
For the legal details, see the `LICENSE` file.
|
For the legal details, see the `LICENSE` file.
|
||||||
|
|
||||||
|
### Why this name ###
|
||||||
|
Sorry, we're germans :-), no english native speakers ...
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
# AppVeyor file
|
||||||
|
# http://www.appveyor.com/docs/appveyor-yml
|
||||||
|
|
||||||
|
# clone directory
|
||||||
|
clone_folder: c:\projects\assimp
|
||||||
|
|
||||||
|
# branches to build
|
||||||
|
branches:
|
||||||
|
# whitelist
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
platform:
|
||||||
|
- x86
|
||||||
|
- x64
|
||||||
|
|
||||||
|
configuration:
|
||||||
|
- 14 2015
|
||||||
|
- 12 2013
|
||||||
|
#- MinGW
|
||||||
|
#- 10 2010 # only works for x86
|
||||||
|
|
||||||
|
init:
|
||||||
|
- if "%platform%" EQU "x64" ( for %%a in (2008 2010 MinGW) do ( if "%Configuration%"=="%%a" (echo "Skipping unsupported configuration" && exit /b 1 ) ) )
|
||||||
|
|
||||||
|
install:
|
||||||
|
# Make compiler command line tools available
|
||||||
|
- call c:\projects\assimp\scripts\appveyor\compiler_setup.bat
|
||||||
|
|
||||||
|
build_script:
|
||||||
|
- cd c:\projects\assimp
|
||||||
|
- if "%platform%" equ "x64" (cmake CMakeLists.txt -G "Visual Studio %Configuration% Win64")
|
||||||
|
- if "%platform%" equ "x86" (cmake CMakeLists.txt -G "Visual Studio %Configuration%")
|
||||||
|
- if "%platform%" equ "x64" (msbuild /m /p:Configuration=Release /p:Platform="x64" Assimp.sln)
|
||||||
|
- if "%platform%" equ "x86" (msbuild /m /p:Configuration=Release /p:Platform="Win32" Assimp.sln)
|
||||||
|
|
||||||
|
after_build:
|
||||||
|
- 7z a assimp.7z c:\projects\assimp\bin\release\* c:\projects\assimp\lib\release\*
|
||||||
|
|
||||||
|
artifacts:
|
||||||
|
- path: assimp.7z
|
||||||
|
name: assimp_lib
|
|
@ -23,8 +23,16 @@ if( MSVC )
|
||||||
set(MSVC_PREFIX "vc80")
|
set(MSVC_PREFIX "vc80")
|
||||||
elseif( MSVC90 )
|
elseif( MSVC90 )
|
||||||
set(MSVC_PREFIX "vc90")
|
set(MSVC_PREFIX "vc90")
|
||||||
else()
|
elseif( MSVC10 )
|
||||||
set(MSVC_PREFIX "vc100")
|
set(MSVC_PREFIX "vc100")
|
||||||
|
elseif( MSVC11 )
|
||||||
|
set(MSVC_PREFIX "vc110")
|
||||||
|
elseif( MSVC12 )
|
||||||
|
set(MSVC_PREFIX "vc120")
|
||||||
|
elseif( MSVC14 )
|
||||||
|
set(MSVC_PREFIX "vc140")
|
||||||
|
else()
|
||||||
|
set(MSVC_PREFIX "vc150")
|
||||||
endif()
|
endif()
|
||||||
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" FORCE)
|
set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" FORCE)
|
||||||
else()
|
else()
|
||||||
|
@ -40,9 +48,7 @@ set( ASSIMP_LINK_FLAGS "" )
|
||||||
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
|
set( ASSIMP_LIBRARY_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_LIB_INSTALL_DIR@")
|
||||||
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
|
set( ASSIMP_INCLUDE_DIRS "${ASSIMP_ROOT_DIR}/@ASSIMP_INCLUDE_INSTALL_DIR@")
|
||||||
set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
|
set( ASSIMP_LIBRARIES assimp${ASSIMP_LIBRARY_SUFFIX})
|
||||||
if (CMAKE_BUILD_TYPE EQUAL "DEBUG")
|
set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}@CMAKE_DEBUG_POSTFIX@)
|
||||||
set( ASSIMP_LIBRARIES ${ASSIMP_LIBRARIES}D)
|
|
||||||
endif (CMAKE_BUILD_TYPE EQUAL "DEBUG")
|
|
||||||
|
|
||||||
# search for the boost version assimp was compiled with
|
# search for the boost version assimp was compiled with
|
||||||
#set(Boost_USE_MULTITHREAD ON)
|
#set(Boost_USE_MULTITHREAD ON)
|
||||||
|
@ -58,7 +64,7 @@ endif (CMAKE_BUILD_TYPE EQUAL "DEBUG")
|
||||||
# the boost version assimp was compiled with
|
# the boost version assimp was compiled with
|
||||||
set( ASSIMP_Boost_VERSION "@Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@")
|
set( ASSIMP_Boost_VERSION "@Boost_MAJOR_VERSION@.@Boost_MINOR_VERSION@")
|
||||||
|
|
||||||
# for compatibility wiht pkg-config
|
# for compatibility with pkg-config
|
||||||
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
|
set(ASSIMP_CFLAGS_OTHER "${ASSIMP_CXX_FLAGS}")
|
||||||
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
|
set(ASSIMP_LDFLAGS_OTHER "${ASSIMP_LINK_FLAGS}")
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
prefix=@CMAKE_INSTALL_PREFIX@
|
prefix=@CMAKE_INSTALL_PREFIX@
|
||||||
exec_prefix=@CMAKE_INSTALL_PREFIX@/@ASSIMP_BIN_INSTALL_DIR@
|
exec_prefix=@CMAKE_INSTALL_PREFIX@/
|
||||||
libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
|
libdir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_LIB_INSTALL_DIR@
|
||||||
includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@/assimp
|
includedir=@CMAKE_INSTALL_PREFIX@/@ASSIMP_INCLUDE_INSTALL_DIR@/assimp
|
||||||
|
|
||||||
|
@ -7,4 +7,5 @@ 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.
|
||||||
Version: @PROJECT_VERSION@
|
Version: @PROJECT_VERSION@
|
||||||
Libs: -L${libdir} -lassimp@ASSIMP_LIBRARY_SUFFIX@
|
Libs: -L${libdir} -lassimp@ASSIMP_LIBRARY_SUFFIX@
|
||||||
|
Libs.private: @LIBSTDC++_LIBRARIES@ @ZLIB_LIBRARIES_LINKED@
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
include(ExternalProject)
|
|
||||||
|
|
||||||
if(MSYS OR MINGW)
|
|
||||||
set(DISABLE_PTHREADS ON)
|
|
||||||
else()
|
|
||||||
set(DISABLE_PTHREADS OFF)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
set(RELEASE_LIB_DIR ReleaseLibs)
|
|
||||||
set(DEBUG_LIB_DIR DebugLibs)
|
|
||||||
else()
|
|
||||||
set(RELEASE_LIB_DIR "")
|
|
||||||
set(DEBUG_LIB_DIR "")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(GTEST_CMAKE_ARGS
|
|
||||||
"-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
|
|
||||||
"-Dgtest_force_shared_crt=ON"
|
|
||||||
"-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}")
|
|
||||||
set(GTEST_RELEASE_LIB_DIR "")
|
|
||||||
set(GTEST_DEBUGLIB_DIR "")
|
|
||||||
if (MSVC)
|
|
||||||
set(GTEST_CMAKE_ARGS ${GTEST_CMAKE_ARGS}
|
|
||||||
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG:PATH=${DEBUG_LIB_DIR}"
|
|
||||||
"-DCMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE:PATH=${RELEASE_LIB_DIR}")
|
|
||||||
set(GTEST_LIB_DIR)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(GTEST_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/gtest")
|
|
||||||
|
|
||||||
ExternalProject_Add(gtest
|
|
||||||
GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
|
|
||||||
TIMEOUT 10
|
|
||||||
PREFIX "${GTEST_PREFIX}"
|
|
||||||
CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
|
|
||||||
LOG_DOWNLOAD ON
|
|
||||||
LOG_CONFIGURE ON
|
|
||||||
LOG_BUILD ON
|
|
||||||
# Disable install
|
|
||||||
INSTALL_COMMAND ""
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LIB_PREFIX "${CMAKE_STATIC_LIBRARY_PREFIX}")
|
|
||||||
set(LIB_SUFFIX "${CMAKE_STATIC_LIBRARY_SUFFIX}")
|
|
||||||
set(GTEST_LOCATION "${GTEST_PREFIX}/src/gtest-build")
|
|
||||||
set(GTEST_DEBUG_LIBRARIES
|
|
||||||
"${GTEST_LOCATION}/${DEBUG_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
|
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
SET(GTEST_RELEASE_LIBRARIES
|
|
||||||
"${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
|
|
||||||
"${CMAKE_THREAD_LIBS_INIT}")
|
|
||||||
|
|
||||||
if(MSVC_VERSION EQUAL 1700)
|
|
||||||
add_definitions(-D_VARIADIC_MAX=10)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
ExternalProject_Get_Property(gtest source_dir)
|
|
||||||
include_directories(${source_dir}/include)
|
|
||||||
include_directories(${source_dir}/gtest/include)
|
|
||||||
|
|
||||||
ExternalProject_Get_Property(gtest binary_dir)
|
|
||||||
link_directories(${binary_dir})
|
|
|
@ -0,0 +1,126 @@
|
||||||
|
#
|
||||||
|
# The MIT License (MIT)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014 Joakim Söderberg <joakim.soderberg@gmail.com>
|
||||||
|
#
|
||||||
|
|
||||||
|
set(_CMAKE_SCRIPT_PATH ${CMAKE_CURRENT_LIST_DIR}) # must be outside coveralls_setup() to get correct path
|
||||||
|
|
||||||
|
#
|
||||||
|
# Param _COVERAGE_SRCS A list of source files that coverage should be collected for.
|
||||||
|
# Param _COVERALLS_UPLOAD Upload the result to coveralls?
|
||||||
|
#
|
||||||
|
|
||||||
|
function(coveralls_setup _COVERAGE_SRCS _COVERALLS_UPLOAD)
|
||||||
|
|
||||||
|
if (ARGC GREATER 2)
|
||||||
|
set(_CMAKE_SCRIPT_PATH ${ARGN})
|
||||||
|
message(STATUS "Coveralls: Using alternate CMake script dir: ${_CMAKE_SCRIPT_PATH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT EXISTS "${_CMAKE_SCRIPT_PATH}/CoverallsClear.cmake")
|
||||||
|
message(FATAL_ERROR "Coveralls: Missing ${_CMAKE_SCRIPT_PATH}/CoverallsClear.cmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT EXISTS "${_CMAKE_SCRIPT_PATH}/CoverallsGenerateGcov.cmake")
|
||||||
|
message(FATAL_ERROR "Coveralls: Missing ${_CMAKE_SCRIPT_PATH}/CoverallsGenerateGcov.cmake")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# When passing a CMake list to an external process, the list
|
||||||
|
# will be converted from the format "1;2;3" to "1 2 3".
|
||||||
|
# This means the script we're calling won't see it as a list
|
||||||
|
# of sources, but rather just one long path. We remedy this
|
||||||
|
# by replacing ";" with "*" and then reversing that in the script
|
||||||
|
# that we're calling.
|
||||||
|
# http://cmake.3232098.n2.nabble.com/Passing-a-CMake-list-quot-as-is-quot-to-a-custom-target-td6505681.html
|
||||||
|
set(COVERAGE_SRCS_TMP ${_COVERAGE_SRCS})
|
||||||
|
set(COVERAGE_SRCS "")
|
||||||
|
foreach (COVERAGE_SRC ${COVERAGE_SRCS_TMP})
|
||||||
|
set(COVERAGE_SRCS "${COVERAGE_SRCS}*${COVERAGE_SRC}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
#message("Coverage sources: ${COVERAGE_SRCS}")
|
||||||
|
set(COVERALLS_FILE ${PROJECT_BINARY_DIR}/coveralls.json)
|
||||||
|
|
||||||
|
add_custom_target(coveralls_generate
|
||||||
|
|
||||||
|
# Zero the coverage counters.
|
||||||
|
COMMAND ${CMAKE_COMMAND} -DPROJECT_BINARY_DIR="${PROJECT_BINARY_DIR}" -P "${_CMAKE_SCRIPT_PATH}/CoverallsClear.cmake"
|
||||||
|
|
||||||
|
# Run regress tests.
|
||||||
|
COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure
|
||||||
|
|
||||||
|
# Generate Gcov and translate it into coveralls JSON.
|
||||||
|
# We do this by executing an external CMake script.
|
||||||
|
# (We don't want this to run at CMake generation time, but after compilation and everything has run).
|
||||||
|
COMMAND ${CMAKE_COMMAND}
|
||||||
|
-DCOVERAGE_SRCS="${COVERAGE_SRCS}" # TODO: This is passed like: "a b c", not "a;b;c"
|
||||||
|
-DCOVERALLS_OUTPUT_FILE="${COVERALLS_FILE}"
|
||||||
|
-DCOV_PATH="${PROJECT_BINARY_DIR}"
|
||||||
|
-DPROJECT_ROOT="${PROJECT_SOURCE_DIR}"
|
||||||
|
-P "${_CMAKE_SCRIPT_PATH}/CoverallsGenerateGcov.cmake"
|
||||||
|
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
COMMENT "Generating coveralls output..."
|
||||||
|
)
|
||||||
|
|
||||||
|
if (_COVERALLS_UPLOAD)
|
||||||
|
message("COVERALLS UPLOAD: ON")
|
||||||
|
|
||||||
|
find_program(CURL_EXECUTABLE curl)
|
||||||
|
|
||||||
|
if (NOT CURL_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "Coveralls: curl not found! Aborting")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_custom_target(coveralls_upload
|
||||||
|
# Upload the JSON to coveralls.
|
||||||
|
COMMAND ${CURL_EXECUTABLE}
|
||||||
|
-S -F json_file=@${COVERALLS_FILE}
|
||||||
|
https://coveralls.io/api/v1/jobs
|
||||||
|
|
||||||
|
DEPENDS coveralls_generate
|
||||||
|
|
||||||
|
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||||
|
COMMENT "Uploading coveralls output...")
|
||||||
|
|
||||||
|
add_custom_target(coveralls DEPENDS coveralls_upload)
|
||||||
|
else()
|
||||||
|
message("COVERALLS UPLOAD: OFF")
|
||||||
|
add_custom_target(coveralls DEPENDS coveralls_generate)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
macro(coveralls_turn_on_coverage)
|
||||||
|
if(NOT (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
AND (NOT "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang"))
|
||||||
|
message(FATAL_ERROR "Coveralls: Compiler ${CMAKE_C_COMPILER_ID} is not GNU gcc! Aborting... You can set this on the command line using CC=/usr/bin/gcc CXX=/usr/bin/g++ cmake <options> ..")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||||
|
message(FATAL_ERROR "Coveralls: Code coverage results with an optimised (non-Debug) build may be misleading! Add -DCMAKE_BUILD_TYPE=Debug")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
|
||||||
|
endmacro()
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#
|
||||||
|
# The MIT License (MIT)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014 Joakim Söderberg <joakim.soderberg@gmail.com>
|
||||||
|
#
|
||||||
|
|
||||||
|
# do not follow symlinks in file(GLOB_RECURSE ...)
|
||||||
|
cmake_policy(SET CMP0009 NEW)
|
||||||
|
|
||||||
|
file(GLOB_RECURSE GCDA_FILES "${PROJECT_BINARY_DIR}/*.gcda")
|
||||||
|
if(NOT GCDA_FILES STREQUAL "")
|
||||||
|
file(REMOVE ${GCDA_FILES})
|
||||||
|
endif()
|
|
@ -0,0 +1,482 @@
|
||||||
|
#
|
||||||
|
# The MIT License (MIT)
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in all
|
||||||
|
# copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
# SOFTWARE.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2014 Joakim Söderberg <joakim.soderberg@gmail.com>
|
||||||
|
#
|
||||||
|
# This is intended to be run by a custom target in a CMake project like this.
|
||||||
|
# 0. Compile program with coverage support.
|
||||||
|
# 1. Clear coverage data. (Recursively delete *.gcda in build dir)
|
||||||
|
# 2. Run the unit tests.
|
||||||
|
# 3. Run this script specifying which source files the coverage should be performed on.
|
||||||
|
#
|
||||||
|
# This script will then use gcov to generate .gcov files in the directory specified
|
||||||
|
# via the COV_PATH var. This should probably be the same as your cmake build dir.
|
||||||
|
#
|
||||||
|
# It then parses the .gcov files to convert them into the Coveralls JSON format:
|
||||||
|
# https://coveralls.io/docs/api
|
||||||
|
#
|
||||||
|
# Example for running as standalone CMake script from the command line:
|
||||||
|
# (Note it is important the -P is at the end...)
|
||||||
|
# $ cmake -DCOV_PATH=$(pwd)
|
||||||
|
# -DCOVERAGE_SRCS="catcierge_rfid.c;catcierge_timer.c"
|
||||||
|
# -P ../cmake/CoverallsGcovUpload.cmake
|
||||||
|
#
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Make sure we have the needed arguments.
|
||||||
|
#
|
||||||
|
if (NOT COVERALLS_OUTPUT_FILE)
|
||||||
|
message(FATAL_ERROR "Coveralls: No coveralls output file specified. Please set COVERALLS_OUTPUT_FILE")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT COV_PATH)
|
||||||
|
message(FATAL_ERROR "Coveralls: Missing coverage directory path where gcov files will be generated. Please set COV_PATH")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT COVERAGE_SRCS)
|
||||||
|
message(FATAL_ERROR "Coveralls: Missing the list of source files that we should get the coverage data for COVERAGE_SRCS")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT PROJECT_ROOT)
|
||||||
|
message(FATAL_ERROR "Coveralls: Missing PROJECT_ROOT.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Since it's not possible to pass a CMake list properly in the
|
||||||
|
# "1;2;3" format to an external process, we have replaced the
|
||||||
|
# ";" with "*", so reverse that here so we get it back into the
|
||||||
|
# CMake list format.
|
||||||
|
string(REGEX REPLACE "\\*" ";" COVERAGE_SRCS ${COVERAGE_SRCS})
|
||||||
|
|
||||||
|
if (NOT DEFINED ENV{GCOV})
|
||||||
|
find_program(GCOV_EXECUTABLE gcov)
|
||||||
|
else()
|
||||||
|
find_program(GCOV_EXECUTABLE $ENV{GCOV})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# convert all paths in COVERAGE_SRCS to absolute paths
|
||||||
|
set(COVERAGE_SRCS_TMP "")
|
||||||
|
foreach (COVERAGE_SRC ${COVERAGE_SRCS})
|
||||||
|
if (NOT "${COVERAGE_SRC}" MATCHES "^/")
|
||||||
|
set(COVERAGE_SRC ${PROJECT_ROOT}/${COVERAGE_SRC})
|
||||||
|
endif()
|
||||||
|
list(APPEND COVERAGE_SRCS_TMP ${COVERAGE_SRC})
|
||||||
|
endforeach()
|
||||||
|
set(COVERAGE_SRCS ${COVERAGE_SRCS_TMP})
|
||||||
|
unset(COVERAGE_SRCS_TMP)
|
||||||
|
|
||||||
|
if (NOT GCOV_EXECUTABLE)
|
||||||
|
message(FATAL_ERROR "gcov not found! Aborting...")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(Git)
|
||||||
|
|
||||||
|
set(JSON_REPO_TEMPLATE
|
||||||
|
"{
|
||||||
|
\"head\": {
|
||||||
|
\"id\": \"\@GIT_COMMIT_HASH\@\",
|
||||||
|
\"author_name\": \"\@GIT_AUTHOR_NAME\@\",
|
||||||
|
\"author_email\": \"\@GIT_AUTHOR_EMAIL\@\",
|
||||||
|
\"committer_name\": \"\@GIT_COMMITTER_NAME\@\",
|
||||||
|
\"committer_email\": \"\@GIT_COMMITTER_EMAIL\@\",
|
||||||
|
\"message\": \"\@GIT_COMMIT_MESSAGE\@\"
|
||||||
|
},
|
||||||
|
\"branch\": \"@GIT_BRANCH@\",
|
||||||
|
\"remotes\": []
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# TODO: Fill in git remote data
|
||||||
|
if (GIT_FOUND)
|
||||||
|
# Branch.
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_BRANCH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
|
||||||
|
macro (git_log_format FORMAT_CHARS VAR_NAME)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%${FORMAT_CHARS}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE ${VAR_NAME}
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
git_log_format(an GIT_AUTHOR_NAME)
|
||||||
|
git_log_format(ae GIT_AUTHOR_EMAIL)
|
||||||
|
git_log_format(cn GIT_COMMITTER_NAME)
|
||||||
|
git_log_format(ce GIT_COMMITTER_EMAIL)
|
||||||
|
git_log_format(B GIT_COMMIT_MESSAGE)
|
||||||
|
git_log_format(H GIT_COMMIT_HASH)
|
||||||
|
|
||||||
|
if(GIT_COMMIT_MESSAGE)
|
||||||
|
string(REPLACE "\n" "\\n" GIT_COMMIT_MESSAGE ${GIT_COMMIT_MESSAGE})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message("Git exe: ${GIT_EXECUTABLE}")
|
||||||
|
message("Git branch: ${GIT_BRANCH}")
|
||||||
|
message("Git author: ${GIT_AUTHOR_NAME}")
|
||||||
|
message("Git e-mail: ${GIT_AUTHOR_EMAIL}")
|
||||||
|
message("Git commiter name: ${GIT_COMMITTER_NAME}")
|
||||||
|
message("Git commiter e-mail: ${GIT_COMMITTER_EMAIL}")
|
||||||
|
message("Git commit hash: ${GIT_COMMIT_HASH}")
|
||||||
|
message("Git commit message: ${GIT_COMMIT_MESSAGE}")
|
||||||
|
|
||||||
|
string(CONFIGURE ${JSON_REPO_TEMPLATE} JSON_REPO_DATA)
|
||||||
|
else()
|
||||||
|
set(JSON_REPO_DATA "{}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
############################# Macros #########################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# This macro converts from the full path format gcov outputs:
|
||||||
|
#
|
||||||
|
# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
|
||||||
|
#
|
||||||
|
# to the original source file path the .gcov is for:
|
||||||
|
#
|
||||||
|
# /path/to/project/root/subdir/the_file.c
|
||||||
|
#
|
||||||
|
macro(get_source_path_from_gcov_filename _SRC_FILENAME _GCOV_FILENAME)
|
||||||
|
|
||||||
|
# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
|
||||||
|
# ->
|
||||||
|
# #path#to#project#root#subdir#the_file.c.gcov
|
||||||
|
get_filename_component(_GCOV_FILENAME_WEXT ${_GCOV_FILENAME} NAME)
|
||||||
|
|
||||||
|
# #path#to#project#root#subdir#the_file.c.gcov -> /path/to/project/root/subdir/the_file.c
|
||||||
|
string(REGEX REPLACE "\\.gcov$" "" SRC_FILENAME_TMP ${_GCOV_FILENAME_WEXT})
|
||||||
|
string(REGEX REPLACE "\#" "/" SRC_FILENAME_TMP ${SRC_FILENAME_TMP})
|
||||||
|
set(${_SRC_FILENAME} "${SRC_FILENAME_TMP}")
|
||||||
|
endmacro()
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Get the coverage data.
|
||||||
|
file(GLOB_RECURSE GCDA_FILES "${COV_PATH}/*.gcda")
|
||||||
|
message("GCDA files:")
|
||||||
|
|
||||||
|
# Get a list of all the object directories needed by gcov
|
||||||
|
# (The directories the .gcda files and .o files are found in)
|
||||||
|
# and run gcov on those.
|
||||||
|
foreach(GCDA ${GCDA_FILES})
|
||||||
|
message("Process: ${GCDA}")
|
||||||
|
message("------------------------------------------------------------------------------")
|
||||||
|
get_filename_component(GCDA_DIR ${GCDA} PATH)
|
||||||
|
|
||||||
|
#
|
||||||
|
# The -p below refers to "Preserve path components",
|
||||||
|
# This means that the generated gcov filename of a source file will
|
||||||
|
# keep the original files entire filepath, but / is replaced with #.
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# /path/to/project/root/build/CMakeFiles/the_file.dir/subdir/the_file.c.gcda
|
||||||
|
# ------------------------------------------------------------------------------
|
||||||
|
# File '/path/to/project/root/subdir/the_file.c'
|
||||||
|
# Lines executed:68.34% of 199
|
||||||
|
# /path/to/project/root/subdir/the_file.c:creating '#path#to#project#root#subdir#the_file.c.gcov'
|
||||||
|
#
|
||||||
|
# If -p is not specified then the file is named only "the_file.c.gcov"
|
||||||
|
#
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GCOV_EXECUTABLE} -p -o ${GCDA_DIR} ${GCDA}
|
||||||
|
WORKING_DIRECTORY ${COV_PATH}
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# TODO: Make these be absolute path
|
||||||
|
file(GLOB ALL_GCOV_FILES ${COV_PATH}/*.gcov)
|
||||||
|
|
||||||
|
# Get only the filenames to use for filtering.
|
||||||
|
#set(COVERAGE_SRCS_NAMES "")
|
||||||
|
#foreach (COVSRC ${COVERAGE_SRCS})
|
||||||
|
# get_filename_component(COVSRC_NAME ${COVSRC} NAME)
|
||||||
|
# message("${COVSRC} -> ${COVSRC_NAME}")
|
||||||
|
# list(APPEND COVERAGE_SRCS_NAMES "${COVSRC_NAME}")
|
||||||
|
#endforeach()
|
||||||
|
|
||||||
|
#
|
||||||
|
# Filter out all but the gcov files we want.
|
||||||
|
#
|
||||||
|
# We do this by comparing the list of COVERAGE_SRCS filepaths that the
|
||||||
|
# user wants the coverage data for with the paths of the generated .gcov files,
|
||||||
|
# so that we only keep the relevant gcov files.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# COVERAGE_SRCS =
|
||||||
|
# /path/to/project/root/subdir/the_file.c
|
||||||
|
#
|
||||||
|
# ALL_GCOV_FILES =
|
||||||
|
# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
|
||||||
|
# /path/to/project/root/build/#path#to#project#root#subdir#other_file.c.gcov
|
||||||
|
#
|
||||||
|
# Result should be:
|
||||||
|
# GCOV_FILES =
|
||||||
|
# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
|
||||||
|
#
|
||||||
|
set(GCOV_FILES "")
|
||||||
|
#message("Look in coverage sources: ${COVERAGE_SRCS}")
|
||||||
|
message("\nFilter out unwanted GCOV files:")
|
||||||
|
message("===============================")
|
||||||
|
|
||||||
|
set(COVERAGE_SRCS_REMAINING ${COVERAGE_SRCS})
|
||||||
|
|
||||||
|
foreach (GCOV_FILE ${ALL_GCOV_FILES})
|
||||||
|
|
||||||
|
#
|
||||||
|
# /path/to/project/root/build/#path#to#project#root#subdir#the_file.c.gcov
|
||||||
|
# ->
|
||||||
|
# /path/to/project/root/subdir/the_file.c
|
||||||
|
get_source_path_from_gcov_filename(GCOV_SRC_PATH ${GCOV_FILE})
|
||||||
|
file(RELATIVE_PATH GCOV_SRC_REL_PATH "${PROJECT_ROOT}" "${GCOV_SRC_PATH}")
|
||||||
|
|
||||||
|
# Is this in the list of source files?
|
||||||
|
# TODO: We want to match against relative path filenames from the source file root...
|
||||||
|
list(FIND COVERAGE_SRCS ${GCOV_SRC_PATH} WAS_FOUND)
|
||||||
|
|
||||||
|
if (NOT WAS_FOUND EQUAL -1)
|
||||||
|
message("YES: ${GCOV_FILE}")
|
||||||
|
list(APPEND GCOV_FILES ${GCOV_FILE})
|
||||||
|
|
||||||
|
# We remove it from the list, so we don't bother searching for it again.
|
||||||
|
# Also files left in COVERAGE_SRCS_REMAINING after this loop ends should
|
||||||
|
# have coverage data generated from them (no lines are covered).
|
||||||
|
list(REMOVE_ITEM COVERAGE_SRCS_REMAINING ${GCOV_SRC_PATH})
|
||||||
|
else()
|
||||||
|
message("NO: ${GCOV_FILE}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# TODO: Enable setting these
|
||||||
|
set(JSON_SERVICE_NAME "travis-ci")
|
||||||
|
set(JSON_SERVICE_JOB_ID $ENV{TRAVIS_JOB_ID})
|
||||||
|
set(JSON_REPO_TOKEN $ENV{COVERALLS_REPO_TOKEN})
|
||||||
|
|
||||||
|
set(JSON_TEMPLATE
|
||||||
|
"{
|
||||||
|
\"repo_token\": \"\@JSON_REPO_TOKEN\@\",
|
||||||
|
\"service_name\": \"\@JSON_SERVICE_NAME\@\",
|
||||||
|
\"service_job_id\": \"\@JSON_SERVICE_JOB_ID\@\",
|
||||||
|
\"source_files\": \@JSON_GCOV_FILES\@,
|
||||||
|
\"git\": \@JSON_REPO_DATA\@
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(SRC_FILE_TEMPLATE
|
||||||
|
"{
|
||||||
|
\"name\": \"\@GCOV_SRC_REL_PATH\@\",
|
||||||
|
\"source_digest\": \"\@GCOV_CONTENTS_MD5\@\",
|
||||||
|
\"coverage\": \@GCOV_FILE_COVERAGE\@
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
|
||||||
|
message("\nGenerate JSON for files:")
|
||||||
|
message("=========================")
|
||||||
|
|
||||||
|
set(JSON_GCOV_FILES "[")
|
||||||
|
|
||||||
|
# Read the GCOV files line by line and get the coverage data.
|
||||||
|
foreach (GCOV_FILE ${GCOV_FILES})
|
||||||
|
|
||||||
|
get_source_path_from_gcov_filename(GCOV_SRC_PATH ${GCOV_FILE})
|
||||||
|
file(RELATIVE_PATH GCOV_SRC_REL_PATH "${PROJECT_ROOT}" "${GCOV_SRC_PATH}")
|
||||||
|
|
||||||
|
# The new coveralls API doesn't need the entire source (Yay!)
|
||||||
|
# However, still keeping that part for now. Will cleanup in the future.
|
||||||
|
file(MD5 "${GCOV_SRC_PATH}" GCOV_CONTENTS_MD5)
|
||||||
|
message("MD5: ${GCOV_SRC_PATH} = ${GCOV_CONTENTS_MD5}")
|
||||||
|
|
||||||
|
# Loads the gcov file as a list of lines.
|
||||||
|
# (We first open the file and replace all occurences of [] with _
|
||||||
|
# because CMake will fail to parse a line containing unmatched brackets...
|
||||||
|
# also the \ to escaped \n in macros screws up things.)
|
||||||
|
# https://public.kitware.com/Bug/view.php?id=15369
|
||||||
|
file(READ ${GCOV_FILE} GCOV_CONTENTS)
|
||||||
|
string(REPLACE "[" "_" GCOV_CONTENTS "${GCOV_CONTENTS}")
|
||||||
|
string(REPLACE "]" "_" GCOV_CONTENTS "${GCOV_CONTENTS}")
|
||||||
|
string(REPLACE "\\" "_" GCOV_CONTENTS "${GCOV_CONTENTS}")
|
||||||
|
|
||||||
|
# Remove file contents to avoid encoding issues (cmake 2.8 has no ENCODING option)
|
||||||
|
string(REGEX REPLACE "([^:]*):([^:]*):([^\n]*)\n" "\\1:\\2: \n" GCOV_CONTENTS "${GCOV_CONTENTS}")
|
||||||
|
file(WRITE ${GCOV_FILE}_tmp "${GCOV_CONTENTS}")
|
||||||
|
|
||||||
|
file(STRINGS ${GCOV_FILE}_tmp GCOV_LINES)
|
||||||
|
list(LENGTH GCOV_LINES LINE_COUNT)
|
||||||
|
|
||||||
|
# Instead of trying to parse the source from the
|
||||||
|
# gcov file, simply read the file contents from the source file.
|
||||||
|
# (Parsing it from the gcov is hard because C-code uses ; in many places
|
||||||
|
# which also happens to be the same as the CMake list delimeter).
|
||||||
|
file(READ ${GCOV_SRC_PATH} GCOV_FILE_SOURCE)
|
||||||
|
|
||||||
|
string(REPLACE "\\" "\\\\" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
string(REGEX REPLACE "\"" "\\\\\"" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
string(REPLACE "\t" "\\\\t" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
string(REPLACE "\r" "\\\\r" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
string(REPLACE "\n" "\\\\n" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
# According to http://json.org/ these should be escaped as well.
|
||||||
|
# Don't know how to do that in CMake however...
|
||||||
|
#string(REPLACE "\b" "\\\\b" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
#string(REPLACE "\f" "\\\\f" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
#string(REGEX REPLACE "\u([a-fA-F0-9]{4})" "\\\\u\\1" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")
|
||||||
|
|
||||||
|
# We want a json array of coverage data as a single string
|
||||||
|
# start building them from the contents of the .gcov
|
||||||
|
set(GCOV_FILE_COVERAGE "[")
|
||||||
|
|
||||||
|
set(GCOV_LINE_COUNT 1) # Line number for the .gcov.
|
||||||
|
set(DO_SKIP 0)
|
||||||
|
foreach (GCOV_LINE ${GCOV_LINES})
|
||||||
|
#message("${GCOV_LINE}")
|
||||||
|
# Example of what we're parsing:
|
||||||
|
# Hitcount |Line | Source
|
||||||
|
# " 8: 26: if (!allowed || (strlen(allowed) == 0))"
|
||||||
|
string(REGEX REPLACE
|
||||||
|
"^([^:]*):([^:]*):(.*)$"
|
||||||
|
"\\1;\\2;\\3"
|
||||||
|
RES
|
||||||
|
"${GCOV_LINE}")
|
||||||
|
|
||||||
|
# Check if we should exclude lines using the Lcov syntax.
|
||||||
|
string(REGEX MATCH "LCOV_EXCL_START" START_SKIP "${GCOV_LINE}")
|
||||||
|
string(REGEX MATCH "LCOV_EXCL_END" END_SKIP "${GCOV_LINE}")
|
||||||
|
string(REGEX MATCH "LCOV_EXCL_LINE" LINE_SKIP "${GCOV_LINE}")
|
||||||
|
|
||||||
|
set(RESET_SKIP 0)
|
||||||
|
if (LINE_SKIP AND NOT DO_SKIP)
|
||||||
|
set(DO_SKIP 1)
|
||||||
|
set(RESET_SKIP 1)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (START_SKIP)
|
||||||
|
set(DO_SKIP 1)
|
||||||
|
message("${GCOV_LINE_COUNT}: Start skip")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (END_SKIP)
|
||||||
|
set(DO_SKIP 0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
list(LENGTH RES RES_COUNT)
|
||||||
|
|
||||||
|
if (RES_COUNT GREATER 2)
|
||||||
|
list(GET RES 0 HITCOUNT)
|
||||||
|
list(GET RES 1 LINE)
|
||||||
|
list(GET RES 2 SOURCE)
|
||||||
|
|
||||||
|
string(STRIP ${HITCOUNT} HITCOUNT)
|
||||||
|
string(STRIP ${LINE} LINE)
|
||||||
|
|
||||||
|
# Lines with 0 line numbers are metadata and can be ignored.
|
||||||
|
if (NOT ${LINE} EQUAL 0)
|
||||||
|
|
||||||
|
if (DO_SKIP)
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}null, ")
|
||||||
|
else()
|
||||||
|
# Translate the hitcount into valid JSON values.
|
||||||
|
if (${HITCOUNT} STREQUAL "#####" OR ${HITCOUNT} STREQUAL "=====")
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}0, ")
|
||||||
|
elseif (${HITCOUNT} STREQUAL "-")
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}null, ")
|
||||||
|
else()
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}${HITCOUNT}, ")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
message(WARNING "Failed to properly parse line (RES_COUNT = ${RES_COUNT}) ${GCOV_FILE}:${GCOV_LINE_COUNT}\n-->${GCOV_LINE}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (RESET_SKIP)
|
||||||
|
set(DO_SKIP 0)
|
||||||
|
endif()
|
||||||
|
math(EXPR GCOV_LINE_COUNT "${GCOV_LINE_COUNT}+1")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
message("${GCOV_LINE_COUNT} of ${LINE_COUNT} lines read!")
|
||||||
|
|
||||||
|
# Advanced way of removing the trailing comma in the JSON array.
|
||||||
|
# "[1, 2, 3, " -> "[1, 2, 3"
|
||||||
|
string(REGEX REPLACE ",[ ]*$" "" GCOV_FILE_COVERAGE ${GCOV_FILE_COVERAGE})
|
||||||
|
|
||||||
|
# Append the trailing ] to complete the JSON array.
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}]")
|
||||||
|
|
||||||
|
# Generate the final JSON for this file.
|
||||||
|
message("Generate JSON for file: ${GCOV_SRC_REL_PATH}...")
|
||||||
|
string(CONFIGURE ${SRC_FILE_TEMPLATE} FILE_JSON)
|
||||||
|
|
||||||
|
set(JSON_GCOV_FILES "${JSON_GCOV_FILES}${FILE_JSON}, ")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Loop through all files we couldn't find any coverage for
|
||||||
|
# as well, and generate JSON for those as well with 0% coverage.
|
||||||
|
foreach(NOT_COVERED_SRC ${COVERAGE_SRCS_REMAINING})
|
||||||
|
|
||||||
|
# Set variables for json replacement
|
||||||
|
set(GCOV_SRC_PATH ${NOT_COVERED_SRC})
|
||||||
|
file(MD5 "${GCOV_SRC_PATH}" GCOV_CONTENTS_MD5)
|
||||||
|
file(RELATIVE_PATH GCOV_SRC_REL_PATH "${PROJECT_ROOT}" "${GCOV_SRC_PATH}")
|
||||||
|
|
||||||
|
# Loads the source file as a list of lines.
|
||||||
|
file(STRINGS ${NOT_COVERED_SRC} SRC_LINES)
|
||||||
|
|
||||||
|
set(GCOV_FILE_COVERAGE "[")
|
||||||
|
set(GCOV_FILE_SOURCE "")
|
||||||
|
|
||||||
|
foreach (SOURCE ${SRC_LINES})
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}null, ")
|
||||||
|
|
||||||
|
string(REPLACE "\\" "\\\\" SOURCE "${SOURCE}")
|
||||||
|
string(REGEX REPLACE "\"" "\\\\\"" SOURCE "${SOURCE}")
|
||||||
|
string(REPLACE "\t" "\\\\t" SOURCE "${SOURCE}")
|
||||||
|
string(REPLACE "\r" "\\\\r" SOURCE "${SOURCE}")
|
||||||
|
set(GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}${SOURCE}\\n")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Remove trailing comma, and complete JSON array with ]
|
||||||
|
string(REGEX REPLACE ",[ ]*$" "" GCOV_FILE_COVERAGE ${GCOV_FILE_COVERAGE})
|
||||||
|
set(GCOV_FILE_COVERAGE "${GCOV_FILE_COVERAGE}]")
|
||||||
|
|
||||||
|
# Generate the final JSON for this file.
|
||||||
|
message("Generate JSON for non-gcov file: ${NOT_COVERED_SRC}...")
|
||||||
|
string(CONFIGURE ${SRC_FILE_TEMPLATE} FILE_JSON)
|
||||||
|
set(JSON_GCOV_FILES "${JSON_GCOV_FILES}${FILE_JSON}, ")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Get rid of trailing comma.
|
||||||
|
string(REGEX REPLACE ",[ ]*$" "" JSON_GCOV_FILES ${JSON_GCOV_FILES})
|
||||||
|
set(JSON_GCOV_FILES "${JSON_GCOV_FILES}]")
|
||||||
|
|
||||||
|
# Generate the final complete JSON!
|
||||||
|
message("Generate final JSON...")
|
||||||
|
string(CONFIGURE ${JSON_TEMPLATE} JSON)
|
||||||
|
|
||||||
|
file(WRITE "${COVERALLS_OUTPUT_FILE}" "${JSON}")
|
||||||
|
message("###########################################################################")
|
||||||
|
message("Generated coveralls JSON containing coverage data:")
|
||||||
|
message("${COVERALLS_OUTPUT_FILE}")
|
||||||
|
message("###########################################################################")
|
|
@ -35,6 +35,7 @@ if(WIN32) # The only platform it makes sense to check for DirectX SDK
|
||||||
"C:/Program Files (x86)/Microsoft DirectX SDK*"
|
"C:/Program Files (x86)/Microsoft DirectX SDK*"
|
||||||
"C:/apps/Microsoft DirectX SDK*"
|
"C:/apps/Microsoft DirectX SDK*"
|
||||||
"C:/Program Files/Microsoft DirectX SDK*"
|
"C:/Program Files/Microsoft DirectX SDK*"
|
||||||
|
"C:/Program Files (x86)/Windows Kits/8.1"
|
||||||
"$ENV{ProgramFiles}/Microsoft DirectX SDK*"
|
"$ENV{ProgramFiles}/Microsoft DirectX SDK*"
|
||||||
)
|
)
|
||||||
create_search_paths(DirectX)
|
create_search_paths(DirectX)
|
||||||
|
|
|
@ -127,6 +127,7 @@ MACRO(findpkg_framework fwk)
|
||||||
/System/Library/Frameworks
|
/System/Library/Frameworks
|
||||||
/Network/Library/Frameworks
|
/Network/Library/Frameworks
|
||||||
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/
|
/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/
|
||||||
|
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS3.0.sdk/System/Library/Frameworks/
|
||||||
)
|
)
|
||||||
FOREACH(dir ${${fwk}_FRAMEWORK_PATH})
|
FOREACH(dir ${${fwk}_FRAMEWORK_PATH})
|
||||||
SET(fwkpath ${dir}/${fwk}.framework)
|
SET(fwkpath ${dir}/${fwk}.framework)
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Try to find real time libraries
|
||||||
|
# Once done, this will define
|
||||||
|
#
|
||||||
|
# RT_FOUND - system has rt library
|
||||||
|
# RT_LIBRARIES - rt libraries directory
|
||||||
|
#
|
||||||
|
# Source: https://gitlab.cern.ch/dss/eos/commit/44070e575faaa46bd998708ef03eedb381506ff0
|
||||||
|
#
|
||||||
|
|
||||||
|
if(RT_LIBRARIES)
|
||||||
|
set(RT_FIND_QUIETLY TRUE)
|
||||||
|
endif(RT_LIBRARIES)
|
||||||
|
|
||||||
|
find_library(RT_LIBRARY rt)
|
||||||
|
set(RT_LIBRARIES ${RT_LIBRARY})
|
||||||
|
# handle the QUIETLY and REQUIRED arguments and set
|
||||||
|
# RT_FOUND to TRUE if all listed variables are TRUE
|
||||||
|
include(FindPackageHandleStandardArgs)
|
||||||
|
find_package_handle_standard_args(rt DEFAULT_MSG RT_LIBRARY)
|
||||||
|
mark_as_advanced(RT_LIBRARY)
|
|
@ -1,25 +1,81 @@
|
||||||
FIND_PATH(
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
set(ASSIMP_ARCHITECTURE "64")
|
||||||
|
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
|
set(ASSIMP_ARCHITECTURE "32")
|
||||||
|
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(ASSIMP_ROOT_DIR CACHE PATH "ASSIMP root directory")
|
||||||
|
|
||||||
|
# Find path of each library
|
||||||
|
find_path(ASSIMP_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
assimp/anim.h
|
||||||
|
HINTS
|
||||||
|
${ASSIMP_ROOT_DIR}/include
|
||||||
|
)
|
||||||
|
|
||||||
|
if(MSVC12)
|
||||||
|
set(ASSIMP_MSVC_VERSION "vc120")
|
||||||
|
elseif(MSVC14)
|
||||||
|
set(ASSIMP_MSVC_VERSION "vc140")
|
||||||
|
endif(MSVC12)
|
||||||
|
|
||||||
|
if(MSVC12 OR MSVC14)
|
||||||
|
|
||||||
|
find_path(ASSIMP_LIBRARY_DIR
|
||||||
|
NAMES
|
||||||
|
assimp-${ASSIMP_MSVC_VERSION}-mt.lib
|
||||||
|
HINTS
|
||||||
|
${ASSIMP_ROOT_DIR}/lib${ASSIMP_ARCHITECTURE}
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(ASSIMP_LIBRARY_RELEASE assimp-${ASSIMP_MSVC_VERSION}-mt.lib PATHS ${ASSIMP_LIBRARY_DIR})
|
||||||
|
find_library(ASSIMP_LIBRARY_DEBUG assimp-${ASSIMP_MSVC_VERSION}-mtd.lib PATHS ${ASSIMP_LIBRARY_DIR})
|
||||||
|
|
||||||
|
set(ASSIMP_LIBRARY
|
||||||
|
optimized ${ASSIMP_LIBRARY_RELEASE}
|
||||||
|
debug ${ASSIMP_LIBRARY_DEBUG}
|
||||||
|
)
|
||||||
|
|
||||||
|
set(ASSIMP_LIBRARIES "ASSIMP_LIBRARY_RELEASE" "ASSIMP_LIBRARY_DEBUG")
|
||||||
|
|
||||||
|
FUNCTION(ASSIMP_COPY_BINARIES TargetDirectory)
|
||||||
|
ADD_CUSTOM_TARGET(AssimpCopyBinaries
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE}/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll ${TargetDirectory}/Debug/assimp-${ASSIMP_MSVC_VERSION}-mtd.dll
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy ${ASSIMP_ROOT_DIR}/bin${ASSIMP_ARCHITECTURE}/assimp-${ASSIMP_MSVC_VERSION}-mt.dll ${TargetDirectory}/Release/assimp-${ASSIMP_MSVC_VERSION}-mt.dll
|
||||||
|
COMMENT "Copying Assimp binaries to '${TargetDirectory}'"
|
||||||
|
VERBATIM)
|
||||||
|
ENDFUNCTION(ASSIMP_COPY_BINARIES)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
else(WIN32)
|
||||||
|
|
||||||
|
find_path(
|
||||||
assimp_INCLUDE_DIRS
|
assimp_INCLUDE_DIRS
|
||||||
NAMES postprocess.h scene.h version.h config.h cimport.h
|
NAMES postprocess.h scene.h version.h config.h cimport.h
|
||||||
PATHS /usr/local/include/
|
PATHS /usr/local/include/
|
||||||
)
|
)
|
||||||
|
|
||||||
FIND_LIBRARY(
|
find_library(
|
||||||
assimp_LIBRARIES
|
assimp_LIBRARIES
|
||||||
NAMES assimp
|
NAMES assimp
|
||||||
PATHS /usr/local/lib/
|
PATHS /usr/local/lib/
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
||||||
SET(assimp_FOUND TRUE)
|
SET(assimp_FOUND TRUE)
|
||||||
ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
|
||||||
|
|
||||||
IF (assimp_FOUND)
|
if (assimp_FOUND)
|
||||||
IF (NOT assimp_FIND_QUIETLY)
|
if (NOT assimp_FIND_QUIETLY)
|
||||||
MESSAGE(STATUS "Found asset importer library: ${assimp_LIBRARIES}")
|
message(STATUS "Found asset importer library: ${assimp_LIBRARIES}")
|
||||||
ENDIF (NOT assimp_FIND_QUIETLY)
|
endif (NOT assimp_FIND_QUIETLY)
|
||||||
ELSE (assimp_FOUND)
|
else (assimp_FOUND)
|
||||||
IF (assimp_FIND_REQUIRED)
|
if (assimp_FIND_REQUIRED)
|
||||||
MESSAGE(FATAL_ERROR "Could not find asset importer library")
|
message(FATAL_ERROR "Could not find asset importer library")
|
||||||
ENDIF (assimp_FIND_REQUIRED)
|
endif (assimp_FIND_REQUIRED)
|
||||||
ENDIF (assimp_FOUND)
|
endif (assimp_FOUND)
|
||||||
|
|
||||||
|
endif(WIN32)
|
|
@ -0,0 +1,16 @@
|
||||||
|
# this one sets internal to crosscompile (in theory)
|
||||||
|
SET(CMAKE_SYSTEM_NAME Windows)
|
||||||
|
|
||||||
|
# the minimalistic settings
|
||||||
|
SET(CMAKE_C_COMPILER "/usr/bin/x86_64-w64-mingw32-gcc")
|
||||||
|
SET(CMAKE_CXX_COMPILER "/usr/bin/x86_64-w64-mingw32-g++")
|
||||||
|
SET(CMAKE_RC_COMPILER "/usr/bin/x86_64-w64-mingw32-windres")
|
||||||
|
|
||||||
|
# where is the target (so called staging) environment
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
|
||||||
|
|
||||||
|
# search for programs in the build host directories (default BOTH)
|
||||||
|
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
# for libraries and headers in the target directories
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
|
@ -0,0 +1,8 @@
|
||||||
|
# See <http://EditorConfig.org> for details
|
||||||
|
|
||||||
|
[*.{h,hpp,c,cpp}]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = space
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -41,12 +41,17 @@ 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 */
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
#include "TargetAnimation.h"
|
#include "TargetAnimation.h"
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include "StringComparison.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -65,8 +70,9 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
|
||||||
{
|
{
|
||||||
std::string s = mScene->mMaterials[i].mName;
|
std::string s = mScene->mMaterials[i].mName;
|
||||||
for (std::string::iterator it = s.begin(); it != s.end(); ++it)
|
for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
|
||||||
*it = ::tolower(*it);
|
*it = static_cast< char >( ::tolower( *it ) );
|
||||||
|
}
|
||||||
|
|
||||||
if (std::string::npos == s.find("default"))continue;
|
if (std::string::npos == s.find("default"))continue;
|
||||||
|
|
||||||
|
@ -191,7 +197,7 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
|
||||||
|
|
||||||
// Setup the texture blend factor
|
// Setup the texture blend factor
|
||||||
if (is_not_qnan(texture.mTextureBlend))
|
if (is_not_qnan(texture.mTextureBlend))
|
||||||
mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
||||||
|
|
||||||
// Setup the texture mapping mode
|
// Setup the texture mapping mode
|
||||||
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
mat.AddProperty<int>((int*)&texture.mMapMode,1,AI_MATKEY_MAPPINGMODE_U(type,0));
|
||||||
|
@ -201,14 +207,14 @@ void CopyTexture(aiMaterial& mat, D3DS::Texture& texture, aiTextureType type)
|
||||||
// FIXME: this is not really correct ...
|
// FIXME: this is not really correct ...
|
||||||
if (texture.mMapMode == aiTextureMapMode_Mirror)
|
if (texture.mMapMode == aiTextureMapMode_Mirror)
|
||||||
{
|
{
|
||||||
texture.mScaleU *= 2.f;
|
texture.mScaleU *= 2.0;
|
||||||
texture.mScaleV *= 2.f;
|
texture.mScaleV *= 2.0;
|
||||||
texture.mOffsetU /= 2.f;
|
texture.mOffsetU /= 2.0;
|
||||||
texture.mOffsetV /= 2.f;
|
texture.mOffsetV /= 2.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup texture UV transformations
|
// Setup texture UV transformations
|
||||||
mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
|
mat.AddProperty<ai_real>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -259,10 +265,10 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material& oldMat,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opacity
|
// Opacity
|
||||||
mat.AddProperty<float>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
|
mat.AddProperty<ai_real>( &oldMat.mTransparency,1,AI_MATKEY_OPACITY);
|
||||||
|
|
||||||
// Bump height scaling
|
// Bump height scaling
|
||||||
mat.AddProperty<float>( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING);
|
mat.AddProperty<ai_real>( &oldMat.mBumpHeight,1,AI_MATKEY_BUMPSCALING);
|
||||||
|
|
||||||
// Two sided rendering?
|
// Two sided rendering?
|
||||||
if (oldMat.mTwoSided)
|
if (oldMat.mTwoSided)
|
||||||
|
@ -353,7 +359,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||||
|
|
||||||
// we need to split all meshes by their materials
|
// we need to split all meshes by their materials
|
||||||
for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i) {
|
for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(); i != mScene->mMeshes.end();++i) {
|
||||||
boost::scoped_array< std::vector<unsigned int> > aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
|
std::unique_ptr< std::vector<unsigned int>[] > aiSplit(new std::vector<unsigned int>[mScene->mMaterials.size()]);
|
||||||
|
|
||||||
name.length = ASSIMP_itoa10(name.data,num++);
|
name.length = ASSIMP_itoa10(name.data,num++);
|
||||||
|
|
||||||
|
@ -396,7 +402,7 @@ void Discreet3DSImporter::ConvertMeshes(aiScene* pcOut)
|
||||||
}
|
}
|
||||||
for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q)
|
for (unsigned int q = 0, base = 0; q < aiSplit[p].size();++q)
|
||||||
{
|
{
|
||||||
register unsigned int index = aiSplit[p][q];
|
unsigned int index = aiSplit[p][q];
|
||||||
aiFace& face = meshOut->mFaces[q];
|
aiFace& face = meshOut->mFaces[q];
|
||||||
|
|
||||||
face.mIndices = new unsigned int[3];
|
face.mIndices = new unsigned int[3];
|
||||||
|
@ -658,14 +664,14 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
|
nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
|
||||||
|
|
||||||
// Rotations are quaternion offsets
|
// Rotations are quaternion offsets
|
||||||
aiQuaternion abs;
|
aiQuaternion abs1;
|
||||||
for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
|
for (unsigned int n = 0; n < nda->mNumRotationKeys;++n)
|
||||||
{
|
{
|
||||||
const aiQuatKey& q = pcIn->aRotationKeys[n];
|
const aiQuatKey& q = pcIn->aRotationKeys[n];
|
||||||
|
|
||||||
abs = (n ? abs * q.mValue : q.mValue);
|
abs1 = (n ? abs1 * q.mValue : q.mValue);
|
||||||
nda->mRotationKeys[n].mTime = q.mTime;
|
nda->mRotationKeys[n].mTime = q.mTime;
|
||||||
nda->mRotationKeys[n].mValue = abs.Normalize();
|
nda->mRotationKeys[n].mValue = abs1.Normalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +690,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
|
||||||
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
pcOut->mChildren = new aiNode*[pcIn->mChildren.size()];
|
||||||
|
|
||||||
// Recursively process all children
|
// Recursively process all children
|
||||||
const unsigned int size = pcIn->mChildren.size();
|
const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
|
||||||
for (unsigned int i = 0; i < size;++i)
|
for (unsigned int i = 0; i < size;++i)
|
||||||
{
|
{
|
||||||
pcOut->mChildren[i] = new aiNode();
|
pcOut->mChildren[i] = new aiNode();
|
||||||
|
@ -736,7 +742,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
|
DefaultLogger::get()->warn("No hierarchy information has been found in the file. ");
|
||||||
|
|
||||||
pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
|
pcOut->mRootNode->mNumChildren = pcOut->mNumMeshes +
|
||||||
mScene->mCameras.size() + mScene->mLights.size();
|
static_cast<unsigned int>(mScene->mCameras.size() + mScene->mLights.size());
|
||||||
|
|
||||||
pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ];
|
pcOut->mRootNode->mChildren = new aiNode* [ pcOut->mRootNode->mNumChildren ];
|
||||||
pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
|
pcOut->mRootNode->mName.Set("<3DSDummyRoot>");
|
||||||
|
@ -752,7 +758,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
|
||||||
pcNode->mNumMeshes = 1;
|
pcNode->mNumMeshes = 1;
|
||||||
|
|
||||||
// Build a name for the node
|
// Build a name for the node
|
||||||
pcNode->mName.length = sprintf(pcNode->mName.data,"3DSMesh_%i",i);
|
pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u",i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build dummy nodes for all cameras
|
// Build dummy nodes for all cameras
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -38,18 +38,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
|
|
||||||
#include "3DSExporter.h"
|
#include "3DSExporter.h"
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
|
#include "3DSHelper.h"
|
||||||
#include "SceneCombiner.h"
|
#include "SceneCombiner.h"
|
||||||
#include "SplitLargeMeshes.h"
|
#include "SplitLargeMeshes.h"
|
||||||
|
#include "StringComparison.h"
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
using namespace D3DS;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -81,7 +87,7 @@ namespace {
|
||||||
const std::size_t chunk_size = head_pos - chunk_start_pos;
|
const std::size_t chunk_size = head_pos - chunk_start_pos;
|
||||||
|
|
||||||
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
|
writer.SetCurrentPos(chunk_start_pos + SIZE_OFFSET);
|
||||||
writer.PutU4(chunk_size);
|
writer.PutU4(static_cast<uint32_t>(chunk_size));
|
||||||
writer.SetCurrentPos(head_pos);
|
writer.SetCurrentPos(head_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,9 +150,9 @@ namespace {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
// Worker function for exporting a scene to 3DS. Prototyped and registered in Exporter.cpp
|
||||||
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
boost::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
std::shared_ptr<IOStream> outfile (pIOSystem->Open(pFile, "wb"));
|
||||||
if(!outfile) {
|
if(!outfile) {
|
||||||
throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
|
throw DeadlyExportError("Could not open output .3ds file: " + std::string(pFile));
|
||||||
}
|
}
|
||||||
|
@ -160,7 +166,7 @@ void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScen
|
||||||
// in |Exporter::ExportFormatEntry|.
|
// in |Exporter::ExportFormatEntry|.
|
||||||
aiScene* scenecopy_tmp;
|
aiScene* scenecopy_tmp;
|
||||||
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
SceneCombiner::CopyScene(&scenecopy_tmp,pScene);
|
||||||
std::auto_ptr<aiScene> scenecopy(scenecopy_tmp);
|
std::unique_ptr<aiScene> scenecopy(scenecopy_tmp);
|
||||||
|
|
||||||
SplitLargeMeshesProcess_Triangle tri_splitter;
|
SplitLargeMeshesProcess_Triangle tri_splitter;
|
||||||
tri_splitter.SetLimit(0xffff);
|
tri_splitter.SetLimit(0xffff);
|
||||||
|
@ -177,7 +183,7 @@ void ExportScene3DS(const char* pFile, IOSystem* pIOSystem, const aiScene* pScen
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* scene)
|
Discreet3DSExporter:: Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* scene)
|
||||||
: scene(scene)
|
: scene(scene)
|
||||||
, writer(outfile)
|
, writer(outfile)
|
||||||
{
|
{
|
||||||
|
@ -188,8 +194,8 @@ Discreet3DSExporter:: Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, c
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_OBJMESH);
|
||||||
WriteMeshes();
|
|
||||||
WriteMaterials();
|
WriteMaterials();
|
||||||
|
WriteMeshes();
|
||||||
|
|
||||||
{
|
{
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MASTER_SCALE);
|
||||||
|
@ -294,7 +300,7 @@ void Discreet3DSExporter::WriteMaterials()
|
||||||
WriteColor(color);
|
WriteColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
aiShadingMode shading_mode;
|
aiShadingMode shading_mode = aiShadingMode_Flat;
|
||||||
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
|
if (mat.Get(AI_MATKEY_SHADING_MODEL, shading_mode) == AI_SUCCESS) {
|
||||||
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_MAT_SHADING);
|
||||||
|
|
||||||
|
@ -320,6 +326,7 @@ void Discreet3DSExporter::WriteMaterials()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
shading_mode_out = Discreet3DS::Flat;
|
||||||
ai_assert(false);
|
ai_assert(false);
|
||||||
};
|
};
|
||||||
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
|
writer.PutU2(static_cast<uint16_t>(shading_mode_out));
|
||||||
|
@ -360,7 +367,7 @@ void Discreet3DSExporter::WriteTexture(const aiMaterial& mat, aiTextureType type
|
||||||
aiTextureMapMode map_mode[2] = {
|
aiTextureMapMode map_mode[2] = {
|
||||||
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
|
aiTextureMapMode_Wrap, aiTextureMapMode_Wrap
|
||||||
};
|
};
|
||||||
float blend = 1.0f;
|
ai_real blend = 1.0;
|
||||||
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
|
if (mat.GetTexture(type, 0, &path, NULL, NULL, &blend, NULL, map_mode) != AI_SUCCESS || !path.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -555,6 +562,12 @@ void Discreet3DSExporter::WritePercentChunk(float f) {
|
||||||
writer.PutF4(f);
|
writer.PutF4(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void Discreet3DSExporter::WritePercentChunk(double f) {
|
||||||
|
ChunkWriter chunk(writer, Discreet3DS::CHUNK_PERCENTD);
|
||||||
|
writer.PutF8(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_3DS_EXPORTER
|
#endif // ASSIMP_BUILD_NO_3DS_EXPORTER
|
||||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -45,11 +45,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_3DSEXPORTER_H_INC
|
#define AI_3DSEXPORTER_H_INC
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "StreamWriter.h"
|
#include "StreamWriter.h"
|
||||||
|
#include "./../include/assimp/material.h"
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
|
struct aiMaterial;
|
||||||
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
@ -60,7 +64,7 @@ namespace Assimp
|
||||||
class Discreet3DSExporter
|
class Discreet3DSExporter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Discreet3DSExporter(boost::shared_ptr<IOStream> outfile, const aiScene* pScene);
|
Discreet3DSExporter(std::shared_ptr<IOStream> outfile, const aiScene* pScene);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -76,6 +80,7 @@ private:
|
||||||
void WriteString(const aiString& s);
|
void WriteString(const aiString& s);
|
||||||
void WriteColor(const aiColor3D& color);
|
void WriteColor(const aiColor3D& color);
|
||||||
void WritePercentChunk(float f);
|
void WritePercentChunk(float f);
|
||||||
|
void WritePercentChunk(double f);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,6 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "SpatialSort.h"
|
#include "SpatialSort.h"
|
||||||
#include "SmoothingGroups.h"
|
#include "SmoothingGroups.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
#include "qnan.h"
|
||||||
|
#include "./../include/assimp/material.h"
|
||||||
|
#include "./../include/assimp/camera.h"
|
||||||
|
#include "./../include/assimp/light.h"
|
||||||
|
#include "./../include/assimp/anim.h"
|
||||||
|
#include <stdio.h> //sprintf
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace D3DS {
|
namespace D3DS {
|
||||||
|
@ -122,6 +129,7 @@ public:
|
||||||
|
|
||||||
CHUNK_PERCENTW = 0x0030, // int2 percentage
|
CHUNK_PERCENTW = 0x0030, // int2 percentage
|
||||||
CHUNK_PERCENTF = 0x0031, // float4 percentage
|
CHUNK_PERCENTF = 0x0031, // float4 percentage
|
||||||
|
CHUNK_PERCENTD = 0x0032, // float8 percentage
|
||||||
// ********************************************************************
|
// ********************************************************************
|
||||||
|
|
||||||
// Prj master chunk
|
// Prj master chunk
|
||||||
|
@ -320,29 +328,30 @@ struct Texture
|
||||||
{
|
{
|
||||||
//! Default constructor
|
//! Default constructor
|
||||||
Texture()
|
Texture()
|
||||||
: mOffsetU (0.0f)
|
: mOffsetU (0.0)
|
||||||
, mOffsetV (0.0f)
|
, mOffsetV (0.0)
|
||||||
, mScaleU (1.0f)
|
, mScaleU (1.0)
|
||||||
, mScaleV (1.0f)
|
, mScaleV (1.0)
|
||||||
, mRotation (0.0f)
|
, mRotation (0.0)
|
||||||
, mMapMode (aiTextureMapMode_Wrap)
|
, mMapMode (aiTextureMapMode_Wrap)
|
||||||
|
, bPrivate()
|
||||||
, iUVSrc (0)
|
, iUVSrc (0)
|
||||||
{
|
{
|
||||||
mTextureBlend = get_qnan();
|
mTextureBlend = get_qnan();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Specifies the blend factor for the texture
|
//! Specifies the blend factor for the texture
|
||||||
float mTextureBlend;
|
ai_real mTextureBlend;
|
||||||
|
|
||||||
//! Specifies the filename of the texture
|
//! Specifies the filename of the texture
|
||||||
std::string mMapName;
|
std::string mMapName;
|
||||||
|
|
||||||
//! Specifies texture coordinate offsets/scaling/rotations
|
//! Specifies texture coordinate offsets/scaling/rotations
|
||||||
float mOffsetU;
|
ai_real mOffsetU;
|
||||||
float mOffsetV;
|
ai_real mOffsetV;
|
||||||
float mScaleU;
|
ai_real mScaleU;
|
||||||
float mScaleV;
|
ai_real mScaleV;
|
||||||
float mRotation;
|
ai_real mRotation;
|
||||||
|
|
||||||
//! Specifies the mapping mode to be used for the texture
|
//! Specifies the mapping mode to be used for the texture
|
||||||
aiTextureMapMode mMapMode;
|
aiTextureMapMode mMapMode;
|
||||||
|
@ -360,19 +369,18 @@ struct Material
|
||||||
{
|
{
|
||||||
//! Default constructor. Builds a default name for the material
|
//! Default constructor. Builds a default name for the material
|
||||||
Material()
|
Material()
|
||||||
:
|
: mDiffuse ( ai_real( 0.6 ), ai_real( 0.6 ), ai_real( 0.6 ) ) // FIX ... we won't want object to be black
|
||||||
mDiffuse (0.6f,0.6f,0.6f), // FIX ... we won't want object to be black
|
, mSpecularExponent ( ai_real( 0.0 ) )
|
||||||
mSpecularExponent (0.0f),
|
, mShininessStrength ( ai_real( 1.0 ) )
|
||||||
mShininessStrength (1.0f),
|
, mShading(Discreet3DS::Gouraud)
|
||||||
mShading(Discreet3DS::Gouraud),
|
, mTransparency ( ai_real( 1.0 ) )
|
||||||
mTransparency (1.0f),
|
, mBumpHeight ( ai_real( 1.0 ) )
|
||||||
mBumpHeight (1.0f),
|
, mTwoSided (false)
|
||||||
mTwoSided (false)
|
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
|
|
||||||
char szTemp[128];
|
char szTemp[128];
|
||||||
sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,9 +389,9 @@ struct Material
|
||||||
//! Diffuse color of the material
|
//! Diffuse color of the material
|
||||||
aiColor3D mDiffuse;
|
aiColor3D mDiffuse;
|
||||||
//! Specular exponent
|
//! Specular exponent
|
||||||
float mSpecularExponent;
|
ai_real mSpecularExponent;
|
||||||
//! Shininess strength, in percent
|
//! Shininess strength, in percent
|
||||||
float mShininessStrength;
|
ai_real mShininessStrength;
|
||||||
//! Specular color of the material
|
//! Specular color of the material
|
||||||
aiColor3D mSpecular;
|
aiColor3D mSpecular;
|
||||||
//! Ambient color of the material
|
//! Ambient color of the material
|
||||||
|
@ -391,7 +399,7 @@ struct Material
|
||||||
//! Shading type to be used
|
//! Shading type to be used
|
||||||
Discreet3DS::shadetype3ds mShading;
|
Discreet3DS::shadetype3ds mShading;
|
||||||
//! Opacity of the material
|
//! Opacity of the material
|
||||||
float mTransparency;
|
ai_real mTransparency;
|
||||||
//! Diffuse texture channel
|
//! Diffuse texture channel
|
||||||
Texture sTexDiffuse;
|
Texture sTexDiffuse;
|
||||||
//! Opacity texture channel
|
//! Opacity texture channel
|
||||||
|
@ -407,7 +415,7 @@ struct Material
|
||||||
//! Shininess texture channel
|
//! Shininess texture channel
|
||||||
Texture sTexShininess;
|
Texture sTexShininess;
|
||||||
//! Scaling factor for the bump values
|
//! Scaling factor for the bump values
|
||||||
float mBumpHeight;
|
ai_real mBumpHeight;
|
||||||
//! Emissive color
|
//! Emissive color
|
||||||
aiColor3D mEmissive;
|
aiColor3D mEmissive;
|
||||||
//! Ambient texture channel
|
//! Ambient texture channel
|
||||||
|
@ -428,7 +436,7 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
||||||
|
|
||||||
// Generate a default name for the mesh
|
// Generate a default name for the mesh
|
||||||
char szTemp[128];
|
char szTemp[128];
|
||||||
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +459,7 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
|
||||||
struct aiFloatKey
|
struct aiFloatKey
|
||||||
{
|
{
|
||||||
double mTime; ///< The time of this key
|
double mTime; ///< The time of this key
|
||||||
float mValue; ///< The value of this key
|
ai_real mValue; ///< The value of this key
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
@ -468,7 +476,7 @@ struct aiFloatKey
|
||||||
{return mTime < o.mTime;}
|
{return mTime < o.mTime;}
|
||||||
|
|
||||||
bool operator > (const aiFloatKey& o) const
|
bool operator > (const aiFloatKey& o) const
|
||||||
{return mTime < o.mTime;}
|
{return mTime > o.mTime;}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -477,18 +485,18 @@ struct aiFloatKey
|
||||||
/** Helper structure to represent a 3ds file node */
|
/** Helper structure to represent a 3ds file node */
|
||||||
struct Node
|
struct Node
|
||||||
{
|
{
|
||||||
Node()
|
Node():
|
||||||
|
mParent(NULL)
|
||||||
: mHierarchyPos (0)
|
, mInstanceNumber(0)
|
||||||
|
, mHierarchyPos (0)
|
||||||
, mHierarchyIndex (0)
|
, mHierarchyIndex (0)
|
||||||
, mInstanceCount (1)
|
, mInstanceCount (1)
|
||||||
|
|
||||||
{
|
{
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
|
|
||||||
// Generate a default name for the node
|
// Generate a default name for the node
|
||||||
char szTemp[128];
|
char szTemp[128];
|
||||||
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
|
|
||||||
aRotationKeys.reserve (20);
|
aRotationKeys.reserve (20);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -45,11 +45,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* http://www.the-labs.com/Blender/3DS-details.html
|
* http://www.the-labs.com/Blender/3DS-details.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "3DSLoader.h"
|
#include "3DSLoader.h"
|
||||||
|
#include "Macros.h"
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include "StringComparison.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -81,8 +86,8 @@ static const aiImporterDesc desc = {
|
||||||
int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \
|
int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk); \
|
||||||
if(chunkSize <= 0) \
|
if(chunkSize <= 0) \
|
||||||
continue; \
|
continue; \
|
||||||
const int oldReadLimit = stream->GetReadLimit(); \
|
const unsigned int oldReadLimit = stream->SetReadLimit( \
|
||||||
stream->SetReadLimit(stream->GetCurrentPos() + chunkSize); \
|
stream->GetCurrentPos() + chunkSize); \
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -98,6 +103,14 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
Discreet3DSImporter::Discreet3DSImporter()
|
Discreet3DSImporter::Discreet3DSImporter()
|
||||||
|
: stream(),
|
||||||
|
mLastNodeIndex(),
|
||||||
|
mCurrentNode(),
|
||||||
|
mRootNode(),
|
||||||
|
mScene(),
|
||||||
|
mMasterScale(),
|
||||||
|
bHasBG(),
|
||||||
|
bIsPrj()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -169,18 +182,21 @@ void Discreet3DSImporter::InternReadFile( const std::string& pFile,
|
||||||
ParseMainChunk();
|
ParseMainChunk();
|
||||||
|
|
||||||
// Process all meshes in the file. First check whether all
|
// Process all meshes in the file. First check whether all
|
||||||
// face indices haev valid values. The generate our
|
// face indices have valid values. The generate our
|
||||||
// internal verbose representation. Finally compute normal
|
// internal verbose representation. Finally compute normal
|
||||||
// vectors from the smoothing groups we read from the
|
// vectors from the smoothing groups we read from the
|
||||||
// file.
|
// file.
|
||||||
for (std::vector<D3DS::Mesh>::iterator i = mScene->mMeshes.begin(),
|
for (auto &mesh : mScene->mMeshes) {
|
||||||
end = mScene->mMeshes.end(); i != end;++i) {
|
if (mesh.mFaces.size() > 0 && mesh.mPositions.size() == 0) {
|
||||||
CheckIndices(*i);
|
delete mScene;
|
||||||
MakeUnique (*i);
|
throw DeadlyImportError("3DS file contains faces but no vertices: " + pFile);
|
||||||
ComputeNormalsWithSmoothingsGroups<D3DS::Face>(*i);
|
}
|
||||||
|
CheckIndices(mesh);
|
||||||
|
MakeUnique (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();
|
||||||
|
@ -442,20 +458,20 @@ void Discreet3DSImporter::ParseChunk(const char* name, unsigned int num)
|
||||||
camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
|
camera->mLookAt.x = stream->GetF4() - camera->mPosition.x;
|
||||||
camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
|
camera->mLookAt.y = stream->GetF4() - camera->mPosition.y;
|
||||||
camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
|
camera->mLookAt.z = stream->GetF4() - camera->mPosition.z;
|
||||||
float len = camera->mLookAt.Length();
|
ai_real len = camera->mLookAt.Length();
|
||||||
if (len < 1e-5f) {
|
if (len < 1e-5) {
|
||||||
|
|
||||||
// There are some files with lookat == position. Don't know why or whether it's ok or not.
|
// There are some files with lookat == position. Don't know why or whether it's ok or not.
|
||||||
DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
|
DefaultLogger::get()->error("3DS: Unable to read proper camera look-at vector");
|
||||||
camera->mLookAt = aiVector3D(0.f,1.f,0.f);
|
camera->mLookAt = aiVector3D(0.0,1.0,0.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
else camera->mLookAt /= len;
|
else camera->mLookAt /= len;
|
||||||
|
|
||||||
// And finally - the camera rotation angle, in counter clockwise direction
|
// And finally - the camera rotation angle, in counter clockwise direction
|
||||||
const float angle = AI_DEG_TO_RAD( stream->GetF4() );
|
const ai_real angle = AI_DEG_TO_RAD( stream->GetF4() );
|
||||||
aiQuaternion quat(camera->mLookAt,angle);
|
aiQuaternion quat(camera->mLookAt,angle);
|
||||||
camera->mUp = quat.GetMatrix() * aiVector3D(0.f,1.f,0.f);
|
camera->mUp = quat.GetMatrix() * aiVector3D(0.0,1.0,0.0);
|
||||||
|
|
||||||
// Read the lense angle
|
// Read the lense angle
|
||||||
camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
|
camera->mHorizontalFOV = AI_DEG_TO_RAD ( stream->GetF4() );
|
||||||
|
@ -663,7 +679,7 @@ void Discreet3DSImporter::ParseHierarchyChunk(uint16_t parent)
|
||||||
|
|
||||||
if ( pcNode)
|
if ( pcNode)
|
||||||
{
|
{
|
||||||
// if the source is not a CHUNK_TRACKINFO block it wont be an object instance
|
// if the source is not a CHUNK_TRACKINFO block it won't be an object instance
|
||||||
if (parent != Discreet3DS::CHUNK_TRACKINFO)
|
if (parent != Discreet3DS::CHUNK_TRACKINFO)
|
||||||
{
|
{
|
||||||
mCurrentNode = pcNode;
|
mCurrentNode = pcNode;
|
||||||
|
@ -944,6 +960,9 @@ void Discreet3DSImporter::ParseFaceChunk()
|
||||||
// This is the list of smoothing groups - a bitfield for every face.
|
// This is the list of smoothing groups - a bitfield for every face.
|
||||||
// Up to 32 smoothing groups assigned to a single face.
|
// Up to 32 smoothing groups assigned to a single face.
|
||||||
unsigned int num = chunkSize/4, m = 0;
|
unsigned int num = chunkSize/4, m = 0;
|
||||||
|
if (num > mMesh.mFaces.size()) {
|
||||||
|
throw DeadlyImportError("3DS: More smoothing groups than faces");
|
||||||
|
}
|
||||||
for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num;++i, ++m) {
|
for (std::vector<D3DS::Face>::iterator i = mMesh.mFaces.begin(); m != num;++i, ++m) {
|
||||||
// nth bit is set for nth smoothing group
|
// nth bit is set for nth smoothing group
|
||||||
(*i).iSmoothGroup = stream->GetI4();
|
(*i).iSmoothGroup = stream->GetI4();
|
||||||
|
@ -1148,13 +1167,14 @@ void Discreet3DSImporter::ParseMaterialChunk()
|
||||||
case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
|
case Discreet3DS::CHUNK_MAT_TRANSPARENCY:
|
||||||
{
|
{
|
||||||
// This is the material's transparency
|
// This is the material's transparency
|
||||||
float* pcf = &mScene->mMaterials.back().mTransparency;
|
ai_real* pcf = &mScene->mMaterials.back().mTransparency;
|
||||||
*pcf = ParsePercentageChunk();
|
*pcf = ParsePercentageChunk();
|
||||||
|
|
||||||
// NOTE: transparency, not opacity
|
// NOTE: transparency, not opacity
|
||||||
if (is_qnan(*pcf))
|
if (is_qnan(*pcf))
|
||||||
*pcf = 1.0f;
|
*pcf = ai_real( 1.0 );
|
||||||
else *pcf = 1.0f - *pcf * (float)0xFFFF / 100.0f;
|
else
|
||||||
|
*pcf = ai_real( 1.0 ) - *pcf * (ai_real)0xFFFF / ai_real( 100.0 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1170,30 +1190,32 @@ void Discreet3DSImporter::ParseMaterialChunk()
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_SHININESS:
|
case Discreet3DS::CHUNK_MAT_SHININESS:
|
||||||
{ // This is the shininess of the material
|
{ // This is the shininess of the material
|
||||||
float* pcf = &mScene->mMaterials.back().mSpecularExponent;
|
ai_real* pcf = &mScene->mMaterials.back().mSpecularExponent;
|
||||||
*pcf = ParsePercentageChunk();
|
*pcf = ParsePercentageChunk();
|
||||||
if (is_qnan(*pcf))
|
if (is_qnan(*pcf))
|
||||||
*pcf = 0.0f;
|
*pcf = 0.0;
|
||||||
else *pcf *= (float)0xFFFF;
|
else *pcf *= (ai_real)0xFFFF;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
|
case Discreet3DS::CHUNK_MAT_SHININESS_PERCENT:
|
||||||
{ // This is the shininess strength of the material
|
{ // This is the shininess strength of the material
|
||||||
float* pcf = &mScene->mMaterials.back().mShininessStrength;
|
ai_real* pcf = &mScene->mMaterials.back().mShininessStrength;
|
||||||
*pcf = ParsePercentageChunk();
|
*pcf = ParsePercentageChunk();
|
||||||
if (is_qnan(*pcf))
|
if (is_qnan(*pcf))
|
||||||
*pcf = 0.0f;
|
*pcf = ai_real( 0.0 );
|
||||||
else *pcf *= (float)0xffff / 100.0f;
|
else
|
||||||
|
*pcf *= (ai_real)0xffff / ai_real( 100.0 );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
|
case Discreet3DS::CHUNK_MAT_SELF_ILPCT:
|
||||||
{ // This is the self illumination strength of the material
|
{ // This is the self illumination strength of the material
|
||||||
float f = ParsePercentageChunk();
|
ai_real f = ParsePercentageChunk();
|
||||||
if (is_qnan(f))
|
if (is_qnan(f))
|
||||||
f = 0.0f;
|
f = ai_real( 0.0 );
|
||||||
else f *= (float)0xFFFF / 100.0f;
|
else
|
||||||
|
f *= (ai_real)0xFFFF / ai_real( 100.0 );
|
||||||
mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
|
mScene->mMaterials.back().mEmissive = aiColor3D(f,f,f);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1251,6 +1273,11 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case Discreet3DS::CHUNK_PERCENTD:
|
||||||
|
// Manually parse the blend factor
|
||||||
|
pcOut->mTextureBlend = ai_real( stream->GetF8() );
|
||||||
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTF:
|
case Discreet3DS::CHUNK_PERCENTF:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = stream->GetF4();
|
pcOut->mTextureBlend = stream->GetF4();
|
||||||
|
@ -1258,7 +1285,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTW:
|
case Discreet3DS::CHUNK_PERCENTW:
|
||||||
// Manually parse the blend factor
|
// Manually parse the blend factor
|
||||||
pcOut->mTextureBlend = (float)((uint16_t)stream->GetI2()) / 100.0f;
|
pcOut->mTextureBlend = (ai_real)((uint16_t)stream->GetI2()) / ai_real( 100.0 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
|
case Discreet3DS::CHUNK_MAT_MAP_USCALE:
|
||||||
|
@ -1317,7 +1344,7 @@ void Discreet3DSImporter::ParseTextureChunk(D3DS::Texture* pcOut)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Read a percentage chunk
|
// Read a percentage chunk
|
||||||
float Discreet3DSImporter::ParsePercentageChunk()
|
ai_real Discreet3DSImporter::ParsePercentageChunk()
|
||||||
{
|
{
|
||||||
Discreet3DS::Chunk chunk;
|
Discreet3DS::Chunk chunk;
|
||||||
ReadChunk(&chunk);
|
ReadChunk(&chunk);
|
||||||
|
@ -1325,19 +1352,18 @@ float Discreet3DSImporter::ParsePercentageChunk()
|
||||||
if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
|
if (Discreet3DS::CHUNK_PERCENTF == chunk.Flag)
|
||||||
return stream->GetF4();
|
return stream->GetF4();
|
||||||
else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
|
else if (Discreet3DS::CHUNK_PERCENTW == chunk.Flag)
|
||||||
return (float)((uint16_t)stream->GetI2()) / (float)0xFFFF;
|
return (ai_real)((uint16_t)stream->GetI2()) / (ai_real)0xFFFF;
|
||||||
return get_qnan();
|
return get_qnan();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
|
// Read a color chunk. If a percentage chunk is found instead it is read as a grayscale color
|
||||||
void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
void Discreet3DSImporter::ParseColorChunk( aiColor3D* out, bool acceptPercent )
|
||||||
bool acceptPercent)
|
|
||||||
{
|
{
|
||||||
ai_assert(out != NULL);
|
ai_assert(out != NULL);
|
||||||
|
|
||||||
// error return value
|
// error return value
|
||||||
const float qnan = get_qnan();
|
const ai_real qnan = get_qnan();
|
||||||
static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
|
static const aiColor3D clrError = aiColor3D(qnan,qnan,qnan);
|
||||||
|
|
||||||
Discreet3DS::Chunk chunk;
|
Discreet3DS::Chunk chunk;
|
||||||
|
@ -1353,7 +1379,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
||||||
bGamma = true;
|
bGamma = true;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_RGBF:
|
case Discreet3DS::CHUNK_RGBF:
|
||||||
if (sizeof(float) * 3 > diff) {
|
if (sizeof(ai_real) * 3 > diff) {
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1365,13 +1391,16 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
||||||
case Discreet3DS::CHUNK_LINRGBB:
|
case Discreet3DS::CHUNK_LINRGBB:
|
||||||
bGamma = true;
|
bGamma = true;
|
||||||
case Discreet3DS::CHUNK_RGBB:
|
case Discreet3DS::CHUNK_RGBB:
|
||||||
if (sizeof(char) * 3 > diff) {
|
{
|
||||||
|
if ( sizeof( char ) * 3 > diff ) {
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
|
const ai_real invVal = ai_real( 1.0 ) / ai_real( 255.0 );
|
||||||
out->g = (float)(uint8_t)stream->GetI1() / 255.0f;
|
out->r = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
|
||||||
out->b = (float)(uint8_t)stream->GetI1() / 255.0f;
|
out->g = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
|
||||||
|
out->b = ( ai_real ) ( uint8_t ) stream->GetI1() * invVal;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Percentage chunks are accepted, too.
|
// Percentage chunks are accepted, too.
|
||||||
|
@ -1385,7 +1414,7 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D* out,
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_PERCENTW:
|
case Discreet3DS::CHUNK_PERCENTW:
|
||||||
if (acceptPercent && 1 <= diff) {
|
if (acceptPercent && 1 <= diff) {
|
||||||
out->g = out->b = out->r = (float)(uint8_t)stream->GetI1() / 255.0f;
|
out->g = out->b = out->r = (ai_real)(uint8_t)stream->GetI1() / ai_real( 255.0 );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*out = clrError;
|
*out = clrError;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,12 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_3DSIMPORTER_H_INC
|
#define AI_3DSIMPORTER_H_INC
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
|
||||||
|
|
||||||
struct aiNode;
|
|
||||||
#include "3DSHelper.h"
|
#include "3DSHelper.h"
|
||||||
|
#include "StreamReader.h"
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -117,7 +119,7 @@ protected:
|
||||||
* chunk behind afterwards. If no percentage chunk is found
|
* chunk behind afterwards. If no percentage chunk is found
|
||||||
* QNAN is returned.
|
* QNAN is returned.
|
||||||
*/
|
*/
|
||||||
float ParsePercentageChunk();
|
ai_real ParsePercentageChunk();
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Parse a color chunk. mCurrent will point to the next
|
/** Parse a color chunk. mCurrent will point to the next
|
||||||
|
@ -263,7 +265,7 @@ protected:
|
||||||
aiColor3D mClrAmbient;
|
aiColor3D mClrAmbient;
|
||||||
|
|
||||||
/** Master scaling factor of the scene */
|
/** Master scaling factor of the scene */
|
||||||
float mMasterScale;
|
ai_real mMasterScale;
|
||||||
|
|
||||||
/** Path to the background image of the scene */
|
/** Path to the background image of the scene */
|
||||||
std::string mBackgroundImage;
|
std::string mBackgroundImage;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file Implementation of the AC3D importer class */
|
/** @file Implementation of the AC3D importer class */
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_AC_IMPORTER
|
||||||
|
|
||||||
|
@ -51,6 +51,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "Subdivision.h"
|
#include "Subdivision.h"
|
||||||
|
#include "Importer.h"
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/light.h>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/material.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/config.h>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -79,6 +89,9 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// read a string (may be enclosed in double quotation marks). buffer must point to "
|
// read a string (may be enclosed in double quotation marks). buffer must point to "
|
||||||
#define AI_AC_GET_STRING(out) \
|
#define AI_AC_GET_STRING(out) \
|
||||||
|
if (*buffer == '\0') { \
|
||||||
|
throw DeadlyImportError("AC3D: Unexpected EOF in string"); \
|
||||||
|
} \
|
||||||
++buffer; \
|
++buffer; \
|
||||||
const char* sz = buffer; \
|
const char* sz = buffer; \
|
||||||
while ('\"' != *buffer) \
|
while ('\"' != *buffer) \
|
||||||
|
@ -119,6 +132,15 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
AC3DImporter::AC3DImporter()
|
AC3DImporter::AC3DImporter()
|
||||||
|
: buffer(),
|
||||||
|
configSplitBFCull(),
|
||||||
|
configEvalSubdivision(),
|
||||||
|
mNumMeshes(),
|
||||||
|
mLights(),
|
||||||
|
lights(),
|
||||||
|
groups(),
|
||||||
|
polys(),
|
||||||
|
worlds()
|
||||||
{
|
{
|
||||||
// nothing to be done here
|
// nothing to be done here
|
||||||
}
|
}
|
||||||
|
@ -189,7 +211,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
||||||
|
|
||||||
// Generate a default name for both the light source and the node
|
// Generate a default name for both the light source and the node
|
||||||
// FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
|
// FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
|
||||||
light->mName.length = ::sprintf(light->mName.data,"ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
|
light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i",static_cast<unsigned int>(mLights->size())-1);
|
||||||
obj.name = std::string( light->mName.data );
|
obj.name = std::string( light->mName.data );
|
||||||
|
|
||||||
DefaultLogger::get()->debug("AC3D: Light source encountered");
|
DefaultLogger::get()->debug("AC3D: Light source encountered");
|
||||||
|
@ -274,6 +296,9 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
||||||
SkipSpaces(&buffer);
|
SkipSpaces(&buffer);
|
||||||
|
|
||||||
unsigned int t = strtoul10(buffer,&buffer);
|
unsigned int t = strtoul10(buffer,&buffer);
|
||||||
|
if (t >= AI_MAX_ALLOC(aiVector3D)) {
|
||||||
|
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
|
||||||
|
}
|
||||||
obj.vertices.reserve(t);
|
obj.vertices.reserve(t);
|
||||||
for (unsigned int i = 0; i < t;++i)
|
for (unsigned int i = 0; i < t;++i)
|
||||||
{
|
{
|
||||||
|
@ -327,8 +352,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
||||||
{
|
{
|
||||||
if(!GetNextLine())
|
if(!GetNextLine())
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("AC3D: Unexpected EOF: surface is incomplete");
|
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (TokenMatch(buffer,"mat",3))
|
if (TokenMatch(buffer,"mat",3))
|
||||||
{
|
{
|
||||||
|
@ -489,7 +513,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
|
|
||||||
for (it = object.surfaces.begin(); it != end; ++it)
|
for (it = object.surfaces.begin(); it != end; ++it)
|
||||||
{
|
{
|
||||||
register unsigned int idx = (*it).mat;
|
unsigned int idx = (*it).mat;
|
||||||
if (idx >= needMat.size())
|
if (idx >= needMat.size())
|
||||||
{
|
{
|
||||||
DefaultLogger::get()->error("AC3D: material index is out of range");
|
DefaultLogger::get()->error("AC3D: material index is out of range");
|
||||||
|
@ -563,9 +587,19 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
|
|
||||||
// allocate storage for vertices and normals
|
// allocate storage for vertices and normals
|
||||||
mesh->mNumFaces = (*cit).first;
|
mesh->mNumFaces = (*cit).first;
|
||||||
|
if (mesh->mNumFaces == 0) {
|
||||||
|
throw DeadlyImportError("AC3D: No faces");
|
||||||
|
} else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) {
|
||||||
|
throw DeadlyImportError("AC3D: Too many faces, would run out of memory");
|
||||||
|
}
|
||||||
aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
|
aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
|
||||||
|
|
||||||
mesh->mNumVertices = (*cit).second;
|
mesh->mNumVertices = (*cit).second;
|
||||||
|
if (mesh->mNumVertices == 0) {
|
||||||
|
throw DeadlyImportError("AC3D: No vertices");
|
||||||
|
} else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
|
||||||
|
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
|
||||||
|
}
|
||||||
aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||||
unsigned int cur = 0;
|
unsigned int cur = 0;
|
||||||
|
|
||||||
|
@ -598,6 +632,9 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
face.mIndices[i] = cur++;
|
face.mIndices[i] = cur++;
|
||||||
|
|
||||||
// copy vertex positions
|
// copy vertex positions
|
||||||
|
if (static_cast<unsigned>(vertices - mesh->mVertices) >= mesh->mNumVertices) {
|
||||||
|
throw DeadlyImportError("AC3D: Invalid number of vertices");
|
||||||
|
}
|
||||||
*vertices = object.vertices[entry.first] + object.translation;
|
*vertices = object.vertices[entry.first] + object.translation;
|
||||||
|
|
||||||
|
|
||||||
|
@ -617,7 +654,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
it2 = (*it).entries.begin();
|
it2 = (*it).entries.begin();
|
||||||
|
|
||||||
// either a closed or an unclosed line
|
// either a closed or an unclosed line
|
||||||
register unsigned int tmp = (unsigned int)(*it).entries.size();
|
unsigned int tmp = (unsigned int)(*it).entries.size();
|
||||||
if (0x2 == type)--tmp;
|
if (0x2 == type)--tmp;
|
||||||
for (unsigned int m = 0; m < tmp;++m)
|
for (unsigned int m = 0; m < tmp;++m)
|
||||||
{
|
{
|
||||||
|
@ -629,6 +666,10 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
face.mIndices[1] = cur++;
|
face.mIndices[1] = cur++;
|
||||||
|
|
||||||
// copy vertex positions
|
// copy vertex positions
|
||||||
|
if (it2 == (*it).entries.end() ) {
|
||||||
|
throw DeadlyImportError("AC3D: Bad line");
|
||||||
|
}
|
||||||
|
ai_assert((*it2).first < object.vertices.size());
|
||||||
*vertices++ = object.vertices[(*it2).first];
|
*vertices++ = object.vertices[(*it2).first];
|
||||||
|
|
||||||
// copy texture coordinates
|
// copy texture coordinates
|
||||||
|
@ -667,7 +708,7 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
// collect all meshes using the same material group.
|
// collect all meshes using the same material group.
|
||||||
if (object.subDiv) {
|
if (object.subDiv) {
|
||||||
if (configEvalSubdivision) {
|
if (configEvalSubdivision) {
|
||||||
boost::scoped_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
|
std::unique_ptr<Subdivider> div(Subdivider::Create(Subdivider::CATMULL_CLARKE));
|
||||||
DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name);
|
DefaultLogger::get()->info("AC3D: Evaluating subdivision surface: "+object.name);
|
||||||
|
|
||||||
std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
|
std::vector<aiMesh*> cpy(meshes.size()-oldm,NULL);
|
||||||
|
@ -692,18 +733,18 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
||||||
switch (object.type)
|
switch (object.type)
|
||||||
{
|
{
|
||||||
case Object::Group:
|
case Object::Group:
|
||||||
node->mName.length = ::sprintf(node->mName.data,"ACGroup_%i",groups++);
|
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i",groups++);
|
||||||
break;
|
break;
|
||||||
case Object::Poly:
|
case Object::Poly:
|
||||||
node->mName.length = ::sprintf(node->mName.data,"ACPoly_%i",polys++);
|
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i",polys++);
|
||||||
break;
|
break;
|
||||||
case Object::Light:
|
case Object::Light:
|
||||||
node->mName.length = ::sprintf(node->mName.data,"ACLight_%i",lights++);
|
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i",lights++);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// there shouldn't be more than one world, but we don't care
|
// there shouldn't be more than one world, but we don't care
|
||||||
case Object::World:
|
case Object::World:
|
||||||
node->mName.length = ::sprintf(node->mName.data,"ACWorld_%i",worlds++);
|
node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i",worlds++);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -746,7 +787,7 @@ void AC3DImporter::SetupProperties(const Importer* pImp)
|
||||||
void AC3DImporter::InternReadFile( const std::string& pFile,
|
void AC3DImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file.get() == NULL)
|
if( file.get() == NULL)
|
||||||
|
@ -843,7 +884,7 @@ void AC3DImporter::InternReadFile( const std::string& pFile,
|
||||||
// copy meshes
|
// copy meshes
|
||||||
if (meshes.empty())
|
if (meshes.empty())
|
||||||
{
|
{
|
||||||
throw DeadlyImportError("An unknown error occured during converting");
|
throw DeadlyImportError("An unknown error occurred during converting");
|
||||||
}
|
}
|
||||||
pScene->mNumMeshes = (unsigned int)meshes.size();
|
pScene->mNumMeshes = (unsigned int)meshes.size();
|
||||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -47,7 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
struct aiMesh;
|
||||||
|
struct aiMaterial;
|
||||||
|
struct aiLight;
|
||||||
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -124,6 +130,7 @@ public:
|
||||||
, surfaces()
|
, surfaces()
|
||||||
, numRefs (0)
|
, numRefs (0)
|
||||||
, subDiv (0)
|
, subDiv (0)
|
||||||
|
, crease()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Type description
|
// Type description
|
||||||
|
|
|
@ -0,0 +1,704 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter.cpp
|
||||||
|
/// \brief AMF-format files importer for Assimp: main algorithm implementation.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
|
|
||||||
|
// Header files, Assimp.
|
||||||
|
#include "AMFImporter.hpp"
|
||||||
|
#include "AMFImporter_Macro.hpp"
|
||||||
|
|
||||||
|
#include "fast_atof.h"
|
||||||
|
#include "DefaultIOSystem.h"
|
||||||
|
|
||||||
|
// Header files, stdlib.
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \var aiImporterDesc AMFImporter::Description
|
||||||
|
/// Conastant which hold importer description
|
||||||
|
const aiImporterDesc AMFImporter::Description = {
|
||||||
|
"Additive manufacturing file format(AMF) Importer",
|
||||||
|
"smalcom",
|
||||||
|
"",
|
||||||
|
"See documentation in source code. Chapter: Limitations.",
|
||||||
|
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"amf"
|
||||||
|
};
|
||||||
|
|
||||||
|
void AMFImporter::Clear()
|
||||||
|
{
|
||||||
|
mNodeElement_Cur = nullptr;
|
||||||
|
mUnit.clear();
|
||||||
|
mMaterial_Converted.clear();
|
||||||
|
mTexture_Converted.clear();
|
||||||
|
// Delete all elements
|
||||||
|
if(mNodeElement_List.size())
|
||||||
|
{
|
||||||
|
for(CAMFImporter_NodeElement* ne: mNodeElement_List) { delete ne; }
|
||||||
|
|
||||||
|
mNodeElement_List.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AMFImporter::~AMFImporter()
|
||||||
|
{
|
||||||
|
if(mReader != nullptr) delete mReader;
|
||||||
|
// Clear() is accounting if data already is deleted. So, just check again if all data is deleted.
|
||||||
|
Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
/************************************************************ Functions: find set ************************************************************/
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
|
||||||
|
bool AMFImporter::Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const
|
||||||
|
{
|
||||||
|
for(CAMFImporter_NodeElement* ne: mNodeElement_List)
|
||||||
|
{
|
||||||
|
if((ne->ID == pID) && (ne->Type == pType))
|
||||||
|
{
|
||||||
|
if(pNodeElement != nullptr) *pNodeElement = ne;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}// for(CAMFImporter_NodeElement* ne: mNodeElement_List)
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMFImporter::Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
|
||||||
|
{
|
||||||
|
aiString node_name(pID.c_str());
|
||||||
|
|
||||||
|
for(aiNode* node: pNodeList)
|
||||||
|
{
|
||||||
|
if(node->mName == node_name)
|
||||||
|
{
|
||||||
|
if(pNode != nullptr) *pNode = node;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}// for(aiNode* node: pNodeList)
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMFImporter::Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
|
||||||
|
{
|
||||||
|
for(const SPP_Material& mat: mMaterial_Converted)
|
||||||
|
{
|
||||||
|
if(mat.ID == pID)
|
||||||
|
{
|
||||||
|
if(pConvertedMaterial != nullptr) *pConvertedMaterial = &mat;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}// for(const SPP_Material& mat: mMaterial_Converted)
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
/************************************************************ Functions: throw set ***********************************************************/
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
|
||||||
|
void AMFImporter::Throw_CloseNotFound(const std::string& pNode)
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("Close tag for node <" + pNode + "> not found. Seems file is corrupt.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Throw_IncorrectAttr(const std::string& pAttrName)
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("Node <" + std::string(mReader->getNodeName()) + "> has incorrect attribute \"" + pAttrName + "\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Throw_IncorrectAttrValue(const std::string& pAttrName)
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("Attribute \"" + pAttrName + "\" in node <" + std::string(mReader->getNodeName()) + "> has incorrect value.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription)
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("\"" + pNodeType + "\" node can be used only once in " + mReader->getNodeName() + ". Description: " + pDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Throw_ID_NotFound(const std::string& pID) const
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("Not found node with name \"" + pID + "\".");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
/************************************************************* Functions: XML set ************************************************************/
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
|
||||||
|
void AMFImporter::XML_CheckNode_MustHaveChildren()
|
||||||
|
{
|
||||||
|
if(mReader->isEmptyElement()) throw DeadlyImportError(std::string("Node <") + mReader->getNodeName() + "> must have children.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
|
||||||
|
{
|
||||||
|
static const size_t Uns_Skip_Len = 3;
|
||||||
|
const char* Uns_Skip[Uns_Skip_Len] = { "composite", "edge", "normal" };
|
||||||
|
|
||||||
|
static bool skipped_before[Uns_Skip_Len] = { false, false, false };
|
||||||
|
|
||||||
|
std::string nn(mReader->getNodeName());
|
||||||
|
bool found = false;
|
||||||
|
bool close_found = false;
|
||||||
|
size_t sk_idx;
|
||||||
|
|
||||||
|
for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
|
||||||
|
{
|
||||||
|
if(nn != Uns_Skip[sk_idx]) continue;
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
if(mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
close_found = true;
|
||||||
|
|
||||||
|
goto casu_cres;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(mReader->read())
|
||||||
|
{
|
||||||
|
if((mReader->getNodeType() == irr::io::EXN_ELEMENT_END) && (nn == mReader->getNodeName()))
|
||||||
|
{
|
||||||
|
close_found = true;
|
||||||
|
|
||||||
|
goto casu_cres;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}// for(sk_idx = 0; sk_idx < Uns_Skip_Len; sk_idx++)
|
||||||
|
|
||||||
|
casu_cres:
|
||||||
|
|
||||||
|
if(!found) throw DeadlyImportError("Unknown node \"" + nn + "\" in " + pParentNodeName + ".");
|
||||||
|
if(!close_found) Throw_CloseNotFound(nn);
|
||||||
|
|
||||||
|
if(!skipped_before[sk_idx])
|
||||||
|
{
|
||||||
|
skipped_before[sk_idx] = true;
|
||||||
|
LogWarning("Skipping node \"" + nn + "\" in " + pParentNodeName + ".");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMFImporter::XML_SearchNode(const std::string& pNodeName)
|
||||||
|
{
|
||||||
|
while(mReader->read())
|
||||||
|
{
|
||||||
|
if((mReader->getNodeType() == irr::io::EXN_ELEMENT) && XML_CheckNode_NameEqual(pNodeName)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AMFImporter::XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
|
||||||
|
{
|
||||||
|
std::string val(mReader->getAttributeValue(pAttrIdx));
|
||||||
|
|
||||||
|
if((val == "false") || (val == "0"))
|
||||||
|
return false;
|
||||||
|
else if((val == "true") || (val == "1"))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
throw DeadlyImportError("Bool attribute value can contain \"false\"/\"0\" or \"true\"/\"1\" not the \"" + val + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
float AMFImporter::XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
|
||||||
|
{
|
||||||
|
std::string val;
|
||||||
|
float tvalf;
|
||||||
|
|
||||||
|
ParseHelper_FixTruncatedFloatString(mReader->getAttributeValue(pAttrIdx), val);
|
||||||
|
fast_atoreal_move(val.c_str(), tvalf, false);
|
||||||
|
|
||||||
|
return tvalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AMFImporter::XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
|
||||||
|
{
|
||||||
|
return strtoul10(mReader->getAttributeValue(pAttrIdx));
|
||||||
|
}
|
||||||
|
|
||||||
|
float AMFImporter::XML_ReadNode_GetVal_AsFloat()
|
||||||
|
{
|
||||||
|
std::string val;
|
||||||
|
float tvalf;
|
||||||
|
|
||||||
|
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. No data, seems file is corrupt.");
|
||||||
|
if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsFloat. Invalid type of XML element, seems file is corrupt.");
|
||||||
|
|
||||||
|
ParseHelper_FixTruncatedFloatString(mReader->getNodeData(), val);
|
||||||
|
fast_atoreal_move(val.c_str(), tvalf, false);
|
||||||
|
|
||||||
|
return tvalf;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t AMFImporter::XML_ReadNode_GetVal_AsU32()
|
||||||
|
{
|
||||||
|
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. No data, seems file is corrupt.");
|
||||||
|
if(mReader->getNodeType() != irr::io::EXN_TEXT) throw DeadlyImportError("XML_ReadNode_GetVal_AsU32. Invalid type of XML element, seems file is corrupt.");
|
||||||
|
|
||||||
|
return strtoul10(mReader->getNodeData());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::XML_ReadNode_GetVal_AsString(std::string& pValue)
|
||||||
|
{
|
||||||
|
if(!mReader->read()) throw DeadlyImportError("XML_ReadNode_GetVal_AsString. No data, seems file is corrupt.");
|
||||||
|
if(mReader->getNodeType() != irr::io::EXN_TEXT)
|
||||||
|
throw DeadlyImportError("XML_ReadNode_GetVal_AsString. Invalid type of XML element, seems file is corrupt.");
|
||||||
|
|
||||||
|
pValue = mReader->getNodeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
/************************************************************ Functions: parse set ***********************************************************/
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
|
||||||
|
void AMFImporter::ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(pNode);// add new element to current element child list.
|
||||||
|
mNodeElement_Cur = pNode;// switch current element to new one.
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::ParseHelper_Node_Exit()
|
||||||
|
{
|
||||||
|
// check if we can walk up.
|
||||||
|
if(mNodeElement_Cur != nullptr) mNodeElement_Cur = mNodeElement_Cur->Parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
|
||||||
|
{
|
||||||
|
size_t instr_len;
|
||||||
|
|
||||||
|
pOutString.clear();
|
||||||
|
instr_len = strlen(pInStr);
|
||||||
|
if(!instr_len) return;
|
||||||
|
|
||||||
|
pOutString.reserve(instr_len * 3 / 2);
|
||||||
|
// check and correct floats in format ".x". Must be "x.y".
|
||||||
|
if(pInStr[0] == '.') pOutString.push_back('0');
|
||||||
|
|
||||||
|
pOutString.push_back(pInStr[0]);
|
||||||
|
for(size_t ci = 1; ci < instr_len; ci++)
|
||||||
|
{
|
||||||
|
if((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t')))
|
||||||
|
{
|
||||||
|
pOutString.push_back('0');
|
||||||
|
pOutString.push_back('.');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pOutString.push_back(pInStr[ci]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar)
|
||||||
|
{
|
||||||
|
return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
|
||||||
|
{
|
||||||
|
// With help from
|
||||||
|
// René Nyffenegger http://www.adp-gmbh.ch/cpp/common/base64.html
|
||||||
|
const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||||
|
|
||||||
|
uint8_t tidx = 0;
|
||||||
|
uint8_t arr4[4], arr3[3];
|
||||||
|
|
||||||
|
// check input data
|
||||||
|
if(pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
|
||||||
|
// prepare output place
|
||||||
|
pOutputData.clear();
|
||||||
|
pOutputData.reserve(pInputBase64.size() / 4 * 3);
|
||||||
|
|
||||||
|
for(size_t in_len = pInputBase64.size(), in_idx = 0; (in_len > 0) && (pInputBase64[in_idx] != '='); in_len--)
|
||||||
|
{
|
||||||
|
if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
|
||||||
|
{
|
||||||
|
arr4[tidx++] = pInputBase64[in_idx++];
|
||||||
|
if(tidx == 4)
|
||||||
|
{
|
||||||
|
for(tidx = 0; tidx < 4; tidx++) arr4[tidx] = (uint8_t)base64_chars.find(arr4[tidx]);
|
||||||
|
|
||||||
|
arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
|
||||||
|
arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
|
||||||
|
arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
|
||||||
|
for(tidx = 0; tidx < 3; tidx++) pOutputData.push_back(arr3[tidx]);
|
||||||
|
|
||||||
|
tidx = 0;
|
||||||
|
}// if(tidx == 4)
|
||||||
|
}// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx]))
|
||||||
|
else
|
||||||
|
{
|
||||||
|
in_idx++;
|
||||||
|
}// if(ParseHelper_Decode_Base64_IsBase64(pInputBase64[in_idx])) else
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tidx)
|
||||||
|
{
|
||||||
|
for(uint8_t i = tidx; i < 4; i++) arr4[i] = 0;
|
||||||
|
for(uint8_t i = 0; i < 4; i++) arr4[i] = (uint8_t)(base64_chars.find(arr4[i]));
|
||||||
|
|
||||||
|
arr3[0] = (arr4[0] << 2) + ((arr4[1] & 0x30) >> 4);
|
||||||
|
arr3[1] = ((arr4[1] & 0x0F) << 4) + ((arr4[2] & 0x3C) >> 2);
|
||||||
|
arr3[2] = ((arr4[2] & 0x03) << 6) + arr4[3];
|
||||||
|
for(uint8_t i = 0; i < (tidx - 1); i++) pOutputData.push_back(arr3[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::ParseFile(const std::string& pFile, IOSystem* pIOHandler)
|
||||||
|
{
|
||||||
|
irr::io::IrrXMLReader* OldReader = mReader;// store current XMLreader.
|
||||||
|
std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
|
||||||
|
|
||||||
|
// Check whether we can read from the file
|
||||||
|
if(file.get() == NULL) throw DeadlyImportError("Failed to open AMF file " + pFile + ".");
|
||||||
|
|
||||||
|
// generate a XML reader for it
|
||||||
|
std::unique_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
|
||||||
|
mReader = irr::io::createIrrXMLReader(mIOWrapper.get());
|
||||||
|
if(!mReader) throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
|
||||||
|
//
|
||||||
|
// start reading
|
||||||
|
// search for root tag <amf>
|
||||||
|
if(XML_SearchNode("amf"))
|
||||||
|
ParseNode_Root();
|
||||||
|
else
|
||||||
|
throw DeadlyImportError("Root node \"amf\" not found.");
|
||||||
|
|
||||||
|
delete mReader;
|
||||||
|
// restore old XMLreader
|
||||||
|
mReader = OldReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
// <amf
|
||||||
|
// unit="" - The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
|
||||||
|
// version="" - Version of file format.
|
||||||
|
// >
|
||||||
|
// </amf>
|
||||||
|
// Root XML element.
|
||||||
|
// Multi elements - No.
|
||||||
|
void AMFImporter::ParseNode_Root()
|
||||||
|
{
|
||||||
|
std::string unit, version;
|
||||||
|
CAMFImporter_NodeElement *ne( nullptr );
|
||||||
|
|
||||||
|
// Read attributes for node <amf>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("unit", unit, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("version", version, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND_WSKIP;
|
||||||
|
|
||||||
|
// Check attributes
|
||||||
|
if(!mUnit.empty())
|
||||||
|
{
|
||||||
|
if((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) Throw_IncorrectAttrValue("unit");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create root node element.
|
||||||
|
ne = new CAMFImporter_NodeElement_Root(nullptr);
|
||||||
|
mNodeElement_Cur = ne;// set first "current" element
|
||||||
|
// and assign attribute's values
|
||||||
|
((CAMFImporter_NodeElement_Root*)ne)->Unit = unit;
|
||||||
|
((CAMFImporter_NodeElement_Root*)ne)->Version = version;
|
||||||
|
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("amf");
|
||||||
|
if(XML_CheckNode_NameEqual("object")) { ParseNode_Object(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("material")) { ParseNode_Material(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("texture")) { ParseNode_Texture(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("constellation")) { ParseNode_Constellation(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("amf");
|
||||||
|
mNodeElement_Cur = ne;// force restore "current" element
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <constellation
|
||||||
|
// id="" - The Object ID of the new constellation being defined.
|
||||||
|
// >
|
||||||
|
// </constellation>
|
||||||
|
// A collection of objects or constellations with specific relative locations.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <amf>.
|
||||||
|
void AMFImporter::ParseNode_Constellation()
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
CAMFImporter_NodeElement* ne( nullptr );
|
||||||
|
|
||||||
|
// Read attributes for node <constellation>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create and if needed - define new grouping object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Constellation(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Constellation& als = *((CAMFImporter_NodeElement_Constellation*)ne);// alias for convenience
|
||||||
|
|
||||||
|
if(!id.empty()) als.ID = id;
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("constellation");
|
||||||
|
if(XML_CheckNode_NameEqual("instance")) { ParseNode_Instance(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("constellation");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <instance
|
||||||
|
// objectid="" - The Object ID of the new constellation being defined.
|
||||||
|
// >
|
||||||
|
// </instance>
|
||||||
|
// A collection of objects or constellations with specific relative locations.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <amf>.
|
||||||
|
void AMFImporter::ParseNode_Instance()
|
||||||
|
{
|
||||||
|
std::string objectid;
|
||||||
|
CAMFImporter_NodeElement* ne( nullptr );
|
||||||
|
|
||||||
|
// Read attributes for node <constellation>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("objectid", objectid, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// used object id must be defined, check that.
|
||||||
|
if(objectid.empty()) throw DeadlyImportError("\"objectid\" in <instance> must be defined.");
|
||||||
|
// create and define new grouping object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Instance(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);// alias for convenience
|
||||||
|
|
||||||
|
als.ObjectID = objectid;
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool read_flag[6] = { false, false, false, false, false, false };
|
||||||
|
|
||||||
|
als.Delta.Set(0, 0, 0);
|
||||||
|
als.Rotation.Set(0, 0, 0);
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("instance");
|
||||||
|
MACRO_NODECHECK_READCOMP_F("deltax", read_flag[0], als.Delta.x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("deltay", read_flag[1], als.Delta.y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("deltaz", read_flag[2], als.Delta.z);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("rx", read_flag[3], als.Rotation.x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("ry", read_flag[4], als.Rotation.y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("rz", read_flag[5], als.Rotation.z);
|
||||||
|
MACRO_NODECHECK_LOOPEND("instance");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
// also convert degrees to radians.
|
||||||
|
als.Rotation.x = AI_MATH_PI_F * als.Rotation.x / 180.0f;
|
||||||
|
als.Rotation.y = AI_MATH_PI_F * als.Rotation.y / 180.0f;
|
||||||
|
als.Rotation.z = AI_MATH_PI_F * als.Rotation.z / 180.0f;
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <object
|
||||||
|
// id="" - A unique ObjectID for the new object being defined.
|
||||||
|
// >
|
||||||
|
// </object>
|
||||||
|
// An object definition.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <amf>.
|
||||||
|
void AMFImporter::ParseNode_Object()
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
CAMFImporter_NodeElement* ne( nullptr );
|
||||||
|
|
||||||
|
// Read attributes for node <object>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create and if needed - define new geometry object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Object(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Object& als = *((CAMFImporter_NodeElement_Object*)ne);// alias for convenience
|
||||||
|
|
||||||
|
if(!id.empty()) als.ID = id;
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool col_read = false;
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("object");
|
||||||
|
if(XML_CheckNode_NameEqual("color"))
|
||||||
|
{
|
||||||
|
// Check if color already defined for object.
|
||||||
|
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <object>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Color();
|
||||||
|
col_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("mesh")) { ParseNode_Mesh(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("object");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <metadata
|
||||||
|
// type="" - The type of the attribute.
|
||||||
|
// >
|
||||||
|
// </metadata>
|
||||||
|
// Specify additional information about an entity.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <amf>, <object>, <volume>, <material>, <vertex>.
|
||||||
|
//
|
||||||
|
// Reserved types are:
|
||||||
|
// "Name" - The alphanumeric label of the entity, to be used by the interpreter if interacting with the user.
|
||||||
|
// "Description" - A description of the content of the entity
|
||||||
|
// "URL" - A link to an external resource relating to the entity
|
||||||
|
// "Author" - Specifies the name(s) of the author(s) of the entity
|
||||||
|
// "Company" - Specifying the company generating the entity
|
||||||
|
// "CAD" - specifies the name of the originating CAD software and version
|
||||||
|
// "Revision" - specifies the revision of the entity
|
||||||
|
// "Tolerance" - specifies the desired manufacturing tolerance of the entity in entity's unit system
|
||||||
|
// "Volume" - specifies the total volume of the entity, in the entity's unit system, to be used for verification (object and volume only)
|
||||||
|
void AMFImporter::ParseNode_Metadata()
|
||||||
|
{
|
||||||
|
std::string type, value;
|
||||||
|
CAMFImporter_NodeElement* ne( nullptr );
|
||||||
|
|
||||||
|
// read attribute
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
// and value of node.
|
||||||
|
value = mReader->getNodeData();
|
||||||
|
// Create node element and assign read data.
|
||||||
|
ne = new CAMFImporter_NodeElement_Metadata(mNodeElement_Cur);
|
||||||
|
((CAMFImporter_NodeElement_Metadata*)ne)->Type = type;
|
||||||
|
((CAMFImporter_NodeElement_Metadata*)ne)->Value = value;
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
/******************************************************** Functions: BaseImporter set ********************************************************/
|
||||||
|
/*********************************************************************************************************************************************/
|
||||||
|
|
||||||
|
bool AMFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const
|
||||||
|
{
|
||||||
|
const std::string extension = GetExtension(pFile);
|
||||||
|
|
||||||
|
if ( extension == "amf" ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!extension.length() || pCheckSig)
|
||||||
|
{
|
||||||
|
const char* tokens[] = { "<amf" };
|
||||||
|
|
||||||
|
return SearchFileHeaderForToken( pIOHandler, pFile, tokens, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::GetExtensionList(std::set<std::string>& pExtensionList)
|
||||||
|
{
|
||||||
|
pExtensionList.insert("amf");
|
||||||
|
}
|
||||||
|
|
||||||
|
const aiImporterDesc* AMFImporter::GetInfo () const
|
||||||
|
{
|
||||||
|
return &Description;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
||||||
|
{
|
||||||
|
Clear();// delete old graph.
|
||||||
|
ParseFile(pFile, pIOHandler);
|
||||||
|
Postprocess_BuildScene(pScene);
|
||||||
|
// scene graph is ready, exit.
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
|
|
@ -0,0 +1,563 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter.hpp
|
||||||
|
/// \brief AMF-format files importer for Assimp.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
// Thanks to acorn89 for support.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef INCLUDED_AI_AMF_IMPORTER_H
|
||||||
|
#define INCLUDED_AI_AMF_IMPORTER_H
|
||||||
|
|
||||||
|
#include "AMFImporter_Node.hpp"
|
||||||
|
|
||||||
|
// Header files, Assimp.
|
||||||
|
#include "assimp/DefaultLogger.hpp"
|
||||||
|
#include "assimp/importerdesc.h"
|
||||||
|
#include "assimp/ProgressHandler.hpp"
|
||||||
|
#include "assimp/types.h"
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include "irrXMLWrapper.h"
|
||||||
|
|
||||||
|
// Header files, stdlib.
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
/// \class AMFImporter
|
||||||
|
/// Class that holding scene graph which include: geometry, metadata, materials etc.
|
||||||
|
///
|
||||||
|
/// Implementing features.
|
||||||
|
///
|
||||||
|
/// Limitations.
|
||||||
|
///
|
||||||
|
/// 1. When for texture mapping used set of source textures (r, g, b, a) not only one then attribute "tiled" for all set will be true if it true in any of
|
||||||
|
/// source textures.
|
||||||
|
/// Example. Triangle use for texture mapping three textures. Two of them has "tiled" set to false and one - set to true. In scene all three textures
|
||||||
|
/// will be tiled.
|
||||||
|
///
|
||||||
|
/// Unsupported features:
|
||||||
|
/// 1. Node <composite>, formulas in <composite> and <color>. For implementing this feature can be used expression parser "muParser" like in project
|
||||||
|
/// "amf_tools".
|
||||||
|
/// 2. Attribute "profile" in node <color>.
|
||||||
|
/// 3. Curved geometry: <edge>, <normal> and children nodes of them.
|
||||||
|
/// 4. Attributes: "unit" and "version" in <amf> read but do nothing.
|
||||||
|
/// 5. <metadata> stored only for root node <amf>.
|
||||||
|
/// 6. Color averaging of vertices for which <triangle>'s set different colors.
|
||||||
|
///
|
||||||
|
/// Supported nodes:
|
||||||
|
/// General:
|
||||||
|
/// <amf>; <constellation>; <instance> and children <deltax>, <deltay>, <deltaz>, <rx>, <ry>, <rz>; <metadata>;
|
||||||
|
///
|
||||||
|
/// Geometry:
|
||||||
|
/// <object>; <mesh>; <vertices>; <vertex>; <coordinates> and children <x>, <y>, <z>; <volume>; <triangle> and children <v1>, <v2>, <v3>;
|
||||||
|
///
|
||||||
|
/// Material:
|
||||||
|
/// <color> and children <r>, <g>, <b>, <a>; <texture>; <material>;
|
||||||
|
/// two variants of texture coordinates:
|
||||||
|
/// new - <texmap> and children <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>
|
||||||
|
/// old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
|
||||||
|
///
|
||||||
|
class AMFImporter : public BaseImporter
|
||||||
|
{
|
||||||
|
/***********************************************/
|
||||||
|
/******************** Types ********************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
struct SPP_Material;// forward declaration
|
||||||
|
|
||||||
|
/// \struct SPP_Composite
|
||||||
|
/// Data type for postprocessing step. More suitable container for part of material's composition.
|
||||||
|
struct SPP_Composite
|
||||||
|
{
|
||||||
|
SPP_Material* Material;///< Pointer to material - part of composition.
|
||||||
|
std::string Formula;///< Formula for calculating ratio of \ref Material.
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \struct SPP_Material
|
||||||
|
/// Data type for postprocessing step. More suitable container for material.
|
||||||
|
struct SPP_Material
|
||||||
|
{
|
||||||
|
std::string ID;///< Material ID.
|
||||||
|
std::list<CAMFImporter_NodeElement_Metadata*> Metadata;///< Metadata of material.
|
||||||
|
CAMFImporter_NodeElement_Color* Color;///< Color of material.
|
||||||
|
std::list<SPP_Composite> Composition;///< List of child materials if current material is composition of few another.
|
||||||
|
|
||||||
|
/// \fn aiColor4D GetColor(const float pX, const float pY, const float pZ) const
|
||||||
|
/// Return color calculated for specified coordinate.
|
||||||
|
/// \param [in] pX - "x" coordinate.
|
||||||
|
/// \param [in] pY - "y" coordinate.
|
||||||
|
/// \param [in] pZ - "z" coordinate.
|
||||||
|
/// \return calculated color.
|
||||||
|
aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \struct SPP_Texture
|
||||||
|
/// Data type for post-processing step. More suitable container for texture.
|
||||||
|
struct SPP_Texture
|
||||||
|
{
|
||||||
|
std::string ID;
|
||||||
|
size_t Width, Height, Depth;
|
||||||
|
bool Tiled;
|
||||||
|
char FormatHint[ 9 ];// 8 for string + 1 for terminator.
|
||||||
|
uint8_t *Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \struct SComplexFace
|
||||||
|
/// Data type for post-processing step. Contain face data.
|
||||||
|
struct SComplexFace
|
||||||
|
{
|
||||||
|
aiFace Face;///< Face vertices.
|
||||||
|
const CAMFImporter_NodeElement_Color* Color;///< Face color. Equal to nullptr if color is not set for the face.
|
||||||
|
const CAMFImporter_NodeElement_TexMap* TexMap;///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Constants ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static const aiImporterDesc Description;
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Variables ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement* mNodeElement_Cur;///< Current element.
|
||||||
|
std::list<CAMFImporter_NodeElement*> mNodeElement_List;///< All elements of scene graph.
|
||||||
|
irr::io::IrrXMLReader* mReader;///< Pointer to XML-reader object
|
||||||
|
std::string mUnit;
|
||||||
|
std::list<SPP_Material> mMaterial_Converted;///< List of converted materials for postprocessing step.
|
||||||
|
std::list<SPP_Texture> mTexture_Converted;///< List of converted textures for postprocessing step.
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Functions ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// \fn AMFImporter(const AMFImporter& pScene)
|
||||||
|
/// Disabled copy constructor.
|
||||||
|
AMFImporter(const AMFImporter& pScene);
|
||||||
|
|
||||||
|
/// \fn AMFImporter& operator=(const AMFImporter& pScene)
|
||||||
|
/// Disabled assign operator.
|
||||||
|
AMFImporter& operator=(const AMFImporter& pScene);
|
||||||
|
|
||||||
|
/// \fn void Clear()
|
||||||
|
/// Clear all temporary data.
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/************* Functions: find set *************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, aiNode** pNode) const
|
||||||
|
/// Find specified node element in node elements list ( \ref mNodeElement_List).
|
||||||
|
/// \param [in] pID - ID(name) of requested node element.
|
||||||
|
/// \param [in] pType - type of node element.
|
||||||
|
/// \param [out] pNode - pointer to pointer to item found.
|
||||||
|
/// \return true - if the node element is found, else - false.
|
||||||
|
bool Find_NodeElement(const std::string& pID, const CAMFImporter_NodeElement::EType pType, CAMFImporter_NodeElement** pNodeElement) const;
|
||||||
|
|
||||||
|
/// \fn bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const
|
||||||
|
/// Find requested aiNode in node list.
|
||||||
|
/// \param [in] pID - ID(name) of requested node.
|
||||||
|
/// \param [in] pNodeList - list of nodes where to find the node.
|
||||||
|
/// \param [out] pNode - pointer to pointer to item found.
|
||||||
|
/// \return true - if the node is found, else - false.
|
||||||
|
bool Find_ConvertedNode(const std::string& pID, std::list<aiNode*>& pNodeList, aiNode** pNode) const;
|
||||||
|
|
||||||
|
/// \fn bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const
|
||||||
|
/// Find material in list for converted materials. Use at postprocessing step.
|
||||||
|
/// \param [in] pID - material ID.
|
||||||
|
/// \param [out] pConvertedMaterial - pointer to found converted material (\ref SPP_Material).
|
||||||
|
/// \return true - if the material is found, else - false.
|
||||||
|
bool Find_ConvertedMaterial(const std::string& pID, const SPP_Material** pConvertedMaterial) const;
|
||||||
|
|
||||||
|
/// \fn bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A, uint32_t* pConvertedTextureIndex = nullptr) const
|
||||||
|
/// Find texture in list of converted textures. Use at postprocessing step,
|
||||||
|
/// \param [in] pID_R - ID of source "red" texture.
|
||||||
|
/// \param [in] pID_G - ID of source "green" texture.
|
||||||
|
/// \param [in] pID_B - ID of source "blue" texture.
|
||||||
|
/// \param [in] pID_A - ID of source "alpha" texture. Use empty string to find RGB-texture.
|
||||||
|
/// \param [out] pConvertedTextureIndex - pointer where index in list of found texture will be written. If equivalent to nullptr then nothing will be
|
||||||
|
/// written.
|
||||||
|
/// \return true - if the texture is found, else - false.
|
||||||
|
bool Find_ConvertedTexture(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A,
|
||||||
|
uint32_t* pConvertedTextureIndex = nullptr) const;
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/********* Functions: postprocess set **********/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray, std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
|
||||||
|
/// Get data stored in <vertices> and place it to arrays.
|
||||||
|
/// \param [in] pNodeElement - reference to node element which kept <object> data.
|
||||||
|
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates kept in <vertices>.
|
||||||
|
/// \param [in] pVertexColorArray - reference to vertices colors for all <vertex's. If color for vertex is not set then corresponding member of array
|
||||||
|
/// contain nullptr.
|
||||||
|
void PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
|
||||||
|
std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const;
|
||||||
|
|
||||||
|
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
|
||||||
|
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
|
||||||
|
/// converted texture will be returned. Convertion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
|
||||||
|
/// to converted textures list.
|
||||||
|
/// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
|
||||||
|
/// \param [in] pID_R - ID of source "red" texture.
|
||||||
|
/// \param [in] pID_G - ID of source "green" texture.
|
||||||
|
/// \param [in] pID_B - ID of source "blue" texture.
|
||||||
|
/// \param [in] pID_A - ID of source "alpha" texture.
|
||||||
|
/// \return index of the texture in array of the converted textures.
|
||||||
|
size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A);
|
||||||
|
|
||||||
|
/// \fn void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> > pOutputList_Separated)
|
||||||
|
/// Separate input list by texture IDs. This step is needed because aiMesh can contain mesh which is use only one texture (or set: diffuse, bump etc).
|
||||||
|
/// \param [in] pInputList - input list with faces. Some of them can contain color or texture mapping, or both of them, or nothing. Will be cleared after
|
||||||
|
/// processing.
|
||||||
|
/// \param [out] pOutputList_Separated - output list of the faces lists. Separated faces list by used texture IDs. Will be cleared before processing.
|
||||||
|
void PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated);
|
||||||
|
|
||||||
|
/// \fn void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const
|
||||||
|
/// Check if child elements of node element is metadata and add it to scene node.
|
||||||
|
/// \param [in] pMetadataList - reference to list with collected metadata.
|
||||||
|
/// \param [out] pSceneNode - scene node in which metadata will be added.
|
||||||
|
void Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& pMetadataList, aiNode& pSceneNode) const;
|
||||||
|
|
||||||
|
/// \fn void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
|
||||||
|
/// To create aiMesh and aiNode for it from <object>.
|
||||||
|
/// \param [in] pNodeElement - reference to node element which kept <object> data.
|
||||||
|
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
|
||||||
|
/// \param [out] pSceneNode - pointer to place where new aiNode will be created.
|
||||||
|
void Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode);
|
||||||
|
|
||||||
|
/// \fn void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray, const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
|
||||||
|
/// Create mesh for every <volume> in <mesh>.
|
||||||
|
/// \param [in] pNodeElement - reference to node element which kept <mesh> data.
|
||||||
|
/// \param [in] pVertexCoordinateArray - reference to vertices coordinates for all <volume>'s.
|
||||||
|
/// \param [in] pVertexColorArray - reference to vertices colors for all <volume>'s. If color for vertex is not set then corresponding member of array
|
||||||
|
/// contain nullptr.
|
||||||
|
/// \param [in] pObjectColor - pointer to colors for <object>. If color is not set then argument contain nullptr.
|
||||||
|
/// \param [in] pMaterialList - reference to a list with defined materials.
|
||||||
|
/// \param [out] pMeshList - reference to a list with all aiMesh of the scene.
|
||||||
|
/// \param [out] pSceneNode - reference to aiNode which will own new aiMesh's.
|
||||||
|
void Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
|
||||||
|
const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray, const CAMFImporter_NodeElement_Color* pObjectColor,
|
||||||
|
std::list<aiMesh*>& pMeshList, aiNode& pSceneNode);
|
||||||
|
|
||||||
|
/// \fn void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
|
||||||
|
/// Convert material from \ref CAMFImporter_NodeElement_Material to \ref SPP_Material.
|
||||||
|
/// \param [in] pMaterial - source CAMFImporter_NodeElement_Material.
|
||||||
|
void Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial);
|
||||||
|
|
||||||
|
/// \fn void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
|
||||||
|
/// Create and add to aiNode's list new part of scene graph defined by <constellation>.
|
||||||
|
/// \param [in] pConstellation - reference to <constellation> node.
|
||||||
|
/// \param [out] pNodeList - reference to aiNode's list.
|
||||||
|
void Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const;
|
||||||
|
|
||||||
|
/// \fn void Postprocess_BuildScene()
|
||||||
|
/// Build Assimp scene graph in aiScene from collected data.
|
||||||
|
/// \param [out] pScene - pointer to aiScene where tree will be built.
|
||||||
|
void Postprocess_BuildScene(aiScene* pScene);
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/************* Functions: throw set ************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void Throw_CloseNotFound(const std::string& pNode)
|
||||||
|
/// Call that function when close tag of node not found and exception must be raised.
|
||||||
|
/// E.g.:
|
||||||
|
/// <amf>
|
||||||
|
/// <object>
|
||||||
|
/// </amf> <!--- object not closed --->
|
||||||
|
/// \throw DeadlyImportError.
|
||||||
|
/// \param [in] pNode - node name in which exception happened.
|
||||||
|
void Throw_CloseNotFound(const std::string& pNode);
|
||||||
|
|
||||||
|
/// \fn void Throw_IncorrectAttr(const std::string& pAttrName)
|
||||||
|
/// Call that function when attribute name is incorrect and exception must be raised.
|
||||||
|
/// \param [in] pAttrName - attribute name.
|
||||||
|
/// \throw DeadlyImportError.
|
||||||
|
void Throw_IncorrectAttr(const std::string& pAttrName);
|
||||||
|
|
||||||
|
/// \fn void Throw_IncorrectAttrValue(const std::string& pAttrName)
|
||||||
|
/// Call that function when attribute value is incorrect and exception must be raised.
|
||||||
|
/// \param [in] pAttrName - attribute name.
|
||||||
|
/// \throw DeadlyImportError.
|
||||||
|
void Throw_IncorrectAttrValue(const std::string& pAttrName);
|
||||||
|
|
||||||
|
/// \fn void Throw_MoreThanOnceDefined(const std::string& pNode, const std::string& pDescription)
|
||||||
|
/// Call that function when some type of nodes are defined twice or more when must be used only once and exception must be raised.
|
||||||
|
/// E.g.:
|
||||||
|
/// <object>
|
||||||
|
/// <color>... <!--- color defined --->
|
||||||
|
/// <color>... <!--- color defined again --->
|
||||||
|
/// </object>
|
||||||
|
/// \throw DeadlyImportError.
|
||||||
|
/// \param [in] pNodeType - type of node which defined one more time.
|
||||||
|
/// \param [in] pDescription - message about error. E.g. what the node defined while exception raised.
|
||||||
|
void Throw_MoreThanOnceDefined(const std::string& pNodeType, const std::string& pDescription);
|
||||||
|
|
||||||
|
/// \fn void Throw_ID_NotFound(const std::string& pID) const
|
||||||
|
/// Call that function when referenced element ID are not found in graph and exception must be raised.
|
||||||
|
/// \param [in] pID - ID of of element which not found.
|
||||||
|
/// \throw DeadlyImportError.
|
||||||
|
void Throw_ID_NotFound(const std::string& pID) const;
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/************** Functions: LOG set *************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void LogInfo(const std::string& pMessage)
|
||||||
|
/// Short variant for calling \ref DefaultLogger::get()->info()
|
||||||
|
void LogInfo(const std::string& pMessage) { DefaultLogger::get()->info(pMessage); }
|
||||||
|
|
||||||
|
/// \fn void LogWarning(const std::string& pMessage)
|
||||||
|
/// Short variant for calling \ref DefaultLogger::get()->warn()
|
||||||
|
void LogWarning(const std::string& pMessage) { DefaultLogger::get()->warn(pMessage); }
|
||||||
|
|
||||||
|
/// \fn void LogError(const std::string& pMessage)
|
||||||
|
/// Short variant for calling \ref DefaultLogger::get()->error()
|
||||||
|
void LogError(const std::string& pMessage) { DefaultLogger::get()->error(pMessage); }
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/************** Functions: XML set *************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void XML_CheckNode_MustHaveChildren()
|
||||||
|
/// Check if current node have children: <node>...</node>. If not then exception will throwed.
|
||||||
|
void XML_CheckNode_MustHaveChildren();
|
||||||
|
|
||||||
|
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
|
||||||
|
/// Chek if current node name is equal to pNodeName.
|
||||||
|
/// \param [in] pNodeName - name for checking.
|
||||||
|
/// return true if current node name is equal to pNodeName, else - false.
|
||||||
|
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }
|
||||||
|
|
||||||
|
/// \fn void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName)
|
||||||
|
/// Skip unsupported node and report about that. Depend on node name can be skipped begin tag of node all whole node.
|
||||||
|
/// \param [in] pParentNodeName - parent node name. Used for reporting.
|
||||||
|
void XML_CheckNode_SkipUnsupported(const std::string& pParentNodeName);
|
||||||
|
|
||||||
|
/// \fn bool XML_SearchNode(const std::string& pNodeName)
|
||||||
|
/// Search for specified node in file. XML file read pointer(mReader) will point to found node or file end after search is end.
|
||||||
|
/// \param [in] pNodeName - requested node name.
|
||||||
|
/// return true - if node is found, else - false.
|
||||||
|
bool XML_SearchNode(const std::string& pNodeName);
|
||||||
|
|
||||||
|
/// \fn bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx)
|
||||||
|
/// Read attribute value.
|
||||||
|
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
||||||
|
/// \return read data.
|
||||||
|
bool XML_ReadNode_GetAttrVal_AsBool(const int pAttrIdx);
|
||||||
|
|
||||||
|
/// \fn float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx)
|
||||||
|
/// Read attribute value.
|
||||||
|
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
||||||
|
/// \return read data.
|
||||||
|
float XML_ReadNode_GetAttrVal_AsFloat(const int pAttrIdx);
|
||||||
|
|
||||||
|
/// \fn uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx)
|
||||||
|
/// Read attribute value.
|
||||||
|
/// \param [in] pAttrIdx - attribute index (\ref mReader->getAttribute* set).
|
||||||
|
/// \return read data.
|
||||||
|
uint32_t XML_ReadNode_GetAttrVal_AsU32(const int pAttrIdx);
|
||||||
|
|
||||||
|
/// \fn float XML_ReadNode_GetVal_AsFloat()
|
||||||
|
/// Read node value.
|
||||||
|
/// \return read data.
|
||||||
|
float XML_ReadNode_GetVal_AsFloat();
|
||||||
|
|
||||||
|
/// \fn uint32_t XML_ReadNode_GetVal_AsU32()
|
||||||
|
/// Read node value.
|
||||||
|
/// \return read data.
|
||||||
|
uint32_t XML_ReadNode_GetVal_AsU32();
|
||||||
|
|
||||||
|
/// \fn void XML_ReadNode_GetVal_AsString(std::string& pValue)
|
||||||
|
/// Read node value.
|
||||||
|
/// \return read data.
|
||||||
|
void XML_ReadNode_GetVal_AsString(std::string& pValue);
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/******** Functions: parse set private *********/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode)
|
||||||
|
/// Make pNode as current and enter deeper for parsing child nodes. At end \ref ParseHelper_Node_Exit must be called.
|
||||||
|
/// \param [in] pNode - new current node.
|
||||||
|
void ParseHelper_Node_Enter(CAMFImporter_NodeElement* pNode);
|
||||||
|
|
||||||
|
/// \fn void ParseHelper_Group_End()
|
||||||
|
/// This function must be called when exiting from grouping node. \ref ParseHelper_Group_Begin.
|
||||||
|
void ParseHelper_Node_Exit();
|
||||||
|
|
||||||
|
/// \fn void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString)
|
||||||
|
/// Attribute values of floating point types can take form ".x"(without leading zero). irrXMLReader can not read this form of values and it
|
||||||
|
/// must be converted to right form - "0.xxx".
|
||||||
|
/// \param [in] pInStr - pointer to input string which can contain incorrect form of values.
|
||||||
|
/// \param [out[ pOutString - output string with right form of values.
|
||||||
|
void ParseHelper_FixTruncatedFloatString(const char* pInStr, std::string& pOutString);
|
||||||
|
|
||||||
|
/// \fn void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const
|
||||||
|
/// Decode Base64-encoded data.
|
||||||
|
/// \param [in] pInputBase64 - reference to input Base64-encoded string.
|
||||||
|
/// \param [out] pOutputData - reference to output array for decoded data.
|
||||||
|
void ParseHelper_Decode_Base64(const std::string& pInputBase64, std::vector<uint8_t>& pOutputData) const;
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Root()
|
||||||
|
/// Parse <AMF> node of the file.
|
||||||
|
void ParseNode_Root();
|
||||||
|
|
||||||
|
/******** Functions: top nodes *********/
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Constellation()
|
||||||
|
/// Parse <constellation> node of the file.
|
||||||
|
void ParseNode_Constellation();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Constellation()
|
||||||
|
/// Parse <instance> node of the file.
|
||||||
|
void ParseNode_Instance();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Material()
|
||||||
|
/// Parse <material> node of the file.
|
||||||
|
void ParseNode_Material();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Metadata()
|
||||||
|
/// Parse <metadata> node.
|
||||||
|
void ParseNode_Metadata();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Object()
|
||||||
|
/// Parse <object> node of the file.
|
||||||
|
void ParseNode_Object();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Texture()
|
||||||
|
/// Parse <texture> node of the file.
|
||||||
|
void ParseNode_Texture();
|
||||||
|
|
||||||
|
/******** Functions: geometry nodes *********/
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Coordinates()
|
||||||
|
/// Parse <coordinates> node of the file.
|
||||||
|
void ParseNode_Coordinates();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Edge()
|
||||||
|
/// Parse <edge> node of the file.
|
||||||
|
void ParseNode_Edge();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Mesh()
|
||||||
|
/// Parse <mesh> node of the file.
|
||||||
|
void ParseNode_Mesh();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Triangle()
|
||||||
|
/// Parse <triangle> node of the file.
|
||||||
|
void ParseNode_Triangle();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Vertex()
|
||||||
|
/// Parse <vertex> node of the file.
|
||||||
|
void ParseNode_Vertex();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Vertices()
|
||||||
|
/// Parse <vertices> node of the file.
|
||||||
|
void ParseNode_Vertices();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Volume()
|
||||||
|
/// Parse <volume> node of the file.
|
||||||
|
void ParseNode_Volume();
|
||||||
|
|
||||||
|
/******** Functions: material nodes *********/
|
||||||
|
|
||||||
|
/// \fn void ParseNode_Color()
|
||||||
|
/// Parse <color> node of the file.
|
||||||
|
void ParseNode_Color();
|
||||||
|
|
||||||
|
/// \fn void ParseNode_TexMap(const bool pUseOldName = false)
|
||||||
|
/// Parse <texmap> of <map> node of the file.
|
||||||
|
/// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
|
||||||
|
void ParseNode_TexMap(const bool pUseOldName = false);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \fn AMFImporter()
|
||||||
|
/// Default constructor.
|
||||||
|
AMFImporter()
|
||||||
|
: mNodeElement_Cur(nullptr), mReader(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// \fn ~AMFImporter()
|
||||||
|
/// Default destructor.
|
||||||
|
~AMFImporter();
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/******** Functions: parse set, public *********/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
/// \fn void ParseFile(const std::string& pFile, IOSystem* pIOHandler)
|
||||||
|
/// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
|
||||||
|
/// Also exception can be throwed if trouble will found.
|
||||||
|
/// \param [in] pFile - name of file to be parsed.
|
||||||
|
/// \param [in] pIOHandler - pointer to IO helper object.
|
||||||
|
void ParseFile(const std::string& pFile, IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/********* Functions: BaseImporter set *********/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
bool CanRead(const std::string& pFile, IOSystem* pIOHandler, bool pCheckSig) const;
|
||||||
|
void GetExtensionList(std::set<std::string>& pExtensionList);
|
||||||
|
void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
const aiImporterDesc* GetInfo ()const;
|
||||||
|
|
||||||
|
};// class AMFImporter
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_AMF_IMPORTER_H
|
|
@ -0,0 +1,355 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter_Geometry.cpp
|
||||||
|
/// \brief Parsing data from geometry nodes.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
|
|
||||||
|
#include "AMFImporter.hpp"
|
||||||
|
#include "AMFImporter_Macro.hpp"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
// <mesh>
|
||||||
|
// </mesh>
|
||||||
|
// A 3D mesh hull.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <object>.
|
||||||
|
void AMFImporter::ParseNode_Mesh()
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// create new mesh object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Mesh(mNodeElement_Cur);
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool vert_read = false;
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("mesh");
|
||||||
|
if(XML_CheckNode_NameEqual("vertices"))
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(vert_read) Throw_MoreThanOnceDefined("vertices", "Only one vertices set can be defined for <mesh>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Vertices();
|
||||||
|
vert_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("volume")) { ParseNode_Volume(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("mesh");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <vertices>
|
||||||
|
// </vertices>
|
||||||
|
// The list of vertices to be used in defining triangles.
|
||||||
|
// Multi elements - No.
|
||||||
|
// Parent element - <mesh>.
|
||||||
|
void AMFImporter::ParseNode_Vertices()
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// create new mesh object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Vertices(mNodeElement_Cur);
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("vertices");
|
||||||
|
if(XML_CheckNode_NameEqual("vertex")) { ParseNode_Vertex(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("vertices");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <vertex>
|
||||||
|
// </vertex>
|
||||||
|
// A vertex to be referenced in triangles.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <vertices>.
|
||||||
|
void AMFImporter::ParseNode_Vertex()
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// create new mesh object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Vertex(mNodeElement_Cur);
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool col_read = false;
|
||||||
|
bool coord_read = false;
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("vertex");
|
||||||
|
if(XML_CheckNode_NameEqual("color"))
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <vertex>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Color();
|
||||||
|
col_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("coordinates"))
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(coord_read) Throw_MoreThanOnceDefined("coordinates", "Only one coordinates set can be defined for <vertex>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Coordinates();
|
||||||
|
coord_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("vertex");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <coordinates>
|
||||||
|
// </coordinates>
|
||||||
|
// Specifies the 3D location of this vertex.
|
||||||
|
// Multi elements - No.
|
||||||
|
// Parent element - <vertex>.
|
||||||
|
//
|
||||||
|
// Children elements:
|
||||||
|
// <x>, <y>, <z>
|
||||||
|
// Multi elements - No.
|
||||||
|
// X, Y, or Z coordinate, respectively, of a vertex position in space.
|
||||||
|
void AMFImporter::ParseNode_Coordinates()
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// create new color object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Coordinates(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Coordinates& als = *((CAMFImporter_NodeElement_Coordinates*)ne);// alias for convenience
|
||||||
|
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool read_flag[3] = { false, false, false };
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("coordinates");
|
||||||
|
MACRO_NODECHECK_READCOMP_F("x", read_flag[0], als.Coordinate.x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("y", read_flag[1], als.Coordinate.y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("z", read_flag[2], als.Coordinate.z);
|
||||||
|
MACRO_NODECHECK_LOOPEND("coordinates");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
// check that all components was defined
|
||||||
|
if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all coordinate's components are defined.");
|
||||||
|
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <volume
|
||||||
|
// materialid="" - Which material to use.
|
||||||
|
// type="" - What this volume describes can be “region” or “support”. If none specified, “object” is assumed. If support, then the geometric
|
||||||
|
// requirements 1-8 listed in section 5 do not need to be maintained.
|
||||||
|
// >
|
||||||
|
// </volume>
|
||||||
|
// Defines a volume from the established vertex list.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <mesh>.
|
||||||
|
void AMFImporter::ParseNode_Volume()
|
||||||
|
{
|
||||||
|
std::string materialid;
|
||||||
|
std::string type;
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// Read attributes for node <color>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("materialid", materialid, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create new object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Volume(mNodeElement_Cur);
|
||||||
|
// and assign read data
|
||||||
|
((CAMFImporter_NodeElement_Volume*)ne)->MaterialID = materialid;
|
||||||
|
((CAMFImporter_NodeElement_Volume*)ne)->Type = type;
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool col_read = false;
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("volume");
|
||||||
|
if(XML_CheckNode_NameEqual("color"))
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <volume>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Color();
|
||||||
|
col_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("triangle")) { ParseNode_Triangle(); continue; }
|
||||||
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("volume");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <triangle>
|
||||||
|
// </triangle>
|
||||||
|
// Defines a 3D triangle from three vertices, according to the right-hand rule (counter-clockwise when looking from the outside).
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <volume>.
|
||||||
|
//
|
||||||
|
// Children elements:
|
||||||
|
// <v1>, <v2>, <v3>
|
||||||
|
// Multi elements - No.
|
||||||
|
// Index of the desired vertices in a triangle or edge.
|
||||||
|
void AMFImporter::ParseNode_Triangle()
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// create new color object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Triangle(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Triangle& als = *((CAMFImporter_NodeElement_Triangle*)ne);// alias for convenience
|
||||||
|
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool col_read = false, tex_read = false;
|
||||||
|
bool read_flag[3] = { false, false, false };
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("triangle");
|
||||||
|
if(XML_CheckNode_NameEqual("color"))
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <triangle>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Color();
|
||||||
|
col_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("texmap"))// new name of node: "texmap".
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(tex_read) Throw_MoreThanOnceDefined("texmap", "Only one texture coordinate can be defined for <triangle>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_TexMap();
|
||||||
|
tex_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if(XML_CheckNode_NameEqual("map"))// old name of node: "map".
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(tex_read) Throw_MoreThanOnceDefined("map", "Only one texture coordinate can be defined for <triangle>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_TexMap(true);
|
||||||
|
tex_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
MACRO_NODECHECK_READCOMP_U32("v1", read_flag[0], als.V[0]);
|
||||||
|
MACRO_NODECHECK_READCOMP_U32("v2", read_flag[1], als.V[1]);
|
||||||
|
MACRO_NODECHECK_READCOMP_U32("v3", read_flag[2], als.V[2]);
|
||||||
|
MACRO_NODECHECK_LOOPEND("triangle");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
// check that all components was defined
|
||||||
|
if((read_flag[0] && read_flag[1] && read_flag[2]) == 0) throw DeadlyImportError("Not all vertices of the triangle are defined.");
|
||||||
|
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
|
|
@ -0,0 +1,164 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter_Macro.hpp
|
||||||
|
/// \brief Useful macrodefines.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED
|
||||||
|
#define AMFIMPORTER_MACRO_HPP_INCLUDED
|
||||||
|
|
||||||
|
/// \def MACRO_ATTRREAD_LOOPBEG
|
||||||
|
/// Begin of loop that read attributes values.
|
||||||
|
#define MACRO_ATTRREAD_LOOPBEG \
|
||||||
|
for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
|
||||||
|
{ \
|
||||||
|
std::string an(mReader->getAttributeName(idx));
|
||||||
|
|
||||||
|
/// \def MACRO_ATTRREAD_LOOPEND
|
||||||
|
/// End of loop that read attributes values.
|
||||||
|
#define MACRO_ATTRREAD_LOOPEND \
|
||||||
|
Throw_IncorrectAttr(an); \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \def MACRO_ATTRREAD_LOOPEND_WSKIP
|
||||||
|
/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but
|
||||||
|
/// \ref MACRO_ATTRREAD_LOOPEND throw an exception.
|
||||||
|
#define MACRO_ATTRREAD_LOOPEND_WSKIP \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \def MACRO_ATTRREAD_CHECK_REF
|
||||||
|
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
|
||||||
|
/// "continue" will called.
|
||||||
|
/// \param [in] pAttrName - attribute name.
|
||||||
|
/// \param [out] pVarName - output variable name.
|
||||||
|
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
|
||||||
|
#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
|
||||||
|
if(an == pAttrName) \
|
||||||
|
{ \
|
||||||
|
pFunction(idx, pVarName); \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \def MACRO_ATTRREAD_CHECK_RET
|
||||||
|
/// Check curent attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
|
||||||
|
/// If result was read then "continue" will called.
|
||||||
|
/// \param [in] pAttrName - attribute name.
|
||||||
|
/// \param [out] pVarName - output variable name.
|
||||||
|
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
|
||||||
|
#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
|
||||||
|
if(an == pAttrName) \
|
||||||
|
{ \
|
||||||
|
pVarName = pFunction(idx); \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
|
||||||
|
/// Begin of loop of parsing child nodes. Do not add ';' at end.
|
||||||
|
/// \param [in] pNodeName - current node name.
|
||||||
|
#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
|
||||||
|
do { \
|
||||||
|
bool close_found = false; \
|
||||||
|
\
|
||||||
|
while(mReader->read()) \
|
||||||
|
{ \
|
||||||
|
if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
|
||||||
|
{
|
||||||
|
|
||||||
|
/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
|
||||||
|
/// End of loop of parsing child nodes.
|
||||||
|
/// \param [in] pNodeName - current node name.
|
||||||
|
#define MACRO_NODECHECK_LOOPEND(pNodeName) \
|
||||||
|
XML_CheckNode_SkipUnsupported(pNodeName); \
|
||||||
|
}/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
|
||||||
|
else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
|
||||||
|
{ \
|
||||||
|
if(XML_CheckNode_NameEqual(pNodeName)) \
|
||||||
|
{ \
|
||||||
|
close_found = true; \
|
||||||
|
\
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
}/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
|
||||||
|
}/* while(mReader->read()) */ \
|
||||||
|
\
|
||||||
|
if(!close_found) Throw_CloseNotFound(pNodeName); \
|
||||||
|
\
|
||||||
|
} while(false)
|
||||||
|
|
||||||
|
/// \def MACRO_NODECHECK_READCOMP_F
|
||||||
|
/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "float".
|
||||||
|
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
||||||
|
/// \param [in] pNodeName - node name.
|
||||||
|
/// \param [in, out] pReadFlag - read flag.
|
||||||
|
/// \param [out] pVarName - output variable name.
|
||||||
|
#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \
|
||||||
|
if(XML_CheckNode_NameEqual(pNodeName)) \
|
||||||
|
{ \
|
||||||
|
/* Check if field already read before. */ \
|
||||||
|
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
|
||||||
|
/* Read color component and assign it to object. */ \
|
||||||
|
pVarName = XML_ReadNode_GetVal_AsFloat(); \
|
||||||
|
pReadFlag = true; \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
/// \def MACRO_NODECHECK_READCOMP_U32
|
||||||
|
/// Check curent node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
|
||||||
|
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
|
||||||
|
/// \param [in] pNodeName - node name.
|
||||||
|
/// \param [in, out] pReadFlag - read flag.
|
||||||
|
/// \param [out] pVarName - output variable name.
|
||||||
|
#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \
|
||||||
|
if(XML_CheckNode_NameEqual(pNodeName)) \
|
||||||
|
{ \
|
||||||
|
/* Check if field already read before. */ \
|
||||||
|
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
|
||||||
|
/* Read color component and assign it to object. */ \
|
||||||
|
pVarName = XML_ReadNode_GetVal_AsU32(); \
|
||||||
|
pReadFlag = true; \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // AMFIMPORTER_MACRO_HPP_INCLUDED
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter_Material.cpp
|
||||||
|
/// \brief Parsing data from material nodes.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
|
|
||||||
|
#include "AMFImporter.hpp"
|
||||||
|
#include "AMFImporter_Macro.hpp"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
// <color
|
||||||
|
// profile="" - The ICC color space used to interpret the three color channels <r>, <g> and <b>.
|
||||||
|
// >
|
||||||
|
// </color>
|
||||||
|
// A color definition.
|
||||||
|
// Multi elements - No.
|
||||||
|
// Parent element - <material>, <object>, <volume>, <vertex>, <triangle>.
|
||||||
|
//
|
||||||
|
// "profile" can be one of "sRGB", "AdobeRGB", "Wide-Gamut-RGB", "CIERGB", "CIELAB", or "CIEXYZ".
|
||||||
|
// Children elements:
|
||||||
|
// <r>, <g>, <b>, <a>
|
||||||
|
// Multi elements - No.
|
||||||
|
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
|
||||||
|
// values can be specified as constants, or as a formula depending on the coordinates.
|
||||||
|
void AMFImporter::ParseNode_Color()
|
||||||
|
{
|
||||||
|
std::string profile;
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// Read attributes for node <color>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("profile", profile, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create new color object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Color(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Color& als = *((CAMFImporter_NodeElement_Color*)ne);// alias for convenience
|
||||||
|
|
||||||
|
als.Profile = profile;
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool read_flag[4] = { false, false, false, false };
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("color");
|
||||||
|
MACRO_NODECHECK_READCOMP_F("r", read_flag[0], als.Color.r);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("g", read_flag[1], als.Color.g);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("b", read_flag[2], als.Color.b);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("a", read_flag[3], als.Color.a);
|
||||||
|
MACRO_NODECHECK_LOOPEND("color");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
// check that all components was defined
|
||||||
|
if(!(read_flag[0] && read_flag[1] && read_flag[2])) throw DeadlyImportError("Not all color components are defined.");
|
||||||
|
// check if <a> is absent. Then manualy add "a == 1".
|
||||||
|
if(!read_flag[3]) als.Color.a = 1;
|
||||||
|
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
als.Composed = false;
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <material
|
||||||
|
// id="" - A unique material id. material ID "0" is reserved to denote no material (void) or sacrificial material.
|
||||||
|
// >
|
||||||
|
// </material>
|
||||||
|
// An available material.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <amf>.
|
||||||
|
void AMFImporter::ParseNode_Material()
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// Read attributes for node <color>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create new object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Material(mNodeElement_Cur);
|
||||||
|
// and assign read data
|
||||||
|
((CAMFImporter_NodeElement_Material*)ne)->ID = id;
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement())
|
||||||
|
{
|
||||||
|
bool col_read = false;
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("material");
|
||||||
|
if(XML_CheckNode_NameEqual("color"))
|
||||||
|
{
|
||||||
|
// Check if data already defined.
|
||||||
|
if(col_read) Throw_MoreThanOnceDefined("color", "Only one color can be defined for <material>.");
|
||||||
|
// read data and set flag about it
|
||||||
|
ParseNode_Color();
|
||||||
|
col_read = true;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(XML_CheckNode_NameEqual("metadata")) { ParseNode_Metadata(); continue; }
|
||||||
|
MACRO_NODECHECK_LOOPEND("material");
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
}// if(!mReader->isEmptyElement())
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
}// if(!mReader->isEmptyElement()) else
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <texture
|
||||||
|
// id="" - Assigns a unique texture id for the new texture.
|
||||||
|
// width="" - Width (horizontal size, x) of the texture, in pixels.
|
||||||
|
// height="" - Height (lateral size, y) of the texture, in pixels.
|
||||||
|
// depth="" - Depth (vertical size, z) of the texture, in pixels.
|
||||||
|
// type="" - Encoding of the data in the texture. Currently allowed values are "grayscale" only. In grayscale mode, each pixel is represented by one byte
|
||||||
|
// in the range of 0-255. When the texture is referenced using the tex function, these values are converted into a single floating point number in the
|
||||||
|
// range of 0-1 (see Annex 2). A full color graphics will typically require three textures, one for each of the color channels. A graphic involving
|
||||||
|
// transparency may require a fourth channel.
|
||||||
|
// tiled="" - If true then texture repeated when UV-coordinates is greater than 1.
|
||||||
|
// >
|
||||||
|
// </triangle>
|
||||||
|
// Specifies an texture data to be used as a map. Lists a sequence of Base64 values specifying values for pixels from left to right then top to bottom,
|
||||||
|
// then layer by layer.
|
||||||
|
// Multi elements - Yes.
|
||||||
|
// Parent element - <amf>.
|
||||||
|
void AMFImporter::ParseNode_Texture()
|
||||||
|
{
|
||||||
|
std::string id;
|
||||||
|
uint32_t width = 0;
|
||||||
|
uint32_t height = 0;
|
||||||
|
uint32_t depth = 1;
|
||||||
|
std::string type;
|
||||||
|
bool tiled = false;
|
||||||
|
std::string enc64_data;
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// Read attributes for node <color>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("id", id, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("width", width, XML_ReadNode_GetAttrVal_AsU32);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("height", height, XML_ReadNode_GetAttrVal_AsU32);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("depth", depth, XML_ReadNode_GetAttrVal_AsU32);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("type", type, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("tiled", tiled, XML_ReadNode_GetAttrVal_AsBool);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create new texture object.
|
||||||
|
ne = new CAMFImporter_NodeElement_Texture(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_Texture& als = *((CAMFImporter_NodeElement_Texture*)ne);// alias for convenience
|
||||||
|
|
||||||
|
// Check for child nodes
|
||||||
|
if(!mReader->isEmptyElement()) XML_ReadNode_GetVal_AsString(enc64_data);
|
||||||
|
|
||||||
|
// check that all components was defined
|
||||||
|
if(id.empty()) throw DeadlyImportError("ID for texture must be defined.");
|
||||||
|
if(width < 1) Throw_IncorrectAttrValue("width");
|
||||||
|
if(height < 1) Throw_IncorrectAttrValue("height");
|
||||||
|
if(depth < 1) Throw_IncorrectAttrValue("depth");
|
||||||
|
if(type != "grayscale") Throw_IncorrectAttrValue("type");
|
||||||
|
if(enc64_data.empty()) throw DeadlyImportError("Texture data not defined.");
|
||||||
|
// copy data
|
||||||
|
als.ID = id;
|
||||||
|
als.Width = width;
|
||||||
|
als.Height = height;
|
||||||
|
als.Depth = depth;
|
||||||
|
als.Tiled = tiled;
|
||||||
|
ParseHelper_Decode_Base64(enc64_data, als.Data);
|
||||||
|
// check data size
|
||||||
|
if((width * height * depth) != als.Data.size()) throw DeadlyImportError("Texture has incorrect data size.");
|
||||||
|
|
||||||
|
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element
|
||||||
|
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
// <texmap
|
||||||
|
// rtexid="" - Texture ID for red color component.
|
||||||
|
// gtexid="" - Texture ID for green color component.
|
||||||
|
// btexid="" - Texture ID for blue color component.
|
||||||
|
// atexid="" - Texture ID for alpha color component. Optional.
|
||||||
|
// >
|
||||||
|
// </texmap>, old name: <map>
|
||||||
|
// Specifies texture coordinates for triangle.
|
||||||
|
// Multi elements - No.
|
||||||
|
// Parent element - <triangle>.
|
||||||
|
// Children elements:
|
||||||
|
// <utex1>, <utex2>, <utex3>, <vtex1>, <vtex2>, <vtex3>. Old name: <u1>, <u2>, <u3>, <v1>, <v2>, <v3>.
|
||||||
|
// Multi elements - No.
|
||||||
|
// Texture coordinates for every vertex of triangle.
|
||||||
|
void AMFImporter::ParseNode_TexMap(const bool pUseOldName)
|
||||||
|
{
|
||||||
|
std::string rtexid, gtexid, btexid, atexid;
|
||||||
|
CAMFImporter_NodeElement* ne;
|
||||||
|
|
||||||
|
// Read attributes for node <color>.
|
||||||
|
MACRO_ATTRREAD_LOOPBEG;
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("rtexid", rtexid, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("gtexid", gtexid, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("btexid", btexid, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_CHECK_RET("atexid", atexid, mReader->getAttributeValue);
|
||||||
|
MACRO_ATTRREAD_LOOPEND;
|
||||||
|
|
||||||
|
// create new texture coordinates object.
|
||||||
|
ne = new CAMFImporter_NodeElement_TexMap(mNodeElement_Cur);
|
||||||
|
|
||||||
|
CAMFImporter_NodeElement_TexMap& als = *((CAMFImporter_NodeElement_TexMap*)ne);// alias for convenience
|
||||||
|
// check data
|
||||||
|
if(rtexid.empty() && gtexid.empty() && btexid.empty()) throw DeadlyImportError("ParseNode_TexMap. At least one texture ID must be defined.");
|
||||||
|
// Check for children nodes
|
||||||
|
XML_CheckNode_MustHaveChildren();
|
||||||
|
// read children nodes
|
||||||
|
bool read_flag[6] = { false, false, false, false, false, false };
|
||||||
|
|
||||||
|
ParseHelper_Node_Enter(ne);
|
||||||
|
if(!pUseOldName)
|
||||||
|
{
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("texmap");
|
||||||
|
MACRO_NODECHECK_READCOMP_F("utex1", read_flag[0], als.TextureCoordinate[0].x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("utex2", read_flag[1], als.TextureCoordinate[1].x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("utex3", read_flag[2], als.TextureCoordinate[2].x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("vtex1", read_flag[3], als.TextureCoordinate[0].y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("vtex2", read_flag[4], als.TextureCoordinate[1].y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("vtex3", read_flag[5], als.TextureCoordinate[2].y);
|
||||||
|
MACRO_NODECHECK_LOOPEND("texmap");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MACRO_NODECHECK_LOOPBEGIN("map");
|
||||||
|
MACRO_NODECHECK_READCOMP_F("u1", read_flag[0], als.TextureCoordinate[0].x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("u2", read_flag[1], als.TextureCoordinate[1].x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("u3", read_flag[2], als.TextureCoordinate[2].x);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("v1", read_flag[3], als.TextureCoordinate[0].y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("v2", read_flag[4], als.TextureCoordinate[1].y);
|
||||||
|
MACRO_NODECHECK_READCOMP_F("v3", read_flag[5], als.TextureCoordinate[2].y);
|
||||||
|
MACRO_NODECHECK_LOOPEND("map");
|
||||||
|
}// if(!pUseOldName) else
|
||||||
|
|
||||||
|
ParseHelper_Node_Exit();
|
||||||
|
|
||||||
|
// check that all components was defined
|
||||||
|
if(!(read_flag[0] && read_flag[1] && read_flag[2] && read_flag[3] && read_flag[4] && read_flag[5]))
|
||||||
|
throw DeadlyImportError("Not all texture coordinates are defined.");
|
||||||
|
|
||||||
|
// copy attributes data
|
||||||
|
als.TextureID_R = rtexid;
|
||||||
|
als.TextureID_G = gtexid;
|
||||||
|
als.TextureID_B = btexid;
|
||||||
|
als.TextureID_A = atexid;
|
||||||
|
|
||||||
|
mNodeElement_List.push_back(ne);// add to node element list because its a new object in graph.
|
||||||
|
}
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
|
|
@ -0,0 +1,423 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter_Node.hpp
|
||||||
|
/// \brief Elements of scene graph.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef INCLUDED_AI_AMF_IMPORTER_NODE_H
|
||||||
|
#define INCLUDED_AI_AMF_IMPORTER_NODE_H
|
||||||
|
|
||||||
|
// Header files, stdlib.
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// Header files, Assimp.
|
||||||
|
#include "assimp/types.h"
|
||||||
|
#include "assimp/scene.h"
|
||||||
|
|
||||||
|
/// \class CAMFImporter_NodeElement
|
||||||
|
/// Base class for elements of nodes.
|
||||||
|
class CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/***********************************************/
|
||||||
|
/******************** Types ********************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \enum EType
|
||||||
|
/// Define what data type contain node element.
|
||||||
|
enum EType
|
||||||
|
{
|
||||||
|
ENET_Color, ///< Color element: <color>.
|
||||||
|
ENET_Constellation,///< Grouping element: <constellation>.
|
||||||
|
ENET_Coordinates, ///< Coordinates element: <coordinates>.
|
||||||
|
ENET_Edge, ///< Edge element: <edge>.
|
||||||
|
ENET_Instance, ///< Grouping element: <constellation>.
|
||||||
|
ENET_Material, ///< Material element: <material>.
|
||||||
|
ENET_Metadata, ///< Metadata element: <metadata>.
|
||||||
|
ENET_Mesh, ///< Metadata element: <mesh>.
|
||||||
|
ENET_Object, ///< Element which hold object: <object>.
|
||||||
|
ENET_Root, ///< Root element: <amf>.
|
||||||
|
ENET_Triangle, ///< Triangle element: <triangle>.
|
||||||
|
ENET_TexMap, ///< Texture coordinates element: <texmap> or <map>.
|
||||||
|
ENET_Texture, ///< Texture element: <texture>.
|
||||||
|
ENET_Vertex, ///< Vertex element: <vertex>.
|
||||||
|
ENET_Vertices, ///< Vertex element: <vertices>.
|
||||||
|
ENET_Volume, ///< Volume element: <volume>.
|
||||||
|
|
||||||
|
ENET_Invalid ///< Element has invalid type and possible contain invalid data.
|
||||||
|
};
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Constants ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
const EType Type;///< Type of element.
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Variables ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
std::string ID;///< ID of element.
|
||||||
|
CAMFImporter_NodeElement* Parent;///< Parrent element. If nullptr then this node is root.
|
||||||
|
std::list<CAMFImporter_NodeElement*> Child;///< Child elements.
|
||||||
|
|
||||||
|
/***********************************************/
|
||||||
|
/****************** Functions ******************/
|
||||||
|
/***********************************************/
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement)
|
||||||
|
/// Disabled copy constructor.
|
||||||
|
CAMFImporter_NodeElement(const CAMFImporter_NodeElement& pNodeElement);
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement)
|
||||||
|
/// Disabled assign operator.
|
||||||
|
CAMFImporter_NodeElement& operator=(const CAMFImporter_NodeElement& pNodeElement);
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement()
|
||||||
|
/// Disabled default constructor.
|
||||||
|
CAMFImporter_NodeElement();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement(const EType pType, CAMFImporter_NodeElement* pParent)
|
||||||
|
/// In constructor inheritor must set element type.
|
||||||
|
/// \param [in] pType - element type.
|
||||||
|
/// \param [in] pParent - parent element.
|
||||||
|
CAMFImporter_NodeElement(const EType pType, CAMFImporter_NodeElement* pParent)
|
||||||
|
: Type(pType), Parent(pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// class IAMFImporter_NodeElement
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Constellation
|
||||||
|
/// A collection of objects or constellations with specific relative locations.
|
||||||
|
struct CAMFImporter_NodeElement_Constellation : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Constellation(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Constellation, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Constellation
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Instance
|
||||||
|
/// Part of constellation.
|
||||||
|
struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
std::string ObjectID;///< ID of object for instanciation.
|
||||||
|
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
|
||||||
|
/// create an instance of the object in the current constellation.
|
||||||
|
aiVector3D Delta;
|
||||||
|
|
||||||
|
/// \var Rotation - The rotation, in degrees, to rotate the referenced object about its x, y, and z axes, respectively, to create an
|
||||||
|
/// instance of the object in the current constellation. Rotations shall be executed in order of x first, then y, then z.
|
||||||
|
aiVector3D Rotation;
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Instance(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Instance, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Instance
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Metadata
|
||||||
|
/// Structure that define metadata node.
|
||||||
|
struct CAMFImporter_NodeElement_Metadata : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
std::string Type;///< Type of "Value".
|
||||||
|
std::string Value;///< Value.
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Metadata(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Metadata, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Metadata
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Root
|
||||||
|
/// Structure that define root node.
|
||||||
|
struct CAMFImporter_NodeElement_Root : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
std::string Unit;///< The units to be used. May be "inch", "millimeter", "meter", "feet", or "micron".
|
||||||
|
std::string Version;///< Version of format.
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Root(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Root, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Root
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Color
|
||||||
|
/// Structure that define object node.
|
||||||
|
struct CAMFImporter_NodeElement_Color : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
bool Composed;///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
|
||||||
|
std::string Color_Composed[4];///< By components formulas of composed color. [0..3] => RGBA.
|
||||||
|
aiColor4D Color;///< Constant color.
|
||||||
|
std::string Profile;///< The ICC color space used to interpret the three color channels <r>, <g> and <b>..
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Color(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Color, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Color
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Material
|
||||||
|
/// Structure that define material node.
|
||||||
|
struct CAMFImporter_NodeElement_Material : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Material(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Material, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Material
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Object
|
||||||
|
/// Structure that define object node.
|
||||||
|
struct CAMFImporter_NodeElement_Object : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Object(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Object, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Object
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Mesh
|
||||||
|
/// Structure that define mesh node.
|
||||||
|
struct CAMFImporter_NodeElement_Mesh : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Mesh(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Mesh, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Mesh
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Vertex
|
||||||
|
/// Structure that define vertex node.
|
||||||
|
struct CAMFImporter_NodeElement_Vertex : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Vertex(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Vertex, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Vertex
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Edge
|
||||||
|
/// Structure that define edge node.
|
||||||
|
struct CAMFImporter_NodeElement_Edge : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Edge(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Edge, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Vertex
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Vertices
|
||||||
|
/// Structure that define vertices node.
|
||||||
|
struct CAMFImporter_NodeElement_Vertices : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/// \fn CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Vertices(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Vertices, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Vertices
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Volume
|
||||||
|
/// Structure that define volume node.
|
||||||
|
struct CAMFImporter_NodeElement_Volume : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
std::string MaterialID;///< Which material to use.
|
||||||
|
std::string Type;///< What this volume describes can be “region” or “support”. If none specified, “object” is assumed.
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Volume(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Volume, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Volume
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Coordinates
|
||||||
|
/// Structure that define coordinates node.
|
||||||
|
struct CAMFImporter_NodeElement_Coordinates : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
aiVector3D Coordinate;///< Coordinate.
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Coordinates(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Coordinates, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Coordinates
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_TexMap
|
||||||
|
/// Structure that define texture coordinates node.
|
||||||
|
struct CAMFImporter_NodeElement_TexMap : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
aiVector3D TextureCoordinate[3];///< Texture coordinates.
|
||||||
|
std::string TextureID_R;///< Texture ID for red color component.
|
||||||
|
std::string TextureID_G;///< Texture ID for green color component.
|
||||||
|
std::string TextureID_B;///< Texture ID for blue color component.
|
||||||
|
std::string TextureID_A;///< Texture ID for alpha color component.
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_TexMap(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_TexMap, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_TexMap
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Triangle
|
||||||
|
/// Structure that define triangle node.
|
||||||
|
struct CAMFImporter_NodeElement_Triangle : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
size_t V[3];///< Triangle vertices.
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Triangle(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Triangle, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Triangle
|
||||||
|
|
||||||
|
/// \struct CAMFImporter_NodeElement_Texture
|
||||||
|
/// Structure that define texture node.
|
||||||
|
struct CAMFImporter_NodeElement_Texture : public CAMFImporter_NodeElement
|
||||||
|
{
|
||||||
|
/****************** Variables ******************/
|
||||||
|
|
||||||
|
size_t Width, Height, Depth;///< Size of the texture.
|
||||||
|
std::vector<uint8_t> Data;///< Data of the texture.
|
||||||
|
bool Tiled;
|
||||||
|
|
||||||
|
/****************** Functions ******************/
|
||||||
|
|
||||||
|
/// \fn CAMFImporter_NodeElement_Texture(CAMFImporter_NodeElement* pParent)
|
||||||
|
/// Constructor.
|
||||||
|
/// \param [in] pParent - pointer to parent node.
|
||||||
|
CAMFImporter_NodeElement_Texture(CAMFImporter_NodeElement* pParent)
|
||||||
|
: CAMFImporter_NodeElement(ENET_Texture, pParent)
|
||||||
|
{}
|
||||||
|
|
||||||
|
};// struct CAMFImporter_NodeElement_Texture
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_AMF_IMPORTER_NODE_H
|
|
@ -0,0 +1,966 @@
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, 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 AMFImporter_Postprocess.cpp
|
||||||
|
/// \brief Convert built scenegraph and objects to Assimp scenegraph.
|
||||||
|
/// \date 2016
|
||||||
|
/// \author smal.root@gmail.com
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
|
||||||
|
|
||||||
|
#include "AMFImporter.hpp"
|
||||||
|
|
||||||
|
// Header files, Assimp.
|
||||||
|
#include "SceneCombiner.h"
|
||||||
|
#include "StandardShapes.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
|
||||||
|
// Header files, stdlib.
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
aiColor4D AMFImporter::SPP_Material::GetColor(const float pX, const float pY, const float pZ) const
|
||||||
|
{
|
||||||
|
aiColor4D tcol;
|
||||||
|
|
||||||
|
// Check if stored data are supported.
|
||||||
|
if(Composition.size() != 0)
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("IME. GetColor for composition");
|
||||||
|
}
|
||||||
|
else if(Color->Composed)
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("IME. GetColor, composed color");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tcol = Color->Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if default color must be used
|
||||||
|
if((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0))
|
||||||
|
{
|
||||||
|
tcol.r = 0.5f;
|
||||||
|
tcol.g = 0.5f;
|
||||||
|
tcol.b = 0.5f;
|
||||||
|
tcol.a = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tcol;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const CAMFImporter_NodeElement_Mesh& pNodeElement, std::vector<aiVector3D>& pVertexCoordinateArray,
|
||||||
|
std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray) const
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement_Vertices* vn = nullptr;
|
||||||
|
size_t col_idx;
|
||||||
|
|
||||||
|
// All data stored in "vertices", search for it.
|
||||||
|
for(CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
|
||||||
|
{
|
||||||
|
if(ne_child->Type == CAMFImporter_NodeElement::ENET_Vertices) vn = (CAMFImporter_NodeElement_Vertices*)ne_child;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If "vertices" not found then no work for us.
|
||||||
|
if(vn == nullptr) return;
|
||||||
|
|
||||||
|
pVertexCoordinateArray.reserve(vn->Child.size());// all coordinates stored as child and we need to reserve space for future push_back's.
|
||||||
|
pVertexColorArray.resize(vn->Child.size());// colors count equal vertices count.
|
||||||
|
col_idx = 0;
|
||||||
|
// Inside vertices collect all data and place to arrays
|
||||||
|
for(CAMFImporter_NodeElement* vn_child: vn->Child)
|
||||||
|
{
|
||||||
|
// vertices, colors
|
||||||
|
if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
|
||||||
|
{
|
||||||
|
// by default clear color for current vertex
|
||||||
|
pVertexColorArray[col_idx] = nullptr;
|
||||||
|
|
||||||
|
for(CAMFImporter_NodeElement* vtx: vn_child->Child)
|
||||||
|
{
|
||||||
|
if(vtx->Type == CAMFImporter_NodeElement::ENET_Coordinates)
|
||||||
|
{
|
||||||
|
pVertexCoordinateArray.push_back(((CAMFImporter_NodeElement_Coordinates*)vtx)->Coordinate);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vtx->Type == CAMFImporter_NodeElement::ENET_Color)
|
||||||
|
{
|
||||||
|
pVertexColorArray[col_idx] = (CAMFImporter_NodeElement_Color*)vtx;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}// for(CAMFImporter_NodeElement* vtx: vn_child->Child)
|
||||||
|
|
||||||
|
col_idx++;
|
||||||
|
}// if(vn_child->Type == CAMFImporter_NodeElement::ENET_Vertex)
|
||||||
|
}// for(CAMFImporter_NodeElement* vn_child: vn->Child)
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B,
|
||||||
|
const std::string& pID_A)
|
||||||
|
{
|
||||||
|
size_t TextureConverted_Index;
|
||||||
|
std::string TextureConverted_ID;
|
||||||
|
|
||||||
|
// check input data
|
||||||
|
if(pID_R.empty() && pID_G.empty() && pID_B.empty() && pID_A.empty())
|
||||||
|
throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. At least one texture ID must be defined.");
|
||||||
|
|
||||||
|
// Create ID
|
||||||
|
TextureConverted_ID = pID_R + "_" + pID_G + "_" + pID_B + "_" + pID_A;
|
||||||
|
// Check if texture specified by set of IDs is converted already.
|
||||||
|
TextureConverted_Index = 0;
|
||||||
|
for(const SPP_Texture& tex_convd: mTexture_Converted)
|
||||||
|
{
|
||||||
|
if(tex_convd.ID == TextureConverted_ID)
|
||||||
|
return TextureConverted_Index;
|
||||||
|
else
|
||||||
|
TextureConverted_Index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Converted texture not found, create it.
|
||||||
|
//
|
||||||
|
CAMFImporter_NodeElement_Texture* src_texture[4]{nullptr};
|
||||||
|
std::vector<CAMFImporter_NodeElement_Texture*> src_texture_4check;
|
||||||
|
SPP_Texture converted_texture;
|
||||||
|
|
||||||
|
{// find all specified source textures
|
||||||
|
CAMFImporter_NodeElement* t_tex;
|
||||||
|
|
||||||
|
// R
|
||||||
|
if(!pID_R.empty())
|
||||||
|
{
|
||||||
|
if(!Find_NodeElement(pID_R, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_R);
|
||||||
|
|
||||||
|
src_texture[0] = (CAMFImporter_NodeElement_Texture*)t_tex;
|
||||||
|
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_texture[0] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// G
|
||||||
|
if(!pID_G.empty())
|
||||||
|
{
|
||||||
|
if(!Find_NodeElement(pID_G, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_G);
|
||||||
|
|
||||||
|
src_texture[1] = (CAMFImporter_NodeElement_Texture*)t_tex;
|
||||||
|
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_texture[1] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// B
|
||||||
|
if(!pID_B.empty())
|
||||||
|
{
|
||||||
|
if(!Find_NodeElement(pID_B, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_B);
|
||||||
|
|
||||||
|
src_texture[2] = (CAMFImporter_NodeElement_Texture*)t_tex;
|
||||||
|
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_texture[2] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A
|
||||||
|
if(!pID_A.empty())
|
||||||
|
{
|
||||||
|
if(!Find_NodeElement(pID_A, CAMFImporter_NodeElement::ENET_Texture, &t_tex)) Throw_ID_NotFound(pID_A);
|
||||||
|
|
||||||
|
src_texture[3] = (CAMFImporter_NodeElement_Texture*)t_tex;
|
||||||
|
src_texture_4check.push_back((CAMFImporter_NodeElement_Texture*)t_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_texture[3] = nullptr;
|
||||||
|
}
|
||||||
|
}// END: find all specified source textures
|
||||||
|
|
||||||
|
// check that all textures has same size
|
||||||
|
if(src_texture_4check.size() > 1)
|
||||||
|
{
|
||||||
|
for (size_t i = 0, i_e = (src_texture_4check.size() - 1); i < i_e; i++)
|
||||||
|
{
|
||||||
|
if((src_texture_4check[i]->Width != src_texture_4check[i + 1]->Width) || (src_texture_4check[i]->Height != src_texture_4check[i + 1]->Height) ||
|
||||||
|
(src_texture_4check[i]->Depth != src_texture_4check[i + 1]->Depth))
|
||||||
|
{
|
||||||
|
throw DeadlyImportError("PostprocessHelper_GetTextureID_Or_Create. Source texture must has the same size.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}// if(src_texture_4check.size() > 1)
|
||||||
|
|
||||||
|
// set texture attributes
|
||||||
|
converted_texture.Width = src_texture_4check[0]->Width;
|
||||||
|
converted_texture.Height = src_texture_4check[0]->Height;
|
||||||
|
converted_texture.Depth = src_texture_4check[0]->Depth;
|
||||||
|
// if one of source texture is tiled then converted texture is tiled too.
|
||||||
|
converted_texture.Tiled = false;
|
||||||
|
for(uint8_t i = 0; i < src_texture_4check.size(); i++) converted_texture.Tiled |= src_texture_4check[i]->Tiled;
|
||||||
|
|
||||||
|
// Create format hint.
|
||||||
|
strcpy(converted_texture.FormatHint, "rgba0000");// copy initial string.
|
||||||
|
if(!pID_R.empty()) converted_texture.FormatHint[4] = '8';
|
||||||
|
if(!pID_G.empty()) converted_texture.FormatHint[5] = '8';
|
||||||
|
if(!pID_B.empty()) converted_texture.FormatHint[6] = '8';
|
||||||
|
if(!pID_A.empty()) converted_texture.FormatHint[7] = '8';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Сopy data of textures.
|
||||||
|
//
|
||||||
|
size_t tex_size = 0;
|
||||||
|
size_t step = 0;
|
||||||
|
size_t off_g = 0;
|
||||||
|
size_t off_b = 0;
|
||||||
|
|
||||||
|
// Calculate size of the target array and rule how data will be copied.
|
||||||
|
if(!pID_R.empty()) { tex_size += src_texture[0]->Data.size(); step++, off_g++, off_b++; }
|
||||||
|
if(!pID_G.empty()) { tex_size += src_texture[1]->Data.size(); step++, off_b++; }
|
||||||
|
if(!pID_B.empty()) { tex_size += src_texture[2]->Data.size(); step++; }
|
||||||
|
if(!pID_A.empty()) { tex_size += src_texture[3]->Data.size(); step++; }
|
||||||
|
|
||||||
|
// Create target array.
|
||||||
|
converted_texture.Data = new uint8_t[tex_size];
|
||||||
|
// And copy data
|
||||||
|
auto CopyTextureData = [&](const std::string& pID, const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
|
||||||
|
{
|
||||||
|
if(!pID.empty())
|
||||||
|
{
|
||||||
|
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++)
|
||||||
|
converted_texture.Data[idx_target] = src_texture[pSrcTexNum]->Data.at(idx_src);
|
||||||
|
}
|
||||||
|
};// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void
|
||||||
|
|
||||||
|
CopyTextureData(pID_R, 0, step, 0);
|
||||||
|
CopyTextureData(pID_G, off_g, step, 1);
|
||||||
|
CopyTextureData(pID_B, off_b, step, 2);
|
||||||
|
CopyTextureData(pID_A, step - 1, step, 3);
|
||||||
|
|
||||||
|
// Store new converted texture ID
|
||||||
|
converted_texture.ID = TextureConverted_ID;
|
||||||
|
// Store new converted texture
|
||||||
|
mTexture_Converted.push_back(converted_texture);
|
||||||
|
|
||||||
|
return TextureConverted_Index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::PostprocessHelper_SplitFacesByTextureID(std::list<SComplexFace>& pInputList, std::list<std::list<SComplexFace> >& pOutputList_Separated)
|
||||||
|
{
|
||||||
|
auto texmap_is_equal = [](const CAMFImporter_NodeElement_TexMap* pTexMap1, const CAMFImporter_NodeElement_TexMap* pTexMap2) -> bool
|
||||||
|
{
|
||||||
|
if((pTexMap1 == nullptr) && (pTexMap2 == nullptr)) return true;
|
||||||
|
if(pTexMap1 == nullptr) return false;
|
||||||
|
if(pTexMap2 == nullptr) return false;
|
||||||
|
|
||||||
|
if(pTexMap1->TextureID_R != pTexMap2->TextureID_R) return false;
|
||||||
|
if(pTexMap1->TextureID_G != pTexMap2->TextureID_G) return false;
|
||||||
|
if(pTexMap1->TextureID_B != pTexMap2->TextureID_B) return false;
|
||||||
|
if(pTexMap1->TextureID_A != pTexMap2->TextureID_A) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
pOutputList_Separated.clear();
|
||||||
|
if(pInputList.size() == 0) return;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SComplexFace face_start = pInputList.front();
|
||||||
|
std::list<SComplexFace> face_list_cur;
|
||||||
|
|
||||||
|
for(std::list<SComplexFace>::iterator it = pInputList.begin(), it_end = pInputList.end(); it != it_end;)
|
||||||
|
{
|
||||||
|
if(texmap_is_equal(face_start.TexMap, it->TexMap))
|
||||||
|
{
|
||||||
|
auto it_old = it;
|
||||||
|
|
||||||
|
it++;
|
||||||
|
face_list_cur.push_back(*it_old);
|
||||||
|
pInputList.erase(it_old);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(face_list_cur.size() > 0) pOutputList_Separated.push_back(face_list_cur);
|
||||||
|
|
||||||
|
} while(pInputList.size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Postprocess_AddMetadata(const std::list<CAMFImporter_NodeElement_Metadata*>& metadataList, aiNode& sceneNode) const
|
||||||
|
{
|
||||||
|
if ( !metadataList.empty() )
|
||||||
|
{
|
||||||
|
if(sceneNode.mMetaData != nullptr) throw DeadlyImportError("Postprocess. MetaData member in node are not nullptr. Something went wrong.");
|
||||||
|
|
||||||
|
// copy collected metadata to output node.
|
||||||
|
sceneNode.mMetaData = aiMetadata::Alloc( static_cast<unsigned int>(metadataList.size()) );
|
||||||
|
size_t meta_idx( 0 );
|
||||||
|
|
||||||
|
for(const CAMFImporter_NodeElement_Metadata& metadata: metadataList)
|
||||||
|
{
|
||||||
|
sceneNode.mMetaData->Set(static_cast<unsigned int>(meta_idx++), metadata.Type, aiString(metadata.Value));
|
||||||
|
}
|
||||||
|
}// if(!metadataList.empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Postprocess_BuildNodeAndObject(const CAMFImporter_NodeElement_Object& pNodeElement, std::list<aiMesh*>& pMeshList, aiNode** pSceneNode)
|
||||||
|
{
|
||||||
|
CAMFImporter_NodeElement_Color* object_color = nullptr;
|
||||||
|
|
||||||
|
// create new aiNode and set name as <object> has.
|
||||||
|
*pSceneNode = new aiNode;
|
||||||
|
(*pSceneNode)->mName = pNodeElement.ID;
|
||||||
|
// read mesh and color
|
||||||
|
for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
|
||||||
|
{
|
||||||
|
std::vector<aiVector3D> vertex_arr;
|
||||||
|
std::vector<CAMFImporter_NodeElement_Color*> color_arr;
|
||||||
|
|
||||||
|
// color for object
|
||||||
|
if(ne_child->Type == CAMFImporter_NodeElement::ENET_Color) object_color = (CAMFImporter_NodeElement_Color*)ne_child;
|
||||||
|
|
||||||
|
if(ne_child->Type == CAMFImporter_NodeElement::ENET_Mesh)
|
||||||
|
{
|
||||||
|
// Create arrays from children of mesh: vertices.
|
||||||
|
PostprocessHelper_CreateMeshDataArray(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr);
|
||||||
|
// Use this arrays as a source when creating every aiMesh
|
||||||
|
Postprocess_BuildMeshSet(*((CAMFImporter_NodeElement_Mesh*)ne_child), vertex_arr, color_arr, object_color, pMeshList, **pSceneNode);
|
||||||
|
}
|
||||||
|
}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement)
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Postprocess_BuildMeshSet(const CAMFImporter_NodeElement_Mesh& pNodeElement, const std::vector<aiVector3D>& pVertexCoordinateArray,
|
||||||
|
const std::vector<CAMFImporter_NodeElement_Color*>& pVertexColorArray,
|
||||||
|
const CAMFImporter_NodeElement_Color* pObjectColor, std::list<aiMesh*>& pMeshList, aiNode& pSceneNode)
|
||||||
|
{
|
||||||
|
std::list<unsigned int> mesh_idx;
|
||||||
|
|
||||||
|
// all data stored in "volume", search for it.
|
||||||
|
for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
|
||||||
|
{
|
||||||
|
const CAMFImporter_NodeElement_Color* ne_volume_color = nullptr;
|
||||||
|
const SPP_Material* cur_mat = nullptr;
|
||||||
|
|
||||||
|
if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
|
||||||
|
{
|
||||||
|
/******************* Get faces *******************/
|
||||||
|
const CAMFImporter_NodeElement_Volume* ne_volume = reinterpret_cast<const CAMFImporter_NodeElement_Volume*>(ne_child);
|
||||||
|
|
||||||
|
std::list<SComplexFace> complex_faces_list;// List of the faces of the volume.
|
||||||
|
std::list<std::list<SComplexFace> > complex_faces_toplist;// List of the face list for every mesh.
|
||||||
|
|
||||||
|
// check if volume use material
|
||||||
|
if(!ne_volume->MaterialID.empty())
|
||||||
|
{
|
||||||
|
if(!Find_ConvertedMaterial(ne_volume->MaterialID, &cur_mat)) Throw_ID_NotFound(ne_volume->MaterialID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// inside "volume" collect all data and place to arrays or create new objects
|
||||||
|
for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)
|
||||||
|
{
|
||||||
|
// color for volume
|
||||||
|
if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Color)
|
||||||
|
{
|
||||||
|
ne_volume_color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_volume_child);
|
||||||
|
}
|
||||||
|
else if(ne_volume_child->Type == CAMFImporter_NodeElement::ENET_Triangle)// triangles, triangles colors
|
||||||
|
{
|
||||||
|
const CAMFImporter_NodeElement_Triangle& tri_al = *reinterpret_cast<const CAMFImporter_NodeElement_Triangle*>(ne_volume_child);
|
||||||
|
|
||||||
|
SComplexFace complex_face;
|
||||||
|
|
||||||
|
// initialize pointers
|
||||||
|
complex_face.Color = nullptr;
|
||||||
|
complex_face.TexMap = nullptr;
|
||||||
|
// get data from triangle children: color, texture coordinates.
|
||||||
|
if(tri_al.Child.size())
|
||||||
|
{
|
||||||
|
for(const CAMFImporter_NodeElement* ne_triangle_child: tri_al.Child)
|
||||||
|
{
|
||||||
|
if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_Color)
|
||||||
|
complex_face.Color = reinterpret_cast<const CAMFImporter_NodeElement_Color*>(ne_triangle_child);
|
||||||
|
else if(ne_triangle_child->Type == CAMFImporter_NodeElement::ENET_TexMap)
|
||||||
|
complex_face.TexMap = reinterpret_cast<const CAMFImporter_NodeElement_TexMap*>(ne_triangle_child);
|
||||||
|
}
|
||||||
|
}// if(tri_al.Child.size())
|
||||||
|
|
||||||
|
// create new face and store it.
|
||||||
|
complex_face.Face.mNumIndices = 3;
|
||||||
|
complex_face.Face.mIndices = new unsigned int[3];
|
||||||
|
complex_face.Face.mIndices[0] = static_cast<unsigned int>(tri_al.V[0]);
|
||||||
|
complex_face.Face.mIndices[1] = static_cast<unsigned int>(tri_al.V[1]);
|
||||||
|
complex_face.Face.mIndices[2] = static_cast<unsigned int>(tri_al.V[2]);
|
||||||
|
complex_faces_list.push_back(complex_face);
|
||||||
|
}
|
||||||
|
}// for(const CAMFImporter_NodeElement* ne_volume_child: ne_volume->Child)
|
||||||
|
|
||||||
|
/**** Split faces list: one list per mesh ****/
|
||||||
|
PostprocessHelper_SplitFacesByTextureID(complex_faces_list, complex_faces_toplist);
|
||||||
|
|
||||||
|
/***** Create mesh for every faces list ******/
|
||||||
|
for(std::list<SComplexFace>& face_list_cur: complex_faces_toplist)
|
||||||
|
{
|
||||||
|
auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
|
||||||
|
{
|
||||||
|
size_t rv;
|
||||||
|
|
||||||
|
if(pBiggerThan != nullptr)
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
for(const SComplexFace& face: pFaceList)
|
||||||
|
{
|
||||||
|
for(size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++)
|
||||||
|
{
|
||||||
|
if(face.Face.mIndices[idx_vert] > *pBiggerThan)
|
||||||
|
{
|
||||||
|
rv = face.Face.mIndices[idx_vert];
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(found) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found) return *pBiggerThan;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = pFaceList.front().Face.mIndices[0];
|
||||||
|
}// if(pBiggerThan != nullptr) else
|
||||||
|
|
||||||
|
for(const SComplexFace& face: pFaceList)
|
||||||
|
{
|
||||||
|
for(size_t vi = 0; vi < face.Face.mNumIndices; vi++)
|
||||||
|
{
|
||||||
|
if(face.Face.mIndices[vi] < rv)
|
||||||
|
{
|
||||||
|
if(pBiggerThan != nullptr)
|
||||||
|
{
|
||||||
|
if(face.Face.mIndices[vi] > *pBiggerThan) rv = face.Face.mIndices[vi];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rv = face.Face.mIndices[vi];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}// for(const SComplexFace& face: pFaceList)
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
};// auto VertexIndex_GetMinimal = [](const std::list<SComplexFace>& pFaceList, const size_t* pBiggerThan) -> size_t
|
||||||
|
|
||||||
|
auto VertexIndex_Replace = [](std::list<SComplexFace>& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void
|
||||||
|
{
|
||||||
|
for(const SComplexFace& face: pFaceList)
|
||||||
|
{
|
||||||
|
for(size_t vi = 0; vi < face.Face.mNumIndices; vi++)
|
||||||
|
{
|
||||||
|
if(face.Face.mIndices[vi] == pIdx_From) face.Face.mIndices[vi] = static_cast<unsigned int>(pIdx_To);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};// auto VertexIndex_Replace = [](std::list<SComplexFace>& pFaceList, const size_t pIdx_From, const size_t pIdx_To) -> void
|
||||||
|
|
||||||
|
auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D
|
||||||
|
{
|
||||||
|
// Color priorities(In descending order):
|
||||||
|
// 1. triangle color;
|
||||||
|
// 2. vertex color;
|
||||||
|
// 3. volume color;
|
||||||
|
// 4. object color;
|
||||||
|
// 5. material;
|
||||||
|
// 6. default - invisible coat.
|
||||||
|
//
|
||||||
|
// Fill vertices colors in color priority list above that's points from 1 to 6.
|
||||||
|
if((pIdx < pVertexColorArray.size()) && (pVertexColorArray[pIdx] != nullptr))// check for vertex color
|
||||||
|
{
|
||||||
|
if(pVertexColorArray[pIdx]->Composed)
|
||||||
|
throw DeadlyImportError("IME: vertex color composed");
|
||||||
|
else
|
||||||
|
return pVertexColorArray[pIdx]->Color;
|
||||||
|
}
|
||||||
|
else if(ne_volume_color != nullptr)// check for volume color
|
||||||
|
{
|
||||||
|
if(ne_volume_color->Composed)
|
||||||
|
throw DeadlyImportError("IME: volume color composed");
|
||||||
|
else
|
||||||
|
return ne_volume_color->Color;
|
||||||
|
}
|
||||||
|
else if(pObjectColor != nullptr)// check for object color
|
||||||
|
{
|
||||||
|
if(pObjectColor->Composed)
|
||||||
|
throw DeadlyImportError("IME: object color composed");
|
||||||
|
else
|
||||||
|
return pObjectColor->Color;
|
||||||
|
}
|
||||||
|
else if(cur_mat != nullptr)// check for material
|
||||||
|
{
|
||||||
|
return cur_mat->GetColor(pVertexCoordinateArray.at(pIdx).x, pVertexCoordinateArray.at(pIdx).y, pVertexCoordinateArray.at(pIdx).z);
|
||||||
|
}
|
||||||
|
else// set default color.
|
||||||
|
{
|
||||||
|
return {0, 0, 0, 0};
|
||||||
|
}// if((vi < pVertexColorArray.size()) && (pVertexColorArray[vi] != nullptr)) else
|
||||||
|
|
||||||
|
};// auto Vertex_CalculateColor = [&](const size_t pIdx) -> aiColor4D
|
||||||
|
|
||||||
|
aiMesh* tmesh = new aiMesh;
|
||||||
|
|
||||||
|
tmesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;// Only triangles is supported by AMF.
|
||||||
|
//
|
||||||
|
// set geometry and colors (vertices)
|
||||||
|
//
|
||||||
|
// copy faces/triangles
|
||||||
|
tmesh->mNumFaces = static_cast<unsigned int>(face_list_cur.size());
|
||||||
|
tmesh->mFaces = new aiFace[tmesh->mNumFaces];
|
||||||
|
|
||||||
|
// Create vertices list and optimize indices. Optimisation mean following.In AMF all volumes use one big list of vertices. And one volume
|
||||||
|
// can use only part of vertices list, for example: vertices list contain few thousands of vertices and volume use vertices 1, 3, 10.
|
||||||
|
// Do you need all this thousands of garbage? Of course no. So, optimisation step transformate sparse indices set to continuous.
|
||||||
|
size_t VertexCount_Max = tmesh->mNumFaces * 3;// 3 - triangles.
|
||||||
|
std::vector<aiVector3D> vert_arr, texcoord_arr;
|
||||||
|
std::vector<aiColor4D> col_arr;
|
||||||
|
|
||||||
|
vert_arr.reserve(VertexCount_Max * 2);// "* 2" - see below TODO.
|
||||||
|
col_arr.reserve(VertexCount_Max * 2);
|
||||||
|
|
||||||
|
{// fill arrays
|
||||||
|
size_t vert_idx_from, vert_idx_to;
|
||||||
|
|
||||||
|
// first iteration.
|
||||||
|
vert_idx_to = 0;
|
||||||
|
vert_idx_from = VertexIndex_GetMinimal(face_list_cur, nullptr);
|
||||||
|
vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
|
||||||
|
col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
|
||||||
|
if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
|
||||||
|
|
||||||
|
// rest iterations
|
||||||
|
do
|
||||||
|
{
|
||||||
|
vert_idx_from = VertexIndex_GetMinimal(face_list_cur, &vert_idx_to);
|
||||||
|
if(vert_idx_from == vert_idx_to) break;// all indices are transferred,
|
||||||
|
|
||||||
|
vert_arr.push_back(pVertexCoordinateArray.at(vert_idx_from));
|
||||||
|
col_arr.push_back(Vertex_CalculateColor(vert_idx_from));
|
||||||
|
vert_idx_to++;
|
||||||
|
if(vert_idx_from != vert_idx_to) VertexIndex_Replace(face_list_cur, vert_idx_from, vert_idx_to);
|
||||||
|
|
||||||
|
} while(true);
|
||||||
|
}// fill arrays. END.
|
||||||
|
|
||||||
|
//
|
||||||
|
// check if triangle colors are used and create additional faces if needed.
|
||||||
|
//
|
||||||
|
for(const SComplexFace& face_cur: face_list_cur)
|
||||||
|
{
|
||||||
|
if(face_cur.Color != nullptr)
|
||||||
|
{
|
||||||
|
aiColor4D face_color;
|
||||||
|
size_t vert_idx_new = vert_arr.size();
|
||||||
|
|
||||||
|
if(face_cur.Color->Composed)
|
||||||
|
throw DeadlyImportError("IME: face color composed");
|
||||||
|
else
|
||||||
|
face_color = face_cur.Color->Color;
|
||||||
|
|
||||||
|
for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
|
||||||
|
{
|
||||||
|
vert_arr.push_back(vert_arr.at(face_cur.Face.mIndices[idx_ind]));
|
||||||
|
col_arr.push_back(face_color);
|
||||||
|
face_cur.Face.mIndices[idx_ind] = static_cast<unsigned int>(vert_idx_new++);
|
||||||
|
}
|
||||||
|
}// if(face_cur.Color != nullptr)
|
||||||
|
}// for(const SComplexFace& face_cur: face_list_cur)
|
||||||
|
|
||||||
|
//
|
||||||
|
// if texture is used then copy texture coordinates too.
|
||||||
|
//
|
||||||
|
if(face_list_cur.front().TexMap != nullptr)
|
||||||
|
{
|
||||||
|
size_t idx_vert_new = vert_arr.size();
|
||||||
|
///TODO: clean unused vertices. "* 2": in certain cases - mesh full of triangle colors - vert_arr will contain duplicated vertices for
|
||||||
|
/// colored triangles and initial vertices (for colored vertices) which in real became unused. This part need more thinking about
|
||||||
|
/// optimisation.
|
||||||
|
bool* idx_vert_used;
|
||||||
|
|
||||||
|
idx_vert_used = new bool[VertexCount_Max * 2];
|
||||||
|
for(size_t i = 0, i_e = VertexCount_Max * 2; i < i_e; i++) idx_vert_used[i] = false;
|
||||||
|
|
||||||
|
// This ID's will be used when set materials ID in scene.
|
||||||
|
tmesh->mMaterialIndex = static_cast<unsigned int>(PostprocessHelper_GetTextureID_Or_Create(face_list_cur.front().TexMap->TextureID_R,
|
||||||
|
face_list_cur.front().TexMap->TextureID_G,
|
||||||
|
face_list_cur.front().TexMap->TextureID_B,
|
||||||
|
face_list_cur.front().TexMap->TextureID_A));
|
||||||
|
texcoord_arr.resize(VertexCount_Max * 2);
|
||||||
|
for(const SComplexFace& face_cur: face_list_cur)
|
||||||
|
{
|
||||||
|
for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
|
||||||
|
{
|
||||||
|
const size_t idx_vert = face_cur.Face.mIndices[idx_ind];
|
||||||
|
|
||||||
|
if(!idx_vert_used[idx_vert])
|
||||||
|
{
|
||||||
|
texcoord_arr.at(idx_vert) = face_cur.TexMap->TextureCoordinate[idx_ind];
|
||||||
|
idx_vert_used[idx_vert] = true;
|
||||||
|
}
|
||||||
|
else if(texcoord_arr.at(idx_vert) != face_cur.TexMap->TextureCoordinate[idx_ind])
|
||||||
|
{
|
||||||
|
// in that case one vertex is shared with many texture coordinates. We need to duplicate vertex with another texture
|
||||||
|
// coordinates.
|
||||||
|
vert_arr.push_back(vert_arr.at(idx_vert));
|
||||||
|
col_arr.push_back(col_arr.at(idx_vert));
|
||||||
|
texcoord_arr.at(idx_vert_new) = face_cur.TexMap->TextureCoordinate[idx_ind];
|
||||||
|
face_cur.Face.mIndices[idx_ind] = static_cast<unsigned int>(idx_vert_new++);
|
||||||
|
}
|
||||||
|
}// for(size_t idx_ind = 0; idx_ind < face_cur.Face.mNumIndices; idx_ind++)
|
||||||
|
}// for(const SComplexFace& face_cur: face_list_cur)
|
||||||
|
|
||||||
|
delete [] idx_vert_used;
|
||||||
|
// shrink array
|
||||||
|
texcoord_arr.resize(idx_vert_new);
|
||||||
|
}// if(face_list_cur.front().TexMap != nullptr)
|
||||||
|
|
||||||
|
//
|
||||||
|
// copy collected data to mesh
|
||||||
|
//
|
||||||
|
tmesh->mNumVertices = static_cast<unsigned int>(vert_arr.size());
|
||||||
|
tmesh->mVertices = new aiVector3D[tmesh->mNumVertices];
|
||||||
|
tmesh->mColors[0] = new aiColor4D[tmesh->mNumVertices];
|
||||||
|
tmesh->mFaces = new aiFace[face_list_cur.size()];
|
||||||
|
|
||||||
|
memcpy(tmesh->mVertices, vert_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
|
||||||
|
memcpy(tmesh->mColors[0], col_arr.data(), tmesh->mNumVertices * sizeof(aiColor4D));
|
||||||
|
if(texcoord_arr.size() > 0)
|
||||||
|
{
|
||||||
|
tmesh->mTextureCoords[0] = new aiVector3D[tmesh->mNumVertices];
|
||||||
|
memcpy(tmesh->mTextureCoords[0], texcoord_arr.data(), tmesh->mNumVertices * sizeof(aiVector3D));
|
||||||
|
tmesh->mNumUVComponents[0] = 2;// U and V stored in "x", "y" of aiVector3D.
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t idx_face = 0;
|
||||||
|
for(const SComplexFace& face_cur: face_list_cur) tmesh->mFaces[idx_face++] = face_cur.Face;
|
||||||
|
|
||||||
|
// store new aiMesh
|
||||||
|
mesh_idx.push_back(static_cast<unsigned int>(pMeshList.size()));
|
||||||
|
pMeshList.push_back(tmesh);
|
||||||
|
}// for(const std::list<SComplexFace>& face_list_cur: complex_faces_toplist)
|
||||||
|
}// if(ne_child->Type == CAMFImporter_NodeElement::ENET_Volume)
|
||||||
|
}// for(const CAMFImporter_NodeElement* ne_child: pNodeElement.Child)
|
||||||
|
|
||||||
|
// if meshes was created then assign new indices with current aiNode
|
||||||
|
if(mesh_idx.size() > 0)
|
||||||
|
{
|
||||||
|
std::list<unsigned int>::const_iterator mit = mesh_idx.begin();
|
||||||
|
|
||||||
|
pSceneNode.mNumMeshes = static_cast<unsigned int>(mesh_idx.size());
|
||||||
|
pSceneNode.mMeshes = new unsigned int[pSceneNode.mNumMeshes];
|
||||||
|
for(size_t i = 0; i < pSceneNode.mNumMeshes; i++) pSceneNode.mMeshes[i] = *mit++;
|
||||||
|
}// if(mesh_idx.size() > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Postprocess_BuildMaterial(const CAMFImporter_NodeElement_Material& pMaterial)
|
||||||
|
{
|
||||||
|
SPP_Material new_mat;
|
||||||
|
|
||||||
|
new_mat.ID = pMaterial.ID;
|
||||||
|
for(const CAMFImporter_NodeElement* mat_child: pMaterial.Child)
|
||||||
|
{
|
||||||
|
if(mat_child->Type == CAMFImporter_NodeElement::ENET_Color)
|
||||||
|
{
|
||||||
|
new_mat.Color = (CAMFImporter_NodeElement_Color*)mat_child;
|
||||||
|
}
|
||||||
|
else if(mat_child->Type == CAMFImporter_NodeElement::ENET_Metadata)
|
||||||
|
{
|
||||||
|
new_mat.Metadata.push_back((CAMFImporter_NodeElement_Metadata*)mat_child);
|
||||||
|
}
|
||||||
|
}// for(const CAMFImporter_NodeElement* mat_child; pMaterial.Child)
|
||||||
|
|
||||||
|
// place converted material to special list
|
||||||
|
mMaterial_Converted.push_back(new_mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Postprocess_BuildConstellation(CAMFImporter_NodeElement_Constellation& pConstellation, std::list<aiNode*>& pNodeList) const
|
||||||
|
{
|
||||||
|
aiNode* con_node;
|
||||||
|
std::list<aiNode*> ch_node;
|
||||||
|
|
||||||
|
// We will build next hierarchy:
|
||||||
|
// aiNode as parent (<constellation>) for set of nodes as a children
|
||||||
|
// |- aiNode for transformation (<instance> -> <delta...>, <r...>) - aiNode for pointing to object ("objectid")
|
||||||
|
// ...
|
||||||
|
// \_ aiNode for transformation (<instance> -> <delta...>, <r...>) - aiNode for pointing to object ("objectid")
|
||||||
|
con_node = new aiNode;
|
||||||
|
con_node->mName = pConstellation.ID;
|
||||||
|
// Walk through children and search for instances of another objects, constellations.
|
||||||
|
for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
|
||||||
|
{
|
||||||
|
aiMatrix4x4 tmat;
|
||||||
|
aiNode* t_node;
|
||||||
|
aiNode* found_node;
|
||||||
|
|
||||||
|
if(ne->Type == CAMFImporter_NodeElement::ENET_Metadata) continue;
|
||||||
|
if(ne->Type != CAMFImporter_NodeElement::ENET_Instance) throw DeadlyImportError("Only <instance> nodes can be in <constellation>.");
|
||||||
|
|
||||||
|
// create alias for conveniance
|
||||||
|
CAMFImporter_NodeElement_Instance& als = *((CAMFImporter_NodeElement_Instance*)ne);
|
||||||
|
// find referenced object
|
||||||
|
if(!Find_ConvertedNode(als.ObjectID, pNodeList, &found_node)) Throw_ID_NotFound(als.ObjectID);
|
||||||
|
|
||||||
|
// create node for apllying transformation
|
||||||
|
t_node = new aiNode;
|
||||||
|
t_node->mParent = con_node;
|
||||||
|
// apply transformation
|
||||||
|
aiMatrix4x4::Translation(als.Delta, tmat), t_node->mTransformation *= tmat;
|
||||||
|
aiMatrix4x4::RotationX(als.Rotation.x, tmat), t_node->mTransformation *= tmat;
|
||||||
|
aiMatrix4x4::RotationY(als.Rotation.y, tmat), t_node->mTransformation *= tmat;
|
||||||
|
aiMatrix4x4::RotationZ(als.Rotation.z, tmat), t_node->mTransformation *= tmat;
|
||||||
|
// create array for one child node
|
||||||
|
t_node->mNumChildren = 1;
|
||||||
|
t_node->mChildren = new aiNode*[t_node->mNumChildren];
|
||||||
|
SceneCombiner::Copy(&t_node->mChildren[0], found_node);
|
||||||
|
t_node->mChildren[0]->mParent = t_node;
|
||||||
|
ch_node.push_back(t_node);
|
||||||
|
}// for(const CAMFImporter_NodeElement* ne: pConstellation.Child)
|
||||||
|
|
||||||
|
// copy found aiNode's as children
|
||||||
|
if(ch_node.size() == 0) throw DeadlyImportError("<constellation> must have at least one <instance>.");
|
||||||
|
|
||||||
|
size_t ch_idx = 0;
|
||||||
|
|
||||||
|
con_node->mNumChildren = static_cast<unsigned int>(ch_node.size());
|
||||||
|
con_node->mChildren = new aiNode*[con_node->mNumChildren];
|
||||||
|
for(aiNode* node: ch_node) con_node->mChildren[ch_idx++] = node;
|
||||||
|
|
||||||
|
// and place "root" of <constellation> node to node list
|
||||||
|
pNodeList.push_back(con_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AMFImporter::Postprocess_BuildScene(aiScene* pScene)
|
||||||
|
{
|
||||||
|
std::list<aiNode*> node_list;
|
||||||
|
std::list<aiMesh*> mesh_list;
|
||||||
|
std::list<CAMFImporter_NodeElement_Metadata*> meta_list;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Because for AMF "material" is just complex colors mixing so aiMaterial will not be used.
|
||||||
|
// For building aiScene we are must to do few steps:
|
||||||
|
// at first creating root node for aiScene.
|
||||||
|
pScene->mRootNode = new aiNode;
|
||||||
|
pScene->mRootNode->mParent = nullptr;
|
||||||
|
pScene->mFlags |= AI_SCENE_FLAGS_ALLOW_SHARED;
|
||||||
|
// search for root(<amf>) element
|
||||||
|
CAMFImporter_NodeElement* root_el = nullptr;
|
||||||
|
|
||||||
|
for(CAMFImporter_NodeElement* ne: mNodeElement_List)
|
||||||
|
{
|
||||||
|
if(ne->Type != CAMFImporter_NodeElement::ENET_Root) continue;
|
||||||
|
|
||||||
|
root_el = ne;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}// for(const CAMFImporter_NodeElement* ne: mNodeElement_List)
|
||||||
|
|
||||||
|
// Check if root element are found.
|
||||||
|
if(root_el == nullptr) throw DeadlyImportError("Root(<amf>) element not found.");
|
||||||
|
|
||||||
|
// after that walk through children of root and collect data. Five types of nodes can be placed at top level - in <amf>: <object>, <material>, <texture>,
|
||||||
|
// <constellation> and <metadata>. But at first we must read <material> and <texture> because they will be used in <object>. <metadata> can be read
|
||||||
|
// at any moment.
|
||||||
|
//
|
||||||
|
// 1. <material>
|
||||||
|
// 2. <texture> will be converted later when processing triangles list. \sa Postprocess_BuildMeshSet
|
||||||
|
for(const CAMFImporter_NodeElement* root_child: root_el->Child)
|
||||||
|
{
|
||||||
|
if(root_child->Type == CAMFImporter_NodeElement::ENET_Material) Postprocess_BuildMaterial(*((CAMFImporter_NodeElement_Material*)root_child));
|
||||||
|
}
|
||||||
|
|
||||||
|
// After "appearance" nodes we must read <object> because it will be used in <constellation> -> <instance>.
|
||||||
|
//
|
||||||
|
// 3. <object>
|
||||||
|
for(const CAMFImporter_NodeElement* root_child: root_el->Child)
|
||||||
|
{
|
||||||
|
if(root_child->Type == CAMFImporter_NodeElement::ENET_Object)
|
||||||
|
{
|
||||||
|
aiNode* tnode = nullptr;
|
||||||
|
|
||||||
|
// for <object> mesh and node must be built: object ID assigned to aiNode name and will be used in future for <instance>
|
||||||
|
Postprocess_BuildNodeAndObject(*((CAMFImporter_NodeElement_Object*)root_child), mesh_list, &tnode);
|
||||||
|
if(tnode != nullptr) node_list.push_back(tnode);
|
||||||
|
|
||||||
|
}
|
||||||
|
}// for(const CAMFImporter_NodeElement* root_child: root_el->Child)
|
||||||
|
|
||||||
|
// And finally read rest of nodes.
|
||||||
|
//
|
||||||
|
for(const CAMFImporter_NodeElement* root_child: root_el->Child)
|
||||||
|
{
|
||||||
|
// 4. <constellation>
|
||||||
|
if(root_child->Type == CAMFImporter_NodeElement::ENET_Constellation)
|
||||||
|
{
|
||||||
|
// <object> and <constellation> at top of self abstraction use aiNode. So we can use only aiNode list for creating new aiNode's.
|
||||||
|
Postprocess_BuildConstellation(*((CAMFImporter_NodeElement_Constellation*)root_child), node_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5, <metadata>
|
||||||
|
if(root_child->Type == CAMFImporter_NodeElement::ENET_Metadata) meta_list.push_back((CAMFImporter_NodeElement_Metadata*)root_child);
|
||||||
|
}// for(const CAMFImporter_NodeElement* root_child: root_el->Child)
|
||||||
|
|
||||||
|
// at now we can add collected metadata to root node
|
||||||
|
Postprocess_AddMetadata(meta_list, *pScene->mRootNode);
|
||||||
|
//
|
||||||
|
// Check constellation children
|
||||||
|
//
|
||||||
|
// As said in specification:
|
||||||
|
// "When multiple objects and constellations are defined in a single file, only the top level objects and constellations are available for printing."
|
||||||
|
// What that means? For example: if some object is used in constellation then you must show only constellation but not original object.
|
||||||
|
// And at this step we are checking that relations.
|
||||||
|
nl_clean_loop:
|
||||||
|
|
||||||
|
if(node_list.size() > 1)
|
||||||
|
{
|
||||||
|
// walk through all nodes
|
||||||
|
for(std::list<aiNode*>::iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
|
||||||
|
{
|
||||||
|
// and try to find them in another top nodes.
|
||||||
|
std::list<aiNode*>::const_iterator next_it = nl_it;
|
||||||
|
|
||||||
|
next_it++;
|
||||||
|
for(; next_it != node_list.end(); next_it++)
|
||||||
|
{
|
||||||
|
if((*next_it)->FindNode((*nl_it)->mName) != nullptr)
|
||||||
|
{
|
||||||
|
// if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
|
||||||
|
node_list.erase(nl_it);
|
||||||
|
|
||||||
|
goto nl_clean_loop;
|
||||||
|
}
|
||||||
|
}// for(; next_it != node_list.end(); next_it++)
|
||||||
|
}// for(std::list<aiNode*>::const_iterator nl_it = node_list.begin(); nl_it != node_list.end(); nl_it++)
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// move created objects to aiScene
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Nodes
|
||||||
|
if(node_list.size() > 0)
|
||||||
|
{
|
||||||
|
std::list<aiNode*>::const_iterator nl_it = node_list.begin();
|
||||||
|
|
||||||
|
pScene->mRootNode->mNumChildren = static_cast<unsigned int>(node_list.size());
|
||||||
|
pScene->mRootNode->mChildren = new aiNode*[pScene->mRootNode->mNumChildren];
|
||||||
|
for(size_t i = 0; i < pScene->mRootNode->mNumChildren; i++)
|
||||||
|
{
|
||||||
|
// Objects and constellation that must be showed placed at top of hierarchy in <amf> node. So all aiNode's in node_list must have
|
||||||
|
// mRootNode only as parent.
|
||||||
|
(*nl_it)->mParent = pScene->mRootNode;
|
||||||
|
pScene->mRootNode->mChildren[i] = *nl_it++;
|
||||||
|
}
|
||||||
|
}// if(node_list.size() > 0)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Meshes
|
||||||
|
if(mesh_list.size() > 0)
|
||||||
|
{
|
||||||
|
std::list<aiMesh*>::const_iterator ml_it = mesh_list.begin();
|
||||||
|
|
||||||
|
pScene->mNumMeshes = static_cast<unsigned int>(mesh_list.size());
|
||||||
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||||
|
for(size_t i = 0; i < pScene->mNumMeshes; i++) pScene->mMeshes[i] = *ml_it++;
|
||||||
|
}// if(mesh_list.size() > 0)
|
||||||
|
|
||||||
|
//
|
||||||
|
// Textures
|
||||||
|
pScene->mNumTextures = static_cast<unsigned int>(mTexture_Converted.size());
|
||||||
|
if(pScene->mNumTextures > 0)
|
||||||
|
{
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
pScene->mTextures = new aiTexture*[pScene->mNumTextures];
|
||||||
|
for(const SPP_Texture& tex_convd: mTexture_Converted)
|
||||||
|
{
|
||||||
|
pScene->mTextures[idx] = new aiTexture;
|
||||||
|
pScene->mTextures[idx]->mWidth = static_cast<unsigned int>(tex_convd.Width);
|
||||||
|
pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
|
||||||
|
pScene->mTextures[idx]->pcData = (aiTexel*)tex_convd.Data;
|
||||||
|
// texture format description.
|
||||||
|
strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint);
|
||||||
|
idx++;
|
||||||
|
}// for(const SPP_Texture& tex_convd: mTexture_Converted)
|
||||||
|
|
||||||
|
// Create materials for embedded textures.
|
||||||
|
idx = 0;
|
||||||
|
pScene->mNumMaterials = static_cast<unsigned int>(mTexture_Converted.size());
|
||||||
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
|
||||||
|
for(const SPP_Texture& tex_convd: mTexture_Converted)
|
||||||
|
{
|
||||||
|
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx));
|
||||||
|
const int mode = aiTextureOp_Multiply;
|
||||||
|
const int repeat = tex_convd.Tiled ? 1 : 0;
|
||||||
|
|
||||||
|
pScene->mMaterials[idx] = new aiMaterial;
|
||||||
|
pScene->mMaterials[idx]->AddProperty(&texture_id, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
pScene->mMaterials[idx]->AddProperty(&mode, 1, AI_MATKEY_TEXOP_DIFFUSE(0));
|
||||||
|
pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_U_DIFFUSE(0));
|
||||||
|
pScene->mMaterials[idx]->AddProperty(&repeat, 1, AI_MATKEY_MAPPINGMODE_V_DIFFUSE(0));
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}// if(pScene->mNumTextures > 0)
|
||||||
|
}// END: after that walk through children of root and collect data
|
||||||
|
|
||||||
|
}// namespace Assimp
|
||||||
|
|
||||||
|
#endif // !ASSIMP_BUILD_NO_AMF_IMPORTER
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the ASE importer class
|
* @brief Implementation of the ASE importer class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
@ -51,6 +50,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
#include "SkeletonMeshBuilder.h"
|
#include "SkeletonMeshBuilder.h"
|
||||||
#include "TargetAnimation.h"
|
#include "TargetAnimation.h"
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
// utilities
|
// utilities
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
|
@ -74,7 +79,11 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
ASEImporter::ASEImporter()
|
ASEImporter::ASEImporter()
|
||||||
: noSkeletonMesh()
|
: mParser(),
|
||||||
|
mBuffer(),
|
||||||
|
pcScene(),
|
||||||
|
configRecomputeNormals(),
|
||||||
|
noSkeletonMesh()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -121,7 +130,7 @@ void ASEImporter::SetupProperties(const Importer* pImp)
|
||||||
void ASEImporter::InternReadFile( const std::string& pFile,
|
void ASEImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file.get() == NULL) {
|
if( file.get() == NULL) {
|
||||||
|
@ -216,17 +225,13 @@ void ASEImporter::InternReadFile( const std::string& pFile,
|
||||||
+ mParser->m_vCameras.size() + mParser->m_vDummies.size());
|
+ mParser->m_vCameras.size() + mParser->m_vDummies.size());
|
||||||
|
|
||||||
// Lights
|
// Lights
|
||||||
for (std::vector<ASE::Light>::iterator it = mParser->m_vLights.begin(),
|
for (auto &light : mParser->m_vLights)nodes.push_back(&light);
|
||||||
end = mParser->m_vLights.end();it != end; ++it)nodes.push_back(&(*it));
|
|
||||||
// Cameras
|
// Cameras
|
||||||
for (std::vector<ASE::Camera>::iterator it = mParser->m_vCameras.begin(),
|
for (auto &camera : mParser->m_vCameras)nodes.push_back(&camera);
|
||||||
end = mParser->m_vCameras.end();it != end; ++it)nodes.push_back(&(*it));
|
|
||||||
// Meshes
|
// Meshes
|
||||||
for (std::vector<ASE::Mesh>::iterator it = mParser->m_vMeshes.begin(),
|
for (auto &mesh : mParser->m_vMeshes)nodes.push_back(&mesh);
|
||||||
end = mParser->m_vMeshes.end();it != end; ++it)nodes.push_back(&(*it));
|
|
||||||
// Dummies
|
// Dummies
|
||||||
for (std::vector<ASE::Dummy>::iterator it = mParser->m_vDummies.begin(),
|
for (auto &dummy : mParser->m_vDummies)nodes.push_back(&dummy);
|
||||||
end = mParser->m_vDummies.end();it != end; ++it)nodes.push_back(&(*it));
|
|
||||||
|
|
||||||
// build the final node graph
|
// build the final node graph
|
||||||
BuildNodes(nodes);
|
BuildNodes(nodes);
|
||||||
|
@ -648,8 +653,8 @@ void ASEImporter::BuildNodes(std::vector<BaseNode*>& nodes) {
|
||||||
ch->mParent = root;
|
ch->mParent = root;
|
||||||
|
|
||||||
// Change the transformation matrix of all nodes
|
// Change the transformation matrix of all nodes
|
||||||
for (std::vector<BaseNode*>::iterator it = nodes.begin(), end = nodes.end();it != end; ++it) {
|
for (BaseNode *node : nodes) {
|
||||||
aiMatrix4x4& m = (*it)->mTransform;
|
aiMatrix4x4& m = node->mTransform;
|
||||||
m.Transpose(); // row-order vs column-order
|
m.Transpose(); // row-order vs column-order
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -814,10 +819,10 @@ void CopyASETexture(aiMaterial& mat, ASE::Texture& texture, aiTextureType type)
|
||||||
|
|
||||||
// Setup the texture blend factor
|
// Setup the texture blend factor
|
||||||
if (is_not_qnan(texture.mTextureBlend))
|
if (is_not_qnan(texture.mTextureBlend))
|
||||||
mat.AddProperty<float>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
mat.AddProperty<ai_real>( &texture.mTextureBlend, 1, AI_MATKEY_TEXBLEND(type,0));
|
||||||
|
|
||||||
// Setup texture UV transformations
|
// Setup texture UV transformations
|
||||||
mat.AddProperty<float>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
|
mat.AddProperty<ai_real>(&texture.mOffsetU,5,AI_MATKEY_UVTRANSFORM(type,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -860,7 +865,7 @@ void ASEImporter::ConvertMaterial(ASE::Material& mat)
|
||||||
}
|
}
|
||||||
|
|
||||||
// opacity
|
// opacity
|
||||||
mat.pcInstance->AddProperty<float>( &mat.mTransparency,1,AI_MATKEY_OPACITY);
|
mat.pcInstance->AddProperty<ai_real>( &mat.mTransparency,1,AI_MATKEY_OPACITY);
|
||||||
|
|
||||||
// Two sided rendering?
|
// Two sided rendering?
|
||||||
if (mat.mTwoSided)
|
if (mat.mTwoSided)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_ASELOADER_H_INCLUDED
|
#define AI_ASELOADER_H_INCLUDED
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
|
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
#include "ASEParser.h"
|
#include "ASEParser.h"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -25,8 +25,8 @@ conditions are met:
|
||||||
derived from this software without specific prior
|
derived from this software without specific prior
|
||||||
written permission of the assimp team.
|
written permission of the assimp team.
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the ASE parser class
|
* @brief Implementation of the ASE parser class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
|
@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "ASELoader.h"
|
#include "ASELoader.h"
|
||||||
#include "MaterialSystem.h"
|
#include "MaterialSystem.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace Assimp::ASE;
|
using namespace Assimp::ASE;
|
||||||
|
@ -142,9 +143,9 @@ void Parser::LogWarning(const char* szWarn)
|
||||||
|
|
||||||
char szTemp[1024];
|
char szTemp[1024];
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
|
sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn);
|
||||||
#else
|
#else
|
||||||
snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
|
ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// output the warning to the logger ...
|
// output the warning to the logger ...
|
||||||
|
@ -158,9 +159,9 @@ void Parser::LogInfo(const char* szWarn)
|
||||||
|
|
||||||
char szTemp[1024];
|
char szTemp[1024];
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
|
sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
|
||||||
#else
|
#else
|
||||||
snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
|
ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// output the information to the logger ...
|
// output the information to the logger ...
|
||||||
|
@ -168,15 +169,15 @@ void Parser::LogInfo(const char* szWarn)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::LogError(const char* szWarn)
|
AI_WONT_RETURN void Parser::LogError(const char* szWarn)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != szWarn);
|
ai_assert(NULL != szWarn);
|
||||||
|
|
||||||
char szTemp[1024];
|
char szTemp[1024];
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
sprintf_s(szTemp,"Line %i: %s",iLineNumber,szWarn);
|
sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
|
||||||
#else
|
#else
|
||||||
snprintf(szTemp,1024,"Line %i: %s",iLineNumber,szWarn);
|
ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// throw an exception
|
// throw an exception
|
||||||
|
@ -430,7 +431,7 @@ void Parser::ParseLV1SoftSkinBlock()
|
||||||
ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
|
ParseString(bone,"*MESH_SOFTSKINVERTS.Bone");
|
||||||
|
|
||||||
// Find the bone in the mesh's list
|
// Find the bone in the mesh's list
|
||||||
std::pair<int,float> me;
|
std::pair<int,ai_real> me;
|
||||||
me.first = -1;
|
me.first = -1;
|
||||||
|
|
||||||
for (unsigned int n = 0; n < curMesh->mBones.size();++n)
|
for (unsigned int n = 0; n < curMesh->mBones.size();++n)
|
||||||
|
@ -617,12 +618,13 @@ void Parser::ParseLV2MaterialBlock(ASE::Material& mat)
|
||||||
if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
|
if (TokenMatch(filePtr,"MATERIAL_TRANSPARENCY",21))
|
||||||
{
|
{
|
||||||
ParseLV4MeshFloat(mat.mTransparency);
|
ParseLV4MeshFloat(mat.mTransparency);
|
||||||
mat.mTransparency = 1.0f - mat.mTransparency;continue;
|
mat.mTransparency = ai_real( 1.0 ) - mat.mTransparency;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
// material self illumination
|
// material self illumination
|
||||||
if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
|
if (TokenMatch(filePtr,"MATERIAL_SELFILLUM",18))
|
||||||
{
|
{
|
||||||
float f = 0.0f;
|
ai_real f = 0.0;
|
||||||
ParseLV4MeshFloat(f);
|
ParseLV4MeshFloat(f);
|
||||||
|
|
||||||
mat.mEmissive.r = f;
|
mat.mEmissive.r = f;
|
||||||
|
@ -824,7 +826,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
|
||||||
if (!SkipSpaces(&filePtr))
|
if (!SkipSpaces(&filePtr))
|
||||||
{
|
{
|
||||||
|
|
||||||
sprintf(szBuffer,"Unable to parse %s block: Unexpected EOL",szName);
|
ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Unexpected EOL",szName);
|
||||||
LogWarning(szBuffer);
|
LogWarning(szBuffer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -832,7 +834,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
|
||||||
if ('\"' != *filePtr)
|
if ('\"' != *filePtr)
|
||||||
{
|
{
|
||||||
|
|
||||||
sprintf(szBuffer,"Unable to parse %s block: Strings are expected "
|
ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected "
|
||||||
"to be enclosed in double quotation marks",szName);
|
"to be enclosed in double quotation marks",szName);
|
||||||
LogWarning(szBuffer);
|
LogWarning(szBuffer);
|
||||||
return false;
|
return false;
|
||||||
|
@ -844,7 +846,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
|
||||||
if ('\"' == *sz)break;
|
if ('\"' == *sz)break;
|
||||||
else if ('\0' == *sz)
|
else if ('\0' == *sz)
|
||||||
{
|
{
|
||||||
sprintf(szBuffer,"Unable to parse %s block: Strings are expected to "
|
ai_snprintf(szBuffer, 1024, "Unable to parse %s block: Strings are expected to "
|
||||||
"be enclosed in double quotation marks but EOF was reached before "
|
"be enclosed in double quotation marks but EOF was reached before "
|
||||||
"a closing quotation mark was encountered",szName);
|
"a closing quotation mark was encountered",szName);
|
||||||
LogWarning(szBuffer);
|
LogWarning(szBuffer);
|
||||||
|
@ -1133,7 +1135,7 @@ void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
|
||||||
// For the moment we're just reading the three floats -
|
// For the moment we're just reading the three floats -
|
||||||
// we ignore the ádditional information for bezier's and TCBs
|
// we ignore the additional information for bezier's and TCBs
|
||||||
|
|
||||||
// simple scaling keyframe
|
// simple scaling keyframe
|
||||||
if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
|
if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
|
||||||
|
@ -1179,7 +1181,7 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
|
||||||
// For the moment we're just reading the three floats -
|
// For the moment we're just reading the three floats -
|
||||||
// we ignore the ádditional information for bezier's and TCBs
|
// we ignore the additional information for bezier's and TCBs
|
||||||
|
|
||||||
// simple scaling keyframe
|
// simple scaling keyframe
|
||||||
if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
|
if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
|
||||||
|
@ -1225,7 +1227,7 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
|
||||||
bool b = false;
|
bool b = false;
|
||||||
|
|
||||||
// For the moment we're just reading the floats -
|
// For the moment we're just reading the floats -
|
||||||
// we ignore the ádditional information for bezier's and TCBs
|
// we ignore the additional information for bezier's and TCBs
|
||||||
|
|
||||||
// simple scaling keyframe
|
// simple scaling keyframe
|
||||||
if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))
|
if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))
|
||||||
|
@ -1250,7 +1252,7 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
|
||||||
{
|
{
|
||||||
anim.akeyRotations.push_back(aiQuatKey());
|
anim.akeyRotations.push_back(aiQuatKey());
|
||||||
aiQuatKey& key = anim.akeyRotations.back();
|
aiQuatKey& key = anim.akeyRotations.back();
|
||||||
aiVector3D v;float f;
|
aiVector3D v;ai_real f;
|
||||||
ParseLV4MeshFloatTriple(&v.x,iIndex);
|
ParseLV4MeshFloatTriple(&v.x,iIndex);
|
||||||
ParseLV4MeshFloat(f);
|
ParseLV4MeshFloat(f);
|
||||||
key.mTime = (double)iIndex;
|
key.mTime = (double)iIndex;
|
||||||
|
@ -1462,31 +1464,30 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// another mesh UV channel ...
|
// another mesh UV channel ...
|
||||||
if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19))
|
if (TokenMatch(filePtr,"MESH_MAPPINGCHANNEL" ,19)) {
|
||||||
{
|
unsigned int iIndex( 0 );
|
||||||
|
|
||||||
unsigned int iIndex = 0;
|
|
||||||
ParseLV4MeshLong(iIndex);
|
ParseLV4MeshLong(iIndex);
|
||||||
|
if ( 0 == iIndex ) {
|
||||||
if (iIndex < 2)
|
LogWarning( "Mapping channel has an invalid index. Skipping UV channel" );
|
||||||
{
|
// skip it ...
|
||||||
LogWarning("Mapping channel has an invalid index. Skipping UV channel");
|
SkipSection();
|
||||||
|
} else {
|
||||||
|
if ( iIndex < 2 ) {
|
||||||
|
LogWarning( "Mapping channel has an invalid index. Skipping UV channel" );
|
||||||
// skip it ...
|
// skip it ...
|
||||||
SkipSection();
|
SkipSection();
|
||||||
}
|
}
|
||||||
if (iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS)
|
if ( iIndex > AI_MAX_NUMBER_OF_TEXTURECOORDS ) {
|
||||||
{
|
LogWarning( "Too many UV channels specified. Skipping channel .." );
|
||||||
LogWarning("Too many UV channels specified. Skipping channel ..");
|
|
||||||
// skip it ...
|
// skip it ...
|
||||||
SkipSection();
|
SkipSection();
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
// parse the mapping channel
|
// parse the mapping channel
|
||||||
ParseLV3MappingChannel(iIndex-1,mesh);
|
ParseLV3MappingChannel( iIndex - 1, mesh );
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// mesh animation keyframe. Not supported
|
// mesh animation keyframe. Not supported
|
||||||
if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
|
if (TokenMatch(filePtr,"MESH_ANIMATION" ,14))
|
||||||
{
|
{
|
||||||
|
@ -1525,7 +1526,7 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh& mesh)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Number of bones
|
// Number of bones
|
||||||
if (TokenMatch(filePtr,"MESH_NUMBONE" ,11))
|
if (TokenMatch(filePtr,"MESH_NUMBONE" ,12))
|
||||||
{
|
{
|
||||||
ParseLV4MeshLong(iNumBones);
|
ParseLV4MeshLong(iNumBones);
|
||||||
continue;
|
continue;
|
||||||
|
@ -1559,7 +1560,7 @@ void Parser::ParseLV4MeshBones(unsigned int iNumBones,ASE::Mesh& mesh)
|
||||||
++filePtr;
|
++filePtr;
|
||||||
|
|
||||||
// Mesh bone with name ...
|
// Mesh bone with name ...
|
||||||
if (TokenMatch(filePtr,"MESH_BONE_NAME" ,16))
|
if (TokenMatch(filePtr,"MESH_BONE_NAME" ,14))
|
||||||
{
|
{
|
||||||
// parse an index ...
|
// parse an index ...
|
||||||
if(SkipSpaces(&filePtr))
|
if(SkipSpaces(&filePtr))
|
||||||
|
@ -1603,7 +1604,7 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices,ASE::Mesh& mesh
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- ignored
|
// --- ignored
|
||||||
float afVert[3];
|
ai_real afVert[3];
|
||||||
ParseLV4MeshFloatTriple(afVert);
|
ParseLV4MeshFloatTriple(afVert);
|
||||||
|
|
||||||
std::pair<int,float> pairOut;
|
std::pair<int,float> pairOut;
|
||||||
|
@ -2101,7 +2102,7 @@ void Parser::ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut
|
||||||
ParseLV4MeshLongTriple(apOut);
|
ParseLV4MeshLongTriple(apOut);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
|
void Parser::ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != apOut);
|
ai_assert(NULL != apOut);
|
||||||
|
|
||||||
|
@ -2112,7 +2113,7 @@ void Parser::ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut)
|
||||||
ParseLV4MeshFloatTriple(apOut);
|
ParseLV4MeshFloatTriple(apOut);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFloatTriple(float* apOut)
|
void Parser::ParseLV4MeshFloatTriple(ai_real* apOut)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != apOut);
|
ai_assert(NULL != apOut);
|
||||||
|
|
||||||
|
@ -2120,19 +2121,19 @@ void Parser::ParseLV4MeshFloatTriple(float* apOut)
|
||||||
ParseLV4MeshFloat(apOut[i]);
|
ParseLV4MeshFloat(apOut[i]);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshFloat(float& fOut)
|
void Parser::ParseLV4MeshFloat(ai_real& fOut)
|
||||||
{
|
{
|
||||||
// skip spaces and tabs
|
// skip spaces and tabs
|
||||||
if(!SkipSpaces(&filePtr))
|
if(!SkipSpaces(&filePtr))
|
||||||
{
|
{
|
||||||
// LOG
|
// LOG
|
||||||
LogWarning("Unable to parse float: unexpected EOL [#1]");
|
LogWarning("Unable to parse float: unexpected EOL [#1]");
|
||||||
fOut = 0.0f;
|
fOut = 0.0;
|
||||||
++iLineNumber;
|
++iLineNumber;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// parse the first float
|
// parse the first float
|
||||||
filePtr = fast_atoreal_move<float>(filePtr,fOut);
|
filePtr = fast_atoreal_move<ai_real>(filePtr,fOut);
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Parser::ParseLV4MeshLong(unsigned int& iOut)
|
void Parser::ParseLV4MeshLong(unsigned int& iOut)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,15 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_ASEFILEHELPER_H_INC
|
#ifndef AI_ASEFILEHELPER_H_INC
|
||||||
#define AI_ASEFILEHELPER_H_INC
|
#define AI_ASEFILEHELPER_H_INC
|
||||||
|
|
||||||
// STL/CRT headers
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
// public ASSIMP headers
|
// public ASSIMP headers
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
#include "../include/assimp/mesh.h"
|
#include <assimp/mesh.h>
|
||||||
#include "../include/assimp/anim.h"
|
#include <assimp/anim.h>
|
||||||
|
|
||||||
// for some helper routines like IsSpace()
|
// for some helper routines like IsSpace()
|
||||||
#include "ParsingUtils.h"
|
#include "ParsingUtils.h"
|
||||||
|
@ -133,12 +128,12 @@ struct Bone
|
||||||
|
|
||||||
// Generate a default name for the bone
|
// Generate a default name for the bone
|
||||||
char szTemp[128];
|
char szTemp[128];
|
||||||
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Construction from an existing name
|
//! Construction from an existing name
|
||||||
Bone( const std::string& name)
|
explicit Bone( const std::string& name)
|
||||||
: mName (name)
|
: mName (name)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -216,18 +211,18 @@ struct BaseNode
|
||||||
enum Type {Light, Camera, Mesh, Dummy} mType;
|
enum Type {Light, Camera, Mesh, Dummy} mType;
|
||||||
|
|
||||||
//! Constructor. Creates a default name for the node
|
//! Constructor. Creates a default name for the node
|
||||||
BaseNode(Type _mType)
|
explicit BaseNode(Type _mType)
|
||||||
: mType (_mType)
|
: mType (_mType)
|
||||||
, mProcessed (false)
|
, mProcessed (false)
|
||||||
{
|
{
|
||||||
// generate a default name for the node
|
// generate a default name for the node
|
||||||
static int iCnt = 0;
|
static int iCnt = 0;
|
||||||
char szTemp[128]; // should be sufficiently large
|
char szTemp[128]; // should be sufficiently large
|
||||||
::sprintf(szTemp,"UNNAMED_%i",iCnt++);
|
::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
|
||||||
mName = szTemp;
|
mName = szTemp;
|
||||||
|
|
||||||
// Set mTargetPosition to qnan
|
// Set mTargetPosition to qnan
|
||||||
const float qnan = get_qnan();
|
const ai_real qnan = get_qnan();
|
||||||
mTargetPosition.x = qnan;
|
mTargetPosition.x = qnan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,9 +317,9 @@ struct Light : public BaseNode
|
||||||
|
|
||||||
LightType mLightType;
|
LightType mLightType;
|
||||||
aiColor3D mColor;
|
aiColor3D mColor;
|
||||||
float mIntensity;
|
ai_real mIntensity;
|
||||||
float mAngle; // in degrees
|
ai_real mAngle; // in degrees
|
||||||
float mFalloff;
|
ai_real mFalloff;
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
@ -347,7 +342,7 @@ struct Camera : public BaseNode
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
float mFOV, mNear, mFar;
|
ai_real mFOV, mNear, mFar;
|
||||||
CameraType mCameraType;
|
CameraType mCameraType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -549,13 +544,13 @@ private:
|
||||||
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
|
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
|
||||||
//! \param apOut Output buffer (3 floats)
|
//! \param apOut Output buffer (3 floats)
|
||||||
//! \param rIndexOut Output index
|
//! \param rIndexOut Output index
|
||||||
void ParseLV4MeshFloatTriple(float* apOut, unsigned int& rIndexOut);
|
void ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a *MESH_VERT block in a file
|
//! Parse a *MESH_VERT block in a file
|
||||||
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
|
//! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL ...)
|
||||||
//! \param apOut Output buffer (3 floats)
|
//! \param apOut Output buffer (3 floats)
|
||||||
void ParseLV4MeshFloatTriple(float* apOut);
|
void ParseLV4MeshFloatTriple(ai_real* apOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a *MESH_TFACE block in a file
|
//! Parse a *MESH_TFACE block in a file
|
||||||
|
@ -573,7 +568,7 @@ private:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a single float element
|
//! Parse a single float element
|
||||||
//! \param fOut Output float
|
//! \param fOut Output float
|
||||||
void ParseLV4MeshFloat(float& fOut);
|
void ParseLV4MeshFloat(ai_real& fOut);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a single int element
|
//! Parse a single int element
|
||||||
|
@ -602,14 +597,14 @@ private:
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Output an error to the logger
|
//! Output an error to the logger
|
||||||
//! \param szWarn Error message
|
//! \param szWarn Error message
|
||||||
void LogError(const char* szWarn);
|
AI_WONT_RETURN void LogError(const char* szWarn) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
//! Parse a string, enclosed in double quotation marks
|
//! Parse a string, enclosed in double quotation marks
|
||||||
//! \param out Output string
|
//! \param out Output string
|
||||||
//! \param szName Name of the enclosing element -> used in error
|
//! \param szName Name of the enclosing element -> used in error
|
||||||
//! messages.
|
//! messages.
|
||||||
//! \return false if an error occured
|
//! \return false if an error occurred
|
||||||
bool ParseString(std::string& out,const char* szName);
|
bool ParseString(std::string& out,const char* szName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -40,10 +40,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file AssbinExporter.cpp
|
/** @file AssbinExporter.cpp
|
||||||
* ASSBIN exporter main code
|
* ASSBIN exporter main code
|
||||||
*/
|
*/
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#include "assbin_chunks.h"
|
#include "assbin_chunks.h"
|
||||||
#include "./../include/assimp/version.h"
|
#include <assimp/version.h>
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
|
#include "Exceptional.h"
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
# include <zlib.h>
|
# include <zlib.h>
|
||||||
|
@ -99,7 +102,7 @@ inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
|
inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT(sizeof(uint16_t)==2);
|
static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2");
|
||||||
stream->Write(&w,2,1);
|
stream->Write(&w,2,1);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -109,7 +112,7 @@ inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<float>(IOStream * stream, const float& f)
|
inline size_t Write<float>(IOStream * stream, const float& f)
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT(sizeof(float)==4);
|
static_assert(sizeof(float)==4, "sizeof(float)==4");
|
||||||
stream->Write(&f,4,1);
|
stream->Write(&f,4,1);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
@ -119,7 +122,7 @@ inline size_t Write<float>(IOStream * stream, const float& f)
|
||||||
template <>
|
template <>
|
||||||
inline size_t Write<double>(IOStream * stream, const double& f)
|
inline size_t Write<double>(IOStream * stream, const double& f)
|
||||||
{
|
{
|
||||||
BOOST_STATIC_ASSERT(sizeof(double)==8);
|
static_assert(sizeof(double)==8, "sizeof(double)==8");
|
||||||
stream->Write(&f,8,1);
|
stream->Write(&f,8,1);
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
@ -273,13 +276,13 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
if (buffer) delete[] buffer;
|
if (buffer) delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * GetBufferPointer() { return buffer; };
|
void * GetBufferPointer() { return buffer; }
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; };
|
virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; }
|
||||||
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; };
|
virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; }
|
||||||
virtual size_t Tell() const { return cursor; };
|
virtual size_t Tell() const { return cursor; }
|
||||||
virtual void Flush() { };
|
virtual void Flush() { }
|
||||||
|
|
||||||
virtual size_t FileSize() const
|
virtual size_t FileSize() const
|
||||||
{
|
{
|
||||||
|
@ -468,7 +471,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
uint32_t tmp = f.mNumIndices;
|
uint32_t tmp = f.mNumIndices;
|
||||||
hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
|
hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
|
||||||
for (unsigned int i = 0; i < f.mNumIndices; ++i) {
|
for (unsigned int i = 0; i < f.mNumIndices; ++i) {
|
||||||
BOOST_STATIC_ASSERT(AI_MAX_VERTICES <= 0xffffffff);
|
static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff");
|
||||||
tmp = static_cast<uint32_t>( f.mIndices[i] );
|
tmp = static_cast<uint32_t>( f.mIndices[i] );
|
||||||
hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
|
hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
|
||||||
}
|
}
|
||||||
|
@ -482,7 +485,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
|
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
|
||||||
const aiFace& f = mesh->mFaces[i];
|
const aiFace& f = mesh->mFaces[i];
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff);
|
static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
|
||||||
Write<uint16_t>(&chunk,f.mNumIndices);
|
Write<uint16_t>(&chunk,f.mNumIndices);
|
||||||
|
|
||||||
for (unsigned int a = 0; a < f.mNumIndices;++a) {
|
for (unsigned int a = 0; a < f.mNumIndices;++a) {
|
||||||
|
@ -698,7 +701,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
#if _MSC_VER >= 1400
|
#if _MSC_VER >= 1400
|
||||||
sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
|
sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
|
||||||
#else
|
#else
|
||||||
snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
|
ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
|
||||||
#endif
|
#endif
|
||||||
out->Write( s, 44, 1 );
|
out->Write( s, 44, 1 );
|
||||||
// == 44 bytes
|
// == 44 bytes
|
||||||
|
@ -734,7 +737,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
AssbinChunkWriter uncompressedStream( NULL, 0 );
|
AssbinChunkWriter uncompressedStream( NULL, 0 );
|
||||||
WriteBinaryScene( &uncompressedStream, pScene );
|
WriteBinaryScene( &uncompressedStream, pScene );
|
||||||
|
|
||||||
uLongf uncompressedSize = uncompressedStream.Tell();
|
uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
|
||||||
uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
|
uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
|
||||||
uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
|
uint8_t* compressedBuffer = new uint8_t[ compressedSize ];
|
||||||
|
|
||||||
|
@ -754,7 +757,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
AssbinExport exporter;
|
AssbinExport exporter;
|
||||||
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -45,17 +45,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* see assbin_chunks.h
|
* see assbin_chunks.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "AssbinLoader.h"
|
#include "AssbinLoader.h"
|
||||||
#include "assbin_chunks.h"
|
#include "assbin_chunks.h"
|
||||||
#include "MemoryIOWrapper.h"
|
#include "MemoryIOWrapper.h"
|
||||||
|
#include <assimp/mesh.h>
|
||||||
|
#include <assimp/anim.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
# include <zlib.h>
|
# include <zlib.h>
|
||||||
#else
|
#else
|
||||||
# include "../contrib/zlib/zlib.h"
|
# include <contrib/zlib/zlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -138,6 +141,7 @@ aiString Read<aiString>(IOStream * stream)
|
||||||
aiString s;
|
aiString s;
|
||||||
stream->Read(&s.length,4,1);
|
stream->Read(&s.length,4,1);
|
||||||
stream->Read(s.data,s.length,1);
|
stream->Read(s.data,s.length,1);
|
||||||
|
s.data[s.length] = 0;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +198,8 @@ template <typename T> void ReadBounds( IOStream * stream, T* /*p*/, unsigned int
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node )
|
void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AINODE);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AINODE);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
*node = new aiNode();
|
*node = new aiNode();
|
||||||
|
@ -225,7 +230,8 @@ void AssbinImporter::ReadBinaryNode( IOStream * stream, aiNode** node )
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIBONE );
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AIBONE);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
b->mName = Read<aiString>(stream);
|
b->mName = Read<aiString>(stream);
|
||||||
|
@ -248,7 +254,8 @@ void AssbinImporter::ReadBinaryBone( IOStream * stream, aiBone* b )
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIMESH);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AIMESH);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
mesh->mPrimitiveTypes = Read<unsigned int>(stream);
|
mesh->mPrimitiveTypes = Read<unsigned int>(stream);
|
||||||
|
@ -343,7 +350,7 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
|
for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
|
||||||
aiFace& f = mesh->mFaces[i];
|
aiFace& f = mesh->mFaces[i];
|
||||||
|
|
||||||
BOOST_STATIC_ASSERT(AI_MAX_FACE_INDICES <= 0xffff);
|
static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
|
||||||
f.mNumIndices = Read<uint16_t>(stream);
|
f.mNumIndices = Read<uint16_t>(stream);
|
||||||
f.mIndices = new unsigned int[f.mNumIndices];
|
f.mIndices = new unsigned int[f.mNumIndices];
|
||||||
|
|
||||||
|
@ -372,7 +379,8 @@ void AssbinImporter::ReadBinaryMesh( IOStream * stream, aiMesh* mesh )
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
|
void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialProperty* prop)
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIMATERIALPROPERTY);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIALPROPERTY);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
prop->mKey = Read<aiString>(stream);
|
prop->mKey = Read<aiString>(stream);
|
||||||
|
@ -388,7 +396,8 @@ void AssbinImporter::ReadBinaryMaterialProperty(IOStream * stream, aiMaterialPro
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIMATERIAL);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AIMATERIAL);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
|
mat->mNumAllocated = mat->mNumProperties = Read<unsigned int>(stream);
|
||||||
|
@ -409,7 +418,8 @@ void AssbinImporter::ReadBinaryMaterial(IOStream * stream, aiMaterial* mat)
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AINODEANIM);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AINODEANIM);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
nd->mNodeName = Read<aiString>(stream);
|
nd->mNodeName = Read<aiString>(stream);
|
||||||
|
@ -457,7 +467,8 @@ void AssbinImporter::ReadBinaryNodeAnim(IOStream * stream, aiNodeAnim* nd)
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AIANIMATION);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AIANIMATION);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
anim->mName = Read<aiString> (stream);
|
anim->mName = Read<aiString> (stream);
|
||||||
|
@ -477,7 +488,8 @@ void AssbinImporter::ReadBinaryAnim( IOStream * stream, aiAnimation* anim )
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AITEXTURE);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AITEXTURE);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
tex->mWidth = Read<unsigned int>(stream);
|
tex->mWidth = Read<unsigned int>(stream);
|
||||||
|
@ -500,7 +512,8 @@ void AssbinImporter::ReadBinaryTexture(IOStream * stream, aiTexture* tex)
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AILIGHT);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AILIGHT);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
l->mName = Read<aiString>(stream);
|
l->mName = Read<aiString>(stream);
|
||||||
|
@ -526,7 +539,8 @@ void AssbinImporter::ReadBinaryLight( IOStream * stream, aiLight* l )
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AICAMERA);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AICAMERA);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
cam->mName = Read<aiString>(stream);
|
cam->mName = Read<aiString>(stream);
|
||||||
|
@ -541,7 +555,8 @@ void AssbinImporter::ReadBinaryCamera( IOStream * stream, aiCamera* cam )
|
||||||
|
|
||||||
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
void AssbinImporter::ReadBinaryScene( IOStream * stream, aiScene* scene )
|
||||||
{
|
{
|
||||||
ai_assert( Read<uint32_t>(stream) == ASSBIN_CHUNK_AISCENE);
|
uint32_t chunkID = Read<uint32_t>(stream);
|
||||||
|
ai_assert(chunkID == ASSBIN_CHUNK_AISCENE);
|
||||||
/*uint32_t size =*/ Read<uint32_t>(stream);
|
/*uint32_t size =*/ Read<uint32_t>(stream);
|
||||||
|
|
||||||
scene->mFlags = Read<unsigned int>(stream);
|
scene->mFlags = Read<unsigned int>(stream);
|
||||||
|
@ -644,7 +659,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
if (compressed)
|
if (compressed)
|
||||||
{
|
{
|
||||||
uLongf uncompressedSize = Read<uint32_t>(stream);
|
uLongf uncompressedSize = Read<uint32_t>(stream);
|
||||||
uLongf compressedSize = stream->FileSize() - stream->Tell();
|
uLongf compressedSize = static_cast<uLongf>(stream->FileSize() - stream->Tell());
|
||||||
|
|
||||||
unsigned char * compressedData = new unsigned char[ compressedSize ];
|
unsigned char * compressedData = new unsigned char[ compressedSize ];
|
||||||
stream->Read( compressedData, 1, compressedSize );
|
stream->Read( compressedData, 1, compressedSize );
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,7 +46,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_ASSBINIMPORTER_H_INC
|
#define AI_ASSBINIMPORTER_H_INC
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
|
|
||||||
|
struct aiMesh;
|
||||||
|
struct aiNode;
|
||||||
|
struct aiBone;
|
||||||
|
struct aiMaterial;
|
||||||
|
struct aiMaterialProperty;
|
||||||
|
struct aiNodeAnim;
|
||||||
|
struct aiAnimation;
|
||||||
|
struct aiTexture;
|
||||||
|
struct aiLight;
|
||||||
|
struct aiCamera;
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSBIN_IMPORTER
|
||||||
|
|
||||||
|
|
151
code/Assimp.cpp
151
code/Assimp.cpp
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -42,17 +42,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the Plain-C API
|
* @brief Implementation of the Plain-C API
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
#include <assimp/cimport.h>
|
||||||
#include "../include/assimp/cimport.h"
|
#include <assimp/LogStream.hpp>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/importerdesc.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
#include "GenericProperty.h"
|
#include "GenericProperty.h"
|
||||||
#include "CInterfaceIOWrapper.h"
|
#include "CInterfaceIOWrapper.h"
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
|
#include "Exceptional.h"
|
||||||
|
#include "ScenePrivate.h"
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include <list>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
# include <boost/thread/thread.hpp>
|
# include <thread>
|
||||||
# include <boost/thread/mutex.hpp>
|
# include <mutex>
|
||||||
#endif
|
#endif
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
@ -84,12 +92,18 @@ namespace Assimp
|
||||||
|
|
||||||
/** Verbose logging active or not? */
|
/** Verbose logging active or not? */
|
||||||
static aiBool gVerboseLogging = false;
|
static aiBool gVerboseLogging = false;
|
||||||
}
|
|
||||||
|
/** will return all registered importers. */
|
||||||
|
void GetImporterInstanceList(std::vector< BaseImporter* >& out);
|
||||||
|
|
||||||
|
/** will delete all registered importers. */
|
||||||
|
void DeleteImporterInstanceList(std::vector< BaseImporter* >& out);
|
||||||
|
} // namespace assimp
|
||||||
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
/** Global mutex to manage the access to the logstream map */
|
/** Global mutex to manage the access to the log-stream map */
|
||||||
static boost::mutex gLogStreamMutex;
|
static std::mutex gLogStreamMutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,14 +112,14 @@ static boost::mutex gLogStreamMutex;
|
||||||
class LogToCallbackRedirector : public LogStream
|
class LogToCallbackRedirector : public LogStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LogToCallbackRedirector(const aiLogStream& s)
|
explicit LogToCallbackRedirector(const aiLogStream& s)
|
||||||
: stream (s) {
|
: stream (s) {
|
||||||
ai_assert(NULL != s.callback);
|
ai_assert(NULL != s.callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
~LogToCallbackRedirector() {
|
~LogToCallbackRedirector() {
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
// (HACK) Check whether the 'stream.user' pointer points to a
|
// (HACK) Check whether the 'stream.user' pointer points to a
|
||||||
// custom LogStream allocated by #aiGetPredefinedLogStream.
|
// custom LogStream allocated by #aiGetPredefinedLogStream.
|
||||||
|
@ -136,7 +150,7 @@ void ReportSceneNotFoundError()
|
||||||
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
|
DefaultLogger::get()->error("Unable to find the Assimp::Importer for this aiScene. "
|
||||||
"The C-API does not accept scenes produced by the C++ API and vice versa");
|
"The C-API does not accept scenes produced by the C++ API and vice versa");
|
||||||
|
|
||||||
assert(false);
|
ai_assert(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -216,7 +230,8 @@ const aiScene* aiImportFileFromMemoryWithProperties(
|
||||||
const char* pHint,
|
const char* pHint,
|
||||||
const aiPropertyStore* props)
|
const aiPropertyStore* props)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pBuffer && 0 != pLength);
|
ai_assert( NULL != pBuffer );
|
||||||
|
ai_assert( 0 != pLength );
|
||||||
|
|
||||||
const aiScene* scene = NULL;
|
const aiScene* scene = NULL;
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
@ -305,10 +320,38 @@ ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API const aiScene *aiApplyCustomizedPostProcessing( const aiScene *scene,
|
||||||
|
BaseProcess* process,
|
||||||
|
bool requestValidation ) {
|
||||||
|
const aiScene* sc( NULL );
|
||||||
|
|
||||||
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
|
// find the importer associated with this data
|
||||||
|
const ScenePrivateData* priv = ScenePriv( scene );
|
||||||
|
if ( NULL == priv || NULL == priv->mOrigImporter ) {
|
||||||
|
ReportSceneNotFoundError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sc = priv->mOrigImporter->ApplyCustomizedPostProcessing( process, requestValidation );
|
||||||
|
|
||||||
|
if ( !sc ) {
|
||||||
|
aiReleaseImport( scene );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIMP_END_EXCEPTION_REGION( const aiScene* );
|
||||||
|
|
||||||
|
return sc;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void CallbackToLogRedirector (const char* msg, char* dt)
|
void CallbackToLogRedirector (const char* msg, char* dt)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != msg && NULL != dt);
|
ai_assert( NULL != msg );
|
||||||
|
ai_assert( NULL != dt );
|
||||||
LogStream* s = (LogStream*)dt;
|
LogStream* s = (LogStream*)dt;
|
||||||
|
|
||||||
s->write(msg);
|
s->write(msg);
|
||||||
|
@ -340,7 +383,7 @@ ASSIMP_API void aiAttachLogStream( const aiLogStream* stream )
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LogStream* lg = new LogToCallbackRedirector(*stream);
|
LogStream* lg = new LogToCallbackRedirector(*stream);
|
||||||
|
@ -359,9 +402,9 @@ ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
// find the logstream associated with this data
|
// find the log-stream associated with this data
|
||||||
LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
|
LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
|
||||||
// it should be there... else the user is playing fools with us
|
// it should be there... else the user is playing fools with us
|
||||||
if( it == gActiveLogStreams.end()) {
|
if( it == gActiveLogStreams.end()) {
|
||||||
|
@ -384,14 +427,20 @@ ASSIMP_API void aiDetachAllLogStreams(void)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
#ifndef ASSIMP_BUILD_SINGLETHREADED
|
||||||
boost::mutex::scoped_lock lock(gLogStreamMutex);
|
std::lock_guard<std::mutex> lock(gLogStreamMutex);
|
||||||
#endif
|
#endif
|
||||||
|
Logger *logger( DefaultLogger::get() );
|
||||||
|
if ( NULL == logger ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
|
for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
|
||||||
DefaultLogger::get()->detatchStream( it->second );
|
logger->detatchStream( it->second );
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
gActiveLogStreams.clear();
|
gActiveLogStreams.clear();
|
||||||
DefaultLogger::kill();
|
DefaultLogger::kill();
|
||||||
|
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,6 +460,20 @@ const char* aiGetErrorString()
|
||||||
return gLastErrorString.c_str();
|
return gLastErrorString.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
// Return the description of a importer given its index
|
||||||
|
const aiImporterDesc* aiGetImportFormatDescription( size_t pIndex)
|
||||||
|
{
|
||||||
|
return Importer().GetImporterInfo(pIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------------------
|
||||||
|
// Return the number of importers
|
||||||
|
size_t aiGetImportFormatCount(void)
|
||||||
|
{
|
||||||
|
return Importer().GetImporterCount();
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns the error text of the last failed import process.
|
// Returns the error text of the last failed import process.
|
||||||
aiBool aiIsExtensionSupported(const char* szExtension)
|
aiBool aiIsExtensionSupported(const char* szExtension)
|
||||||
|
@ -465,7 +528,6 @@ ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
|
||||||
return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
|
return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
|
ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
|
||||||
{
|
{
|
||||||
|
@ -478,17 +540,17 @@ ASSIMP_API void aiSetImportPropertyInteger(aiPropertyStore* p, const char* szNam
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<int>(pp->ints,szName,value,NULL);
|
SetGenericProperty<int>(pp->ints,szName,value);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importer::SetPropertyFloat
|
// Importer::SetPropertyFloat
|
||||||
ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, float value)
|
ASSIMP_API void aiSetImportPropertyFloat(aiPropertyStore* p, const char* szName, ai_real value)
|
||||||
{
|
{
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<float>(pp->floats,szName,value,NULL);
|
SetGenericProperty<ai_real>(pp->floats,szName,value);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,7 +564,7 @@ ASSIMP_API void aiSetImportPropertyString(aiPropertyStore* p, const char* szName
|
||||||
}
|
}
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()),NULL);
|
SetGenericProperty<std::string>(pp->strings,szName,std::string(st->C_Str()));
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +578,7 @@ ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName
|
||||||
}
|
}
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
PropertyMap* pp = reinterpret_cast<PropertyMap*>(p);
|
||||||
SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat,NULL);
|
SetGenericProperty<aiMatrix4x4>(pp->matrices,szName,*mat);
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -524,7 +586,8 @@ ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName
|
||||||
// Rotation matrix to quaternion
|
// Rotation matrix to quaternion
|
||||||
ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
|
ASSIMP_API void aiCreateQuaternionFromMatrix(aiQuaternion* quat,const aiMatrix3x3* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != quat && NULL != mat);
|
ai_assert( NULL != quat );
|
||||||
|
ai_assert( NULL != mat );
|
||||||
*quat = aiQuaternion(*mat);
|
*quat = aiQuaternion(*mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -534,7 +597,10 @@ ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
|
||||||
aiQuaternion* rotation,
|
aiQuaternion* rotation,
|
||||||
aiVector3D* position)
|
aiVector3D* position)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != rotation && NULL != position && NULL != scaling && NULL != mat);
|
ai_assert( NULL != rotation );
|
||||||
|
ai_assert( NULL != position );
|
||||||
|
ai_assert( NULL != scaling );
|
||||||
|
ai_assert( NULL != mat );
|
||||||
mat->Decompose(*scaling,*rotation,*position);
|
mat->Decompose(*scaling,*rotation,*position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,7 +624,8 @@ ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
|
||||||
ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
|
ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
|
||||||
const aiMatrix3x3* mat)
|
const aiMatrix3x3* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat && NULL != vec);
|
ai_assert( NULL != mat );
|
||||||
|
ai_assert( NULL != vec);
|
||||||
*vec *= (*mat);
|
*vec *= (*mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +633,9 @@ ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
|
||||||
ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
|
ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
|
||||||
const aiMatrix4x4* mat)
|
const aiMatrix4x4* mat)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != mat && NULL != vec);
|
ai_assert( NULL != mat );
|
||||||
|
ai_assert( NULL != vec );
|
||||||
|
|
||||||
*vec *= (*mat);
|
*vec *= (*mat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -576,7 +645,8 @@ ASSIMP_API void aiMultiplyMatrix4(
|
||||||
aiMatrix4x4* dst,
|
aiMatrix4x4* dst,
|
||||||
const aiMatrix4x4* src)
|
const aiMatrix4x4* src)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != dst && NULL != src);
|
ai_assert( NULL != dst );
|
||||||
|
ai_assert( NULL != src );
|
||||||
*dst = (*dst) * (*src);
|
*dst = (*dst) * (*src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +655,8 @@ ASSIMP_API void aiMultiplyMatrix3(
|
||||||
aiMatrix3x3* dst,
|
aiMatrix3x3* dst,
|
||||||
const aiMatrix3x3* src)
|
const aiMatrix3x3* src)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != dst && NULL != src);
|
ai_assert( NULL != dst );
|
||||||
|
ai_assert( NULL != src );
|
||||||
*dst = (*dst) * (*src);
|
*dst = (*dst) * (*src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,4 +677,24 @@ ASSIMP_API void aiIdentityMatrix4(
|
||||||
*mat = aiMatrix4x4();
|
*mat = aiMatrix4x4();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) {
|
||||||
|
if( NULL == extension ) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const aiImporterDesc *desc( NULL );
|
||||||
|
std::vector< BaseImporter* > out;
|
||||||
|
GetImporterInstanceList( out );
|
||||||
|
for( size_t i = 0; i < out.size(); ++i ) {
|
||||||
|
if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) {
|
||||||
|
desc = out[ i ]->GetInfo();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteImporterInstanceList(out);
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
Assimp C export interface. See Exporter.cpp for some notes.
|
Assimp C export interface. See Exporter.cpp for some notes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#include "CInterfaceIOWrapper.h"
|
#include "CInterfaceIOWrapper.h"
|
||||||
#include "SceneCombiner.h"
|
#include "SceneCombiner.h"
|
||||||
|
#include "ScenePrivate.h"
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -59,13 +59,38 @@ ASSIMP_API size_t aiGetExportFormatCount(void)
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex)
|
ASSIMP_API const aiExportFormatDesc* aiGetExportFormatDescription( size_t index)
|
||||||
{
|
{
|
||||||
// Note: this is valid as the index always pertains to a builtin exporter,
|
// Note: this is valid as the index always pertains to a built-in exporter,
|
||||||
// for which the returned structure is guaranteed to be of static storage duration.
|
// for which the returned structure is guaranteed to be of static storage duration.
|
||||||
return Exporter().GetExportFormatDescription(pIndex);
|
Exporter exporter;
|
||||||
|
const aiExportFormatDesc* orig( exporter.GetExportFormatDescription( index ) );
|
||||||
|
if (NULL == orig) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
aiExportFormatDesc *desc = new aiExportFormatDesc;
|
||||||
|
desc->description = new char[ strlen( orig->description ) + 1 ]();
|
||||||
|
::strncpy( (char*) desc->description, orig->description, strlen( orig->description ) );
|
||||||
|
desc->fileExtension = new char[ strlen( orig->fileExtension ) + 1 ]();
|
||||||
|
::strncpy( ( char* ) desc->fileExtension, orig->fileExtension, strlen( orig->fileExtension ) );
|
||||||
|
desc->id = new char[ strlen( orig->id ) + 1 ]();
|
||||||
|
::strncpy( ( char* ) desc->id, orig->id, strlen( orig->id ) );
|
||||||
|
|
||||||
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
ASSIMP_API void aiReleaseExportFormatDescription( const aiExportFormatDesc *desc ) {
|
||||||
|
if (NULL == desc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete [] desc->description;
|
||||||
|
delete [] desc->fileExtension;
|
||||||
|
delete [] desc->id;
|
||||||
|
delete desc;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
ASSIMP_API void aiCopyScene(const aiScene* pIn, aiScene** pOut)
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
|
|
||||||
// Actually just a dummy, used by the compiler to build the precompiled header.
|
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#include "./../include/assimp/version.h"
|
|
||||||
|
|
||||||
static const unsigned int MajorVersion = 3;
|
|
||||||
static const unsigned int MinorVersion = 1;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------
|
|
||||||
// Legal information string - dont't remove this.
|
|
||||||
static const char* LEGAL_INFORMATION =
|
|
||||||
|
|
||||||
"Open Asset Import Library (Assimp).\n"
|
|
||||||
"A free C/C++ library to import various 3D file formats into applications\n\n"
|
|
||||||
|
|
||||||
"(c) 2008-2010, assimp team\n"
|
|
||||||
"License under the terms and conditions of the 3-clause BSD license\n"
|
|
||||||
"http://assimp.sourceforge.net\n"
|
|
||||||
;
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Get legal string
|
|
||||||
ASSIMP_API const char* aiGetLegalString () {
|
|
||||||
return LEGAL_INFORMATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Get Assimp minor version
|
|
||||||
ASSIMP_API unsigned int aiGetVersionMinor () {
|
|
||||||
return MinorVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Get Assimp major version
|
|
||||||
ASSIMP_API unsigned int aiGetVersionMajor () {
|
|
||||||
return MajorVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// Get flags used for compilation
|
|
||||||
ASSIMP_API unsigned int aiGetCompileFlags () {
|
|
||||||
|
|
||||||
unsigned int flags = 0;
|
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
|
|
||||||
flags |= ASSIMP_CFLAGS_NOBOOST;
|
|
||||||
#endif
|
|
||||||
#ifdef ASSIMP_BUILD_SINGLETHREADED
|
|
||||||
flags |= ASSIMP_CFLAGS_SINGLETHREADED;
|
|
||||||
#endif
|
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
|
||||||
flags |= ASSIMP_CFLAGS_DEBUG;
|
|
||||||
#endif
|
|
||||||
#ifdef ASSIMP_BUILD_DLL_EXPORT
|
|
||||||
flags |= ASSIMP_CFLAGS_SHARED;
|
|
||||||
#endif
|
|
||||||
#ifdef _STLPORT_VERSION
|
|
||||||
flags |= ASSIMP_CFLAGS_STLPORT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
// include current build revision, which is even updated from time to time -- :-)
|
|
||||||
#include "revision.h"
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
ASSIMP_API unsigned int aiGetVersionRevision ()
|
|
||||||
{
|
|
||||||
return GitVersion;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
ASSIMP_API aiScene::aiScene()
|
|
||||||
: mFlags(0)
|
|
||||||
, mRootNode(NULL)
|
|
||||||
, mNumMeshes(0)
|
|
||||||
, mMeshes(NULL)
|
|
||||||
, mNumMaterials(0)
|
|
||||||
, mMaterials(NULL)
|
|
||||||
, mNumAnimations(0)
|
|
||||||
, mAnimations(NULL)
|
|
||||||
, mNumTextures(0)
|
|
||||||
, mTextures(NULL)
|
|
||||||
, mNumLights(0)
|
|
||||||
, mLights(NULL)
|
|
||||||
, mNumCameras(0)
|
|
||||||
, mCameras(NULL)
|
|
||||||
, mPrivate(new Assimp::ScenePrivateData())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
ASSIMP_API aiScene::~aiScene()
|
|
||||||
{
|
|
||||||
// delete all sub-objects recursively
|
|
||||||
delete mRootNode;
|
|
||||||
|
|
||||||
// To make sure we won't crash if the data is invalid it's
|
|
||||||
// much better to check whether both mNumXXX and mXXX are
|
|
||||||
// valid instead of relying on just one of them.
|
|
||||||
if (mNumMeshes && mMeshes)
|
|
||||||
for( unsigned int a = 0; a < mNumMeshes; a++)
|
|
||||||
delete mMeshes[a];
|
|
||||||
delete [] mMeshes;
|
|
||||||
|
|
||||||
if (mNumMaterials && mMaterials)
|
|
||||||
for( unsigned int a = 0; a < mNumMaterials; a++)
|
|
||||||
delete mMaterials[a];
|
|
||||||
delete [] mMaterials;
|
|
||||||
|
|
||||||
if (mNumAnimations && mAnimations)
|
|
||||||
for( unsigned int a = 0; a < mNumAnimations; a++)
|
|
||||||
delete mAnimations[a];
|
|
||||||
delete [] mAnimations;
|
|
||||||
|
|
||||||
if (mNumTextures && mTextures)
|
|
||||||
for( unsigned int a = 0; a < mNumTextures; a++)
|
|
||||||
delete mTextures[a];
|
|
||||||
delete [] mTextures;
|
|
||||||
|
|
||||||
if (mNumLights && mLights)
|
|
||||||
for( unsigned int a = 0; a < mNumLights; a++)
|
|
||||||
delete mLights[a];
|
|
||||||
delete [] mLights;
|
|
||||||
|
|
||||||
if (mNumCameras && mCameras)
|
|
||||||
for( unsigned int a = 0; a < mNumCameras; a++)
|
|
||||||
delete mCameras[a];
|
|
||||||
delete [] mCameras;
|
|
||||||
|
|
||||||
delete static_cast<Assimp::ScenePrivateData*>( mPrivate );
|
|
||||||
}
|
|
||||||
|
|
162
code/AssimpPCH.h
162
code/AssimpPCH.h
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
|
||||||
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
|
||||||
with or without modification, are permitted provided that the following
|
|
||||||
conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other
|
|
||||||
materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of the assimp team, nor the names of its
|
|
||||||
contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior
|
|
||||||
written permission of the assimp team.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file AssimpPCH.h
|
|
||||||
* PCH master include. Every unit in Assimp has to include it.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef ASSIMP_PCH_INCLUDED
|
|
||||||
#define ASSIMP_PCH_INCLUDED
|
|
||||||
#define ASSIMP_INTERNAL_BUILD
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
/* General compile config taken from defs.h. It is important that the user compiles
|
|
||||||
* using exactly the same settings in defs.h. Settings in AssimpPCH.h may differ,
|
|
||||||
* they won't affect the public API.
|
|
||||||
*/
|
|
||||||
#include "../include/assimp/defs.h"
|
|
||||||
|
|
||||||
// Include our stdint.h replacement header for MSVC, take the global header for gcc/mingw
|
|
||||||
#if defined( _MSC_VER) && (_MSC_VER < 1600)
|
|
||||||
# include "../include/assimp/Compiler/pstdint.h"
|
|
||||||
#else
|
|
||||||
# include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Undefine the min/max macros defined by some platform headers (namely Windows.h) to
|
|
||||||
* avoid obvious conflicts with std::min() and std::max().
|
|
||||||
*/
|
|
||||||
#undef min
|
|
||||||
#undef max
|
|
||||||
|
|
||||||
/* Concatenate two tokens after evaluating them
|
|
||||||
*/
|
|
||||||
#define _AI_CONCAT(a,b) a ## b
|
|
||||||
#define AI_CONCAT(a,b) _AI_CONCAT(a,b)
|
|
||||||
|
|
||||||
/* Helper macro to set a pointer to NULL in debug builds
|
|
||||||
*/
|
|
||||||
#if (defined ASSIMP_BUILD_DEBUG)
|
|
||||||
# define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
|
|
||||||
#else
|
|
||||||
# define AI_DEBUG_INVALIDATE_PTR(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Beginning with MSVC8 some C string manipulation functions are mapped to their _safe_
|
|
||||||
* counterparts (e.g. _itoa_s). This avoids a lot of trouble with deprecation warnings.
|
|
||||||
*/
|
|
||||||
#if _MSC_VER >= 1400 && !(defined _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES)
|
|
||||||
# define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* size_t to unsigned int, possible loss of data. The compiler is right with his warning
|
|
||||||
* but this loss of data won't be a problem for us. So shut up, little boy.
|
|
||||||
*/
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
# pragma warning (disable : 4267)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
|
||||||
/* Actually that's not required for MSVC. It is included somewhere in the deeper parts of
|
|
||||||
* the MSVC STL but it's necessary for proper build with STLport.
|
|
||||||
*/
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
// Runtime/STL headers
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include <cassert>
|
|
||||||
#include <stack>
|
|
||||||
#include <queue>
|
|
||||||
#include <iostream>
|
|
||||||
#include <algorithm>
|
|
||||||
#include <numeric>
|
|
||||||
#include <new>
|
|
||||||
#include <cstdio>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
// Boost headers
|
|
||||||
#include <boost/pointer_cast.hpp>
|
|
||||||
#include <boost/scoped_ptr.hpp>
|
|
||||||
#include <boost/scoped_array.hpp>
|
|
||||||
#include <boost/shared_ptr.hpp>
|
|
||||||
#include <boost/shared_array.hpp>
|
|
||||||
#include <boost/make_shared.hpp>
|
|
||||||
#include <boost/format.hpp>
|
|
||||||
#include <boost/foreach.hpp>
|
|
||||||
#include <boost/static_assert.hpp>
|
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
|
|
||||||
// Public ASSIMP headers
|
|
||||||
#include "../include/assimp/DefaultLogger.hpp"
|
|
||||||
#include "../include/assimp/IOStream.hpp"
|
|
||||||
#include "../include/assimp/IOSystem.hpp"
|
|
||||||
#include "../include/assimp/scene.h"
|
|
||||||
#include "../include/assimp/importerdesc.h"
|
|
||||||
#include "../include/assimp/postprocess.h"
|
|
||||||
#include "../include/assimp/Importer.hpp"
|
|
||||||
#include "../include/assimp/Exporter.hpp"
|
|
||||||
|
|
||||||
// Internal utility headers
|
|
||||||
#include "BaseImporter.h"
|
|
||||||
#include "StringComparison.h"
|
|
||||||
#include "StreamReader.h"
|
|
||||||
#include "qnan.h"
|
|
||||||
#include "ScenePrivate.h"
|
|
||||||
|
|
||||||
|
|
||||||
// We need those constants, workaround for any platforms where nobody defined them yet
|
|
||||||
#if (!defined SIZE_MAX)
|
|
||||||
# define SIZE_MAX (~((size_t)0))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (!defined UINT_MAX)
|
|
||||||
# define UINT_MAX (~((unsigned int)0))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !! ASSIMP_PCH_INCLUDED
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -41,17 +41,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* ASSXML exporter main code
|
* ASSXML exporter main code
|
||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#include "./../include/assimp/version.h"
|
#include "./../include/assimp/version.h"
|
||||||
#include "ProcessHelper.h"
|
#include "ProcessHelper.h"
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
|
||||||
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
|
||||||
# include <zlib.h>
|
# include <zlib.h>
|
||||||
#else
|
#else
|
||||||
# include "../contrib/zlib/zlib.h"
|
# include <contrib/zlib/zlib.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
#ifndef ASSIMP_BUILD_NO_ASSXML_EXPORTER
|
||||||
|
@ -62,13 +65,20 @@ namespace Assimp {
|
||||||
|
|
||||||
namespace AssxmlExport {
|
namespace AssxmlExport {
|
||||||
|
|
||||||
int ioprintf( IOStream * io, const char * format, ... )
|
// -----------------------------------------------------------------------------------
|
||||||
{
|
static int ioprintf( IOStream * io, const char *format, ... ) {
|
||||||
char sz[4096];
|
using namespace std;
|
||||||
|
if ( nullptr == io ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int Size = 4096;
|
||||||
|
char sz[ Size ];
|
||||||
|
::memset( sz, '\0', Size );
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start( va, format );
|
va_start( va, format );
|
||||||
int nSize = vsnprintf( sz, 4096, format, va );
|
const unsigned int nSize = vsnprintf( sz, Size-1, format, va );
|
||||||
ai_assert( nSize < 4096 );
|
ai_assert( nSize < Size );
|
||||||
va_end( va );
|
va_end( va );
|
||||||
|
|
||||||
io->Write( sz, sizeof(char), nSize );
|
io->Write( sz, sizeof(char), nSize );
|
||||||
|
@ -78,8 +88,7 @@ int ioprintf( IOStream * io, const char * format, ... )
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Convert a name to standard XML format
|
// Convert a name to standard XML format
|
||||||
void ConvertName(aiString& out, const aiString& in)
|
static void ConvertName(aiString& out, const aiString& in) {
|
||||||
{
|
|
||||||
out.length = 0;
|
out.length = 0;
|
||||||
for (unsigned int i = 0; i < in.length; ++i) {
|
for (unsigned int i = 0; i < in.length; ++i) {
|
||||||
switch (in.data[i]) {
|
switch (in.data[i]) {
|
||||||
|
@ -102,8 +111,7 @@ void ConvertName(aiString& out, const aiString& in)
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Write a single node as text dump
|
// Write a single node as text dump
|
||||||
void WriteNode(const aiNode* node, IOStream * io, unsigned int depth)
|
static void WriteNode(const aiNode* node, IOStream * io, unsigned int depth) {
|
||||||
{
|
|
||||||
char prefix[512];
|
char prefix[512];
|
||||||
for (unsigned int i = 0; i < depth;++i)
|
for (unsigned int i = 0; i < depth;++i)
|
||||||
prefix[i] = '\t';
|
prefix[i] = '\t';
|
||||||
|
@ -168,32 +176,31 @@ static std::string encodeXML(const std::string& data) {
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// Write a text model dump
|
// Write a text model dump
|
||||||
void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
static
|
||||||
{
|
void WriteDump(const aiScene* scene, IOStream* io, bool shortened) {
|
||||||
time_t tt = ::time(NULL);
|
time_t tt = ::time( NULL );
|
||||||
tm* p = ::gmtime(&tt);
|
tm* p = ::gmtime( &tt );
|
||||||
|
ai_assert( nullptr != p );
|
||||||
aiString name;
|
|
||||||
|
|
||||||
// write header
|
// write header
|
||||||
ioprintf(io,
|
std::string header(
|
||||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||||
"<ASSIMP format_id=\"1\">\n\n"
|
"<ASSIMP format_id=\"1\">\n\n"
|
||||||
|
|
||||||
"<!-- XML Model dump produced by assimp dump\n"
|
"<!-- XML Model dump produced by assimp dump\n"
|
||||||
" Library version: %i.%i.%i\n"
|
" Library version: %i.%i.%i\n"
|
||||||
" %s\n"
|
" %s\n"
|
||||||
"-->"
|
"-->"
|
||||||
" \n\n"
|
" \n\n"
|
||||||
"<Scene flags=\"%i\" postprocessing=\"%i\">\n",
|
"<Scene flags=\"%d\" postprocessing=\"%i\">\n"
|
||||||
|
);
|
||||||
|
|
||||||
aiGetVersionMajor(),aiGetVersionMinor(),aiGetVersionRevision(),asctime(p),
|
const unsigned int majorVersion( aiGetVersionMajor() );
|
||||||
scene->mFlags,
|
const unsigned int minorVersion( aiGetVersionMinor() );
|
||||||
0 /*globalImporter->GetEffectivePostProcessing()*/);
|
const unsigned int rev( aiGetVersionRevision() );
|
||||||
|
const char *curtime( asctime( p ) );
|
||||||
|
ioprintf( io, header.c_str(), majorVersion, minorVersion, rev, curtime, scene->mFlags, 0 );
|
||||||
|
|
||||||
// write the node graph
|
// write the node graph
|
||||||
WriteNode(scene->mRootNode, io, 0);
|
WriteNode(scene->mRootNode, io, 0);
|
||||||
|
@ -263,6 +270,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
||||||
ioprintf(io,"\t</Light>\n");
|
ioprintf(io,"\t</Light>\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
aiString name;
|
||||||
|
|
||||||
// write textures
|
// write textures
|
||||||
if (scene->mNumTextures) {
|
if (scene->mNumTextures) {
|
||||||
|
@ -291,16 +299,17 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
||||||
else if (!shortened){
|
else if (!shortened){
|
||||||
ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);
|
ioprintf(io,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4);
|
||||||
|
|
||||||
// const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1;
|
// const unsigned int width = (unsigned int)std::log10((double)std::max(tex->mHeight,tex->mWidth))+1;
|
||||||
for (unsigned int y = 0; y < tex->mHeight;++y) {
|
for (unsigned int y = 0; y < tex->mHeight;++y) {
|
||||||
for (unsigned int x = 0; x < tex->mWidth;++x) {
|
for (unsigned int x = 0; x < tex->mWidth;++x) {
|
||||||
aiTexel* tx = tex->pcData + y*tex->mWidth+x;
|
aiTexel* tx = tex->pcData + y*tex->mWidth+x;
|
||||||
unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
|
unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a;
|
||||||
ioprintf(io,"\t\t\t%2x %2x %2x %2x",r,g,b,a);
|
ioprintf(io,"\t\t\t%2x %2x %2x %2x",r,g,b,a);
|
||||||
|
|
||||||
// group by four for readibility
|
// group by four for readability
|
||||||
if (0 == (x+y*tex->mWidth) % 4)
|
if ( 0 == ( x + y*tex->mWidth ) % 4 ) {
|
||||||
ioprintf(io,"\n");
|
ioprintf( io, "\n" );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,7 +457,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
||||||
ioprintf(io,"<MeshList num=\"%i\">\n",scene->mNumMeshes);
|
ioprintf(io,"<MeshList num=\"%i\">\n",scene->mNumMeshes);
|
||||||
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
|
for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
|
||||||
aiMesh* mesh = scene->mMeshes[i];
|
aiMesh* mesh = scene->mMeshes[i];
|
||||||
// const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1;
|
// const unsigned int width = (unsigned int)std::log10((double)mesh->mNumVertices)+1;
|
||||||
|
|
||||||
// mesh header
|
// mesh header
|
||||||
ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",
|
ioprintf(io,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%i\">\n",
|
||||||
|
@ -621,7 +630,7 @@ void WriteDump(const aiScene* scene, IOStream* io, bool shortened)
|
||||||
|
|
||||||
} // end of namespace AssxmlExport
|
} // end of namespace AssxmlExport
|
||||||
|
|
||||||
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
|
void ExportSceneAssxml(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties)
|
||||||
{
|
{
|
||||||
IOStream * out = pIOSystem->Open( pFile, "wt" );
|
IOStream * out = pIOSystem->Open( pFile, "wt" );
|
||||||
if (!out) return;
|
if (!out) return;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -43,13 +43,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the b3d importer class
|
* @brief Implementation of the b3d importer class
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "B3DImporter.h"
|
#include "B3DImporter.h"
|
||||||
#include "TextureTransform.h"
|
#include "TextureTransform.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/anim.h>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
@ -107,7 +114,7 @@ void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
cout<<"Hello world from the B3DImporter!"<<endl;
|
cout<<"Hello world from the B3DImporter!"<<endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if( file.get() == NULL)
|
if( file.get() == NULL)
|
||||||
|
@ -127,12 +134,12 @@ void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void B3DImporter::Oops(){
|
AI_WONT_RETURN void B3DImporter::Oops(){
|
||||||
throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
|
throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void B3DImporter::Fail( string str ){
|
AI_WONT_RETURN void B3DImporter::Fail( string str ){
|
||||||
#ifdef DEBUG_B3D
|
#ifdef DEBUG_B3D
|
||||||
cout<<"Error in B3D file data: "<<str<<endl;
|
cout<<"Error in B3D file data: "<<str<<endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,8 +240,10 @@ unsigned B3DImporter::ChunkSize(){
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
T *B3DImporter::to_array( const vector<T> &v ){
|
T *B3DImporter::to_array( const vector<T> &v ){
|
||||||
if( !v.size() ) return 0;
|
if( v.empty() ) {
|
||||||
T *p=new T[v.size()];
|
return 0;
|
||||||
|
}
|
||||||
|
T *p=new T[ v.size() ];
|
||||||
for( size_t i=0;i<v.size();++i ){
|
for( size_t i=0;i<v.size();++i ){
|
||||||
p[i]=v[i];
|
p[i]=v[i];
|
||||||
}
|
}
|
||||||
|
@ -322,7 +331,7 @@ void B3DImporter::ReadVRTS(){
|
||||||
int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
|
int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
|
||||||
int n_verts=ChunkSize()/sz;
|
int n_verts=ChunkSize()/sz;
|
||||||
|
|
||||||
int v0=_vertices.size();
|
int v0=static_cast<int>(_vertices.size());
|
||||||
_vertices.resize( v0+n_verts );
|
_vertices.resize( v0+n_verts );
|
||||||
|
|
||||||
for( int i=0;i<n_verts;++i ){
|
for( int i=0;i<n_verts;++i ){
|
||||||
|
@ -395,7 +404,7 @@ void B3DImporter::ReadTRIS( int v0 ){
|
||||||
void B3DImporter::ReadMESH(){
|
void B3DImporter::ReadMESH(){
|
||||||
/*int matid=*/ReadInt();
|
/*int matid=*/ReadInt();
|
||||||
|
|
||||||
int v0=_vertices.size();
|
int v0= static_cast<int>(_vertices.size());
|
||||||
|
|
||||||
while( ChunkSize() ){
|
while( ChunkSize() ){
|
||||||
string t=ReadChunk();
|
string t=ReadChunk();
|
||||||
|
@ -453,17 +462,17 @@ void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
|
||||||
}
|
}
|
||||||
|
|
||||||
if( flags & 1 ){
|
if( flags & 1 ){
|
||||||
nodeAnim->mNumPositionKeys=trans.size();
|
nodeAnim->mNumPositionKeys=static_cast<unsigned int>(trans.size());
|
||||||
nodeAnim->mPositionKeys=to_array( trans );
|
nodeAnim->mPositionKeys=to_array( trans );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( flags & 2 ){
|
if( flags & 2 ){
|
||||||
nodeAnim->mNumScalingKeys=scale.size();
|
nodeAnim->mNumScalingKeys=static_cast<unsigned int>(scale.size());
|
||||||
nodeAnim->mScalingKeys=to_array( scale );
|
nodeAnim->mScalingKeys=to_array( scale );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( flags & 4 ){
|
if( flags & 4 ){
|
||||||
nodeAnim->mNumRotationKeys=rot.size();
|
nodeAnim->mNumRotationKeys=static_cast<unsigned int>(rot.size());
|
||||||
nodeAnim->mRotationKeys=to_array( rot );
|
nodeAnim->mRotationKeys=to_array( rot );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -497,7 +506,7 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
||||||
|
|
||||||
aiMatrix4x4 tform=trans * rot * scale;
|
aiMatrix4x4 tform=trans * rot * scale;
|
||||||
|
|
||||||
int nodeid=_nodes.size();
|
int nodeid=static_cast<int>(_nodes.size());
|
||||||
|
|
||||||
aiNode *node=new aiNode( name );
|
aiNode *node=new aiNode( name );
|
||||||
_nodes.push_back( node );
|
_nodes.push_back( node );
|
||||||
|
@ -512,9 +521,9 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
||||||
while( ChunkSize() ){
|
while( ChunkSize() ){
|
||||||
string t=ReadChunk();
|
string t=ReadChunk();
|
||||||
if( t=="MESH" ){
|
if( t=="MESH" ){
|
||||||
int n=_meshes.size();
|
unsigned int n= static_cast<unsigned int>(_meshes.size());
|
||||||
ReadMESH();
|
ReadMESH();
|
||||||
for( int i=n;i<(int)_meshes.size();++i ){
|
for( unsigned int i=n;i<static_cast<unsigned int>(_meshes.size());++i ){
|
||||||
meshes.push_back( i );
|
meshes.push_back( i );
|
||||||
}
|
}
|
||||||
}else if( t=="BONE" ){
|
}else if( t=="BONE" ){
|
||||||
|
@ -535,10 +544,10 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
||||||
ExitChunk();
|
ExitChunk();
|
||||||
}
|
}
|
||||||
|
|
||||||
node->mNumMeshes=meshes.size();
|
node->mNumMeshes= static_cast<unsigned int>(meshes.size());
|
||||||
node->mMeshes=to_array( meshes );
|
node->mMeshes=to_array( meshes );
|
||||||
|
|
||||||
node->mNumChildren=children.size();
|
node->mNumChildren=static_cast<unsigned int>(children.size());
|
||||||
node->mChildren=to_array( children );
|
node->mChildren=to_array( children );
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
|
@ -548,7 +557,7 @@ aiNode *B3DImporter::ReadNODE( aiNode *parent ){
|
||||||
void B3DImporter::ReadBB3D( aiScene *scene ){
|
void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||||
|
|
||||||
_textures.clear();
|
_textures.clear();
|
||||||
_materials.size();
|
_materials.clear();
|
||||||
|
|
||||||
_vertices.clear();
|
_vertices.clear();
|
||||||
_meshes.clear();
|
_meshes.clear();
|
||||||
|
@ -563,7 +572,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||||
|
|
||||||
if (!DefaultLogger::isNullLogger()) {
|
if (!DefaultLogger::isNullLogger()) {
|
||||||
char dmp[128];
|
char dmp[128];
|
||||||
sprintf(dmp,"B3D file format version: %i",version);
|
ai_snprintf(dmp, 128, "B3D file format version: %i",version);
|
||||||
DefaultLogger::get()->info(dmp);
|
DefaultLogger::get()->info(dmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +645,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||||
aiNode *bnode=_nodes[i];
|
aiNode *bnode=_nodes[i];
|
||||||
|
|
||||||
bone->mName=bnode->mName;
|
bone->mName=bnode->mName;
|
||||||
bone->mNumWeights=weights.size();
|
bone->mNumWeights= static_cast<unsigned int>(weights.size());
|
||||||
bone->mWeights=to_array( weights );
|
bone->mWeights=to_array( weights );
|
||||||
|
|
||||||
aiMatrix4x4 mat=bnode->mTransformation;
|
aiMatrix4x4 mat=bnode->mTransformation;
|
||||||
|
@ -646,7 +655,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||||
}
|
}
|
||||||
bone->mOffsetMatrix=mat.Inverse();
|
bone->mOffsetMatrix=mat.Inverse();
|
||||||
}
|
}
|
||||||
mesh->mNumBones=bones.size();
|
mesh->mNumBones= static_cast<unsigned int>(bones.size());
|
||||||
mesh->mBones=to_array( bones );
|
mesh->mBones=to_array( bones );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -658,21 +667,21 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
|
||||||
if( !_materials.size() ){
|
if( !_materials.size() ){
|
||||||
_materials.push_back( new aiMaterial );
|
_materials.push_back( new aiMaterial );
|
||||||
}
|
}
|
||||||
scene->mNumMaterials=_materials.size();
|
scene->mNumMaterials= static_cast<unsigned int>(_materials.size());
|
||||||
scene->mMaterials=to_array( _materials );
|
scene->mMaterials=to_array( _materials );
|
||||||
|
|
||||||
//meshes
|
//meshes
|
||||||
scene->mNumMeshes=_meshes.size();
|
scene->mNumMeshes= static_cast<unsigned int>(_meshes.size());
|
||||||
scene->mMeshes=to_array( _meshes );
|
scene->mMeshes=to_array( _meshes );
|
||||||
|
|
||||||
//animations
|
//animations
|
||||||
if( _animations.size()==1 && _nodeAnims.size() ){
|
if( _animations.size()==1 && _nodeAnims.size() ){
|
||||||
|
|
||||||
aiAnimation *anim=_animations.back();
|
aiAnimation *anim=_animations.back();
|
||||||
anim->mNumChannels=_nodeAnims.size();
|
anim->mNumChannels=static_cast<unsigned int>(_nodeAnims.size());
|
||||||
anim->mChannels=to_array( _nodeAnims );
|
anim->mChannels=to_array( _nodeAnims );
|
||||||
|
|
||||||
scene->mNumAnimations=_animations.size();
|
scene->mNumAnimations=static_cast<unsigned int>(_animations.size());
|
||||||
scene->mAnimations=to_array( _animations );
|
scene->mAnimations=to_array( _animations );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -44,13 +43,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_B3DIMPORTER_H_INC
|
#ifndef AI_B3DIMPORTER_H_INC
|
||||||
#define AI_B3DIMPORTER_H_INC
|
#define AI_B3DIMPORTER_H_INC
|
||||||
|
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
#include "../include/assimp/mesh.h"
|
#include <assimp/mesh.h>
|
||||||
#include "../include/assimp/material.h"
|
#include <assimp/material.h>
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
struct aiNodeAnim;
|
||||||
|
struct aiNode;
|
||||||
|
struct aiAnimation;
|
||||||
|
|
||||||
namespace Assimp{
|
namespace Assimp{
|
||||||
|
|
||||||
class B3DImporter : public BaseImporter{
|
class B3DImporter : public BaseImporter{
|
||||||
|
@ -87,8 +91,8 @@ private:
|
||||||
float weights[4];
|
float weights[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
void Oops();
|
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
|
||||||
void Fail( std::string str );
|
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
void ReadTEXS();
|
void ReadTEXS();
|
||||||
void ReadBRUS();
|
void ReadBRUS();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -40,14 +40,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BVH_IMPORTER
|
||||||
|
|
||||||
#include "BVHLoader.h"
|
#include "BVHLoader.h"
|
||||||
#include "fast_atof.h"
|
#include "fast_atof.h"
|
||||||
#include "SkeletonMeshBuilder.h"
|
#include "SkeletonMeshBuilder.h"
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include "TinyFormatter.h"
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"BVH Importer (MoCap)",
|
"BVH Importer (MoCap)",
|
||||||
|
@ -65,7 +71,10 @@ static const aiImporterDesc desc = {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BVHLoader::BVHLoader()
|
BVHLoader::BVHLoader()
|
||||||
: noSkeletonMesh()
|
: mLine(),
|
||||||
|
mAnimTickDuration(),
|
||||||
|
mAnimNumFrames(),
|
||||||
|
noSkeletonMesh()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -110,7 +119,7 @@ void BVHLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSys
|
||||||
mFileName = pFile;
|
mFileName = pFile;
|
||||||
|
|
||||||
// read file into memory
|
// read file into memory
|
||||||
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
if( file.get() == NULL)
|
if( file.get() == NULL)
|
||||||
throw DeadlyImportError( "Failed to open file " + pFile + ".");
|
throw DeadlyImportError( "Failed to open file " + pFile + ".");
|
||||||
|
|
||||||
|
@ -171,12 +180,12 @@ aiNode* BVHLoader::ReadNode()
|
||||||
// first token is name
|
// first token is name
|
||||||
std::string nodeName = GetNextToken();
|
std::string nodeName = GetNextToken();
|
||||||
if( nodeName.empty() || nodeName == "{")
|
if( nodeName.empty() || nodeName == "{")
|
||||||
ThrowException( boost::str( boost::format( "Expected node name, but found \"%s\".") % nodeName));
|
ThrowException( format() << "Expected node name, but found \"" << nodeName << "\"." );
|
||||||
|
|
||||||
// then an opening brace should follow
|
// then an opening brace should follow
|
||||||
std::string openBrace = GetNextToken();
|
std::string openBrace = GetNextToken();
|
||||||
if( openBrace != "{")
|
if( openBrace != "{")
|
||||||
ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
|
ThrowException( format() << "Expected opening brace \"{\", but found \"" << openBrace << "\"." );
|
||||||
|
|
||||||
// Create a node
|
// Create a node
|
||||||
aiNode* node = new aiNode( nodeName);
|
aiNode* node = new aiNode( nodeName);
|
||||||
|
@ -208,7 +217,7 @@ aiNode* BVHLoader::ReadNode()
|
||||||
// The real symbol is "End Site". Second part comes in a separate token
|
// The real symbol is "End Site". Second part comes in a separate token
|
||||||
std::string siteToken = GetNextToken();
|
std::string siteToken = GetNextToken();
|
||||||
if( siteToken != "Site")
|
if( siteToken != "Site")
|
||||||
ThrowException( boost::str( boost::format( "Expected \"End Site\" keyword, but found \"%s %s\".") % token % siteToken));
|
ThrowException( format() << "Expected \"End Site\" keyword, but found \"" << token << " " << siteToken << "\"." );
|
||||||
|
|
||||||
aiNode* child = ReadEndSite( nodeName);
|
aiNode* child = ReadEndSite( nodeName);
|
||||||
child->mParent = node;
|
child->mParent = node;
|
||||||
|
@ -221,14 +230,14 @@ aiNode* BVHLoader::ReadNode()
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// everything else is a parse error
|
// everything else is a parse error
|
||||||
ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
|
ThrowException( format() << "Unknown keyword \"" << token << "\"." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the child nodes if there are any
|
// add the child nodes if there are any
|
||||||
if( childNodes.size() > 0)
|
if( childNodes.size() > 0)
|
||||||
{
|
{
|
||||||
node->mNumChildren = childNodes.size();
|
node->mNumChildren = static_cast<unsigned int>(childNodes.size());
|
||||||
node->mChildren = new aiNode*[node->mNumChildren];
|
node->mChildren = new aiNode*[node->mNumChildren];
|
||||||
std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
|
std::copy( childNodes.begin(), childNodes.end(), node->mChildren);
|
||||||
}
|
}
|
||||||
|
@ -244,7 +253,7 @@ aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
|
||||||
// check opening brace
|
// check opening brace
|
||||||
std::string openBrace = GetNextToken();
|
std::string openBrace = GetNextToken();
|
||||||
if( openBrace != "{")
|
if( openBrace != "{")
|
||||||
ThrowException( boost::str( boost::format( "Expected opening brace \"{\", but found \"%s\".") % openBrace));
|
ThrowException( format() << "Expected opening brace \"{\", but found \"" << openBrace << "\".");
|
||||||
|
|
||||||
// Create a node
|
// Create a node
|
||||||
aiNode* node = new aiNode( "EndSite_" + pParentName);
|
aiNode* node = new aiNode( "EndSite_" + pParentName);
|
||||||
|
@ -266,7 +275,7 @@ aiNode* BVHLoader::ReadEndSite( const std::string& pParentName)
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
// everything else is a parse error
|
// everything else is a parse error
|
||||||
ThrowException( boost::str( boost::format( "Unknown keyword \"%s\".") % token));
|
ThrowException( format() << "Unknown keyword \"" << token << "\"." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +322,7 @@ void BVHLoader::ReadNodeChannels( BVHLoader::Node& pNode)
|
||||||
else if( channelToken == "Zrotation")
|
else if( channelToken == "Zrotation")
|
||||||
pNode.mChannels.push_back( Channel_RotationZ);
|
pNode.mChannels.push_back( Channel_RotationZ);
|
||||||
else
|
else
|
||||||
ThrowException( boost::str( boost::format( "Invalid channel specifier \"%s\".") % channelToken));
|
ThrowException( format() << "Invalid channel specifier \"" << channelToken << "\"." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +333,7 @@ void BVHLoader::ReadMotion( aiScene* /*pScene*/)
|
||||||
// Read number of frames
|
// Read number of frames
|
||||||
std::string tokenFrames = GetNextToken();
|
std::string tokenFrames = GetNextToken();
|
||||||
if( tokenFrames != "Frames:")
|
if( tokenFrames != "Frames:")
|
||||||
ThrowException( boost::str( boost::format( "Expected frame count \"Frames:\", but found \"%s\".") % tokenFrames));
|
ThrowException( format() << "Expected frame count \"Frames:\", but found \"" << tokenFrames << "\".");
|
||||||
|
|
||||||
float numFramesFloat = GetNextTokenAsFloat();
|
float numFramesFloat = GetNextTokenAsFloat();
|
||||||
mAnimNumFrames = (unsigned int) numFramesFloat;
|
mAnimNumFrames = (unsigned int) numFramesFloat;
|
||||||
|
@ -333,7 +342,7 @@ void BVHLoader::ReadMotion( aiScene* /*pScene*/)
|
||||||
std::string tokenDuration1 = GetNextToken();
|
std::string tokenDuration1 = GetNextToken();
|
||||||
std::string tokenDuration2 = GetNextToken();
|
std::string tokenDuration2 = GetNextToken();
|
||||||
if( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
|
if( tokenDuration1 != "Frame" || tokenDuration2 != "Time:")
|
||||||
ThrowException( boost::str( boost::format( "Expected frame duration \"Frame Time:\", but found \"%s %s\".") % tokenDuration1 % tokenDuration2));
|
ThrowException( format() << "Expected frame duration \"Frame Time:\", but found \"" << tokenDuration1 << " " << tokenDuration2 << "\"." );
|
||||||
|
|
||||||
mAnimTickDuration = GetNextTokenAsFloat();
|
mAnimTickDuration = GetNextTokenAsFloat();
|
||||||
|
|
||||||
|
@ -360,7 +369,7 @@ void BVHLoader::ReadMotion( aiScene* /*pScene*/)
|
||||||
// Retrieves the next token
|
// Retrieves the next token
|
||||||
std::string BVHLoader::GetNextToken()
|
std::string BVHLoader::GetNextToken()
|
||||||
{
|
{
|
||||||
// skip any preceeding whitespace
|
// skip any preceding whitespace
|
||||||
while( mReader != mBuffer.end())
|
while( mReader != mBuffer.end())
|
||||||
{
|
{
|
||||||
if( !isspace( *mReader))
|
if( !isspace( *mReader))
|
||||||
|
@ -406,16 +415,16 @@ float BVHLoader::GetNextTokenAsFloat()
|
||||||
ctoken = fast_atoreal_move<float>( ctoken, result);
|
ctoken = fast_atoreal_move<float>( ctoken, result);
|
||||||
|
|
||||||
if( ctoken != token.c_str() + token.length())
|
if( ctoken != token.c_str() + token.length())
|
||||||
ThrowException( boost::str( boost::format( "Expected a floating point number, but found \"%s\".") % token));
|
ThrowException( format() << "Expected a floating point number, but found \"" << token << "\"." );
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Aborts the file reading with an exception
|
// Aborts the file reading with an exception
|
||||||
void BVHLoader::ThrowException( const std::string& pError)
|
AI_WONT_RETURN void BVHLoader::ThrowException( const std::string& pError)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError( boost::str( boost::format( "%s:%d - %s") % mFileName % mLine % pError));
|
throw DeadlyImportError( format() << mFileName << ":" << mLine << " - " << pError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -434,7 +443,7 @@ void BVHLoader::CreateAnimation( aiScene* pScene)
|
||||||
anim->mDuration = double( mAnimNumFrames - 1);
|
anim->mDuration = double( mAnimNumFrames - 1);
|
||||||
|
|
||||||
// now generate the tracks for all nodes
|
// now generate the tracks for all nodes
|
||||||
anim->mNumChannels = mNodes.size();
|
anim->mNumChannels = static_cast<unsigned int>(mNodes.size());
|
||||||
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
|
||||||
|
|
||||||
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
|
// FIX: set the array elements to NULL to ensure proper deletion if an exception is thrown
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,6 +49,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -81,7 +83,7 @@ class BVHLoader : public BaseImporter
|
||||||
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
|
std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
|
||||||
|
|
||||||
Node() { }
|
Node() { }
|
||||||
Node( const aiNode* pNode) : mNode( pNode) { }
|
explicit Node( const aiNode* pNode) : mNode( pNode) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -134,7 +136,7 @@ protected:
|
||||||
float GetNextTokenAsFloat();
|
float GetNextTokenAsFloat();
|
||||||
|
|
||||||
/** Aborts the file reading with an exception */
|
/** Aborts the file reading with an exception */
|
||||||
void ThrowException( const std::string& pError);
|
AI_WONT_RETURN void ThrowException( const std::string& pError) AI_WONT_RETURN_SUFFIX;
|
||||||
|
|
||||||
/** Constructs an animation for the motion data and stores it in the given scene */
|
/** Constructs an animation for the motion data and stores it in the given scene */
|
||||||
void CreateAnimation( aiScene* pScene);
|
void CreateAnimation( aiScene* pScene);
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -43,18 +43,25 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of BaseImporter
|
* @brief Implementation of BaseImporter
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "FileSystemFilter.h"
|
#include "FileSystemFilter.h"
|
||||||
|
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
|
#include "ByteSwapper.h"
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/postprocess.h>
|
||||||
|
#include <ios>
|
||||||
|
#include <list>
|
||||||
|
#include <memory>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BaseImporter::BaseImporter()
|
BaseImporter::BaseImporter()
|
||||||
: progress()
|
: m_progress()
|
||||||
{
|
{
|
||||||
// nothing to do here
|
// nothing to do here
|
||||||
}
|
}
|
||||||
|
@ -70,8 +77,8 @@ BaseImporter::~BaseImporter()
|
||||||
// Imports the given file and returns the imported data.
|
// Imports the given file and returns the imported data.
|
||||||
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
|
aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
progress = pImp->GetProgressHandler();
|
m_progress = pImp->GetProgressHandler();
|
||||||
ai_assert(progress);
|
ai_assert(m_progress);
|
||||||
|
|
||||||
// Gather configuration properties for this run
|
// Gather configuration properties for this run
|
||||||
SetupProperties( pImp );
|
SetupProperties( pImp );
|
||||||
|
@ -89,8 +96,8 @@ aiScene* BaseImporter::ReadFile(const Importer* pImp, const std::string& pFile,
|
||||||
|
|
||||||
} catch( const std::exception& err ) {
|
} catch( const std::exception& err ) {
|
||||||
// extract error description
|
// extract error description
|
||||||
mErrorText = err.what();
|
m_ErrorText = err.what();
|
||||||
DefaultLogger::get()->error(mErrorText);
|
DefaultLogger::get()->error(m_ErrorText);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,47 +136,55 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/*static*/ bool BaseImporter::SearchFileHeaderForToken(IOSystem* pIOHandler,
|
/*static*/ bool BaseImporter::SearchFileHeaderForToken( IOSystem* pIOHandler,
|
||||||
const std::string& pFile,
|
const std::string& pFile,
|
||||||
const char** tokens,
|
const char** tokens,
|
||||||
unsigned int numTokens,
|
unsigned int numTokens,
|
||||||
unsigned int searchBytes /* = 200 */,
|
unsigned int searchBytes /* = 200 */,
|
||||||
bool tokensSol /* false */)
|
bool tokensSol /* false */)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != tokens && 0 != numTokens && 0 != searchBytes);
|
ai_assert( NULL != tokens );
|
||||||
|
ai_assert( 0 != numTokens );
|
||||||
|
ai_assert( 0 != searchBytes);
|
||||||
|
|
||||||
if (!pIOHandler)
|
if (!pIOHandler)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
||||||
if (pStream.get() ) {
|
if (pStream.get() ) {
|
||||||
// read 200 characters from the file
|
// read 200 characters from the file
|
||||||
boost::scoped_array<char> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
std::unique_ptr<char[]> _buffer (new char[searchBytes+1 /* for the '\0' */]);
|
||||||
char* buffer = _buffer.get();
|
char* buffer = _buffer.get();
|
||||||
|
if( NULL == buffer ) {
|
||||||
const unsigned int read = pStream->Read(buffer,1,searchBytes);
|
|
||||||
if (!read)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < read;++i)
|
const size_t read = pStream->Read(buffer,1,searchBytes);
|
||||||
buffer[i] = ::tolower(buffer[i]);
|
if( !read ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( size_t i = 0; i < read; ++i ) {
|
||||||
|
buffer[ i ] = ::tolower( buffer[ i ] );
|
||||||
|
}
|
||||||
|
|
||||||
// It is not a proper handling of unicode files here ...
|
// It is not a proper handling of unicode files here ...
|
||||||
// ehm ... but it works in most cases.
|
// ehm ... but it works in most cases.
|
||||||
char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
|
char* cur = buffer,*cur2 = buffer,*end = &buffer[read];
|
||||||
while (cur != end) {
|
while (cur != end) {
|
||||||
if (*cur)
|
if( *cur ) {
|
||||||
*cur2++ = *cur;
|
*cur2++ = *cur;
|
||||||
|
}
|
||||||
++cur;
|
++cur;
|
||||||
}
|
}
|
||||||
*cur2 = '\0';
|
*cur2 = '\0';
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numTokens;++i) {
|
for (unsigned int i = 0; i < numTokens;++i) {
|
||||||
ai_assert(NULL != tokens[i]);
|
ai_assert(NULL != tokens[i]);
|
||||||
|
|
||||||
|
|
||||||
const char* r = strstr(buffer,tokens[i]);
|
const char* r = strstr(buffer,tokens[i]);
|
||||||
if (!r)
|
if( !r ) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
// We got a match, either we don't care where it is, or it happens to
|
// We got a match, either we don't care where it is, or it happens to
|
||||||
// be in the beginning of the file / line
|
// be in the beginning of the file / line
|
||||||
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
|
if (!tokensSol || r == buffer || r[-1] == '\r' || r[-1] == '\n') {
|
||||||
|
@ -178,6 +193,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,7 +255,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
const uint32_t* magic_u32;
|
const uint32_t* magic_u32;
|
||||||
};
|
};
|
||||||
magic = reinterpret_cast<const char*>(_magic);
|
magic = reinterpret_cast<const char*>(_magic);
|
||||||
boost::scoped_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
||||||
if (pStream.get() ) {
|
if (pStream.get() ) {
|
||||||
|
|
||||||
// skip to offset
|
// skip to offset
|
||||||
|
@ -257,7 +273,7 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||||
|
|
||||||
for (unsigned int i = 0; i < num; ++i) {
|
for (unsigned int i = 0; i < num; ++i) {
|
||||||
// also check against big endian versions of tokens with size 2,4
|
// also check against big endian versions of tokens with size 2,4
|
||||||
// that's just for convinience, the chance that we cause conflicts
|
// that's just for convenience, the chance that we cause conflicts
|
||||||
// is quite low and it can save some lines and prevent nasty bugs
|
// is quite low and it can save some lines and prevent nasty bugs
|
||||||
if (2 == size) {
|
if (2 == size) {
|
||||||
uint16_t rev = *magic_u16;
|
uint16_t rev = *magic_u16;
|
||||||
|
@ -319,7 +335,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
// UTF 32 BE with BOM
|
// UTF 32 BE with BOM
|
||||||
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
if(*((uint32_t*)&data.front()) == 0xFFFE0000) {
|
||||||
|
|
||||||
// swap the endianess ..
|
// swap the endianness ..
|
||||||
for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
|
for(uint32_t* p = (uint32_t*)&data.front(), *end = (uint32_t*)&data.back(); p <= end; ++p) {
|
||||||
AI_SWAP4P(p);
|
AI_SWAP4P(p);
|
||||||
}
|
}
|
||||||
|
@ -350,7 +366,7 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
// UTF 16 BE with BOM
|
// UTF 16 BE with BOM
|
||||||
if(*((uint16_t*)&data.front()) == 0xFFFE) {
|
if(*((uint16_t*)&data.front()) == 0xFFFE) {
|
||||||
|
|
||||||
// swap the endianess ..
|
// swap the endianness ..
|
||||||
for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
|
for(uint16_t* p = (uint16_t*)&data.front(), *end = (uint16_t*)&data.back(); p <= end; ++p) {
|
||||||
ByteSwap::Swap2(p);
|
ByteSwap::Swap2(p);
|
||||||
}
|
}
|
||||||
|
@ -383,11 +399,11 @@ void BaseImporter::ConvertToUTF8(std::vector<char>& data)
|
||||||
// Convert to UTF8 data to ISO-8859-1
|
// Convert to UTF8 data to ISO-8859-1
|
||||||
void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
|
void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
|
||||||
{
|
{
|
||||||
unsigned int size = data.size();
|
size_t size = data.size();
|
||||||
unsigned int i = 0, j = 0;
|
size_t i = 0, j = 0;
|
||||||
|
|
||||||
while(i < size) {
|
while(i < size) {
|
||||||
if((unsigned char) data[i] < 0x80) {
|
if ((unsigned char) data[i] < (size_t) 0x80) {
|
||||||
data[j] = data[i];
|
data[j] = data[i];
|
||||||
} else if(i < size - 1) {
|
} else if(i < size - 1) {
|
||||||
if((unsigned char) data[i] == 0xC2) {
|
if((unsigned char) data[i] == 0xC2) {
|
||||||
|
@ -418,61 +434,80 @@ void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BaseImporter::TextFileToBuffer(IOStream* stream,
|
void BaseImporter::TextFileToBuffer(IOStream* stream,
|
||||||
std::vector<char>& data)
|
std::vector<char>& data,
|
||||||
|
TextFileMode mode)
|
||||||
{
|
{
|
||||||
ai_assert(NULL != stream);
|
ai_assert(NULL != stream);
|
||||||
|
|
||||||
const size_t fileSize = stream->FileSize();
|
const size_t fileSize = stream->FileSize();
|
||||||
|
if (mode == FORBID_EMPTY) {
|
||||||
if(!fileSize) {
|
if(!fileSize) {
|
||||||
throw DeadlyImportError("File is empty");
|
throw DeadlyImportError("File is empty");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data.reserve(fileSize+1);
|
data.reserve(fileSize+1);
|
||||||
data.resize(fileSize);
|
data.resize(fileSize);
|
||||||
|
if(fileSize > 0) {
|
||||||
if(fileSize != stream->Read( &data[0], 1, fileSize)) {
|
if(fileSize != stream->Read( &data[0], 1, fileSize)) {
|
||||||
throw DeadlyImportError("File read error");
|
throw DeadlyImportError("File read error");
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertToUTF8(data);
|
ConvertToUTF8(data);
|
||||||
|
}
|
||||||
|
|
||||||
// append a binary zero to simplify string parsing
|
// append a binary zero to simplify string parsing
|
||||||
data.push_back(0);
|
data.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
// Represents an import request
|
// Represents an import request
|
||||||
struct LoadRequest
|
struct LoadRequest {
|
||||||
{
|
|
||||||
LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
|
LoadRequest(const std::string& _file, unsigned int _flags,const BatchLoader::PropertyMap* _map, unsigned int _id)
|
||||||
: file(_file), flags(_flags), refCnt(1),scene(NULL), loaded(false), id(_id)
|
: file(_file)
|
||||||
{
|
, flags(_flags)
|
||||||
if (_map)
|
, refCnt(1)
|
||||||
|
, scene(NULL)
|
||||||
|
, loaded(false)
|
||||||
|
, id(_id) {
|
||||||
|
if ( _map ) {
|
||||||
map = *_map;
|
map = *_map;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator== ( const std::string& f ) const {
|
||||||
|
return file == f;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string file;
|
const std::string file;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
unsigned int refCnt;
|
unsigned int refCnt;
|
||||||
aiScene* scene;
|
aiScene *scene;
|
||||||
bool loaded;
|
bool loaded;
|
||||||
BatchLoader::PropertyMap map;
|
BatchLoader::PropertyMap map;
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
bool operator== (const std::string& f) {
|
|
||||||
return file == f;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// BatchLoader::pimpl data structure
|
// BatchLoader::pimpl data structure
|
||||||
struct Assimp::BatchData
|
struct Assimp::BatchData {
|
||||||
{
|
BatchData( IOSystem* pIO, bool validate )
|
||||||
BatchData()
|
: pIOSystem( pIO )
|
||||||
: next_id(0xffff)
|
, pImporter( nullptr )
|
||||||
{}
|
, next_id(0xffff)
|
||||||
|
, validate( validate ) {
|
||||||
|
ai_assert( NULL != pIO );
|
||||||
|
|
||||||
|
pImporter = new Importer();
|
||||||
|
pImporter->SetIOHandler( pIO );
|
||||||
|
}
|
||||||
|
|
||||||
|
~BatchData() {
|
||||||
|
pImporter->SetIOHandler( NULL ); /* get pointer back into our possession */
|
||||||
|
delete pImporter;
|
||||||
|
}
|
||||||
|
|
||||||
// IO system to be used for all imports
|
// IO system to be used for all imports
|
||||||
IOSystem* pIOSystem;
|
IOSystem* pIOSystem;
|
||||||
|
@ -488,53 +523,59 @@ struct Assimp::BatchData
|
||||||
|
|
||||||
// Id for next item
|
// Id for next item
|
||||||
unsigned int next_id;
|
unsigned int next_id;
|
||||||
|
|
||||||
|
// Validation enabled state
|
||||||
|
bool validate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::list<LoadRequest>::iterator LoadReqIt;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BatchLoader::BatchLoader(IOSystem* pIO)
|
BatchLoader::BatchLoader(IOSystem* pIO, bool validate )
|
||||||
{
|
{
|
||||||
ai_assert(NULL != pIO);
|
ai_assert(NULL != pIO);
|
||||||
|
|
||||||
data = new BatchData();
|
m_data = new BatchData( pIO, validate );
|
||||||
data->pIOSystem = pIO;
|
|
||||||
|
|
||||||
data->pImporter = new Importer();
|
|
||||||
data->pImporter->SetIOHandler(data->pIOSystem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
BatchLoader::~BatchLoader()
|
BatchLoader::~BatchLoader()
|
||||||
{
|
{
|
||||||
// delete all scenes wthat have not been polled by the user
|
// delete all scenes what have not been polled by the user
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
|
|
||||||
delete (*it).scene;
|
delete (*it).scene;
|
||||||
}
|
}
|
||||||
data->pImporter->SetIOHandler(NULL); /* get pointer back into our posession */
|
delete m_data;
|
||||||
delete data->pImporter;
|
|
||||||
delete data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BatchLoader::setValidation( bool enabled ) {
|
||||||
|
m_data->validate = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
unsigned int BatchLoader::AddLoadRequest (const std::string& file,
|
bool BatchLoader::getValidation() const {
|
||||||
|
return m_data->validate;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int BatchLoader::AddLoadRequest(const std::string& file,
|
||||||
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
|
unsigned int steps /*= 0*/, const PropertyMap* map /*= NULL*/)
|
||||||
{
|
{
|
||||||
ai_assert(!file.empty());
|
ai_assert(!file.empty());
|
||||||
|
|
||||||
// check whether we have this loading request already
|
// check whether we have this loading request already
|
||||||
std::list<LoadRequest>::iterator it;
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
for (it = data->requests.begin();it != data->requests.end(); ++it) {
|
|
||||||
|
|
||||||
// Call IOSystem's path comparison function here
|
// Call IOSystem's path comparison function here
|
||||||
if (data->pIOSystem->ComparePaths((*it).file,file)) {
|
if ( m_data->pIOSystem->ComparePaths((*it).file,file)) {
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
if (!((*it).map == *map))
|
if ( !( ( *it ).map == *map ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (!(*it).map.empty())
|
}
|
||||||
|
else if ( !( *it ).map.empty() ) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
(*it).refCnt++;
|
(*it).refCnt++;
|
||||||
return (*it).id;
|
return (*it).id;
|
||||||
|
@ -542,20 +583,18 @@ unsigned int BatchLoader::AddLoadRequest (const std::string& file,
|
||||||
}
|
}
|
||||||
|
|
||||||
// no, we don't have it. So add it to the queue ...
|
// no, we don't have it. So add it to the queue ...
|
||||||
data->requests.push_back(LoadRequest(file,steps,map,data->next_id));
|
m_data->requests.push_back(LoadRequest(file,steps,map, m_data->next_id));
|
||||||
return data->next_id++;
|
return m_data->next_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiScene* BatchLoader::GetImport (unsigned int which)
|
aiScene* BatchLoader::GetImport( unsigned int which )
|
||||||
{
|
{
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
|
|
||||||
if ((*it).id == which && (*it).loaded) {
|
if ((*it).id == which && (*it).loaded) {
|
||||||
|
|
||||||
aiScene* sc = (*it).scene;
|
aiScene* sc = (*it).scene;
|
||||||
if (!(--(*it).refCnt)) {
|
if (!(--(*it).refCnt)) {
|
||||||
data->requests.erase(it);
|
m_data->requests.erase(it);
|
||||||
}
|
}
|
||||||
return sc;
|
return sc;
|
||||||
}
|
}
|
||||||
|
@ -567,14 +606,15 @@ aiScene* BatchLoader::GetImport (unsigned int which)
|
||||||
void BatchLoader::LoadAll()
|
void BatchLoader::LoadAll()
|
||||||
{
|
{
|
||||||
// no threaded implementation for the moment
|
// no threaded implementation for the moment
|
||||||
for (std::list<LoadRequest>::iterator it = data->requests.begin();it != data->requests.end(); ++it) {
|
for ( LoadReqIt it = m_data->requests.begin();it != m_data->requests.end(); ++it) {
|
||||||
// force validation in debug builds
|
// force validation in debug builds
|
||||||
unsigned int pp = (*it).flags;
|
unsigned int pp = (*it).flags;
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
if ( m_data->validate ) {
|
||||||
pp |= aiProcess_ValidateDataStructure;
|
pp |= aiProcess_ValidateDataStructure;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
// setup config properties if necessary
|
// setup config properties if necessary
|
||||||
ImporterPimpl* pimpl = data->pImporter->Pimpl();
|
ImporterPimpl* pimpl = m_data->pImporter->Pimpl();
|
||||||
pimpl->mFloatProperties = (*it).map.floats;
|
pimpl->mFloatProperties = (*it).map.floats;
|
||||||
pimpl->mIntProperties = (*it).map.ints;
|
pimpl->mIntProperties = (*it).map.ints;
|
||||||
pimpl->mStringProperties = (*it).map.strings;
|
pimpl->mStringProperties = (*it).map.strings;
|
||||||
|
@ -585,14 +625,10 @@ void BatchLoader::LoadAll()
|
||||||
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
|
DefaultLogger::get()->info("%%% BEGIN EXTERNAL FILE %%%");
|
||||||
DefaultLogger::get()->info("File: " + (*it).file);
|
DefaultLogger::get()->info("File: " + (*it).file);
|
||||||
}
|
}
|
||||||
data->pImporter->ReadFile((*it).file,pp);
|
m_data->pImporter->ReadFile((*it).file,pp);
|
||||||
(*it).scene = data->pImporter->GetOrphanedScene();
|
(*it).scene = m_data->pImporter->GetOrphanedScene();
|
||||||
(*it).loaded = true;
|
(*it).loaded = true;
|
||||||
|
|
||||||
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
|
DefaultLogger::get()->info("%%% END EXTERNAL FILE %%%");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,19 +47,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "./../include/assimp/types.h"
|
#include <set>
|
||||||
|
#include <assimp/types.h>
|
||||||
|
#include <assimp/ProgressHandler.hpp>
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
class IOSystem;
|
|
||||||
class Importer;
|
class Importer;
|
||||||
class BaseImporter;
|
class IOSystem;
|
||||||
class BaseProcess;
|
class BaseProcess;
|
||||||
class SharedPostProcessInfo;
|
class SharedPostProcessInfo;
|
||||||
class IOStream;
|
class IOStream;
|
||||||
|
|
||||||
|
|
||||||
// utility to do char4 to uint32 in a portable manner
|
// utility to do char4 to uint32 in a portable manner
|
||||||
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
#define AI_MAKE_MAGIC(string) ((uint32_t)((string[0] << 24) + \
|
||||||
(string[1] << 16) + (string[2] << 8) + string[3]))
|
(string[1] << 16) + (string[2] << 8) + string[3]))
|
||||||
|
@ -68,7 +70,7 @@ class IOStream;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct ScopeGuard
|
struct ScopeGuard
|
||||||
{
|
{
|
||||||
ScopeGuard(T* obj) : obj(obj), mdismiss() {}
|
explicit ScopeGuard(T* obj) : obj(obj), mdismiss() {}
|
||||||
~ScopeGuard () throw() {
|
~ScopeGuard () throw() {
|
||||||
if (!mdismiss) {
|
if (!mdismiss) {
|
||||||
delete obj;
|
delete obj;
|
||||||
|
@ -90,6 +92,11 @@ struct ScopeGuard
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// no copying allowed.
|
||||||
|
ScopeGuard();
|
||||||
|
ScopeGuard( const ScopeGuard & );
|
||||||
|
ScopeGuard &operator = ( const ScopeGuard & );
|
||||||
|
|
||||||
T* obj;
|
T* obj;
|
||||||
bool mdismiss;
|
bool mdismiss;
|
||||||
};
|
};
|
||||||
|
@ -169,12 +176,12 @@ public:
|
||||||
);
|
);
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Returns the error description of the last error that occured.
|
/** Returns the error description of the last error that occurred.
|
||||||
* @return A description of the last error that occured. An empty
|
* @return A description of the last error that occurred. An empty
|
||||||
* string if there was no error.
|
* string if there was no error.
|
||||||
*/
|
*/
|
||||||
const std::string& GetErrorText() const {
|
const std::string& GetErrorText() const {
|
||||||
return mErrorText;
|
return m_ErrorText;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -340,6 +347,13 @@ public: // static utilities
|
||||||
static void ConvertUTF8toISO8859_1(
|
static void ConvertUTF8toISO8859_1(
|
||||||
std::string& data);
|
std::string& data);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/// @brief Enum to define, if empty files are ok or not.
|
||||||
|
enum TextFileMode {
|
||||||
|
ALLOW_EMPTY,
|
||||||
|
FORBID_EMPTY
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Utility for text file loaders which copies the contents of the
|
/** Utility for text file loaders which copies the contents of the
|
||||||
* file into a memory buffer and converts it to our UTF8
|
* file into a memory buffer and converts it to our UTF8
|
||||||
|
@ -347,18 +361,37 @@ public: // static utilities
|
||||||
* @param stream Stream to read from.
|
* @param stream Stream to read from.
|
||||||
* @param data Output buffer to be resized and filled with the
|
* @param data Output buffer to be resized and filled with the
|
||||||
* converted text file data. The buffer is terminated with
|
* converted text file data. The buffer is terminated with
|
||||||
* a binary 0. */
|
* a binary 0.
|
||||||
|
* @param mode Whether it is OK to load empty text files. */
|
||||||
static void TextFileToBuffer(
|
static void TextFileToBuffer(
|
||||||
IOStream* stream,
|
IOStream* stream,
|
||||||
std::vector<char>& data);
|
std::vector<char>& data,
|
||||||
|
TextFileMode mode = FORBID_EMPTY);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Utility function to move a std::vector into a aiScene array
|
||||||
|
* @param vec The vector to be moved
|
||||||
|
* @param out The output pointer to the allocated array.
|
||||||
|
* @param numOut The output count of elements copied. */
|
||||||
|
template<typename T>
|
||||||
|
AI_FORCE_INLINE
|
||||||
|
static void CopyVector(
|
||||||
|
std::vector<T>& vec,
|
||||||
|
T*& out,
|
||||||
|
unsigned int& outLength)
|
||||||
|
{
|
||||||
|
outLength = unsigned(vec.size());
|
||||||
|
if (outLength) {
|
||||||
|
out = new T[outLength];
|
||||||
|
std::swap_ranges(vec.begin(), vec.end(), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// Error description in case there was one.
|
||||||
/** Error description in case there was one. */
|
std::string m_ErrorText;
|
||||||
std::string mErrorText;
|
/// Currently set progress handler.
|
||||||
|
ProgressHandler* m_progress;
|
||||||
/** Currently set progress handler */
|
|
||||||
ProgressHandler* progress;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -41,10 +41,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file Implementation of BaseProcess */
|
/** @file Implementation of BaseProcess */
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "BaseProcess.h"
|
#include "BaseProcess.h"
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
#include "Importer.h"
|
#include "Importer.h"
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -44,7 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "../include/assimp/types.h"
|
#include <assimp/types.h>
|
||||||
#include "GenericProperty.h"
|
#include "GenericProperty.h"
|
||||||
|
|
||||||
struct aiScene;
|
struct aiScene;
|
||||||
|
@ -74,7 +74,7 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct THeapData : public Base
|
struct THeapData : public Base
|
||||||
{
|
{
|
||||||
THeapData(T* in)
|
explicit THeapData(T* in)
|
||||||
: data (in)
|
: data (in)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TStaticData : public Base
|
struct TStaticData : public Base
|
||||||
{
|
{
|
||||||
TStaticData(T in)
|
explicit TStaticData(T in)
|
||||||
: data (in)
|
: data (in)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -45,9 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* Used for file formats which embed their textures into the model file.
|
* Used for file formats which embed their textures into the model file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#include "Bitmap.h"
|
#include "Bitmap.h"
|
||||||
|
#include <assimp/texture.h>
|
||||||
|
#include <assimp/IOStream.hpp>
|
||||||
|
#include "ByteSwapper.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -82,7 +84,12 @@ namespace Assimp {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::size_t Copy(uint8_t* data, T& field) {
|
inline std::size_t Copy(uint8_t* data, T& field) {
|
||||||
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
|
T field_swapped=AI_BE(field);
|
||||||
|
std::memcpy(data, &field_swapped, sizeof(field)); return sizeof(field);
|
||||||
|
#else
|
||||||
std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
|
std::memcpy(data, &AI_BE(field), sizeof(field)); return sizeof(field);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bitmap::WriteHeader(Header& header, IOStream* file) {
|
void Bitmap::WriteHeader(Header& header, IOStream* file) {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -48,8 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_BITMAP_H_INC
|
#ifndef AI_BITMAP_H_INC
|
||||||
#define AI_BITMAP_H_INC
|
#define AI_BITMAP_H_INC
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <cstddef>
|
||||||
|
struct aiTexture;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
class IOStream;
|
||||||
class Bitmap {
|
class Bitmap {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Conversion of Blender's new BMesh stuff
|
* @brief Conversion of Blender's new BMesh stuff
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
|
@ -150,7 +149,7 @@ void BlenderBMeshConverter::ConvertPolyToFaces( const MPoly& poly )
|
||||||
// UVs are optional, so only convert when present.
|
// UVs are optional, so only convert when present.
|
||||||
if ( BMesh->mloopuv.size() )
|
if ( BMesh->mloopuv.size() )
|
||||||
{
|
{
|
||||||
if ( (poly.loopstart + poly.totloop ) >= static_cast<int>( BMesh->mloopuv.size() ) )
|
if ( (poly.loopstart + poly.totloop ) > static_cast<int>( BMesh->mloopuv.size() ) )
|
||||||
{
|
{
|
||||||
ThrowException( "BMesh uv loop array has incorrect size" );
|
ThrowException( "BMesh uv loop array has incorrect size" );
|
||||||
}
|
}
|
||||||
|
@ -181,7 +180,7 @@ void BlenderBMeshConverter::AddFace( int v1, int v2, int v3, int v4 )
|
||||||
// TODO - Work out how materials work
|
// TODO - Work out how materials work
|
||||||
face.mat_nr = 0;
|
face.mat_nr = 0;
|
||||||
triMesh->mface.push_back( face );
|
triMesh->mface.push_back( face );
|
||||||
triMesh->totface = triMesh->mface.size( );
|
triMesh->totface = static_cast<int>(triMesh->mface.size( ));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief Implementation of the Blender `DNA`, that is its own
|
* @brief Implementation of the Blender `DNA`, that is its own
|
||||||
* serialized set of data structures.
|
* serialized set of data structures.
|
||||||
*/
|
*/
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
|
@ -53,13 +53,13 @@ using namespace Assimp;
|
||||||
using namespace Assimp::Blender;
|
using namespace Assimp::Blender;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
#define for_each BOOST_FOREACH
|
static bool match4(StreamReaderAny& stream, const char* string) {
|
||||||
bool match4(StreamReaderAny& stream, const char* string) {
|
ai_assert( nullptr != string );
|
||||||
char tmp[] = {
|
char tmp[] = {
|
||||||
(stream).GetI1(),
|
(const char)(stream).GetI1(),
|
||||||
(stream).GetI1(),
|
(const char)(stream).GetI1(),
|
||||||
(stream).GetI1(),
|
(const char)(stream).GetI1(),
|
||||||
(stream).GetI1()
|
(const char)(stream).GetI1()
|
||||||
};
|
};
|
||||||
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
|
return (tmp[0]==string[0] && tmp[1]==string[1] && tmp[2]==string[2] && tmp[3]==string[3]);
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ struct Type {
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void DNAParser :: Parse ()
|
void DNAParser::Parse ()
|
||||||
{
|
{
|
||||||
StreamReaderAny& stream = *db.reader.get();
|
StreamReaderAny& stream = *db.reader.get();
|
||||||
DNA& dna = db.dna;
|
DNA& dna = db.dna;
|
||||||
|
@ -85,7 +85,7 @@ void DNAParser :: Parse ()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> names (stream.GetI4());
|
std::vector<std::string> names (stream.GetI4());
|
||||||
for_each(std::string& s, names) {
|
for(std::string& s : names) {
|
||||||
while (char c = stream.GetI1()) {
|
while (char c = stream.GetI1()) {
|
||||||
s += c;
|
s += c;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ void DNAParser :: Parse ()
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Type> types (stream.GetI4());
|
std::vector<Type> types (stream.GetI4());
|
||||||
for_each(Type& s, types) {
|
for(Type& s : types) {
|
||||||
while (char c = stream.GetI1()) {
|
while (char c = stream.GetI1()) {
|
||||||
s.name += c;
|
s.name += c;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ void DNAParser :: Parse ()
|
||||||
throw DeadlyImportError("BlenderDNA: Expected TLEN field");
|
throw DeadlyImportError("BlenderDNA: Expected TLEN field");
|
||||||
}
|
}
|
||||||
|
|
||||||
for_each(Type& s, types) {
|
for(Type& s : types) {
|
||||||
s.size = stream.GetI2();
|
s.size = stream.GetI2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,13 +237,15 @@ void DNA :: DumpToFile()
|
||||||
f << "Field format: type name offset size" << "\n";
|
f << "Field format: type name offset size" << "\n";
|
||||||
f << "Structure format: name size" << "\n";
|
f << "Structure format: name size" << "\n";
|
||||||
|
|
||||||
for_each(const Structure& s, structures) {
|
for(const Structure& s : structures) {
|
||||||
f << s.name << " " << s.size << "\n\n";
|
f << s.name << " " << s.size << "\n\n";
|
||||||
for_each(const Field& ff, s.fields) {
|
for(const Field& ff : s.fields) {
|
||||||
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << std::endl;
|
f << "\t" << ff.type << " " << ff.name << " " << ff.offset << " " << ff.size << "\n";
|
||||||
}
|
}
|
||||||
f << std::endl;
|
f << "\n";
|
||||||
}
|
}
|
||||||
|
f << std::flush;
|
||||||
|
|
||||||
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
|
DefaultLogger::get()->info("BlenderDNA: Dumped dna to dna.txt");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -269,17 +271,17 @@ void DNA :: DumpToFile()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
boost::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
|
std::shared_ptr< ElemBase > DNA :: ConvertBlobToStructure(
|
||||||
const Structure& structure,
|
const Structure& structure,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
|
std::map<std::string, FactoryPair >::const_iterator it = converters.find(structure.name);
|
||||||
if (it == converters.end()) {
|
if (it == converters.end()) {
|
||||||
return boost::shared_ptr< ElemBase >();
|
return std::shared_ptr< ElemBase >();
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
|
std::shared_ptr< ElemBase > ret = (structure.*((*it).second.first))();
|
||||||
(structure.*((*it).second.second))(ret,db);
|
(structure.*((*it).second.second))(ret,db);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -344,10 +346,10 @@ void SectionParser :: Next()
|
||||||
stream.SetCurrentPos(current.start + current.size);
|
stream.SetCurrentPos(current.start + current.size);
|
||||||
|
|
||||||
const char tmp[] = {
|
const char tmp[] = {
|
||||||
stream.GetI1(),
|
(const char)stream.GetI1(),
|
||||||
stream.GetI1(),
|
(const char)stream.GetI1(),
|
||||||
stream.GetI1(),
|
(const char)stream.GetI1(),
|
||||||
stream.GetI1()
|
(const char)stream.GetI1()
|
||||||
};
|
};
|
||||||
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
|
current.id = std::string(tmp,tmp[3]?4:tmp[2]?3:tmp[1]?2:1);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,6 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "TinyFormatter.h"
|
#include "TinyFormatter.h"
|
||||||
|
#include "StreamReader.h"
|
||||||
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
// enable verbose log output. really verbose, so be careful.
|
// enable verbose log output. really verbose, so be careful.
|
||||||
#ifdef ASSIMP_BUILD_DEBUG
|
#ifdef ASSIMP_BUILD_DEBUG
|
||||||
|
@ -56,15 +61,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// #define ASSIMP_BUILD_BLENDER_NO_STATS
|
// #define ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template <bool,bool> class StreamReader;
|
|
||||||
typedef StreamReader<true,true> StreamReaderAny;
|
|
||||||
|
|
||||||
namespace Blender {
|
template <bool,bool> class StreamReader;
|
||||||
class FileDatabase;
|
typedef StreamReader<true,true> StreamReaderAny;
|
||||||
struct FileBlockHead;
|
|
||||||
|
|
||||||
template <template <typename> class TOUT>
|
namespace Blender {
|
||||||
class ObjectCache;
|
|
||||||
|
class FileDatabase;
|
||||||
|
struct FileBlockHead;
|
||||||
|
|
||||||
|
template <template <typename> class TOUT>
|
||||||
|
class ObjectCache;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Exception class used by the blender loader to selectively catch exceptions
|
/** Exception class used by the blender loader to selectively catch exceptions
|
||||||
|
@ -73,62 +80,65 @@ namespace Assimp {
|
||||||
* the loader itself, it will still be caught by Assimp due to its
|
* the loader itself, it will still be caught by Assimp due to its
|
||||||
* ancestry. */
|
* ancestry. */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Error : DeadlyImportError
|
struct Error : DeadlyImportError {
|
||||||
{
|
|
||||||
Error (const std::string& s)
|
Error (const std::string& s)
|
||||||
: DeadlyImportError(s)
|
: DeadlyImportError(s) {
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** The only purpose of this structure is to feed a virtual dtor into its
|
/** The only purpose of this structure is to feed a virtual dtor into its
|
||||||
* descendents. It serves as base class for all data structure fields. */
|
* descendents. It serves as base class for all data structure fields. */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ElemBase
|
struct ElemBase {
|
||||||
{
|
virtual ~ElemBase() {
|
||||||
virtual ~ElemBase() {}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
/** Type name of the element. The type
|
/** Type name of the element. The type
|
||||||
* string points is the `c_str` of the `name` attribute of the
|
* string points is the `c_str` of the `name` attribute of the
|
||||||
* corresponding `Structure`, that is, it is only valid as long
|
* corresponding `Structure`, that is, it is only valid as long
|
||||||
* as the DNA is not modified. The dna_type is only set if the
|
* as the DNA is not modified. The dna_type is only set if the
|
||||||
* data type is not static, i.e. a boost::shared_ptr<ElemBase>
|
* data type is not static, i.e. a std::shared_ptr<ElemBase>
|
||||||
* in the scene description would have its type resolved
|
* in the scene description would have its type resolved
|
||||||
* at runtime, so this member is always set. */
|
* at runtime, so this member is always set. */
|
||||||
const char* dna_type;
|
const char* dna_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Represents a generic pointer to a memory location, which can be either 32
|
/** Represents a generic pointer to a memory location, which can be either 32
|
||||||
* or 64 bits. These pointers are loaded from the BLEND file and finally
|
* or 64 bits. These pointers are loaded from the BLEND file and finally
|
||||||
* fixed to point to the real, converted representation of the objects
|
* fixed to point to the real, converted representation of the objects
|
||||||
* they used to point to.*/
|
* they used to point to.*/
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Pointer
|
struct Pointer {
|
||||||
{
|
Pointer()
|
||||||
Pointer() : val() {}
|
: val() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Represents a generic offset within a BLEND file */
|
/** Represents a generic offset within a BLEND file */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct FileOffset
|
struct FileOffset {
|
||||||
{
|
FileOffset()
|
||||||
FileOffset() : val() {}
|
: val() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Dummy derivate of std::vector to be able to use it in templates simultaenously
|
/** Dummy derivate of std::vector to be able to use it in templates simultaenously
|
||||||
* with boost::shared_ptr, which takes only one template argument
|
* with std::shared_ptr, which takes only one template argument
|
||||||
* while std::vector takes three. Also we need to provide some special member
|
* while std::vector takes three. Also we need to provide some special member
|
||||||
* functions of shared_ptr */
|
* functions of shared_ptr */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class vector : public std::vector<T>
|
class vector : public std::vector<T> {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
using std::vector<T>::resize;
|
using std::vector<T>::resize;
|
||||||
using std::vector<T>::empty;
|
using std::vector<T>::empty;
|
||||||
|
@ -145,8 +155,7 @@ public:
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Mixed flags for use in #Field */
|
/** Mixed flags for use in #Field */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
enum FieldFlags
|
enum FieldFlags {
|
||||||
{
|
|
||||||
FieldFlag_Pointer = 0x1,
|
FieldFlag_Pointer = 0x1,
|
||||||
FieldFlag_Array = 0x2
|
FieldFlag_Array = 0x2
|
||||||
};
|
};
|
||||||
|
@ -154,8 +163,7 @@ enum FieldFlags
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Represents a single member of a data structure in a BLEND file */
|
/** Represents a single member of a data structure in a BLEND file */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Field
|
struct Field {
|
||||||
{
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string type;
|
std::string type;
|
||||||
|
|
||||||
|
@ -175,8 +183,7 @@ struct Field
|
||||||
* mission critical so we need them, while others can silently be default
|
* mission critical so we need them, while others can silently be default
|
||||||
* initialized and no animations are harmed. */
|
* initialized and no animations are harmed. */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
enum ErrorPolicy
|
enum ErrorPolicy {
|
||||||
{
|
|
||||||
/** Substitute default value and ignore */
|
/** Substitute default value and ignore */
|
||||||
ErrorPolicy_Igno,
|
ErrorPolicy_Igno,
|
||||||
/** Substitute default value and write to log */
|
/** Substitute default value and write to log */
|
||||||
|
@ -197,15 +204,14 @@ enum ErrorPolicy
|
||||||
* binary `blob` read from the file to such a structure instance with
|
* binary `blob` read from the file to such a structure instance with
|
||||||
* meaningful contents. */
|
* meaningful contents. */
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
class Structure
|
class Structure {
|
||||||
{
|
|
||||||
template <template <typename> class> friend class ObjectCache;
|
template <template <typename> class> friend class ObjectCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Structure()
|
Structure()
|
||||||
: cache_idx(-1)
|
: cache_idx(static_cast<size_t>(-1) ){
|
||||||
{}
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -255,11 +261,11 @@ public:
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// generic converter
|
// generic converter
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Convert(boost::shared_ptr<ElemBase> in,const FileDatabase& db) const;
|
void Convert(std::shared_ptr<ElemBase> in,const FileDatabase& db) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// generic allocator
|
// generic allocator
|
||||||
template <typename T> boost::shared_ptr<ElemBase> Allocate() const;
|
template <typename T> std::shared_ptr<ElemBase> Allocate() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -277,7 +283,7 @@ public:
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// field parsing for pointer or dynamic array types
|
// field parsing for pointer or dynamic array types
|
||||||
// (boost::shared_ptr or boost::shared_array)
|
// (std::shared_ptr)
|
||||||
// The return value indicates whether the data was already cached.
|
// The return value indicates whether the data was already cached.
|
||||||
template <int error_policy, template <typename> class TOUT, typename T>
|
template <int error_policy, template <typename> class TOUT, typename T>
|
||||||
bool ReadFieldPtr(TOUT<T>& out, const char* name,
|
bool ReadFieldPtr(TOUT<T>& out, const char* name,
|
||||||
|
@ -286,7 +292,7 @@ public:
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
// field parsing for static arrays of pointer or dynamic
|
// field parsing for static arrays of pointer or dynamic
|
||||||
// array types (boost::shared_ptr[] or boost::shared_array[])
|
// array types (std::shared_ptr[])
|
||||||
// The return value indicates whether the data was already cached.
|
// The return value indicates whether the data was already cached.
|
||||||
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
template <int error_policy, template <typename> class TOUT, typename T, size_t N>
|
||||||
bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
bool ReadFieldPtr(TOUT<T> (&out)[N], const char* name,
|
||||||
|
@ -313,7 +319,7 @@ private:
|
||||||
const FileDatabase& db, const Field& f, bool) const;
|
const FileDatabase& db, const Field& f, bool) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
bool ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
bool ResolvePointer( std::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||||
const FileDatabase& db, const Field& f, bool) const;
|
const FileDatabase& db, const Field& f, bool) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
@ -324,8 +330,8 @@ private:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
template <typename T> T* _allocate(boost::shared_ptr<T>& out, size_t& s) const {
|
template <typename T> T* _allocate(std::shared_ptr<T>& out, size_t& s) const {
|
||||||
out = boost::shared_ptr<T>(new T());
|
out = std::shared_ptr<T>(new T());
|
||||||
s = 1;
|
s = 1;
|
||||||
return out.get();
|
return out.get();
|
||||||
}
|
}
|
||||||
|
@ -389,7 +395,7 @@ template <> struct Structure :: _defaultInitializer<ErrorPolicy_Fail> {
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------------------
|
||||||
template <> inline bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
template <> inline bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shared_ptr<ElemBase>& out,
|
||||||
const Pointer & ptrval,
|
const Pointer & ptrval,
|
||||||
const FileDatabase& db,
|
const FileDatabase& db,
|
||||||
const Field& f,
|
const Field& f,
|
||||||
|
@ -408,11 +414,11 @@ class DNA
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef void (Structure::*ConvertProcPtr) (
|
typedef void (Structure::*ConvertProcPtr) (
|
||||||
boost::shared_ptr<ElemBase> in,
|
std::shared_ptr<ElemBase> in,
|
||||||
const FileDatabase&
|
const FileDatabase&
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
typedef boost::shared_ptr<ElemBase> (
|
typedef std::shared_ptr<ElemBase> (
|
||||||
Structure::*AllocProcPtr) () const;
|
Structure::*AllocProcPtr) () const;
|
||||||
|
|
||||||
typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair;
|
typedef std::pair< AllocProcPtr, ConvertProcPtr > FactoryPair;
|
||||||
|
@ -459,7 +465,7 @@ public:
|
||||||
* @param structure Destination structure definition
|
* @param structure Destination structure definition
|
||||||
* @param db File database.
|
* @param db File database.
|
||||||
* @return A null pointer if no appropriate converter is available.*/
|
* @return A null pointer if no appropriate converter is available.*/
|
||||||
boost::shared_ptr< ElemBase > ConvertBlobToStructure(
|
std::shared_ptr< ElemBase > ConvertBlobToStructure(
|
||||||
const Structure& structure,
|
const Structure& structure,
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const;
|
) const;
|
||||||
|
@ -704,8 +710,6 @@ class FileDatabase
|
||||||
template <template <typename> class TOUT> friend class ObjectCache;
|
template <template <typename> class TOUT> friend class ObjectCache;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
FileDatabase()
|
FileDatabase()
|
||||||
: _cacheArrays(*this)
|
: _cacheArrays(*this)
|
||||||
, _cache(*this)
|
, _cache(*this)
|
||||||
|
@ -713,13 +717,12 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// publicly accessible fields
|
// publicly accessible fields
|
||||||
bool i64bit;
|
bool i64bit;
|
||||||
bool little;
|
bool little;
|
||||||
|
|
||||||
DNA dna;
|
DNA dna;
|
||||||
boost::shared_ptr< StreamReaderAny > reader;
|
std::shared_ptr< StreamReaderAny > reader;
|
||||||
vector< FileBlockHead > entries;
|
vector< FileBlockHead > entries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -733,7 +736,7 @@ public:
|
||||||
// arrays of objects are never cached because we can't easily
|
// arrays of objects are never cached because we can't easily
|
||||||
// ensure their proper destruction.
|
// ensure their proper destruction.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ObjectCache<boost::shared_ptr>& cache(boost::shared_ptr<T>& /*in*/) const {
|
ObjectCache<std::shared_ptr>& cache(std::shared_ptr<T>& /*in*/) const {
|
||||||
return _cache;
|
return _cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +753,7 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mutable ObjectCache<vector> _cacheArrays;
|
mutable ObjectCache<vector> _cacheArrays;
|
||||||
mutable ObjectCache<boost::shared_ptr> _cache;
|
mutable ObjectCache<std::shared_ptr> _cache;
|
||||||
|
|
||||||
mutable size_t next_cache_idx;
|
mutable size_t next_cache_idx;
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef INCLUDED_AI_BLEND_DNA_INL
|
#ifndef INCLUDED_AI_BLEND_DNA_INL
|
||||||
#define INCLUDED_AI_BLEND_DNA_INL
|
#define INCLUDED_AI_BLEND_DNA_INL
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
|
@ -81,14 +83,14 @@ const Field& Structure :: operator [] (const size_t i) const
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <typename T> boost::shared_ptr<ElemBase> Structure :: Allocate() const
|
template <typename T> std::shared_ptr<ElemBase> Structure :: Allocate() const
|
||||||
{
|
{
|
||||||
return boost::shared_ptr<T>(new T());
|
return std::shared_ptr<T>(new T());
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <typename T> void Structure :: Convert(
|
template <typename T> void Structure :: Convert(
|
||||||
boost::shared_ptr<ElemBase> in,
|
std::shared_ptr<ElemBase> in,
|
||||||
const FileDatabase& db) const
|
const FileDatabase& db) const
|
||||||
{
|
{
|
||||||
Convert<T> (*static_cast<T*> ( in.get() ),db);
|
Convert<T> (*static_cast<T*> ( in.get() ),db);
|
||||||
|
@ -364,7 +366,7 @@ bool Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const Fil
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
inline bool Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
inline bool Structure :: ResolvePointer( std::shared_ptr< FileOffset >& out, const Pointer & ptrval,
|
||||||
const FileDatabase& db,
|
const FileDatabase& db,
|
||||||
const Field&,
|
const Field&,
|
||||||
bool) const
|
bool) const
|
||||||
|
@ -379,7 +381,7 @@ inline bool Structure :: ResolvePointer( boost::shared_ptr< FileOffset >& out, c
|
||||||
// find the file block the pointer is pointing to
|
// find the file block the pointer is pointing to
|
||||||
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
||||||
|
|
||||||
out = boost::shared_ptr< FileOffset > (new FileOffset());
|
out = std::shared_ptr< FileOffset > (new FileOffset());
|
||||||
out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
|
out->val = block->start+ static_cast<size_t>((ptrval.val - block->address.val) );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +426,7 @@ bool Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
template <> bool Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::shared_ptr<ElemBase>& out,
|
template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(std::shared_ptr<ElemBase>& out,
|
||||||
const Pointer & ptrval,
|
const Pointer & ptrval,
|
||||||
const FileDatabase& db,
|
const FileDatabase& db,
|
||||||
const Field&,
|
const Field&,
|
||||||
|
@ -530,7 +532,7 @@ template <typename T> struct signless;
|
||||||
template <> struct signless<char> {typedef unsigned char type;};
|
template <> struct signless<char> {typedef unsigned char type;};
|
||||||
template <> struct signless<short> {typedef unsigned short type;};
|
template <> struct signless<short> {typedef unsigned short type;};
|
||||||
template <> struct signless<int> {typedef unsigned int type;};
|
template <> struct signless<int> {typedef unsigned int type;};
|
||||||
|
template <> struct signless<unsigned char> { typedef unsigned char type; };
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct static_cast_silent {
|
struct static_cast_silent {
|
||||||
template <typename V>
|
template <typename V>
|
||||||
|
@ -612,6 +614,22 @@ template <> inline void Structure :: Convert<char> (char& dest,const FileDatab
|
||||||
ConvertDispatcher(dest,*this,db);
|
ConvertDispatcher(dest,*this,db);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
template <> inline void Structure::Convert<unsigned char>(unsigned char& dest, const FileDatabase& db) const
|
||||||
|
{
|
||||||
|
// automatic rescaling from char to float and vice versa (seems useful for RGB colors)
|
||||||
|
if (name == "float") {
|
||||||
|
dest = static_cast<unsigned char>(db.reader->GetF4() * 255.f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (name == "double") {
|
||||||
|
dest = static_cast<unsigned char>(db.reader->GetF8() * 255.f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ConvertDispatcher(dest, *this, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const
|
template <> inline void Structure :: Convert<float> (float& dest,const FileDatabase& db) const
|
||||||
{
|
{
|
||||||
|
@ -701,7 +719,7 @@ template <template <typename> class TOUT> template <typename T> void ObjectCache
|
||||||
|
|
||||||
typename StructureCache::const_iterator it = caches[s.cache_idx].find(ptr);
|
typename StructureCache::const_iterator it = caches[s.cache_idx].find(ptr);
|
||||||
if (it != caches[s.cache_idx].end()) {
|
if (it != caches[s.cache_idx].end()) {
|
||||||
out = boost::static_pointer_cast<T>( (*it).second );
|
out = std::static_pointer_cast<T>( (*it).second );
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
++db.stats().cache_hits;
|
++db.stats().cache_hits;
|
||||||
|
@ -721,7 +739,7 @@ template <template <typename> class TOUT> template <typename T> void ObjectCache
|
||||||
s.cache_idx = db.next_cache_idx++;
|
s.cache_idx = db.next_cache_idx++;
|
||||||
caches.resize(db.next_cache_idx);
|
caches.resize(db.next_cache_idx);
|
||||||
}
|
}
|
||||||
caches[s.cache_idx][ptr] = boost::static_pointer_cast<ElemBase>( out );
|
caches[s.cache_idx][ptr] = std::static_pointer_cast<ElemBase>( out );
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
#ifndef ASSIMP_BUILD_BLENDER_NO_STATS
|
||||||
++db.stats().cached_objects;
|
++db.stats().cached_objects;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,8 +49,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
#include "BlenderScene.h"
|
#include "BlenderScene.h"
|
||||||
#include "BlenderSceneGen.h"
|
#include "BlenderSceneGen.h"
|
||||||
|
#include <deque>
|
||||||
|
#include "./../include/assimp/material.h"
|
||||||
|
|
||||||
#define for_each(x,y) BOOST_FOREACH(x,y)
|
struct aiTexture;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
@ -66,7 +68,7 @@ namespace Blender {
|
||||||
}
|
}
|
||||||
|
|
||||||
~TempArray () {
|
~TempArray () {
|
||||||
for_each(T* elem, arr) {
|
for(T* elem : arr) {
|
||||||
delete elem;
|
delete elem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,6 +120,16 @@ namespace Blender {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# pragma warning(disable:4351)
|
# pragma warning(disable:4351)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct ObjectCompare {
|
||||||
|
bool operator() (const Object* left, const Object* right) const {
|
||||||
|
return ::strncmp(left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// When keeping objects in sets, sort them by their name.
|
||||||
|
typedef std::set<const Object*, ObjectCompare> ObjectSet;
|
||||||
|
|
||||||
// --------------------------------------------------------------------
|
// --------------------------------------------------------------------
|
||||||
/** ConversionData acts as intermediate storage location for
|
/** ConversionData acts as intermediate storage location for
|
||||||
* the various ConvertXXX routines in BlenderImporter.*/
|
* the various ConvertXXX routines in BlenderImporter.*/
|
||||||
|
@ -130,7 +142,13 @@ namespace Blender {
|
||||||
, db(db)
|
, db(db)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
std::set<const Object*> objects;
|
struct ObjectCompare {
|
||||||
|
bool operator() (const Object* left, const Object* right) const {
|
||||||
|
return ::strncmp( left->id.name, right->id.name, strlen( left->id.name ) ) == 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ObjectSet objects;
|
||||||
|
|
||||||
TempArray <std::vector, aiMesh> meshes;
|
TempArray <std::vector, aiMesh> meshes;
|
||||||
TempArray <std::vector, aiCamera> cameras;
|
TempArray <std::vector, aiCamera> cameras;
|
||||||
|
@ -139,7 +157,7 @@ namespace Blender {
|
||||||
TempArray <std::vector, aiTexture> textures;
|
TempArray <std::vector, aiTexture> textures;
|
||||||
|
|
||||||
// set of all materials referenced by at least one mesh in the scene
|
// set of all materials referenced by at least one mesh in the scene
|
||||||
std::deque< boost::shared_ptr< Material > > materials_raw;
|
std::deque< std::shared_ptr< Material > > materials_raw;
|
||||||
|
|
||||||
// counter to name sentinel textures inserted as substitutes for procedural textures.
|
// counter to name sentinel textures inserted as substitutes for procedural textures.
|
||||||
unsigned int sentinel_cnt;
|
unsigned int sentinel_cnt;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file BlenderLoader.cpp
|
/** @file BlenderLoader.cpp
|
||||||
* @brief Implementation of the Blender3D importer class.
|
* @brief Implementation of the Blender3D importer class.
|
||||||
*/
|
*/
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
//#define ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
// Uncomment this to disable support for (gzip)compressed .BLEND files
|
// Uncomment this to disable support for (gzip)compressed .BLEND files
|
||||||
|
@ -52,9 +52,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderIntermediate.h"
|
#include "BlenderIntermediate.h"
|
||||||
#include "BlenderModifier.h"
|
#include "BlenderModifier.h"
|
||||||
#include "BlenderBMesh.h"
|
#include "BlenderBMesh.h"
|
||||||
|
#include "StringUtils.h"
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include "StringComparison.h"
|
||||||
|
|
||||||
#include "StreamReader.h"
|
#include "StreamReader.h"
|
||||||
#include "MemoryIOWrapper.h"
|
#include "MemoryIOWrapper.h"
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
// zlib is needed for compressed blend files
|
// zlib is needed for compressed blend files
|
||||||
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
|
||||||
|
@ -100,6 +106,8 @@ BlenderImporter::~BlenderImporter()
|
||||||
delete modifier_cache;
|
delete modifier_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* Tokens[] = { "BLENDER" };
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// 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 BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||||
|
@ -111,8 +119,7 @@ bool BlenderImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, b
|
||||||
|
|
||||||
else if ((!extension.length() || checkSig) && pIOHandler) {
|
else if ((!extension.length() || checkSig) && pIOHandler) {
|
||||||
// note: this won't catch compressed files
|
// note: this won't catch compressed files
|
||||||
const char* tokens[] = {"BLENDER"};
|
return SearchFileHeaderForToken(pIOHandler,pFile, Tokens,1);
|
||||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -159,14 +166,14 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FileDatabase file;
|
FileDatabase file;
|
||||||
boost::shared_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
|
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
ThrowException("Could not open file for reading");
|
ThrowException("Could not open file for reading");
|
||||||
}
|
}
|
||||||
|
|
||||||
char magic[8] = {0};
|
char magic[8] = {0};
|
||||||
stream->Read(magic,7,1);
|
stream->Read(magic,7,1);
|
||||||
if (strcmp(magic,"BLENDER")) {
|
if (strcmp(magic, Tokens[0] )) {
|
||||||
// Check for presence of the gzip header. If yes, assume it is a
|
// Check for presence of the gzip header. If yes, assume it is a
|
||||||
// compressed blend file and try uncompressing it, else fail. This is to
|
// compressed blend file and try uncompressing it, else fail. This is to
|
||||||
// avoid uncompressing random files which our loader might end up with.
|
// avoid uncompressing random files which our loader might end up with.
|
||||||
|
@ -185,7 +192,7 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
|
||||||
|
|
||||||
// http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
|
// http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
|
||||||
stream->Seek(0L,aiOrigin_SET);
|
stream->Seek(0L,aiOrigin_SET);
|
||||||
boost::shared_ptr<StreamReaderLE> reader = boost::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
|
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
|
||||||
|
|
||||||
// build a zlib stream
|
// build a zlib stream
|
||||||
z_stream zstream;
|
z_stream zstream;
|
||||||
|
@ -255,9 +262,9 @@ void BlenderImporter::InternReadFile( const std::string& pFile,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderImporter::ParseBlendFile(FileDatabase& out, boost::shared_ptr<IOStream> stream)
|
void BlenderImporter::ParseBlendFile(FileDatabase& out, std::shared_ptr<IOStream> stream)
|
||||||
{
|
{
|
||||||
out.reader = boost::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream,out.little));
|
out.reader = std::shared_ptr<StreamReaderAny>(new StreamReaderAny(stream,out.little));
|
||||||
|
|
||||||
DNAParser dna_reader(out);
|
DNAParser dna_reader(out);
|
||||||
const DNA* dna = NULL;
|
const DNA* dna = NULL;
|
||||||
|
@ -300,7 +307,7 @@ void BlenderImporter::ExtractScene(Scene& out, const FileDatabase& file)
|
||||||
const Structure& ss = file.dna.structures[(*it).second];
|
const Structure& ss = file.dna.structures[(*it).second];
|
||||||
|
|
||||||
// we need a scene somewhere to start with.
|
// we need a scene somewhere to start with.
|
||||||
for_each(const FileBlockHead& bl,file.entries) {
|
for(const FileBlockHead& bl :file.entries) {
|
||||||
|
|
||||||
// Fix: using the DNA index is more reliable to locate scenes
|
// Fix: using the DNA index is more reliable to locate scenes
|
||||||
//if (bl.id == "SC") {
|
//if (bl.id == "SC") {
|
||||||
|
@ -337,15 +344,16 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileD
|
||||||
// the file. This is terrible. Here, we're first looking for
|
// the file. This is terrible. Here, we're first looking for
|
||||||
// all objects which don't have parent objects at all -
|
// all objects which don't have parent objects at all -
|
||||||
std::deque<const Object*> no_parents;
|
std::deque<const Object*> no_parents;
|
||||||
for (boost::shared_ptr<Base> cur = boost::static_pointer_cast<Base> ( in.base.first ); cur; cur = cur->next) {
|
for (std::shared_ptr<Base> cur = std::static_pointer_cast<Base> ( in.base.first ); cur; cur = cur->next) {
|
||||||
if (cur->object) {
|
if (cur->object) {
|
||||||
if(!cur->object->parent) {
|
if(!cur->object->parent) {
|
||||||
no_parents.push_back(cur->object.get());
|
no_parents.push_back(cur->object.get());
|
||||||
}
|
} else {
|
||||||
else conv.objects.insert(cur->object.get());
|
conv.objects.insert( cur->object.get() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (boost::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
|
}
|
||||||
|
for (std::shared_ptr<Base> cur = in.basact; cur; cur = cur->next) {
|
||||||
if (cur->object) {
|
if (cur->object) {
|
||||||
if(cur->object->parent) {
|
if(cur->object->parent) {
|
||||||
conv.objects.insert(cur->object.get());
|
conv.objects.insert(cur->object.get());
|
||||||
|
@ -399,7 +407,7 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in,const FileD
|
||||||
}
|
}
|
||||||
|
|
||||||
// acknowledge that the scene might come out incomplete
|
// acknowledge that the scene might come out incomplete
|
||||||
// by Assimps definition of `complete`: blender scenes
|
// by Assimp's definition of `complete`: blender scenes
|
||||||
// can consist of thousands of cameras or lights with
|
// can consist of thousands of cameras or lights with
|
||||||
// not a single mesh between them.
|
// not a single mesh between them.
|
||||||
if (!out->mNumMeshes) {
|
if (!out->mNumMeshes) {
|
||||||
|
@ -416,7 +424,7 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
|
||||||
// check if the file contents are bundled with the BLEND file
|
// check if the file contents are bundled with the BLEND file
|
||||||
if (img->packedfile) {
|
if (img->packedfile) {
|
||||||
name.data[0] = '*';
|
name.data[0] = '*';
|
||||||
name.length = 1+ ASSIMP_itoa10(name.data+1,MAXLEN-1,conv_data.textures->size());
|
name.length = 1+ ASSIMP_itoa10(name.data+1,static_cast<unsigned int>(MAXLEN-1), static_cast<int32_t>(conv_data.textures->size()));
|
||||||
|
|
||||||
conv_data.textures->push_back(new aiTexture());
|
conv_data.textures->push_back(new aiTexture());
|
||||||
aiTexture* tex = conv_data.textures->back();
|
aiTexture* tex = conv_data.textures->back();
|
||||||
|
@ -425,8 +433,9 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
|
||||||
// so we can extract the file extension from it.
|
// so we can extract the file extension from it.
|
||||||
const size_t nlen = strlen( img->name );
|
const size_t nlen = strlen( img->name );
|
||||||
const char* s = img->name+nlen, *e = s;
|
const char* s = img->name+nlen, *e = s;
|
||||||
|
while ( s >= img->name && *s != '.' ) {
|
||||||
while (s >= img->name && *s != '.')--s;
|
--s;
|
||||||
|
}
|
||||||
|
|
||||||
tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] );
|
tex->achFormatHint[0] = s+1>e ? '\0' : ::tolower( s[1] );
|
||||||
tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] );
|
tex->achFormatHint[1] = s+2>e ? '\0' : ::tolower( s[2] );
|
||||||
|
@ -443,8 +452,7 @@ void BlenderImporter::ResolveImage(aiMaterial* out, const Material* mat, const M
|
||||||
tex->pcData = reinterpret_cast<aiTexel*>(ch);
|
tex->pcData = reinterpret_cast<aiTexel*>(ch);
|
||||||
|
|
||||||
LogInfo("Reading embedded texture, original file was "+std::string(img->name));
|
LogInfo("Reading embedded texture, original file was "+std::string(img->name));
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
name = aiString( img->name );
|
name = aiString( img->name );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -492,7 +500,7 @@ void BlenderImporter::AddSentinelTexture(aiMaterial* out, const Material* mat, c
|
||||||
(void)mat; (void)tex; (void)conv_data;
|
(void)mat; (void)tex; (void)conv_data;
|
||||||
|
|
||||||
aiString name;
|
aiString name;
|
||||||
name.length = sprintf(name.data, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
|
name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s",conv_data.sentinel_cnt++,
|
||||||
GetTextureTypeDisplayString(tex->tex->type)
|
GetTextureTypeDisplayString(tex->tex->type)
|
||||||
);
|
);
|
||||||
out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
|
out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
|
||||||
|
@ -549,40 +557,158 @@ void BlenderImporter::ResolveTexture(aiMaterial* out, const Material* mat, const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData& conv_data)
|
||||||
{
|
{
|
||||||
conv_data.materials->reserve(conv_data.materials_raw.size());
|
|
||||||
|
|
||||||
// add a default material if necessary
|
// add a default material if necessary
|
||||||
unsigned int index = static_cast<unsigned int>( -1 );
|
unsigned int index = static_cast<unsigned int>( -1 );
|
||||||
for_each( aiMesh* mesh, conv_data.meshes.get() ) {
|
for( aiMesh* mesh : conv_data.meshes.get() ) {
|
||||||
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
|
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
|
||||||
|
|
||||||
if (index == static_cast<unsigned int>( -1 )) {
|
if (index == static_cast<unsigned int>( -1 )) {
|
||||||
|
// Setup a default material.
|
||||||
// ok, we need to add a dedicated default material for some poor material-less meshes
|
std::shared_ptr<Material> p(new Material());
|
||||||
boost::shared_ptr<Material> p(new Material());
|
ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name)-2);
|
||||||
strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
|
strcpy( p->id.name+2, AI_DEFAULT_MATERIAL_NAME );
|
||||||
|
|
||||||
|
// Note: MSVC11 does not zero-initialize Material here, although it should.
|
||||||
|
// Thus all relevant fields should be explicitly initialized. We cannot add
|
||||||
|
// a default constructor to Material since the DNA codegen does not support
|
||||||
|
// parsing it.
|
||||||
p->r = p->g = p->b = 0.6f;
|
p->r = p->g = p->b = 0.6f;
|
||||||
p->specr = p->specg = p->specb = 0.6f;
|
p->specr = p->specg = p->specb = 0.6f;
|
||||||
p->ambr = p->ambg = p->ambb = 0.0f;
|
p->ambr = p->ambg = p->ambb = 0.0f;
|
||||||
p->mirr = p->mirg = p->mirb = 0.0f;
|
p->mirr = p->mirg = p->mirb = 0.0f;
|
||||||
p->emit = 0.f;
|
p->emit = 0.f;
|
||||||
p->alpha = 0.f;
|
p->alpha = 0.f;
|
||||||
|
p->har = 0;
|
||||||
// XXX add more / or add default c'tor to Material
|
|
||||||
|
|
||||||
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
||||||
conv_data.materials_raw.push_back(p);
|
conv_data.materials_raw.push_back(p);
|
||||||
|
LogInfo("Adding default material");
|
||||||
LogInfo("Adding default material ...");
|
|
||||||
}
|
}
|
||||||
mesh->mMaterialIndex = index;
|
mesh->mMaterialIndex = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for_each(boost::shared_ptr<Material> mat, conv_data.materials_raw) {
|
void BlenderImporter::AddBlendParams(aiMaterial* result, const Material* source)
|
||||||
|
{
|
||||||
|
aiColor3D diffuseColor(source->r, source->g, source->b);
|
||||||
|
result->AddProperty(&diffuseColor, 1, "$mat.blend.diffuse.color", 0, 0);
|
||||||
|
|
||||||
|
float diffuseIntensity = source->ref;
|
||||||
|
result->AddProperty(&diffuseIntensity, 1, "$mat.blend.diffuse.intensity", 0, 0);
|
||||||
|
|
||||||
|
int diffuseShader = source->diff_shader;
|
||||||
|
result->AddProperty(&diffuseShader, 1, "$mat.blend.diffuse.shader", 0, 0);
|
||||||
|
|
||||||
|
int diffuseRamp = 0;
|
||||||
|
result->AddProperty(&diffuseRamp, 1, "$mat.blend.diffuse.ramp", 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
aiColor3D specularColor(source->specr, source->specg, source->specb);
|
||||||
|
result->AddProperty(&specularColor, 1, "$mat.blend.specular.color", 0, 0);
|
||||||
|
|
||||||
|
float specularIntensity = source->spec;
|
||||||
|
result->AddProperty(&specularIntensity, 1, "$mat.blend.specular.intensity", 0, 0);
|
||||||
|
|
||||||
|
int specularShader = source->spec_shader;
|
||||||
|
result->AddProperty(&specularShader, 1, "$mat.blend.specular.shader", 0, 0);
|
||||||
|
|
||||||
|
int specularRamp = 0;
|
||||||
|
result->AddProperty(&specularRamp, 1, "$mat.blend.specular.ramp", 0, 0);
|
||||||
|
|
||||||
|
int specularHardness = source->har;
|
||||||
|
result->AddProperty(&specularHardness, 1, "$mat.blend.specular.hardness", 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
int transparencyUse = source->mode & MA_TRANSPARENCY ? 1 : 0;
|
||||||
|
result->AddProperty(&transparencyUse, 1, "$mat.blend.transparency.use", 0, 0);
|
||||||
|
|
||||||
|
int transparencyMethod = source->mode & MA_RAYTRANSP ? 2 : (source->mode & MA_ZTRANSP ? 1 : 0);
|
||||||
|
result->AddProperty(&transparencyMethod, 1, "$mat.blend.transparency.method", 0, 0);
|
||||||
|
|
||||||
|
float transparencyAlpha = source->alpha;
|
||||||
|
result->AddProperty(&transparencyAlpha, 1, "$mat.blend.transparency.alpha", 0, 0);
|
||||||
|
|
||||||
|
float transparencySpecular = source->spectra;
|
||||||
|
result->AddProperty(&transparencySpecular, 1, "$mat.blend.transparency.specular", 0, 0);
|
||||||
|
|
||||||
|
float transparencyFresnel = source->fresnel_tra;
|
||||||
|
result->AddProperty(&transparencyFresnel, 1, "$mat.blend.transparency.fresnel", 0, 0);
|
||||||
|
|
||||||
|
float transparencyBlend = source->fresnel_tra_i;
|
||||||
|
result->AddProperty(&transparencyBlend, 1, "$mat.blend.transparency.blend", 0, 0);
|
||||||
|
|
||||||
|
float transparencyIor = source->ang;
|
||||||
|
result->AddProperty(&transparencyIor, 1, "$mat.blend.transparency.ior", 0, 0);
|
||||||
|
|
||||||
|
float transparencyFilter = source->filter;
|
||||||
|
result->AddProperty(&transparencyFilter, 1, "$mat.blend.transparency.filter", 0, 0);
|
||||||
|
|
||||||
|
float transparencyFalloff = source->tx_falloff;
|
||||||
|
result->AddProperty(&transparencyFalloff, 1, "$mat.blend.transparency.falloff", 0, 0);
|
||||||
|
|
||||||
|
float transparencyLimit = source->tx_limit;
|
||||||
|
result->AddProperty(&transparencyLimit, 1, "$mat.blend.transparency.limit", 0, 0);
|
||||||
|
|
||||||
|
int transparencyDepth = source->ray_depth_tra;
|
||||||
|
result->AddProperty(&transparencyDepth, 1, "$mat.blend.transparency.depth", 0, 0);
|
||||||
|
|
||||||
|
float transparencyGlossAmount = source->gloss_tra;
|
||||||
|
result->AddProperty(&transparencyGlossAmount, 1, "$mat.blend.transparency.glossAmount", 0, 0);
|
||||||
|
|
||||||
|
float transparencyGlossThreshold = source->adapt_thresh_tra;
|
||||||
|
result->AddProperty(&transparencyGlossThreshold, 1, "$mat.blend.transparency.glossThreshold", 0, 0);
|
||||||
|
|
||||||
|
int transparencyGlossSamples = source->samp_gloss_tra;
|
||||||
|
result->AddProperty(&transparencyGlossSamples, 1, "$mat.blend.transparency.glossSamples", 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
int mirrorUse = source->mode & MA_RAYMIRROR ? 1 : 0;
|
||||||
|
result->AddProperty(&mirrorUse, 1, "$mat.blend.mirror.use", 0, 0);
|
||||||
|
|
||||||
|
float mirrorReflectivity = source->ray_mirror;
|
||||||
|
result->AddProperty(&mirrorReflectivity, 1, "$mat.blend.mirror.reflectivity", 0, 0);
|
||||||
|
|
||||||
|
aiColor3D mirrorColor(source->mirr, source->mirg, source->mirb);
|
||||||
|
result->AddProperty(&mirrorColor, 1, "$mat.blend.mirror.color", 0, 0);
|
||||||
|
|
||||||
|
float mirrorFresnel = source->fresnel_mir;
|
||||||
|
result->AddProperty(&mirrorFresnel, 1, "$mat.blend.mirror.fresnel", 0, 0);
|
||||||
|
|
||||||
|
float mirrorBlend = source->fresnel_mir_i;
|
||||||
|
result->AddProperty(&mirrorBlend, 1, "$mat.blend.mirror.blend", 0, 0);
|
||||||
|
|
||||||
|
int mirrorDepth = source->ray_depth;
|
||||||
|
result->AddProperty(&mirrorDepth, 1, "$mat.blend.mirror.depth", 0, 0);
|
||||||
|
|
||||||
|
float mirrorMaxDist = source->dist_mir;
|
||||||
|
result->AddProperty(&mirrorMaxDist, 1, "$mat.blend.mirror.maxDist", 0, 0);
|
||||||
|
|
||||||
|
int mirrorFadeTo = source->fadeto_mir;
|
||||||
|
result->AddProperty(&mirrorFadeTo, 1, "$mat.blend.mirror.fadeTo", 0, 0);
|
||||||
|
|
||||||
|
float mirrorGlossAmount = source->gloss_mir;
|
||||||
|
result->AddProperty(&mirrorGlossAmount, 1, "$mat.blend.mirror.glossAmount", 0, 0);
|
||||||
|
|
||||||
|
float mirrorGlossThreshold = source->adapt_thresh_mir;
|
||||||
|
result->AddProperty(&mirrorGlossThreshold, 1, "$mat.blend.mirror.glossThreshold", 0, 0);
|
||||||
|
|
||||||
|
int mirrorGlossSamples = source->samp_gloss_mir;
|
||||||
|
result->AddProperty(&mirrorGlossSamples, 1, "$mat.blend.mirror.glossSamples", 0, 0);
|
||||||
|
|
||||||
|
float mirrorGlossAnisotropic = source->aniso_gloss_mir;
|
||||||
|
result->AddProperty(&mirrorGlossAnisotropic, 1, "$mat.blend.mirror.glossAnisotropic", 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
|
{
|
||||||
|
conv_data.materials->reserve(conv_data.materials_raw.size());
|
||||||
|
|
||||||
|
BuildDefaultMaterial(conv_data);
|
||||||
|
|
||||||
|
for(std::shared_ptr<Material> mat : conv_data.materials_raw) {
|
||||||
|
|
||||||
// reset per material global counters
|
// reset per material global counters
|
||||||
for (size_t i = 0; i < sizeof(conv_data.next_texture)/sizeof(conv_data.next_texture[0]);++i) {
|
for (size_t i = 0; i < sizeof(conv_data.next_texture)/sizeof(conv_data.next_texture[0]);++i) {
|
||||||
|
@ -591,12 +717,12 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
|
|
||||||
aiMaterial* mout = new aiMaterial();
|
aiMaterial* mout = new aiMaterial();
|
||||||
conv_data.materials->push_back(mout);
|
conv_data.materials->push_back(mout);
|
||||||
|
// For any new material field handled here, the default material above must be updated with an appropriate default value.
|
||||||
|
|
||||||
// set material name
|
// set material name
|
||||||
aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
|
aiString name = aiString(mat->id.name+2); // skip over the name prefix 'MA'
|
||||||
mout->AddProperty(&name,AI_MATKEY_NAME);
|
mout->AddProperty(&name,AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
|
||||||
// basic material colors
|
// basic material colors
|
||||||
aiColor3D col(mat->r,mat->g,mat->b);
|
aiColor3D col(mat->r,mat->g,mat->b);
|
||||||
if (mat->r || mat->g || mat->b ) {
|
if (mat->r || mat->g || mat->b ) {
|
||||||
|
@ -623,6 +749,12 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
col = aiColor3D(mat->ambr,mat->ambg,mat->ambb);
|
col = aiColor3D(mat->ambr,mat->ambg,mat->ambb);
|
||||||
mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
|
mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
// is mirror enabled?
|
||||||
|
if( mat->mode & MA_RAYMIRROR ) {
|
||||||
|
const float ray_mirror = mat->ray_mirror;
|
||||||
|
mout->AddProperty(&ray_mirror,1,AI_MATKEY_REFLECTIVITY);
|
||||||
|
}
|
||||||
|
|
||||||
col = aiColor3D(mat->mirr,mat->mirg,mat->mirb);
|
col = aiColor3D(mat->mirr,mat->mirg,mat->mirb);
|
||||||
mout->AddProperty(&col,1,AI_MATKEY_COLOR_REFLECTIVE);
|
mout->AddProperty(&col,1,AI_MATKEY_COLOR_REFLECTIVE);
|
||||||
|
|
||||||
|
@ -633,6 +765,8 @@ void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
|
|
||||||
ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data);
|
ResolveTexture(mout,mat.get(),mat->mtex[i].get(),conv_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddBlendParams(mout, mat.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -659,11 +793,15 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
|
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
// TODO: Resolve various problems with BMesh triangulation before re-enabling.
|
||||||
|
// See issues #400, #373, #318 #315 and #132.
|
||||||
|
#if defined(TODO_FIX_BMESH_CONVERSION)
|
||||||
BlenderBMeshConverter BMeshConverter( mesh );
|
BlenderBMeshConverter BMeshConverter( mesh );
|
||||||
if ( BMeshConverter.ContainsBMesh( ) )
|
if ( BMeshConverter.ContainsBMesh( ) )
|
||||||
{
|
{
|
||||||
mesh = BMeshConverter.TriangulateBMesh( );
|
mesh = BMeshConverter.TriangulateBMesh( );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef std::pair<const int,size_t> MyPair;
|
typedef std::pair<const int,size_t> MyPair;
|
||||||
if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
|
if ((!mesh->totface && !mesh->totloop) || !mesh->totvert) {
|
||||||
|
@ -704,7 +842,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
temp->reserve(temp->size() + per_mat.size());
|
temp->reserve(temp->size() + per_mat.size());
|
||||||
|
|
||||||
std::map<size_t,size_t> mat_num_to_mesh_idx;
|
std::map<size_t,size_t> mat_num_to_mesh_idx;
|
||||||
for_each(MyPair& it, per_mat) {
|
for(MyPair& it : per_mat) {
|
||||||
|
|
||||||
mat_num_to_mesh_idx[it.first] = temp->size();
|
mat_num_to_mesh_idx[it.first] = temp->size();
|
||||||
temp->push_back(new aiMesh());
|
temp->push_back(new aiMesh());
|
||||||
|
@ -717,7 +855,7 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
//out->mNumVertices = 0
|
//out->mNumVertices = 0
|
||||||
out->mFaces = new aiFace[it.second]();
|
out->mFaces = new aiFace[it.second]();
|
||||||
|
|
||||||
// all submeshes created from this mesh are named equally. this allows
|
// all sub-meshes created from this mesh are named equally. this allows
|
||||||
// curious users to recover the original adjacency.
|
// curious users to recover the original adjacency.
|
||||||
out->mName = aiString(mesh->id.name+2);
|
out->mName = aiString(mesh->id.name+2);
|
||||||
// skip over the name prefix 'ME'
|
// skip over the name prefix 'ME'
|
||||||
|
@ -731,8 +869,8 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
ThrowException("Material index is out of range");
|
ThrowException("Material index is out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::shared_ptr<Material> mat = mesh->mat[it.first];
|
std::shared_ptr<Material> mat = mesh->mat[it.first];
|
||||||
const std::deque< boost::shared_ptr<Material> >::iterator has = std::find(
|
const std::deque< std::shared_ptr<Material> >::iterator has = std::find(
|
||||||
conv_data.materials_raw.begin(),
|
conv_data.materials_raw.begin(),
|
||||||
conv_data.materials_raw.end(),mat
|
conv_data.materials_raw.end(),mat
|
||||||
);
|
);
|
||||||
|
@ -983,12 +1121,13 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
const aiFace& f = out->mFaces[out->mNumFaces++];
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
aiColor4D* vo = &out->mColors[0][out->mNumVertices];
|
aiColor4D* vo = &out->mColors[0][out->mNumVertices];
|
||||||
|
const ai_real scaleZeroToOne = 1.f/255.f;
|
||||||
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
|
for (unsigned int j = 0; j < f.mNumIndices; ++j,++vo,++out->mNumVertices) {
|
||||||
const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
|
const MLoopCol& col = mesh->mloopcol[v.loopstart + j];
|
||||||
vo->r = col.r;
|
vo->r = ai_real(col.r) * scaleZeroToOne;
|
||||||
vo->g = col.g;
|
vo->g = ai_real(col.g) * scaleZeroToOne;
|
||||||
vo->b = col.b;
|
vo->b = ai_real(col.b) * scaleZeroToOne;
|
||||||
vo->a = col.a;
|
vo->a = ai_real(col.a) * scaleZeroToOne;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -999,13 +1138,19 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* /*camera*/, ConversionData& /*conv_data*/)
|
aiCamera* BlenderImporter::ConvertCamera(const Scene& /*in*/, const Object* obj, const Camera* cam, ConversionData& /*conv_data*/)
|
||||||
{
|
{
|
||||||
ScopeGuard<aiCamera> out(new aiCamera());
|
ScopeGuard<aiCamera> out(new aiCamera());
|
||||||
out->mName = obj->id.name+2;
|
out->mName = obj->id.name+2;
|
||||||
out->mPosition = aiVector3D(0.f, 0.f, 0.f);
|
out->mPosition = aiVector3D(0.f, 0.f, 0.f);
|
||||||
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||||
out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
|
out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
|
||||||
|
if (cam->sensor_x && cam->lens) {
|
||||||
|
out->mHorizontalFOV = std::atan2(cam->sensor_x, 2.f * cam->lens);
|
||||||
|
}
|
||||||
|
out->mClipPlaneNear = cam->clipsta;
|
||||||
|
out->mClipPlaneFar = cam->clipend;
|
||||||
|
|
||||||
return out.dismiss();
|
return out.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1025,7 +1170,24 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
|
||||||
|
|
||||||
// blender orients directional lights as facing toward -z
|
// blender orients directional lights as facing toward -z
|
||||||
out->mDirection = aiVector3D(0.f, 0.f, -1.f);
|
out->mDirection = aiVector3D(0.f, 0.f, -1.f);
|
||||||
|
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Lamp::Type_Area:
|
||||||
|
out->mType = aiLightSource_AREA;
|
||||||
|
|
||||||
|
if (lamp->area_shape == 0) {
|
||||||
|
out->mSize = aiVector2D(lamp->area_size, lamp->area_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out->mSize = aiVector2D(lamp->area_size, lamp->area_sizey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// blender orients directional lights as facing toward -z
|
||||||
|
out->mDirection = aiVector3D(0.f, 0.f, -1.f);
|
||||||
|
out->mUp = aiVector3D(0.f, 1.f, 0.f);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1040,7 +1202,7 @@ aiLight* BlenderImporter::ConvertLight(const Scene& /*in*/, const Object* obj, c
|
||||||
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
|
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data, const aiMatrix4x4& parentTransform)
|
||||||
{
|
{
|
||||||
std::deque<const Object*> children;
|
std::deque<const Object*> children;
|
||||||
for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
|
for(ObjectSet::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
|
||||||
const Object* object = *it;
|
const Object* object = *it;
|
||||||
if (object->parent == obj) {
|
if (object->parent == obj) {
|
||||||
children.push_back(object);
|
children.push_back(object);
|
||||||
|
@ -1069,7 +1231,7 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
|
||||||
if (conv_data.meshes->size() > old) {
|
if (conv_data.meshes->size() > old) {
|
||||||
node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size()-old)];
|
node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size()-old)];
|
||||||
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
|
||||||
node->mMeshes[i] = i + old;
|
node->mMeshes[i] = static_cast<unsigned int>(i + old);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
break;
|
break;
|
||||||
|
@ -1133,7 +1295,7 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
|
||||||
if (children.size()) {
|
if (children.size()) {
|
||||||
node->mNumChildren = static_cast<unsigned int>(children.size());
|
node->mNumChildren = static_cast<unsigned int>(children.size());
|
||||||
aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren]();
|
aiNode** nd = node->mChildren = new aiNode*[node->mNumChildren]();
|
||||||
for_each (const Object* nobj,children) {
|
for (const Object* nobj :children) {
|
||||||
*nd = ConvertNode(in,nobj,conv_data,node->mTransformation * parentTransform);
|
*nd = ConvertNode(in,nobj,conv_data,node->mTransformation * parentTransform);
|
||||||
(*nd++)->mParent = node;
|
(*nd++)->mParent = node;
|
||||||
}
|
}
|
||||||
|
@ -1145,5 +1307,4 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
|
||||||
return node.dismiss();
|
return node.dismiss();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
#endif
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,6 +46,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "LogAux.h"
|
#include "LogAux.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
struct aiNode;
|
||||||
|
struct aiMesh;
|
||||||
|
struct aiLight;
|
||||||
|
struct aiCamera;
|
||||||
|
struct aiMaterial;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
@ -98,7 +105,6 @@ public:
|
||||||
BlenderImporter();
|
BlenderImporter();
|
||||||
~BlenderImporter();
|
~BlenderImporter();
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@ -126,7 +132,7 @@ protected:
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ParseBlendFile(Blender::FileDatabase& out,
|
void ParseBlendFile(Blender::FileDatabase& out,
|
||||||
boost::shared_ptr<IOStream> stream
|
std::shared_ptr<IOStream> stream
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@ -172,9 +178,18 @@ private:
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
void BuildDefaultMaterial(
|
||||||
|
Blender::ConversionData& conv_data
|
||||||
|
);
|
||||||
|
|
||||||
|
void AddBlendParams(
|
||||||
|
aiMaterial* result,
|
||||||
|
const Blender::Material* source
|
||||||
|
);
|
||||||
|
|
||||||
void BuildMaterials(
|
void BuildMaterials(
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
) ;
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
void ResolveTexture(
|
void ResolveTexture(
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -41,12 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file BlenderModifier.cpp
|
/** @file BlenderModifier.cpp
|
||||||
* @brief Implementation of some blender modifiers (i.e subdivision, mirror).
|
* @brief Implementation of some blender modifiers (i.e subdivision, mirror).
|
||||||
*/
|
*/
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
#include "BlenderModifier.h"
|
#include "BlenderModifier.h"
|
||||||
#include "SceneCombiner.h"
|
#include "SceneCombiner.h"
|
||||||
#include "Subdivision.h"
|
#include "Subdivision.h"
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
|
@ -109,8 +111,8 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_d
|
||||||
// we're allowed to dereference the pointers without risking to crash. We might still be
|
// we're allowed to dereference the pointers without risking to crash. We might still be
|
||||||
// invoking UB btw - we're assuming that the ModifierData member of the respective modifier
|
// invoking UB btw - we're assuming that the ModifierData member of the respective modifier
|
||||||
// structures is at offset sizeof(vftable) with no padding.
|
// structures is at offset sizeof(vftable) with no padding.
|
||||||
const SharedModifierData* cur = boost::static_pointer_cast<const SharedModifierData> ( orig_object.modifiers.first.get() );
|
const SharedModifierData* cur = static_cast<const SharedModifierData *> ( orig_object.modifiers.first.get() );
|
||||||
for (; cur; cur = boost::static_pointer_cast<const SharedModifierData> ( cur->modifier.next.get() ), ++ful) {
|
for (; cur; cur = static_cast<const SharedModifierData *> ( cur->modifier.next.get() ), ++ful) {
|
||||||
ai_assert(cur->dna_type);
|
ai_assert(cur->dna_type);
|
||||||
|
|
||||||
const Structure* s = conv_data.db.dna.Get( cur->dna_type );
|
const Structure* s = conv_data.db.dna.Get( cur->dna_type );
|
||||||
|
@ -149,7 +151,7 @@ void BlenderModifierShowcase::ApplyModifiers(aiNode& out, ConversionData& conv_d
|
||||||
|
|
||||||
BlenderModifier* const modifier = *curmod;
|
BlenderModifier* const modifier = *curmod;
|
||||||
if(modifier->IsActive(dat)) {
|
if(modifier->IsActive(dat)) {
|
||||||
modifier->DoIt(out,conv_data,*boost::static_pointer_cast<const ElemBase>(cur),in,orig_object);
|
modifier->DoIt(out,conv_data,*static_cast<const ElemBase *>(cur),in,orig_object);
|
||||||
cnt++;
|
cnt++;
|
||||||
|
|
||||||
curgod = NULL;
|
curgod = NULL;
|
||||||
|
@ -273,9 +275,6 @@ void BlenderModifier_Mirror :: DoIt(aiNode& out, ConversionData& conv_data, co
|
||||||
orig_object.id.name,"`");
|
orig_object.id.name,"`");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
|
bool BlenderModifier_Subdivision :: IsActive (const ModifierData& modin)
|
||||||
{
|
{
|
||||||
|
@ -308,11 +307,11 @@ void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::scoped_ptr<Subdivider> subd(Subdivider::Create(algo));
|
std::unique_ptr<Subdivider> subd(Subdivider::Create(algo));
|
||||||
ai_assert(subd);
|
ai_assert(subd);
|
||||||
|
|
||||||
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
aiMesh** const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
|
||||||
boost::scoped_array<aiMesh*> tempmeshes(new aiMesh*[out.mNumMeshes]());
|
std::unique_ptr<aiMesh*[]> tempmeshes(new aiMesh*[out.mNumMeshes]());
|
||||||
|
|
||||||
subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
|
subd->Subdivide(meshes,out.mNumMeshes,tempmeshes.get(),std::max( mir.renderLevels, mir.levels ),true);
|
||||||
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
|
std::copy(tempmeshes.get(),tempmeshes.get()+out.mNumMeshes,meshes);
|
||||||
|
@ -321,4 +320,4 @@ void BlenderModifier_Subdivision :: DoIt(aiNode& out, ConversionData& conv_data
|
||||||
orig_object.id.name,"`");
|
orig_object.id.name,"`");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -46,8 +46,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "BlenderIntermediate.h"
|
#include "BlenderIntermediate.h"
|
||||||
#include "TinyFormatter.h"
|
#include "TinyFormatter.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
|
/** Dummy base class for all blender modifiers. Modifiers are reused between imports, so
|
||||||
|
@ -56,8 +57,8 @@ namespace Assimp {
|
||||||
class BlenderModifier
|
class BlenderModifier
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~BlenderModifier() {
|
virtual ~BlenderModifier() {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (ASSIMP)
|
Open Asset Import Library (ASSIMP)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2010, ASSIMP Development Team
|
Copyright (c) 2006-2016, ASSIMP Development Team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -41,7 +41,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
/** @file BlenderScene.cpp
|
/** @file BlenderScene.cpp
|
||||||
* @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
|
* @brief MACHINE GENERATED BY ./scripts/BlenderImporter/genblenddna.py
|
||||||
*/
|
*/
|
||||||
#include "AssimpPCH.h"
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
#include "BlenderDNA.h"
|
#include "BlenderDNA.h"
|
||||||
|
@ -64,7 +64,7 @@ template <> void Structure :: Convert<Object> (
|
||||||
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
|
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
|
||||||
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Object> parent;
|
std::shared_ptr<Object> parent;
|
||||||
ReadFieldPtr<ErrorPolicy_Warn>(parent,"*parent",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(parent,"*parent",db);
|
||||||
dest.parent = parent.get();
|
dest.parent = parent.get();
|
||||||
}
|
}
|
||||||
|
@ -206,6 +206,10 @@ template <> void Structure :: Convert<Lamp> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
|
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.area_sizez,"area_sizez",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.area_shape,"area_shape",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -297,7 +301,6 @@ template <> void Structure :: Convert<Material> (
|
||||||
const FileDatabase& db
|
const FileDatabase& db
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
|
ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
|
ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
|
||||||
|
@ -313,9 +316,11 @@ template <> void Structure :: Convert<Material> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
|
ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
|
ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
|
ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ray_mirror,"ray_mirror",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
|
ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
|
ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
|
ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
|
ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
|
ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
|
ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
|
||||||
|
@ -324,6 +329,91 @@ template <> void Structure :: Convert<Material> (
|
||||||
ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
|
ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtex,"*mtex",db);
|
||||||
|
|
||||||
|
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.amb, "amb", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ang, "ang", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.spectra, "spectra", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.spec, "spec", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.zoffs, "zoffs", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.add, "add", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fresnel_mir, "fresnel_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fresnel_mir_i, "fresnel_mir_i", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fresnel_tra, "fresnel_tra", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fresnel_tra_i, "fresnel_tra_i", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.filter, "filter", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.tx_limit, "tx_limit", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.tx_falloff, "tx_falloff", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.gloss_mir, "gloss_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.gloss_tra, "gloss_tra", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.adapt_thresh_mir, "adapt_thresh_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.adapt_thresh_tra, "adapt_thresh_tra", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.aniso_gloss_mir, "aniso_gloss_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.dist_mir, "dist_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.hasize, "hasize", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.flaresize, "flaresize", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.subsize, "subsize", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.flareboost, "flareboost", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.strand_sta, "strand_sta", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.strand_end, "strand_end", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.strand_ease, "strand_ease", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.strand_surfnor, "strand_surfnor", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.strand_min, "strand_min", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.strand_widthfade, "strand_widthfade", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sbias, "sbias", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.lbias, "lbias", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.shad_alpha, "shad_alpha", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.param, "param", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.rms, "rms", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.rampfac_col, "rampfac_col", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.rampfac_spec, "rampfac_spec", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.friction, "friction", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fh, "fh", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.reflect, "reflect", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fhdist, "fhdist", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.xyfrict, "xyfrict", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_radius, "sss_radius", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_col, "sss_col", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_error, "sss_error", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_scale, "sss_scale", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_ior, "sss_ior", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_colfac, "sss_colfac", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_texfac, "sss_texfac", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_front, "sss_front", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_back, "sss_back", db);
|
||||||
|
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.material_type, "material_type", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ray_depth, "ray_depth", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ray_depth_tra, "ray_depth_tra", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.samp_gloss_mir, "samp_gloss_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.samp_gloss_tra, "samp_gloss_tra", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.fadeto_mir, "fadeto_mir", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.shade_flag, "shade_flag", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.flarec, "flarec", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.starc, "starc", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.linec, "linec", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ringc, "ringc", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.pr_lamp, "pr_lamp", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.pr_texture, "pr_texture", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ml_flag, "ml_flag", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.diff_shader, "diff_shader", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.spec_shader, "spec_shader", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.texco, "texco", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.mapto, "mapto", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.ramp_show, "ramp_show", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.pad3, "pad3", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.dynamode, "dynamode", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.pad2, "pad2", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_flag, "sss_flag", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.sss_preset, "sss_preset", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.shadowonly_flag, "shadowonly_flag", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.index, "index", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.vcol_alpha, "vcol_alpha", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.pad4, "pad4", db);
|
||||||
|
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.seed1, "seed1", db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.seed2, "seed2", db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +425,7 @@ template <> void Structure :: Convert<MTexPoly> (
|
||||||
{
|
{
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::shared_ptr<Image> tpage;
|
std::shared_ptr<Image> tpage;
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(tpage,"*tpage",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(tpage,"*tpage",db);
|
||||||
dest.tpage = tpage.get();
|
dest.tpage = tpage.get();
|
||||||
}
|
}
|
||||||
|
@ -620,7 +710,10 @@ template <> void Structure :: Convert<Camera> (
|
||||||
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
|
||||||
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Warn>(dest.angle,"angle",db);
|
ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
|
||||||
|
ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);
|
||||||
|
ReadField<ErrorPolicy_Igno>(dest.clipend,"clipend",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -712,5 +805,5 @@ void DNA::RegisterConverters() {
|
||||||
converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
|
converters["Image"] = DNA::FactoryPair( &Structure::Allocate<Image>, &Structure::Convert<Image> );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -44,8 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef INCLUDED_AI_BLEND_SCENE_H
|
#ifndef INCLUDED_AI_BLEND_SCENE_H
|
||||||
#define INCLUDED_AI_BLEND_SCENE_H
|
#define INCLUDED_AI_BLEND_SCENE_H
|
||||||
|
|
||||||
|
#include "BlenderDNA.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
// Minor parts of this file are extracts from blender data structures,
|
// Minor parts of this file are extracts from blender data structures,
|
||||||
// declared in the ./source/blender/makesdna directory.
|
// declared in the ./source/blender/makesdna directory.
|
||||||
|
@ -62,7 +64,7 @@ namespace Assimp {
|
||||||
// * C++ style comments only
|
// * C++ style comments only
|
||||||
//
|
//
|
||||||
// * Structures may include the primitive types char, int, short,
|
// * Structures may include the primitive types char, int, short,
|
||||||
// float, double. Signedness specifiers are not allowed on
|
// float, double. Signed specifiers are not allowed on
|
||||||
// integers. Enum types are allowed, but they must have been
|
// integers. Enum types are allowed, but they must have been
|
||||||
// defined in this header.
|
// defined in this header.
|
||||||
//
|
//
|
||||||
|
@ -71,7 +73,7 @@ namespace Assimp {
|
||||||
//
|
//
|
||||||
// * Pointers to other structures or primitive types are allowed.
|
// * Pointers to other structures or primitive types are allowed.
|
||||||
// No references or double pointers or arrays of pointers.
|
// No references or double pointers or arrays of pointers.
|
||||||
// A pointer to a T is normally written as boost::shared_ptr, while a
|
// A pointer to a T is normally written as std::shared_ptr, while a
|
||||||
// pointer to an array of elements is written as boost::
|
// pointer to an array of elements is written as boost::
|
||||||
// shared_array. To avoid cyclic pointers, use raw pointers in
|
// shared_array. To avoid cyclic pointers, use raw pointers in
|
||||||
// one direction.
|
// one direction.
|
||||||
|
@ -83,33 +85,44 @@ namespace Assimp {
|
||||||
// provided they are neither pointers nor arrays.
|
// provided they are neither pointers nor arrays.
|
||||||
//
|
//
|
||||||
// * One of WARN, FAIL can be appended to the declaration (
|
// * One of WARN, FAIL can be appended to the declaration (
|
||||||
// prior to the semiolon to specifiy the error handling policy if
|
// prior to the semicolon to specify the error handling policy if
|
||||||
// this field is missing in the input DNA). If none of those
|
// this field is missing in the input DNA). If none of those
|
||||||
// is specified the default policy is to subtitute a default
|
// is specified the default policy is to substitute a default
|
||||||
// value for the field.
|
// value for the field.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define WARN // warn if field is missing, substitute default value
|
// warn if field is missing, substitute default value
|
||||||
#define FAIL // fail the import if the field does not exist
|
#ifdef WARN
|
||||||
|
# undef WARN
|
||||||
|
#endif
|
||||||
|
#define WARN
|
||||||
|
|
||||||
|
// fail the import if the field does not exist
|
||||||
|
#ifdef FAIL
|
||||||
|
# undef FAIL
|
||||||
|
#endif
|
||||||
|
#define FAIL
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
struct MTex;
|
struct MTex;
|
||||||
struct Image;
|
struct Image;
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#define AI_BLEND_MESH_MAX_VERTS 2000000000L
|
#define AI_BLEND_MESH_MAX_VERTS 2000000000L
|
||||||
|
|
||||||
|
static const size_t MaxNameLen = 1024;
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ID : ElemBase {
|
struct ID : ElemBase {
|
||||||
|
char name[ MaxNameLen ] WARN;
|
||||||
char name[24] WARN;
|
|
||||||
short flag;
|
short flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct ListBase : ElemBase {
|
struct ListBase : ElemBase {
|
||||||
|
std::shared_ptr<ElemBase> first;
|
||||||
boost::shared_ptr<ElemBase> first;
|
std::shared_ptr<ElemBase> last;
|
||||||
boost::shared_ptr<ElemBase> last;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -117,14 +130,13 @@ struct ListBase : ElemBase {
|
||||||
struct PackedFile : ElemBase {
|
struct PackedFile : ElemBase {
|
||||||
int size WARN;
|
int size WARN;
|
||||||
int seek WARN;
|
int seek WARN;
|
||||||
boost::shared_ptr< FileOffset > data WARN;
|
std::shared_ptr< FileOffset > data WARN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct GroupObject : ElemBase {
|
struct GroupObject : ElemBase {
|
||||||
|
std::shared_ptr<GroupObject> prev,next FAIL;
|
||||||
boost::shared_ptr<GroupObject> prev,next FAIL;
|
std::shared_ptr<Object> ob;
|
||||||
boost::shared_ptr<Object> ob;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -132,13 +144,12 @@ struct Group : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
int layer;
|
int layer;
|
||||||
|
|
||||||
boost::shared_ptr<GroupObject> gobject;
|
std::shared_ptr<GroupObject> gobject;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct World : ElemBase {
|
struct World : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -171,7 +182,7 @@ struct MLoopUV : ElemBase {
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
// Note that red and blue are not swapped, as with MCol
|
// Note that red and blue are not swapped, as with MCol
|
||||||
struct MLoopCol : ElemBase {
|
struct MLoopCol : ElemBase {
|
||||||
char r, g, b, a;
|
unsigned char r, g, b, a;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -213,14 +224,13 @@ struct TFace : ElemBase {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MTFace : ElemBase {
|
struct MTFace : ElemBase {
|
||||||
|
|
||||||
float uv[4][2] FAIL;
|
float uv[4][2] FAIL;
|
||||||
char flag;
|
char flag;
|
||||||
short mode;
|
short mode;
|
||||||
short tile;
|
short tile;
|
||||||
short unwrap;
|
short unwrap;
|
||||||
|
|
||||||
// boost::shared_ptr<Image> tpage;
|
// std::shared_ptr<Image> tpage;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -231,12 +241,16 @@ struct MDeformWeight : ElemBase {
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MDeformVert : ElemBase {
|
struct MDeformVert : ElemBase {
|
||||||
|
|
||||||
vector<MDeformWeight> dw WARN;
|
vector<MDeformWeight> dw WARN;
|
||||||
int totweight;
|
int totweight;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
#define MA_RAYMIRROR 0x40000
|
||||||
|
#define MA_TRANSPARENCY 0x10000
|
||||||
|
#define MA_RAYTRANSP 0x20000
|
||||||
|
#define MA_ZTRANSP 0x00040
|
||||||
|
|
||||||
struct Material : ElemBase {
|
struct Material : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
|
@ -246,19 +260,103 @@ struct Material : ElemBase {
|
||||||
float ambr,ambg,ambb WARN;
|
float ambr,ambg,ambb WARN;
|
||||||
float mirr,mirg,mirb;
|
float mirr,mirg,mirb;
|
||||||
float emit WARN;
|
float emit WARN;
|
||||||
|
float ray_mirror;
|
||||||
float alpha WARN;
|
float alpha WARN;
|
||||||
float ref;
|
float ref;
|
||||||
float translucency;
|
float translucency;
|
||||||
|
int mode;
|
||||||
float roughness;
|
float roughness;
|
||||||
float darkness;
|
float darkness;
|
||||||
float refrac;
|
float refrac;
|
||||||
|
|
||||||
boost::shared_ptr<Group> group;
|
float amb;
|
||||||
|
float ang;
|
||||||
|
float spectra;
|
||||||
|
float spec;
|
||||||
|
float zoffs;
|
||||||
|
float add;
|
||||||
|
float fresnel_mir;
|
||||||
|
float fresnel_mir_i;
|
||||||
|
float fresnel_tra;
|
||||||
|
float fresnel_tra_i;
|
||||||
|
float filter;
|
||||||
|
float tx_limit;
|
||||||
|
float tx_falloff;
|
||||||
|
float gloss_mir;
|
||||||
|
float gloss_tra;
|
||||||
|
float adapt_thresh_mir;
|
||||||
|
float adapt_thresh_tra;
|
||||||
|
float aniso_gloss_mir;
|
||||||
|
float dist_mir;
|
||||||
|
float hasize;
|
||||||
|
float flaresize;
|
||||||
|
float subsize;
|
||||||
|
float flareboost;
|
||||||
|
float strand_sta;
|
||||||
|
float strand_end;
|
||||||
|
float strand_ease;
|
||||||
|
float strand_surfnor;
|
||||||
|
float strand_min;
|
||||||
|
float strand_widthfade;
|
||||||
|
float sbias;
|
||||||
|
float lbias;
|
||||||
|
float shad_alpha;
|
||||||
|
float param;
|
||||||
|
float rms;
|
||||||
|
float rampfac_col;
|
||||||
|
float rampfac_spec;
|
||||||
|
float friction;
|
||||||
|
float fh;
|
||||||
|
float reflect;
|
||||||
|
float fhdist;
|
||||||
|
float xyfrict;
|
||||||
|
float sss_radius;
|
||||||
|
float sss_col;
|
||||||
|
float sss_error;
|
||||||
|
float sss_scale;
|
||||||
|
float sss_ior;
|
||||||
|
float sss_colfac;
|
||||||
|
float sss_texfac;
|
||||||
|
float sss_front;
|
||||||
|
float sss_back;
|
||||||
|
|
||||||
|
short material_type;
|
||||||
|
short flag;
|
||||||
|
short ray_depth;
|
||||||
|
short ray_depth_tra;
|
||||||
|
short samp_gloss_mir;
|
||||||
|
short samp_gloss_tra;
|
||||||
|
short fadeto_mir;
|
||||||
|
short shade_flag;
|
||||||
|
short flarec;
|
||||||
|
short starc;
|
||||||
|
short linec;
|
||||||
|
short ringc;
|
||||||
|
short pr_lamp;
|
||||||
|
short pr_texture;
|
||||||
|
short ml_flag;
|
||||||
|
short texco;
|
||||||
|
short mapto;
|
||||||
|
short ramp_show;
|
||||||
|
short pad3;
|
||||||
|
short dynamode;
|
||||||
|
short pad2;
|
||||||
|
short sss_flag;
|
||||||
|
short sss_preset;
|
||||||
|
short shadowonly_flag;
|
||||||
|
short index;
|
||||||
|
short vcol_alpha;
|
||||||
|
short pad4;
|
||||||
|
|
||||||
|
char seed1;
|
||||||
|
char seed2;
|
||||||
|
|
||||||
|
std::shared_ptr<Group> group;
|
||||||
|
|
||||||
short diff_shader WARN;
|
short diff_shader WARN;
|
||||||
short spec_shader WARN;
|
short spec_shader WARN;
|
||||||
|
|
||||||
boost::shared_ptr<MTex> mtex[18];
|
std::shared_ptr<MTex> mtex[18];
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -289,7 +387,7 @@ struct Mesh : ElemBase {
|
||||||
vector<MDeformVert> dvert;
|
vector<MDeformVert> dvert;
|
||||||
vector<MCol> mcol;
|
vector<MCol> mcol;
|
||||||
|
|
||||||
vector< boost::shared_ptr<Material> > mat FAIL;
|
vector< std::shared_ptr<Material> > mat FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -298,7 +396,7 @@ struct Library : ElemBase {
|
||||||
|
|
||||||
char name[240] WARN;
|
char name[240] WARN;
|
||||||
char filename[240] FAIL;
|
char filename[240] FAIL;
|
||||||
boost::shared_ptr<Library> parent WARN;
|
std::shared_ptr<Library> parent WARN;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -310,18 +408,10 @@ struct Camera : ElemBase {
|
||||||
|
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
// struct AnimData *adt;
|
|
||||||
|
|
||||||
Type type,flag WARN;
|
Type type,flag WARN;
|
||||||
float angle WARN;
|
float lens WARN;
|
||||||
//float passepartalpha, angle;
|
float sensor_x WARN;
|
||||||
//float clipsta, clipend;
|
float clipsta, clipend;
|
||||||
//float lens, ortho_scale, drawsize;
|
|
||||||
//float shiftx, shifty;
|
|
||||||
|
|
||||||
//float YF_dofdist, YF_aperture;
|
|
||||||
//short YF_bkhtype, YF_bkhbias;
|
|
||||||
//float YF_bkhrot;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -371,8 +461,8 @@ struct Lamp : ElemBase {
|
||||||
|
|
||||||
//short ray_samp, ray_sampy, ray_sampz;
|
//short ray_samp, ray_sampy, ray_sampz;
|
||||||
//short ray_samp_type;
|
//short ray_samp_type;
|
||||||
//short area_shape;
|
short area_shape;
|
||||||
//float area_size, area_sizey, area_sizez;
|
float area_size, area_sizey, area_sizez;
|
||||||
//float adapt_thresh;
|
//float adapt_thresh;
|
||||||
//short ray_samp_method;
|
//short ray_samp_method;
|
||||||
|
|
||||||
|
@ -446,8 +536,8 @@ struct ModifierData : ElemBase {
|
||||||
eModifierType_ShapeKey
|
eModifierType_ShapeKey
|
||||||
};
|
};
|
||||||
|
|
||||||
boost::shared_ptr<ElemBase> next WARN;
|
std::shared_ptr<ElemBase> next WARN;
|
||||||
boost::shared_ptr<ElemBase> prev WARN;
|
std::shared_ptr<ElemBase> prev WARN;
|
||||||
|
|
||||||
int type, mode;
|
int type, mode;
|
||||||
char name[32];
|
char name[32];
|
||||||
|
@ -491,7 +581,7 @@ struct MirrorModifierData : ElemBase {
|
||||||
|
|
||||||
short axis, flag;
|
short axis, flag;
|
||||||
float tolerance;
|
float tolerance;
|
||||||
boost::shared_ptr<Object> mirror_ob;
|
std::shared_ptr<Object> mirror_ob;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -519,34 +609,60 @@ struct Object : ElemBase {
|
||||||
char parsubstr[32] WARN;
|
char parsubstr[32] WARN;
|
||||||
|
|
||||||
Object* parent WARN;
|
Object* parent WARN;
|
||||||
boost::shared_ptr<Object> track WARN;
|
std::shared_ptr<Object> track WARN;
|
||||||
|
|
||||||
boost::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
|
std::shared_ptr<Object> proxy,proxy_from,proxy_group WARN;
|
||||||
boost::shared_ptr<Group> dup_group WARN;
|
std::shared_ptr<Group> dup_group WARN;
|
||||||
boost::shared_ptr<ElemBase> data FAIL;
|
std::shared_ptr<ElemBase> data FAIL;
|
||||||
|
|
||||||
ListBase modifiers;
|
ListBase modifiers;
|
||||||
|
|
||||||
|
Object()
|
||||||
|
: ElemBase()
|
||||||
|
, type( Type_EMPTY )
|
||||||
|
, parent( nullptr )
|
||||||
|
, track()
|
||||||
|
, proxy()
|
||||||
|
, proxy_from()
|
||||||
|
, data() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Base : ElemBase {
|
struct Base : ElemBase {
|
||||||
Base* prev WARN;
|
Base* prev WARN;
|
||||||
boost::shared_ptr<Base> next WARN;
|
std::shared_ptr<Base> next WARN;
|
||||||
boost::shared_ptr<Object> object WARN;
|
std::shared_ptr<Object> object WARN;
|
||||||
|
|
||||||
|
Base()
|
||||||
|
: ElemBase()
|
||||||
|
, next()
|
||||||
|
, object() {
|
||||||
|
// empty
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Scene : ElemBase {
|
struct Scene : ElemBase {
|
||||||
ID id FAIL;
|
ID id FAIL;
|
||||||
|
|
||||||
boost::shared_ptr<Object> camera WARN;
|
std::shared_ptr<Object> camera WARN;
|
||||||
boost::shared_ptr<World> world WARN;
|
std::shared_ptr<World> world WARN;
|
||||||
boost::shared_ptr<Base> basact WARN;
|
std::shared_ptr<Base> basact WARN;
|
||||||
|
|
||||||
ListBase base;
|
ListBase base;
|
||||||
};
|
|
||||||
|
|
||||||
|
Scene()
|
||||||
|
: ElemBase()
|
||||||
|
, camera()
|
||||||
|
, world()
|
||||||
|
, basact() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct Image : ElemBase {
|
struct Image : ElemBase {
|
||||||
|
@ -566,7 +682,7 @@ struct Image : ElemBase {
|
||||||
//unsigned int bindcode;
|
//unsigned int bindcode;
|
||||||
//unsigned int *repbind;
|
//unsigned int *repbind;
|
||||||
|
|
||||||
boost::shared_ptr<PackedFile> packedfile;
|
std::shared_ptr<PackedFile> packedfile;
|
||||||
//struct PreviewImage * preview;
|
//struct PreviewImage * preview;
|
||||||
|
|
||||||
float lastupdate;
|
float lastupdate;
|
||||||
|
@ -574,6 +690,11 @@ struct Image : ElemBase {
|
||||||
short animspeed;
|
short animspeed;
|
||||||
|
|
||||||
short gen_x, gen_y, gen_type;
|
short gen_x, gen_y, gen_type;
|
||||||
|
|
||||||
|
Image()
|
||||||
|
: ElemBase() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -652,7 +773,7 @@ struct Tex : ElemBase {
|
||||||
|
|
||||||
//bNodeTree *nodetree;
|
//bNodeTree *nodetree;
|
||||||
//Ipo *ipo;
|
//Ipo *ipo;
|
||||||
boost::shared_ptr<Image> ima WARN;
|
std::shared_ptr<Image> ima WARN;
|
||||||
//PluginTex *plugin;
|
//PluginTex *plugin;
|
||||||
//ColorBand *coba;
|
//ColorBand *coba;
|
||||||
//EnvMap *env;
|
//EnvMap *env;
|
||||||
|
@ -661,6 +782,12 @@ struct Tex : ElemBase {
|
||||||
//VoxelData *vd;
|
//VoxelData *vd;
|
||||||
|
|
||||||
//char use_nodes;
|
//char use_nodes;
|
||||||
|
|
||||||
|
Tex()
|
||||||
|
: ElemBase() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
@ -719,8 +846,8 @@ struct MTex : ElemBase {
|
||||||
MapType mapto;
|
MapType mapto;
|
||||||
|
|
||||||
BlendType blendtype;
|
BlendType blendtype;
|
||||||
boost::shared_ptr<Object> object;
|
std::shared_ptr<Object> object;
|
||||||
boost::shared_ptr<Tex> tex;
|
std::shared_ptr<Tex> tex;
|
||||||
char uvname[32];
|
char uvname[32];
|
||||||
|
|
||||||
Projection projx,projy,projz;
|
Projection projx,projy,projz;
|
||||||
|
@ -749,9 +876,13 @@ struct MTex : ElemBase {
|
||||||
//float lifefac, sizefac, ivelfac, pvelfac;
|
//float lifefac, sizefac, ivelfac, pvelfac;
|
||||||
//float shadowfac;
|
//float shadowfac;
|
||||||
//float zenupfac, zendownfac, blendfac;
|
//float zenupfac, zendownfac, blendfac;
|
||||||
|
|
||||||
|
MTex()
|
||||||
|
: ElemBase() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (ASSIMP)
|
Open Asset Import Library (ASSIMP)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2010, ASSIMP Development Team
|
Copyright (c) 2006-2016, ASSIMP Development Team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -44,9 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef INCLUDED_AI_BLEND_SCENEGEN_H
|
#ifndef INCLUDED_AI_BLEND_SCENEGEN_H
|
||||||
#define INCLUDED_AI_BLEND_SCENEGEN_H
|
#define INCLUDED_AI_BLEND_SCENEGEN_H
|
||||||
|
|
||||||
namespace Assimp {
|
#include "BlenderDNA.h"
|
||||||
namespace Blender {
|
#include "BlenderScene.h"
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
namespace Blender {
|
||||||
|
|
||||||
template <> void Structure :: Convert<Object> (
|
template <> void Structure :: Convert<Object> (
|
||||||
Object& dest,
|
Object& dest,
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2013, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
@ -42,7 +42,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
* @brief A simple tessellation wrapper
|
* @brief A simple tessellation wrapper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "AssimpPCH.h"
|
|
||||||
|
|
||||||
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
|
||||||
|
|
||||||
|
@ -51,6 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "BlenderBMesh.h"
|
#include "BlenderBMesh.h"
|
||||||
#include "BlenderTessellator.h"
|
#include "BlenderTessellator.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
|
static const unsigned int BLEND_TESS_MAGIC = 0x83ed9ac3;
|
||||||
|
|
||||||
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
#if ASSIMP_BLEND_WITH_GLU_TESSELLATE
|
||||||
|
@ -141,7 +142,7 @@ void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
|
||||||
{
|
{
|
||||||
// NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
|
// NOTE - Because we are supplying a callback to GLU_TESS_EDGE_FLAG_DATA we don't technically
|
||||||
// need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
|
// need support for GL_TRIANGLE_STRIP and GL_TRIANGLE_FAN but we'll keep it here in case
|
||||||
// GLU tessellate changes or tristrips and fans are wanted.
|
// GLU tessellate changes or tri-strips and fans are wanted.
|
||||||
// See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
|
// See: http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml
|
||||||
for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
|
for ( unsigned int i = 0; i < tessData.drawCalls.size( ); ++i )
|
||||||
{
|
{
|
||||||
|
@ -165,7 +166,7 @@ void BlenderTessellatorGL::TriangulateDrawCalls( const TessDataGL& tessData )
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
|
void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vertexCount )
|
||||||
{
|
{
|
||||||
int triangleCount = vertexCount / 3;
|
const int triangleCount = vertexCount / 3;
|
||||||
for ( int i = 0; i < triangleCount; ++i )
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
{
|
{
|
||||||
int vertexBase = i * 3;
|
int vertexBase = i * 3;
|
||||||
|
@ -176,7 +177,7 @@ void BlenderTessellatorGL::MakeFacesFromTris( const VertexGL* vertices, int vert
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
|
void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int vertexCount )
|
||||||
{
|
{
|
||||||
int triangleCount = vertexCount - 2;
|
const int triangleCount = vertexCount - 2;
|
||||||
for ( int i = 0; i < triangleCount; ++i )
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
{
|
{
|
||||||
int vertexBase = i;
|
int vertexBase = i;
|
||||||
|
@ -187,7 +188,7 @@ void BlenderTessellatorGL::MakeFacesFromTriStrip( const VertexGL* vertices, int
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
|
void BlenderTessellatorGL::MakeFacesFromTriFan( const VertexGL* vertices, int vertexCount )
|
||||||
{
|
{
|
||||||
int triangleCount = vertexCount - 2;
|
const int triangleCount = vertexCount - 2;
|
||||||
for ( int i = 0; i < triangleCount; ++i )
|
for ( int i = 0; i < triangleCount; ++i )
|
||||||
{
|
{
|
||||||
int vertexBase = i;
|
int vertexBase = i;
|
||||||
|
@ -324,7 +325,7 @@ void BlenderTessellatorP2T::Copy3DVertices( const MLoop* polyLoop, int vertexCou
|
||||||
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
|
aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::PlaneP2T& plane ) const
|
||||||
{
|
{
|
||||||
aiVector3D sideA( 1.0f, 0.0f, 0.0f );
|
aiVector3D sideA( 1.0f, 0.0f, 0.0f );
|
||||||
if ( fabs( plane.normal * sideA ) > 0.999f )
|
if ( std::fabs( plane.normal * sideA ) > 0.999f )
|
||||||
{
|
{
|
||||||
sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
|
sideA = aiVector3D( 0.0f, 1.0f, 0.0f );
|
||||||
}
|
}
|
||||||
|
@ -354,7 +355,7 @@ aiMatrix4x4 BlenderTessellatorP2T::GeneratePointTransformMatrix( const Blender::
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
|
void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& transform, std::vector< Blender::PointP2T >& vertices ) const
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < vertices.size( ); ++i )
|
for ( size_t i = 0; i < vertices.size( ); ++i )
|
||||||
{
|
{
|
||||||
PointP2T& point = vertices[ i ];
|
PointP2T& point = vertices[ i ];
|
||||||
point.point3D = transform * point.point3D;
|
point.point3D = transform * point.point3D;
|
||||||
|
@ -366,21 +367,16 @@ void BlenderTessellatorP2T::TransformAndFlattenVectices( const aiMatrix4x4& tran
|
||||||
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
|
void BlenderTessellatorP2T::ReferencePoints( std::vector< Blender::PointP2T >& points, std::vector< p2t::Point* >& pointRefs ) const
|
||||||
{
|
{
|
||||||
pointRefs.resize( points.size( ) );
|
pointRefs.resize( points.size( ) );
|
||||||
for ( unsigned int i = 0; i < points.size( ); ++i )
|
for ( size_t i = 0; i < points.size( ); ++i )
|
||||||
{
|
{
|
||||||
pointRefs[ i ] = &points[ i ].point2D;
|
pointRefs[ i ] = &points[ i ].point2D;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Yes this is filthy... but we have no choice
|
|
||||||
#define OffsetOf( Class, Member ) ( static_cast< unsigned int >( \
|
|
||||||
reinterpret_cast<uint8_t*>(&( reinterpret_cast< Class* >( NULL )->*( &Class::Member ) )) - \
|
|
||||||
static_cast<uint8_t*>(NULL) ) )
|
|
||||||
|
|
||||||
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
|
inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& point ) const
|
||||||
{
|
{
|
||||||
unsigned int pointOffset = OffsetOf( PointP2T, point2D );
|
unsigned int pointOffset = offsetof( PointP2T, point2D );
|
||||||
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
|
PointP2T& pointStruct = *reinterpret_cast< PointP2T* >( reinterpret_cast< char* >( &point ) - pointOffset );
|
||||||
if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
|
if ( pointStruct.magic != static_cast<int>( BLEND_TESS_MAGIC ) )
|
||||||
{
|
{
|
||||||
|
@ -392,7 +388,7 @@ inline PointP2T& BlenderTessellatorP2T::GetActualPointStructure( p2t::Point& poi
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
|
void BlenderTessellatorP2T::MakeFacesFromTriangles( std::vector< p2t::Triangle* >& triangles ) const
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < triangles.size( ); ++i )
|
for ( size_t i = 0; i < triangles.size( ); ++i )
|
||||||
{
|
{
|
||||||
p2t::Triangle& Triangle = *triangles[ i ];
|
p2t::Triangle& Triangle = *triangles[ i ];
|
||||||
|
|
||||||
|
@ -416,11 +412,11 @@ float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) con
|
||||||
{
|
{
|
||||||
float result = 0.0f;
|
float result = 0.0f;
|
||||||
|
|
||||||
for ( int x = 0; x < 3; ++x )
|
for ( unsigned int x = 0; x < 3; ++x )
|
||||||
{
|
{
|
||||||
for ( int y = 0; y < 3; ++y )
|
for ( unsigned int y = 0; y < 3; ++y )
|
||||||
{
|
{
|
||||||
result = p2tMax( fabs( mtx[ x ][ y ] ), result );
|
result = p2tMax( std::fabs( mtx[ x ][ y ] ), result );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,14 +424,14 @@ float BlenderTessellatorP2T::FindLargestMatrixElem( const aiMatrix3x3& mtx ) con
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Aparently Assimp doesn't have matrix scaling
|
// Apparently Assimp doesn't have matrix scaling
|
||||||
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
|
aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float scale ) const
|
||||||
{
|
{
|
||||||
aiMatrix3x3 result;
|
aiMatrix3x3 result;
|
||||||
|
|
||||||
for ( int x = 0; x < 3; ++x )
|
for ( unsigned int x = 0; x < 3; ++x )
|
||||||
{
|
{
|
||||||
for ( int y = 0; y < 3; ++y )
|
for ( unsigned int y = 0; y < 3; ++y )
|
||||||
{
|
{
|
||||||
result[ x ][ y ] = mtx[ x ][ y ] * scale;
|
result[ x ][ y ] = mtx[ x ][ y ] * scale;
|
||||||
}
|
}
|
||||||
|
@ -449,7 +445,7 @@ aiMatrix3x3 BlenderTessellatorP2T::ScaleMatrix( const aiMatrix3x3& mtx, float sc
|
||||||
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
// Adapted from: http://missingbytes.blogspot.co.uk/2012/06/fitting-plane-to-point-cloud.html
|
||||||
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
|
aiVector3D BlenderTessellatorP2T::GetEigenVectorFromLargestEigenValue( const aiMatrix3x3& mtx ) const
|
||||||
{
|
{
|
||||||
float scale = FindLargestMatrixElem( mtx );
|
const float scale = FindLargestMatrixElem( mtx );
|
||||||
aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
|
aiMatrix3x3 mc = ScaleMatrix( mtx, 1.0f / scale );
|
||||||
mc = mc * mc * mc;
|
mc = mc * mc * mc;
|
||||||
|
|
||||||
|
@ -474,20 +470,20 @@ PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& po
|
||||||
{
|
{
|
||||||
PlaneP2T result;
|
PlaneP2T result;
|
||||||
|
|
||||||
aiVector3D sum( 0.0f );
|
aiVector3D sum( 0.0 );
|
||||||
for ( unsigned int i = 0; i < points.size( ); ++i )
|
for ( size_t i = 0; i < points.size( ); ++i )
|
||||||
{
|
{
|
||||||
sum += points[ i ].point3D;
|
sum += points[ i ].point3D;
|
||||||
}
|
}
|
||||||
result.centre = sum * ( 1.0f / points.size( ) );
|
result.centre = sum * (ai_real)( 1.0 / points.size( ) );
|
||||||
|
|
||||||
float sumXX = 0.0f;
|
ai_real sumXX = 0.0;
|
||||||
float sumXY = 0.0f;
|
ai_real sumXY = 0.0;
|
||||||
float sumXZ = 0.0f;
|
ai_real sumXZ = 0.0;
|
||||||
float sumYY = 0.0f;
|
ai_real sumYY = 0.0;
|
||||||
float sumYZ = 0.0f;
|
ai_real sumYZ = 0.0;
|
||||||
float sumZZ = 0.0f;
|
ai_real sumZZ = 0.0;
|
||||||
for ( unsigned int i = 0; i < points.size( ); ++i )
|
for ( size_t i = 0; i < points.size( ); ++i )
|
||||||
{
|
{
|
||||||
aiVector3D offset = points[ i ].point3D - result.centre;
|
aiVector3D offset = points[ i ].point3D - result.centre;
|
||||||
sumXX += offset.x * offset.x;
|
sumXX += offset.x * offset.x;
|
||||||
|
@ -500,7 +496,7 @@ PlaneP2T BlenderTessellatorP2T::FindLLSQPlane( const std::vector< PointP2T >& po
|
||||||
|
|
||||||
aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
|
aiMatrix3x3 mtx( sumXX, sumXY, sumXZ, sumXY, sumYY, sumYZ, sumXZ, sumYZ, sumZZ );
|
||||||
|
|
||||||
float det = mtx.Determinant( );
|
const ai_real det = mtx.Determinant( );
|
||||||
if ( det == 0.0f )
|
if ( det == 0.0f )
|
||||||
{
|
{
|
||||||
result.normal = aiVector3D( 0.0f );
|
result.normal = aiVector3D( 0.0f );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2013, assimp team
|
Copyright (c) 2006-2016, 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,
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
---------------------------------------------------------------------------
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
|
@ -45,6 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED
|
#ifndef AI_BLOBIOSYSTEM_H_INCLUDED
|
||||||
#define AI_BLOBIOSYSTEM_H_INCLUDED
|
#define AI_BLOBIOSYSTEM_H_INCLUDED
|
||||||
|
|
||||||
|
#include "./../include/assimp/IOStream.hpp"
|
||||||
|
#include "./../include/assimp/cexport.h"
|
||||||
|
#include "./../include/assimp/IOSystem.hpp"
|
||||||
|
#include "./../include/assimp/DefaultLogger.hpp"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
class BlobIOSystem;
|
class BlobIOSystem;
|
||||||
|
|
||||||
|
@ -120,9 +128,11 @@ public:
|
||||||
{
|
{
|
||||||
case aiOrigin_CUR:
|
case aiOrigin_CUR:
|
||||||
cursor += pOffset;
|
cursor += pOffset;
|
||||||
|
break;
|
||||||
|
|
||||||
case aiOrigin_END:
|
case aiOrigin_END:
|
||||||
cursor = file_size - pOffset;
|
cursor = file_size - pOffset;
|
||||||
|
break;
|
||||||
|
|
||||||
case aiOrigin_SET:
|
case aiOrigin_SET:
|
||||||
cursor = pOffset;
|
cursor = pOffset;
|
||||||
|
@ -213,7 +223,7 @@ public:
|
||||||
|
|
||||||
virtual ~BlobIOSystem()
|
virtual ~BlobIOSystem()
|
||||||
{
|
{
|
||||||
BOOST_FOREACH(BlobEntry& blobby, blobs) {
|
for(BlobEntry& blobby : blobs) {
|
||||||
delete blobby.second;
|
delete blobby.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +242,7 @@ public:
|
||||||
{
|
{
|
||||||
// one must be the master
|
// one must be the master
|
||||||
aiExportDataBlob* master = NULL, *cur;
|
aiExportDataBlob* master = NULL, *cur;
|
||||||
BOOST_FOREACH(const BlobEntry& blobby, blobs) {
|
for(const BlobEntry& blobby : blobs) {
|
||||||
if (blobby.first == AI_BLOBIO_MAGIC) {
|
if (blobby.first == AI_BLOBIO_MAGIC) {
|
||||||
master = blobby.second;
|
master = blobby.second;
|
||||||
break;
|
break;
|
||||||
|
@ -246,7 +256,7 @@ public:
|
||||||
master->name.Set("");
|
master->name.Set("");
|
||||||
|
|
||||||
cur = master;
|
cur = master;
|
||||||
BOOST_FOREACH(const BlobEntry& blobby, blobs) {
|
for(const BlobEntry& blobby : blobs) {
|
||||||
if (blobby.second == master) {
|
if (blobby.second == master) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
Boost Software License - Version 1.0 - August 17th, 2003
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person or organization
|
|
||||||
obtaining a copy of the software and accompanying documentation covered by
|
|
||||||
this license (the "Software") to use, reproduce, display, distribute,
|
|
||||||
execute, and transmit the Software, and to prepare derivative works of the
|
|
||||||
Software, and to permit third-parties to whom the Software is furnished to
|
|
||||||
do so, all subject to the following:
|
|
||||||
|
|
||||||
The copyright notices in the Software and this entire statement, including
|
|
||||||
the above license grant, this restriction and the following disclaimer,
|
|
||||||
must be included in all copies of the Software, in whole or in part, and
|
|
||||||
all derivative works of the Software, unless such copies or derivative
|
|
||||||
works are solely in the form of machine-executable object code generated by
|
|
||||||
a source language processor.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
||||||
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
|
@ -1,99 +0,0 @@
|
||||||
|
|
||||||
#ifndef BOOST_FOREACH
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// A stripped down version of FOREACH for
|
|
||||||
// illustration purposes. NOT FOR GENERAL USE.
|
|
||||||
// For a complete implementation, see BOOST_FOREACH at
|
|
||||||
// http://boost-sandbox.sourceforge.net/vault/index.php?directory=eric_niebler
|
|
||||||
//
|
|
||||||
// Copyright 2004 Eric Niebler.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0. (See
|
|
||||||
// accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
// Adapted to Assimp November 29th, 2008 (Alexander Gessler).
|
|
||||||
// Added code to handle both const and non-const iterators, simplified some
|
|
||||||
// parts.
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace foreach_detail {
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// auto_any
|
|
||||||
|
|
||||||
struct auto_any_base
|
|
||||||
{
|
|
||||||
operator bool() const { return false; }
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct auto_any : auto_any_base
|
|
||||||
{
|
|
||||||
auto_any(T const& t) : item(t) {}
|
|
||||||
mutable T item;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T& auto_any_cast(auto_any_base const& any)
|
|
||||||
{
|
|
||||||
return static_cast<auto_any<T> const&>(any).item;
|
|
||||||
}
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FOREACH helper function
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
auto_any<typename T::const_iterator> begin(T const& t)
|
|
||||||
{
|
|
||||||
return t.begin();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
auto_any<typename T::const_iterator> end(T const& t)
|
|
||||||
{
|
|
||||||
return t.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
// iterator
|
|
||||||
template<typename T>
|
|
||||||
bool done(auto_any_base const& cur, auto_any_base const& end, T&)
|
|
||||||
{
|
|
||||||
typedef typename T::iterator iter_type;
|
|
||||||
return auto_any_cast<iter_type>(cur) == auto_any_cast<iter_type>(end);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void next(auto_any_base const& cur, T&)
|
|
||||||
{
|
|
||||||
++auto_any_cast<typename T::iterator>(cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename T::reference deref(auto_any_base const& cur, T&)
|
|
||||||
{
|
|
||||||
return *auto_any_cast<typename T::iterator>(cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename T::const_reference deref(auto_any_base const& cur, const T&)
|
|
||||||
{
|
|
||||||
return *auto_any_cast<typename T::iterator>(cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end foreach_detail
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// FOREACH
|
|
||||||
|
|
||||||
#define BOOST_FOREACH(item, container) \
|
|
||||||
if(boost::foreach_detail::auto_any_base const& foreach_magic_b = boost::foreach_detail::begin(container)) {} else \
|
|
||||||
if(boost::foreach_detail::auto_any_base const& foreach_magic_e = boost::foreach_detail::end(container)) {} else \
|
|
||||||
for(;!boost::foreach_detail::done(foreach_magic_b,foreach_magic_e,container); boost::foreach_detail::next(foreach_magic_b,container)) \
|
|
||||||
if (bool ugly_and_unique_break = false) {} else \
|
|
||||||
for(item = boost::foreach_detail::deref(foreach_magic_b,container); !ugly_and_unique_break; ugly_and_unique_break = true)
|
|
||||||
|
|
||||||
} // end boost
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,81 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* DEPRECATED! - use code/TinyFormatter.h instead.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* */
|
|
||||||
|
|
||||||
#ifndef AI_BOOST_FORMAT_DUMMY_INCLUDED
|
|
||||||
#define AI_BOOST_FORMAT_DUMMY_INCLUDED
|
|
||||||
|
|
||||||
#if (!defined BOOST_FORMAT_HPP) || (defined ASSIMP_FORCE_NOBOOST)
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class format
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
format (const std::string& _d)
|
|
||||||
: d(_d)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
format& operator % (T in)
|
|
||||||
{
|
|
||||||
// XXX add replacement for boost::lexical_cast?
|
|
||||||
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << in; // note: ss cannot be an rvalue, or the global operator << (const char*) is not called for T == const char*.
|
|
||||||
chunks.push_back( ss.str());
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
operator std::string () const {
|
|
||||||
std::string res; // pray for NRVO to kick in
|
|
||||||
|
|
||||||
size_t start = 0, last = 0;
|
|
||||||
|
|
||||||
std::vector<std::string>::const_iterator chunkin = chunks.begin();
|
|
||||||
|
|
||||||
for ( start = d.find('%');start != std::string::npos; start = d.find('%',last)) {
|
|
||||||
res += d.substr(last,start-last);
|
|
||||||
last = start+2;
|
|
||||||
if (d[start+1] == '%') {
|
|
||||||
res += "%";
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chunkin == chunks.end()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
res += *chunkin++;
|
|
||||||
}
|
|
||||||
res += d.substr(last);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string d;
|
|
||||||
std::vector<std::string> chunks;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::string str(const std::string& s) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
# error "format.h was already included"
|
|
||||||
#endif //
|
|
||||||
#endif // !! AI_BOOST_FORMAT_DUMMY_INCLUDED
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
/// A quick replacement for boost::lexical_cast for all the Boost haters out there
|
|
||||||
|
|
||||||
#ifndef __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
|
||||||
#define __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
namespace boost
|
|
||||||
{
|
|
||||||
|
|
||||||
/// A quick replacement for boost::lexical_cast - should work for all types a stringstream can handle
|
|
||||||
template <typename TargetType, typename SourceType>
|
|
||||||
TargetType lexical_cast( const SourceType& source)
|
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
TargetType result;
|
|
||||||
|
|
||||||
stream << source;
|
|
||||||
stream >> result;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // __AI_BOOST_WORKAROUND_LEXICAL_CAST
|
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
|
|
||||||
// please note that this replacement implementation does not
|
|
||||||
// provide the performance benefit of the original, which
|
|
||||||
// makes only one allocation as opposed to two allocations
|
|
||||||
// (smart pointer counter and payload) which are usually
|
|
||||||
// required if object and smart pointer are constructed
|
|
||||||
// independently.
|
|
||||||
|
|
||||||
#ifndef INCLUDED_AI_BOOST_MAKE_SHARED
|
|
||||||
#define INCLUDED_AI_BOOST_MAKE_SHARED
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
shared_ptr<T> make_shared() {
|
|
||||||
return shared_ptr<T>(new T());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0) {
|
|
||||||
return shared_ptr<T>(new T(t0));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0,typename T1>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0, const T1& t1) {
|
|
||||||
return shared_ptr<T>(new T(t0,t1));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0,typename T1,typename T2>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2) {
|
|
||||||
return shared_ptr<T>(new T(t0,t1,t2));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0,typename T1,typename T2,typename T3>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
|
|
||||||
return shared_ptr<T>(new T(t0,t1,t2,t3));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0,typename T1,typename T2,typename T3, typename T4>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4) {
|
|
||||||
return shared_ptr<T>(new T(t0,t1,t2,t3,t4));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0,typename T1,typename T2,typename T3, typename T4, typename T5>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5) {
|
|
||||||
return shared_ptr<T>(new T(t0,t1,t2,t3,t4,t5));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, typename T0,typename T1,typename T2,typename T3, typename T4, typename T5, typename T6>
|
|
||||||
shared_ptr<T> make_shared(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6) {
|
|
||||||
return shared_ptr<T>(new T(t0,t1,t2,t3,t4,t5,t6));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,37 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef BOOST_MATH_COMMON_FACTOR_RT_HPP
|
|
||||||
#define BOOST_MATH_COMMON_FACTOR_RT_HPP
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace math {
|
|
||||||
|
|
||||||
// TODO: use binary GCD for unsigned integers ....
|
|
||||||
template < typename IntegerType >
|
|
||||||
IntegerType gcd( IntegerType a, IntegerType b )
|
|
||||||
{
|
|
||||||
const IntegerType zero = (IntegerType)0;
|
|
||||||
while ( true )
|
|
||||||
{
|
|
||||||
if ( a == zero )
|
|
||||||
return b;
|
|
||||||
b %= a;
|
|
||||||
|
|
||||||
if ( b == zero )
|
|
||||||
return a;
|
|
||||||
a %= b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template < typename IntegerType >
|
|
||||||
IntegerType lcm( IntegerType a, IntegerType b )
|
|
||||||
{
|
|
||||||
const IntegerType t = gcd (a,b);
|
|
||||||
if (!t)return t;
|
|
||||||
return a / t * b;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,36 +0,0 @@
|
||||||
// Boost noncopyable.hpp header file --------------------------------------//
|
|
||||||
|
|
||||||
// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost
|
|
||||||
// Software License, Version 1.0. (See accompanying file
|
|
||||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
// See http://www.boost.org/libs/utility for documentation.
|
|
||||||
|
|
||||||
#ifndef BOOST_NONCOPYABLE_HPP_INCLUDED
|
|
||||||
#define BOOST_NONCOPYABLE_HPP_INCLUDED
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// Private copy constructor and copy assignment ensure classes derived from
|
|
||||||
// class noncopyable cannot be copied.
|
|
||||||
|
|
||||||
// Contributed by Dave Abrahams
|
|
||||||
|
|
||||||
namespace noncopyable_ // protection from unintended ADL
|
|
||||||
{
|
|
||||||
class noncopyable
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
noncopyable() {}
|
|
||||||
~noncopyable() {}
|
|
||||||
private: // emphasize the following members are private
|
|
||||||
noncopyable( const noncopyable& );
|
|
||||||
const noncopyable& operator=( const noncopyable& );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef noncopyable_::noncopyable noncopyable;
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_NONCOPYABLE_HPP_INCLUDED
|
|
|
@ -1,45 +0,0 @@
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// (C) Copyright Ion Gaztanaga 2005.
|
|
||||||
// Distributed under the Boost Software License, Version 1.0.
|
|
||||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
|
||||||
// http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
//
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#ifndef BOOST_POINTER_CAST_HPP
|
|
||||||
#define BOOST_POINTER_CAST_HPP
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
//static_pointer_cast overload for raw pointers
|
|
||||||
template<class T, class U>
|
|
||||||
inline T* static_pointer_cast(U *ptr)
|
|
||||||
{
|
|
||||||
return static_cast<T*>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//dynamic_pointer_cast overload for raw pointers
|
|
||||||
template<class T, class U>
|
|
||||||
inline T* dynamic_pointer_cast(U *ptr)
|
|
||||||
{
|
|
||||||
return dynamic_cast<T*>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//const_pointer_cast overload for raw pointers
|
|
||||||
template<class T, class U>
|
|
||||||
inline T* const_pointer_cast(U *ptr)
|
|
||||||
{
|
|
||||||
return const_cast<T*>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//reinterpret_pointer_cast overload for raw pointers
|
|
||||||
template<class T, class U>
|
|
||||||
inline T* reinterpret_pointer_cast(U *ptr)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<T*>(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif //BOOST_POINTER_CAST_HPP
|
|
|
@ -1,79 +0,0 @@
|
||||||
|
|
||||||
#ifndef __AI_BOOST_SCOPED_ARRAY_INCLUDED
|
|
||||||
#define __AI_BOOST_SCOPED_ARRAY_INCLUDED
|
|
||||||
|
|
||||||
#ifndef BOOST_SCOPED_ARRAY_HPP_INCLUDED
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// small replacement for boost::scoped_array
|
|
||||||
template <class T>
|
|
||||||
class scoped_array
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// provide a default construtctor
|
|
||||||
scoped_array()
|
|
||||||
: ptr(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// construction from an existing heap object of type T
|
|
||||||
scoped_array(T* _ptr)
|
|
||||||
: ptr(_ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// automatic destruction of the wrapped object at the
|
|
||||||
// end of our lifetime
|
|
||||||
~scoped_array()
|
|
||||||
{
|
|
||||||
delete[] ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T* get()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T* operator-> ()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void reset (T* t = 0)
|
|
||||||
{
|
|
||||||
delete[] ptr;
|
|
||||||
ptr = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
T & operator[](std::ptrdiff_t i) const
|
|
||||||
{
|
|
||||||
return ptr[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(scoped_array & b)
|
|
||||||
{
|
|
||||||
std::swap(ptr, b.ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// encapsulated object pointer
|
|
||||||
T* ptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline void swap(scoped_array<T> & a, scoped_array<T> & b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace boost
|
|
||||||
|
|
||||||
#else
|
|
||||||
# error "scoped_array.h was already included"
|
|
||||||
#endif
|
|
||||||
#endif // __AI_BOOST_SCOPED_ARRAY_INCLUDED
|
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
|
|
||||||
#ifndef __AI_BOOST_SCOPED_PTR_INCLUDED
|
|
||||||
#define __AI_BOOST_SCOPED_PTR_INCLUDED
|
|
||||||
|
|
||||||
#ifndef BOOST_SCOPED_PTR_HPP_INCLUDED
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// small replacement for boost::scoped_ptr
|
|
||||||
template <class T>
|
|
||||||
class scoped_ptr
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// provide a default construtctor
|
|
||||||
scoped_ptr()
|
|
||||||
: ptr(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// construction from an existing heap object of type T
|
|
||||||
scoped_ptr(T* _ptr)
|
|
||||||
: ptr(_ptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// automatic destruction of the wrapped object at the
|
|
||||||
// end of our lifetime
|
|
||||||
~scoped_ptr()
|
|
||||||
{
|
|
||||||
delete ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T* get() const
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator T*()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T* operator-> ()
|
|
||||||
{
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void reset (T* t = 0)
|
|
||||||
{
|
|
||||||
delete ptr;
|
|
||||||
ptr = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(scoped_ptr & b)
|
|
||||||
{
|
|
||||||
std::swap(ptr, b.ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// encapsulated object pointer
|
|
||||||
T* ptr;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline void swap(scoped_ptr<T> & a, scoped_ptr<T> & b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace boost
|
|
||||||
|
|
||||||
#else
|
|
||||||
# error "scoped_ptr.h was already included"
|
|
||||||
#endif
|
|
||||||
#endif // __AI_BOOST_SCOPED_PTR_INCLUDED
|
|
||||||
|
|
|
@ -1,228 +0,0 @@
|
||||||
|
|
||||||
#ifndef INCLUDED_AI_BOOST_SHARED_ARRAY
|
|
||||||
#define INCLUDED_AI_BOOST_SHARED_ARRAY
|
|
||||||
|
|
||||||
#ifndef BOOST_SHARED_ARRAY_HPP_INCLUDED
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// Internal stub
|
|
||||||
namespace boost {
|
|
||||||
namespace array_detail {
|
|
||||||
class controller {
|
|
||||||
public:
|
|
||||||
|
|
||||||
controller()
|
|
||||||
: cnt(1)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
controller* decref(T* pt) {
|
|
||||||
if (--cnt <= 0) {
|
|
||||||
delete this;
|
|
||||||
delete[] pt;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
controller* incref() {
|
|
||||||
++cnt;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
long get() const {
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
long cnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct empty {};
|
|
||||||
|
|
||||||
template <typename DEST, typename SRC>
|
|
||||||
struct is_convertible_stub {
|
|
||||||
|
|
||||||
struct yes {char s[1];};
|
|
||||||
struct no {char s[2];};
|
|
||||||
|
|
||||||
static yes foo(DEST*);
|
|
||||||
static no foo(...);
|
|
||||||
|
|
||||||
enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool> struct enable_if {};
|
|
||||||
template <> struct enable_if<true> {
|
|
||||||
typedef empty result;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DEST, typename SRC>
|
|
||||||
struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// Small replacement for boost::shared_array, not threadsafe because no
|
|
||||||
// atomic reference counter is in use.
|
|
||||||
// ------------------------------
|
|
||||||
template <class T>
|
|
||||||
class shared_array
|
|
||||||
{
|
|
||||||
template <typename TT> friend class shared_array;
|
|
||||||
|
|
||||||
template<class TT> friend bool operator== (const shared_array<TT>& a, const shared_array<TT>& b);
|
|
||||||
template<class TT> friend bool operator!= (const shared_array<TT>& a, const shared_array<TT>& b);
|
|
||||||
template<class TT> friend bool operator< (const shared_array<TT>& a, const shared_array<TT>& b);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef T element_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// provide a default constructor
|
|
||||||
shared_array()
|
|
||||||
: ptr()
|
|
||||||
, ctr(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// construction from an existing object of type T
|
|
||||||
explicit shared_array(T* ptr)
|
|
||||||
: ptr(ptr)
|
|
||||||
, ctr(ptr ? new array_detail::controller() : NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_array(const shared_array& r)
|
|
||||||
: ptr(r.ptr)
|
|
||||||
, ctr(r.ctr ? r.ctr->incref() : NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Y>
|
|
||||||
shared_array(const shared_array<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
|
||||||
: ptr(r.ptr)
|
|
||||||
, ctr(r.ctr ? r.ctr->incref() : NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// automatic destruction of the wrapped object when all
|
|
||||||
// references are freed.
|
|
||||||
~shared_array() {
|
|
||||||
if (ctr) {
|
|
||||||
ctr = ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_array& operator=(const shared_array& r) {
|
|
||||||
if (this == &r) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (ctr) {
|
|
||||||
ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
ptr = r.ptr;
|
|
||||||
ctr = ptr?r.ctr->incref():NULL;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Y>
|
|
||||||
shared_array& operator=(const shared_array<Y>& r) {
|
|
||||||
if (this == &r) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (ctr) {
|
|
||||||
ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
ptr = r.ptr;
|
|
||||||
ctr = ptr?r.ctr->incref():NULL;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pointer access
|
|
||||||
inline operator T*() {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T* operator-> () const {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// standard semantics
|
|
||||||
inline T* get() {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
T& operator[] (std::ptrdiff_t index) const {
|
|
||||||
return ptr[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const T* get() const {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator bool () const {
|
|
||||||
return ptr != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool unique() const {
|
|
||||||
return use_count() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline long use_count() const {
|
|
||||||
return ctr->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void reset (T* t = 0) {
|
|
||||||
if (ctr) {
|
|
||||||
ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
ptr = t;
|
|
||||||
ctr = ptr?new array_detail::controller():NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(shared_array & b) {
|
|
||||||
std::swap(ptr, b.ptr);
|
|
||||||
std::swap(ctr, b.ctr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// encapsulated object pointer
|
|
||||||
T* ptr;
|
|
||||||
|
|
||||||
// control block
|
|
||||||
array_detail::controller* ctr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline void swap(shared_array<T> & a, shared_array<T> & b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool operator== (const shared_array<T>& a, const shared_array<T>& b) {
|
|
||||||
return a.ptr == b.ptr;
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
bool operator!= (const shared_array<T>& a, const shared_array<T>& b) {
|
|
||||||
return a.ptr != b.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool operator< (const shared_array<T>& a, const shared_array<T>& b) {
|
|
||||||
return a.ptr < b.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace boost
|
|
||||||
|
|
||||||
#else
|
|
||||||
# error "shared_array.h was already included"
|
|
||||||
#endif
|
|
||||||
#endif // INCLUDED_AI_BOOST_SHARED_ARRAY
|
|
|
@ -1,257 +0,0 @@
|
||||||
|
|
||||||
#ifndef INCLUDED_AI_BOOST_SHARED_PTR
|
|
||||||
#define INCLUDED_AI_BOOST_SHARED_PTR
|
|
||||||
|
|
||||||
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// Internal stub
|
|
||||||
namespace boost {
|
|
||||||
namespace detail {
|
|
||||||
class controller {
|
|
||||||
public:
|
|
||||||
|
|
||||||
controller()
|
|
||||||
: cnt(1)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
controller* decref(T* pt) {
|
|
||||||
if (--cnt <= 0) {
|
|
||||||
delete this;
|
|
||||||
delete pt;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
controller* incref() {
|
|
||||||
++cnt;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
long get() const {
|
|
||||||
return cnt;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
long cnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct empty {};
|
|
||||||
|
|
||||||
template <typename DEST, typename SRC>
|
|
||||||
struct is_convertible_stub {
|
|
||||||
|
|
||||||
struct yes {char s[1];};
|
|
||||||
struct no {char s[2];};
|
|
||||||
|
|
||||||
static yes foo(DEST*);
|
|
||||||
static no foo(...);
|
|
||||||
|
|
||||||
enum {result = (sizeof(foo((SRC*)0)) == sizeof(yes) ? 1 : 0)};
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool> struct enable_if {};
|
|
||||||
template <> struct enable_if<true> {
|
|
||||||
typedef empty result;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename DEST, typename SRC>
|
|
||||||
struct is_convertible : public enable_if<is_convertible_stub<DEST,SRC>::result > {
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// Small replacement for boost::shared_ptr, not threadsafe because no
|
|
||||||
// atomic reference counter is in use.
|
|
||||||
// ------------------------------
|
|
||||||
template <class T>
|
|
||||||
class shared_ptr
|
|
||||||
{
|
|
||||||
template <typename TT> friend class shared_ptr;
|
|
||||||
|
|
||||||
template<class TT, class U> friend shared_ptr<TT> static_pointer_cast (shared_ptr<U> ptr);
|
|
||||||
template<class TT, class U> friend shared_ptr<TT> dynamic_pointer_cast (shared_ptr<U> ptr);
|
|
||||||
template<class TT, class U> friend shared_ptr<TT> const_pointer_cast (shared_ptr<U> ptr);
|
|
||||||
|
|
||||||
template<class TT> friend bool operator== (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
|
||||||
template<class TT> friend bool operator!= (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
|
||||||
template<class TT> friend bool operator< (const shared_ptr<TT>& a, const shared_ptr<TT>& b);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef T element_type;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// provide a default constructor
|
|
||||||
shared_ptr()
|
|
||||||
: ptr()
|
|
||||||
, ctr(NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// construction from an existing object of type T
|
|
||||||
explicit shared_ptr(T* ptr)
|
|
||||||
: ptr(ptr)
|
|
||||||
, ctr(ptr ? new detail::controller() : NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr(const shared_ptr& r)
|
|
||||||
: ptr(r.ptr)
|
|
||||||
, ctr(r.ctr ? r.ctr->incref() : NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Y>
|
|
||||||
shared_ptr(const shared_ptr<Y>& r,typename detail::is_convertible<T,Y>::result = detail::empty())
|
|
||||||
: ptr(r.ptr)
|
|
||||||
, ctr(r.ctr ? r.ctr->incref() : NULL)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// automatic destruction of the wrapped object when all
|
|
||||||
// references are freed.
|
|
||||||
~shared_ptr() {
|
|
||||||
if (ctr) {
|
|
||||||
ctr = ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr& operator=(const shared_ptr& r) {
|
|
||||||
if (this == &r) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (ctr) {
|
|
||||||
ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
ptr = r.ptr;
|
|
||||||
ctr = ptr?r.ctr->incref():NULL;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Y>
|
|
||||||
shared_ptr& operator=(const shared_ptr<Y>& r) {
|
|
||||||
if (this == &r) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
if (ctr) {
|
|
||||||
ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
ptr = r.ptr;
|
|
||||||
ctr = ptr?r.ctr->incref():NULL;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pointer access
|
|
||||||
inline operator T*() const {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline T* operator-> () const {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// standard semantics
|
|
||||||
inline T* get() {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const T* get() const {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline operator bool () const {
|
|
||||||
return ptr != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool unique() const {
|
|
||||||
return use_count() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline long use_count() const {
|
|
||||||
return ctr->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void reset (T* t = 0) {
|
|
||||||
if (ctr) {
|
|
||||||
ctr->decref(ptr);
|
|
||||||
}
|
|
||||||
ptr = t;
|
|
||||||
ctr = ptr?new detail::controller():NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap(shared_ptr & b) {
|
|
||||||
std::swap(ptr, b.ptr);
|
|
||||||
std::swap(ctr, b.ctr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
// for use by the various xxx_pointer_cast helper templates
|
|
||||||
explicit shared_ptr(T* ptr, detail::controller* ctr)
|
|
||||||
: ptr(ptr)
|
|
||||||
, ctr(ctr->incref())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// encapsulated object pointer
|
|
||||||
T* ptr;
|
|
||||||
|
|
||||||
// control block
|
|
||||||
detail::controller* ctr;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline void swap(shared_ptr<T> & a, shared_ptr<T> & b)
|
|
||||||
{
|
|
||||||
a.swap(b);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool operator== (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
|
||||||
return a.ptr == b.ptr;
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
bool operator!= (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
|
||||||
return a.ptr != b.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
bool operator< (const shared_ptr<T>& a, const shared_ptr<T>& b) {
|
|
||||||
return a.ptr < b.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class T, class U>
|
|
||||||
inline shared_ptr<T> static_pointer_cast( shared_ptr<U> ptr)
|
|
||||||
{
|
|
||||||
return shared_ptr<T>(static_cast<T*>(ptr.ptr),ptr.ctr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class U>
|
|
||||||
inline shared_ptr<T> dynamic_pointer_cast( shared_ptr<U> ptr)
|
|
||||||
{
|
|
||||||
return shared_ptr<T>(dynamic_cast<T*>(ptr.ptr),ptr.ctr);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T, class U>
|
|
||||||
inline shared_ptr<T> const_pointer_cast( shared_ptr<U> ptr)
|
|
||||||
{
|
|
||||||
return shared_ptr<T>(const_cast<T*>(ptr.ptr),ptr.ctr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // end of namespace boost
|
|
||||||
|
|
||||||
#else
|
|
||||||
# error "shared_ptr.h was already included"
|
|
||||||
#endif
|
|
||||||
#endif // INCLUDED_AI_BOOST_SHARED_PTR
|
|
|
@ -1,20 +0,0 @@
|
||||||
|
|
||||||
#ifndef AI_BOOST_STATIC_ASSERT_INCLUDED
|
|
||||||
#define AI_BOOST_STATIC_ASSERT_INCLUDED
|
|
||||||
|
|
||||||
#ifndef BOOST_STATIC_ASSERT
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
template <bool b> class static_assertion_failure;
|
|
||||||
template <> class static_assertion_failure<true> {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define BOOST_STATIC_ASSERT(eval) \
|
|
||||||
{boost::detail::static_assertion_failure<(eval)> assert_dummy;(void)assert_dummy;}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif // !! AI_BOOST_STATIC_ASSERT_INCLUDED
|
|
|
@ -1,72 +0,0 @@
|
||||||
// boost timer.hpp header file ---------------------------------------------//
|
|
||||||
|
|
||||||
// Copyright Beman Dawes 1994-99. Distributed under the Boost
|
|
||||||
// Software License, Version 1.0. (See accompanying file
|
|
||||||
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
||||||
|
|
||||||
// See http://www.boost.org/libs/timer for documentation.
|
|
||||||
|
|
||||||
// Revision History
|
|
||||||
// 01 Apr 01 Modified to use new <boost/limits.hpp> header. (JMaddock)
|
|
||||||
// 12 Jan 01 Change to inline implementation to allow use without library
|
|
||||||
// builds. See docs for more rationale. (Beman Dawes)
|
|
||||||
// 25 Sep 99 elapsed_max() and elapsed_min() added (John Maddock)
|
|
||||||
// 16 Jul 99 Second beta
|
|
||||||
// 6 Jul 99 Initial boost version
|
|
||||||
|
|
||||||
#ifndef BOOST_TIMER_HPP
|
|
||||||
#define BOOST_TIMER_HPP
|
|
||||||
|
|
||||||
//#include <boost/config.hpp>
|
|
||||||
#include <ctime>
|
|
||||||
//#include <boost/limits.hpp>
|
|
||||||
|
|
||||||
# ifdef BOOST_NO_STDC_NAMESPACE
|
|
||||||
namespace std { using ::clock_t; using ::clock; }
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
|
|
||||||
// timer -------------------------------------------------------------------//
|
|
||||||
|
|
||||||
// A timer object measures elapsed time.
|
|
||||||
|
|
||||||
// It is recommended that implementations measure wall clock rather than CPU
|
|
||||||
// time since the intended use is performance measurement on systems where
|
|
||||||
// total elapsed time is more important than just process or CPU time.
|
|
||||||
|
|
||||||
// Warnings: The maximum measurable elapsed time may well be only 596.5+ hours
|
|
||||||
// due to implementation limitations. The accuracy of timings depends on the
|
|
||||||
// accuracy of timing information provided by the underlying platform, and
|
|
||||||
// this varies a great deal from platform to platform.
|
|
||||||
|
|
||||||
class timer
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
timer() { _start_time = std::clock(); } // postcondition: elapsed()==0
|
|
||||||
// timer( const timer& src ); // post: elapsed()==src.elapsed()
|
|
||||||
// ~timer(){}
|
|
||||||
// timer& operator=( const timer& src ); // post: elapsed()==src.elapsed()
|
|
||||||
void restart() { _start_time = std::clock(); } // post: elapsed()==0
|
|
||||||
double elapsed() const // return elapsed time in seconds
|
|
||||||
{ return double(std::clock() - _start_time) / CLOCKS_PER_SEC; }
|
|
||||||
|
|
||||||
double elapsed_max() const // return estimated maximum value for elapsed()
|
|
||||||
// Portability warning: elapsed_max() may return too high a value on systems
|
|
||||||
// where std::clock_t overflows or resets at surprising values.
|
|
||||||
{
|
|
||||||
return (double((std::numeric_limits<std::clock_t>::max)())
|
|
||||||
- double(_start_time)) / double(CLOCKS_PER_SEC);
|
|
||||||
}
|
|
||||||
|
|
||||||
double elapsed_min() const // return minimum value for elapsed()
|
|
||||||
{ return double(1)/double(CLOCKS_PER_SEC); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::clock_t _start_time;
|
|
||||||
}; // timer
|
|
||||||
|
|
||||||
} // namespace boost
|
|
||||||
|
|
||||||
#endif // BOOST_TIMER_HPP
|
|
|
@ -1,283 +0,0 @@
|
||||||
// A very small replacement for boost::tuple
|
|
||||||
// (c) Alexander Gessler, 2008 [alexander.gessler@gmx.net]
|
|
||||||
|
|
||||||
#ifndef BOOST_TUPLE_INCLUDED
|
|
||||||
#define BOOST_TUPLE_INCLUDED
|
|
||||||
|
|
||||||
namespace boost {
|
|
||||||
namespace detail {
|
|
||||||
|
|
||||||
// Represents an empty tuple slot (up to 5 supported)
|
|
||||||
struct nulltype {};
|
|
||||||
|
|
||||||
// For readable error messages
|
|
||||||
struct tuple_component_idx_out_of_bounds;
|
|
||||||
|
|
||||||
// To share some code for the const/nonconst versions of the getters
|
|
||||||
template <bool b, typename T>
|
|
||||||
struct ConstIf {
|
|
||||||
typedef T t;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct ConstIf<true,T> {
|
|
||||||
typedef const T t;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Predeclare some stuff
|
|
||||||
template <typename, unsigned, typename, bool, unsigned> struct value_getter;
|
|
||||||
|
|
||||||
// Helper to obtain the type of a tuple element
|
|
||||||
template <typename T, unsigned NIDX, typename TNEXT, unsigned N /*= 0*/>
|
|
||||||
struct type_getter {
|
|
||||||
typedef type_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,N> next_elem_getter;
|
|
||||||
typedef typename next_elem_getter::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, unsigned NIDX, typename TNEXT >
|
|
||||||
struct type_getter <T,NIDX,TNEXT,NIDX> {
|
|
||||||
typedef T type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Base class for all explicit specializations of list_elem
|
|
||||||
template <typename T, unsigned NIDX, typename TNEXT >
|
|
||||||
struct list_elem_base {
|
|
||||||
|
|
||||||
// Store template parameters
|
|
||||||
typedef TNEXT next_type;
|
|
||||||
typedef T type;
|
|
||||||
|
|
||||||
static const unsigned nidx = NIDX;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Represents an element in the tuple component list
|
|
||||||
template <typename T, unsigned NIDX, typename TNEXT >
|
|
||||||
struct list_elem : list_elem_base<T,NIDX,TNEXT>{
|
|
||||||
|
|
||||||
// Real members
|
|
||||||
T me;
|
|
||||||
TNEXT next;
|
|
||||||
|
|
||||||
// Get the value of a specific tuple element
|
|
||||||
template <unsigned N>
|
|
||||||
typename type_getter<T,NIDX,TNEXT,N>::type& get () {
|
|
||||||
value_getter <T,NIDX,TNEXT,false,N> s;
|
|
||||||
return s(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the value of a specific tuple element
|
|
||||||
template <unsigned N>
|
|
||||||
const typename type_getter<T,NIDX,TNEXT,N>::type& get () const {
|
|
||||||
value_getter <T,NIDX,TNEXT,true,N> s;
|
|
||||||
return s(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Explicit cast
|
|
||||||
template <typename T2, typename TNEXT2 >
|
|
||||||
operator list_elem<T2,NIDX,TNEXT2> () const {
|
|
||||||
list_elem<T2,NIDX,TNEXT2> ret;
|
|
||||||
ret.me = (T2)me;
|
|
||||||
ret.next = next;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recursively compare two elements (last element returns always true)
|
|
||||||
bool operator == (const list_elem& s) const {
|
|
||||||
return (me == s.me && next == s.next);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Represents a non-used tuple element - the very last element processed
|
|
||||||
template <typename TNEXT, unsigned NIDX >
|
|
||||||
struct list_elem<nulltype,NIDX,TNEXT> : list_elem_base<nulltype,NIDX,TNEXT> {
|
|
||||||
template <unsigned N, bool IS_CONST = true> struct value_getter {
|
|
||||||
/* just dummy members to produce readable error messages */
|
|
||||||
tuple_component_idx_out_of_bounds operator () (typename ConstIf<IS_CONST,list_elem>::t& me);
|
|
||||||
};
|
|
||||||
template <unsigned N> struct type_getter {
|
|
||||||
/* just dummy members to produce readable error messages */
|
|
||||||
typedef tuple_component_idx_out_of_bounds type;
|
|
||||||
};
|
|
||||||
|
|
||||||
// dummy
|
|
||||||
list_elem& operator = (const list_elem& /*other*/) {
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// dummy
|
|
||||||
bool operator == (const list_elem& other) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Represents the absolute end of the list
|
|
||||||
typedef list_elem<nulltype,0,int> list_end;
|
|
||||||
|
|
||||||
// Helper obtain to query the value of a tuple element
|
|
||||||
// NOTE: This can't be a nested class as the compiler won't accept a full or
|
|
||||||
// partial specialization of a nested class of a non-specialized template
|
|
||||||
template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST, unsigned N>
|
|
||||||
struct value_getter {
|
|
||||||
|
|
||||||
// calling list_elem
|
|
||||||
typedef list_elem<T,NIDX,TNEXT> outer_elem;
|
|
||||||
|
|
||||||
// typedef for the getter for next element
|
|
||||||
typedef value_getter<typename TNEXT::type,NIDX+1,typename TNEXT::next_type,
|
|
||||||
IS_CONST, N> next_value_getter;
|
|
||||||
|
|
||||||
typename ConstIf<IS_CONST,typename type_getter<T,NIDX,TNEXT,N>::type>::t&
|
|
||||||
operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
|
|
||||||
|
|
||||||
next_value_getter s;
|
|
||||||
return s(me.next);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, unsigned NIDX, typename TNEXT, bool IS_CONST>
|
|
||||||
struct value_getter <T,NIDX,TNEXT,IS_CONST,NIDX> {
|
|
||||||
typedef list_elem<T,NIDX,TNEXT> outer_elem;
|
|
||||||
|
|
||||||
typename ConstIf<IS_CONST,T>::t& operator () (typename ConstIf<IS_CONST,outer_elem >::t& me) {
|
|
||||||
return me.me;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// A very minimal implementation for up to 5 elements
|
|
||||||
template <typename T0 = detail::nulltype,
|
|
||||||
typename T1 = detail::nulltype,
|
|
||||||
typename T2 = detail::nulltype,
|
|
||||||
typename T3 = detail::nulltype,
|
|
||||||
typename T4 = detail::nulltype>
|
|
||||||
class tuple {
|
|
||||||
|
|
||||||
template <typename T0b,
|
|
||||||
typename T1b,
|
|
||||||
typename T2b,
|
|
||||||
typename T3b,
|
|
||||||
typename T4b >
|
|
||||||
friend class tuple;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
typedef detail::list_elem<T0,0,
|
|
||||||
detail::list_elem<T1,1,
|
|
||||||
detail::list_elem<T2,2,
|
|
||||||
detail::list_elem<T3,3,
|
|
||||||
detail::list_elem<T4,4,
|
|
||||||
detail::list_end > > > > > very_long;
|
|
||||||
|
|
||||||
very_long m;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Get a specific tuple element
|
|
||||||
template <unsigned N>
|
|
||||||
typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () {
|
|
||||||
return m.template get<N>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and the const version
|
|
||||||
template <unsigned N>
|
|
||||||
const typename detail::type_getter<T0,0,typename very_long::next_type, N>::type& get () const {
|
|
||||||
return m.template get<N>();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// comparison operators
|
|
||||||
bool operator== (const tuple& other) const {
|
|
||||||
return m == other.m;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and the other way round
|
|
||||||
bool operator!= (const tuple& other) const {
|
|
||||||
return !(m == other.m);
|
|
||||||
}
|
|
||||||
|
|
||||||
// cast to another tuple - all single elements must be convertible
|
|
||||||
template <typename T0b, typename T1b,typename T2b,typename T3b, typename T4b>
|
|
||||||
operator tuple <T0b,T1b,T2b,T3b,T4b> () const {
|
|
||||||
tuple <T0b,T1b,T2b,T3b,T4b> s;
|
|
||||||
s.m = (typename tuple <T0b,T1b,T2b,T3b,T4b>::very_long)m;
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Another way to access an element ...
|
|
||||||
template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
|
|
||||||
inline typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
|
|
||||||
tuple<T0,T1,T2,T3,T4>& m) {
|
|
||||||
return m.template get<N>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ... and the const version
|
|
||||||
template <unsigned N,typename T0,typename T1,typename T2,typename T3,typename T4>
|
|
||||||
inline const typename tuple<T0,T1,T2,T3,T4>::very_long::template type_getter<N>::type& get (
|
|
||||||
const tuple<T0,T1,T2,T3,T4>& m) {
|
|
||||||
return m.template get<N>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a tuple with 5 elements
|
|
||||||
template <typename T0,typename T1,typename T2,typename T3,typename T4>
|
|
||||||
inline tuple <T0,T1,T2,T3,T4> make_tuple (const T0& t0,
|
|
||||||
const T1& t1,const T2& t2,const T3& t3,const T4& t4) {
|
|
||||||
|
|
||||||
tuple <T0,T1,T2,T3,T4> t;
|
|
||||||
t.template get<0>() = t0;
|
|
||||||
t.template get<1>() = t1;
|
|
||||||
t.template get<2>() = t2;
|
|
||||||
t.template get<3>() = t3;
|
|
||||||
t.template get<4>() = t4;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a tuple with 4 elements
|
|
||||||
template <typename T0,typename T1,typename T2,typename T3>
|
|
||||||
inline tuple <T0,T1,T2,T3> make_tuple (const T0& t0,
|
|
||||||
const T1& t1,const T2& t2,const T3& t3) {
|
|
||||||
tuple <T0,T1,T2,T3> t;
|
|
||||||
t.template get<0>() = t0;
|
|
||||||
t.template get<1>() = t1;
|
|
||||||
t.template get<2>() = t2;
|
|
||||||
t.template get<3>() = t3;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a tuple with 3 elements
|
|
||||||
template <typename T0,typename T1,typename T2>
|
|
||||||
inline tuple <T0,T1,T2> make_tuple (const T0& t0,
|
|
||||||
const T1& t1,const T2& t2) {
|
|
||||||
tuple <T0,T1,T2> t;
|
|
||||||
t.template get<0>() = t0;
|
|
||||||
t.template get<1>() = t1;
|
|
||||||
t.template get<2>() = t2;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a tuple with 2 elements
|
|
||||||
template <typename T0,typename T1>
|
|
||||||
inline tuple <T0,T1> make_tuple (const T0& t0,
|
|
||||||
const T1& t1) {
|
|
||||||
tuple <T0,T1> t;
|
|
||||||
t.template get<0>() = t0;
|
|
||||||
t.template get<1>() = t1;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a tuple with 1 elements (well ...)
|
|
||||||
template <typename T0>
|
|
||||||
inline tuple <T0> make_tuple (const T0& t0) {
|
|
||||||
tuple <T0> t;
|
|
||||||
t.template get<0>() = t0;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Constructs a tuple with 0 elements (well ...)
|
|
||||||
inline tuple <> make_tuple () {
|
|
||||||
tuple <> t;
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // !! BOOST_TUPLE_INCLUDED
|
|
285
code/ByteSwap.h
285
code/ByteSwap.h
|
@ -1,285 +0,0 @@
|
||||||
/*
|
|
||||||
Open Asset Import Library (assimp)
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
Copyright (c) 2006-2012, assimp team
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
|
||||||
with or without modification, are permitted provided that the
|
|
||||||
following conditions are met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the
|
|
||||||
following disclaimer in the documentation and/or other
|
|
||||||
materials provided with the distribution.
|
|
||||||
|
|
||||||
* Neither the name of the assimp team, nor the names of its
|
|
||||||
contributors may be used to endorse or promote products
|
|
||||||
derived from this software without specific prior
|
|
||||||
written permission of the assimp team.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @file Helper class tp perform various byte oder swappings
|
|
||||||
(e.g. little to big endian) */
|
|
||||||
#ifndef AI_BYTESWAP_H_INC
|
|
||||||
#define AI_BYTESWAP_H_INC
|
|
||||||
|
|
||||||
#include "../include/assimp/ai_assert.h"
|
|
||||||
#include "../include/assimp/types.h"
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace Assimp {
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
/** Defines some useful byte order swap routines.
|
|
||||||
*
|
|
||||||
* This is required to read big-endian model formats on little-endian machines,
|
|
||||||
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
class ByteSwap
|
|
||||||
{
|
|
||||||
ByteSwap() {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** Swap two bytes of data
|
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
|
||||||
static inline void Swap2(void* _szOut)
|
|
||||||
{
|
|
||||||
ai_assert(_szOut);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
|
||||||
*szOut = _byteswap_ushort(*szOut);
|
|
||||||
#else
|
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
|
||||||
std::swap(szOut[0],szOut[1]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** Swap four bytes of data
|
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
|
||||||
static inline void Swap4(void* _szOut)
|
|
||||||
{
|
|
||||||
ai_assert(_szOut);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
|
||||||
*szOut = _byteswap_ulong(*szOut);
|
|
||||||
#else
|
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
|
||||||
std::swap(szOut[0],szOut[3]);
|
|
||||||
std::swap(szOut[1],szOut[2]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** Swap eight bytes of data
|
|
||||||
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
|
||||||
static inline void Swap8(void* _szOut)
|
|
||||||
{
|
|
||||||
ai_assert(_szOut);
|
|
||||||
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
|
||||||
*szOut = _byteswap_uint64(*szOut);
|
|
||||||
#else
|
|
||||||
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
|
||||||
std::swap(szOut[0],szOut[7]);
|
|
||||||
std::swap(szOut[1],szOut[6]);
|
|
||||||
std::swap(szOut[2],szOut[5]);
|
|
||||||
std::swap(szOut[3],szOut[4]);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap a float. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(float* fOut) {
|
|
||||||
Swap4(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap a double. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(double* fOut) {
|
|
||||||
Swap8(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap an int16t. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(int16_t* fOut) {
|
|
||||||
Swap2(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Swap(uint16_t* fOut) {
|
|
||||||
Swap2(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap an int32t. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(int32_t* fOut){
|
|
||||||
Swap4(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Swap(uint32_t* fOut){
|
|
||||||
Swap4(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
/** ByteSwap an int64t. Not a joke.
|
|
||||||
* @param[inout] fOut ehm. .. */
|
|
||||||
static inline void Swap(int64_t* fOut) {
|
|
||||||
Swap8(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Swap(uint64_t* fOut) {
|
|
||||||
Swap8(fOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------
|
|
||||||
//! Templatized ByteSwap
|
|
||||||
//! \returns param tOut as swapped
|
|
||||||
template<typename Type>
|
|
||||||
static inline Type Swapped(Type tOut)
|
|
||||||
{
|
|
||||||
return _swapper<Type,sizeof(Type)>()(tOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
template <typename T, size_t size> struct _swapper;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,2> {
|
|
||||||
T operator() (T tOut) {
|
|
||||||
Swap2(&tOut);
|
|
||||||
return tOut;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,4> {
|
|
||||||
T operator() (T tOut) {
|
|
||||||
Swap4(&tOut);
|
|
||||||
return tOut;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T> struct ByteSwap::_swapper<T,8> {
|
|
||||||
T operator() (T tOut) {
|
|
||||||
Swap8(&tOut);
|
|
||||||
return tOut;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// ByteSwap macros for BigEndian/LittleEndian support
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
#if (defined AI_BUILD_BIG_ENDIAN)
|
|
||||||
# define AI_LE(t) (t)
|
|
||||||
# define AI_BE(t) ByteSwap::Swapped(t)
|
|
||||||
# define AI_LSWAP2(p)
|
|
||||||
# define AI_LSWAP4(p)
|
|
||||||
# define AI_LSWAP8(p)
|
|
||||||
# define AI_LSWAP2P(p)
|
|
||||||
# define AI_LSWAP4P(p)
|
|
||||||
# define AI_LSWAP8P(p)
|
|
||||||
# define LE_NCONST const
|
|
||||||
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
|
||||||
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
|
||||||
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
|
||||||
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
|
||||||
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
|
||||||
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
|
||||||
# define BE_NCONST
|
|
||||||
#else
|
|
||||||
# define AI_BE(t) (t)
|
|
||||||
# define AI_LE(t) ByteSwap::Swapped(t)
|
|
||||||
# define AI_SWAP2(p)
|
|
||||||
# define AI_SWAP4(p)
|
|
||||||
# define AI_SWAP8(p)
|
|
||||||
# define AI_SWAP2P(p)
|
|
||||||
# define AI_SWAP4P(p)
|
|
||||||
# define AI_SWAP8P(p)
|
|
||||||
# define BE_NCONST const
|
|
||||||
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
|
||||||
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
|
||||||
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
|
||||||
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
|
||||||
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
|
||||||
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
|
||||||
# define LE_NCONST
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace Intern {
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
template <typename T, bool doit>
|
|
||||||
struct ByteSwapper {
|
|
||||||
void operator() (T* inout) {
|
|
||||||
ByteSwap::Swap(inout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct ByteSwapper<T,false> {
|
|
||||||
void operator() (T*) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
|
||||||
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
|
||||||
struct Getter {
|
|
||||||
void operator() (T* inout, bool le) {
|
|
||||||
#ifdef AI_BUILD_BIG_ENDIAN
|
|
||||||
le = le;
|
|
||||||
#else
|
|
||||||
le = !le;
|
|
||||||
#endif
|
|
||||||
if (le) {
|
|
||||||
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
|
||||||
}
|
|
||||||
else ByteSwapper<T,false> () (inout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <bool SwapEndianess, typename T>
|
|
||||||
struct Getter<SwapEndianess,T,false> {
|
|
||||||
|
|
||||||
void operator() (T* inout, bool /*le*/) {
|
|
||||||
// static branch
|
|
||||||
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // end Intern
|
|
||||||
} // end Assimp
|
|
||||||
|
|
||||||
#endif //!! AI_BYTESWAP_H_INC
|
|
|
@ -0,0 +1,286 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2016, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file Helper class tp perform various byte oder swappings
|
||||||
|
(e.g. little to big endian) */
|
||||||
|
#ifndef AI_BYTESWAPPER_H_INC
|
||||||
|
#define AI_BYTESWAPPER_H_INC
|
||||||
|
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
|
#include <assimp/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
/** Defines some useful byte order swap routines.
|
||||||
|
*
|
||||||
|
* This is required to read big-endian model formats on little-endian machines,
|
||||||
|
* and vice versa. Direct use of this class is DEPRECATED. Use #StreamReader instead. */
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
class ByteSwap
|
||||||
|
{
|
||||||
|
ByteSwap() {}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** Swap two bytes of data
|
||||||
|
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||||
|
static inline void Swap2(void* _szOut)
|
||||||
|
{
|
||||||
|
ai_assert(_szOut);
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
uint16_t* const szOut = reinterpret_cast<uint16_t*>(_szOut);
|
||||||
|
*szOut = _byteswap_ushort(*szOut);
|
||||||
|
#else
|
||||||
|
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||||
|
std::swap(szOut[0],szOut[1]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** Swap four bytes of data
|
||||||
|
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||||
|
static inline void Swap4(void* _szOut)
|
||||||
|
{
|
||||||
|
ai_assert(_szOut);
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
uint32_t* const szOut = reinterpret_cast<uint32_t*>(_szOut);
|
||||||
|
*szOut = _byteswap_ulong(*szOut);
|
||||||
|
#else
|
||||||
|
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||||
|
std::swap(szOut[0],szOut[3]);
|
||||||
|
std::swap(szOut[1],szOut[2]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** Swap eight bytes of data
|
||||||
|
* @param[inout] _szOut A void* to save the reintcasts for the caller. */
|
||||||
|
static inline void Swap8(void* _szOut)
|
||||||
|
{
|
||||||
|
ai_assert(_szOut);
|
||||||
|
|
||||||
|
#if _MSC_VER >= 1400
|
||||||
|
uint64_t* const szOut = reinterpret_cast<uint64_t*>(_szOut);
|
||||||
|
*szOut = _byteswap_uint64(*szOut);
|
||||||
|
#else
|
||||||
|
uint8_t* const szOut = reinterpret_cast<uint8_t*>(_szOut);
|
||||||
|
std::swap(szOut[0],szOut[7]);
|
||||||
|
std::swap(szOut[1],szOut[6]);
|
||||||
|
std::swap(szOut[2],szOut[5]);
|
||||||
|
std::swap(szOut[3],szOut[4]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** ByteSwap a float. Not a joke.
|
||||||
|
* @param[inout] fOut ehm. .. */
|
||||||
|
static inline void Swap(float* fOut) {
|
||||||
|
Swap4(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** ByteSwap a double. Not a joke.
|
||||||
|
* @param[inout] fOut ehm. .. */
|
||||||
|
static inline void Swap(double* fOut) {
|
||||||
|
Swap8(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** ByteSwap an int16t. Not a joke.
|
||||||
|
* @param[inout] fOut ehm. .. */
|
||||||
|
static inline void Swap(int16_t* fOut) {
|
||||||
|
Swap2(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Swap(uint16_t* fOut) {
|
||||||
|
Swap2(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** ByteSwap an int32t. Not a joke.
|
||||||
|
* @param[inout] fOut ehm. .. */
|
||||||
|
static inline void Swap(int32_t* fOut){
|
||||||
|
Swap4(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Swap(uint32_t* fOut){
|
||||||
|
Swap4(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
/** ByteSwap an int64t. Not a joke.
|
||||||
|
* @param[inout] fOut ehm. .. */
|
||||||
|
static inline void Swap(int64_t* fOut) {
|
||||||
|
Swap8(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Swap(uint64_t* fOut) {
|
||||||
|
Swap8(fOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
//! Templatized ByteSwap
|
||||||
|
//! \returns param tOut as swapped
|
||||||
|
template<typename Type>
|
||||||
|
static inline Type Swapped(Type tOut)
|
||||||
|
{
|
||||||
|
return _swapper<Type,sizeof(Type)>()(tOut);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename T, size_t size> struct _swapper;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> struct ByteSwap::_swapper<T,2> {
|
||||||
|
T operator() (T tOut) {
|
||||||
|
Swap2(&tOut);
|
||||||
|
return tOut;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> struct ByteSwap::_swapper<T,4> {
|
||||||
|
T operator() (T tOut) {
|
||||||
|
Swap4(&tOut);
|
||||||
|
return tOut;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> struct ByteSwap::_swapper<T,8> {
|
||||||
|
T operator() (T tOut) {
|
||||||
|
Swap8(&tOut);
|
||||||
|
return tOut;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// ByteSwap macros for BigEndian/LittleEndian support
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
#if (defined AI_BUILD_BIG_ENDIAN)
|
||||||
|
# define AI_LE(t) (t)
|
||||||
|
# define AI_BE(t) ByteSwap::Swapped(t)
|
||||||
|
# define AI_LSWAP2(p)
|
||||||
|
# define AI_LSWAP4(p)
|
||||||
|
# define AI_LSWAP8(p)
|
||||||
|
# define AI_LSWAP2P(p)
|
||||||
|
# define AI_LSWAP4P(p)
|
||||||
|
# define AI_LSWAP8P(p)
|
||||||
|
# define LE_NCONST const
|
||||||
|
# define AI_SWAP2(p) ByteSwap::Swap2(&(p))
|
||||||
|
# define AI_SWAP4(p) ByteSwap::Swap4(&(p))
|
||||||
|
# define AI_SWAP8(p) ByteSwap::Swap8(&(p))
|
||||||
|
# define AI_SWAP2P(p) ByteSwap::Swap2((p))
|
||||||
|
# define AI_SWAP4P(p) ByteSwap::Swap4((p))
|
||||||
|
# define AI_SWAP8P(p) ByteSwap::Swap8((p))
|
||||||
|
# define BE_NCONST
|
||||||
|
#else
|
||||||
|
# define AI_BE(t) (t)
|
||||||
|
# define AI_LE(t) ByteSwap::Swapped(t)
|
||||||
|
# define AI_SWAP2(p)
|
||||||
|
# define AI_SWAP4(p)
|
||||||
|
# define AI_SWAP8(p)
|
||||||
|
# define AI_SWAP2P(p)
|
||||||
|
# define AI_SWAP4P(p)
|
||||||
|
# define AI_SWAP8P(p)
|
||||||
|
# define BE_NCONST const
|
||||||
|
# define AI_LSWAP2(p) ByteSwap::Swap2(&(p))
|
||||||
|
# define AI_LSWAP4(p) ByteSwap::Swap4(&(p))
|
||||||
|
# define AI_LSWAP8(p) ByteSwap::Swap8(&(p))
|
||||||
|
# define AI_LSWAP2P(p) ByteSwap::Swap2((p))
|
||||||
|
# define AI_LSWAP4P(p) ByteSwap::Swap4((p))
|
||||||
|
# define AI_LSWAP8P(p) ByteSwap::Swap8((p))
|
||||||
|
# define LE_NCONST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace Intern {
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
template <typename T, bool doit>
|
||||||
|
struct ByteSwapper {
|
||||||
|
void operator() (T* inout) {
|
||||||
|
ByteSwap::Swap(inout);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ByteSwapper<T,false> {
|
||||||
|
void operator() (T*) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------------
|
||||||
|
template <bool SwapEndianess, typename T, bool RuntimeSwitch>
|
||||||
|
struct Getter {
|
||||||
|
void operator() (T* inout, bool le) {
|
||||||
|
#ifdef AI_BUILD_BIG_ENDIAN
|
||||||
|
le = le;
|
||||||
|
#else
|
||||||
|
le = !le;
|
||||||
|
#endif
|
||||||
|
if (le) {
|
||||||
|
ByteSwapper<T,(sizeof(T)>1?true:false)> () (inout);
|
||||||
|
}
|
||||||
|
else ByteSwapper<T,false> () (inout);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <bool SwapEndianess, typename T>
|
||||||
|
struct Getter<SwapEndianess,T,false> {
|
||||||
|
|
||||||
|
void operator() (T* inout, bool /*le*/) {
|
||||||
|
// static branch
|
||||||
|
ByteSwapper<T,(SwapEndianess && sizeof(T)>1)> () (inout);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // end Intern
|
||||||
|
} // end Assimp
|
||||||
|
|
||||||
|
#endif //!! AI_BYTESWAPPER_H_INC
|
|
@ -0,0 +1,650 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2012, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file C4DImporter.cpp
|
||||||
|
* @brief Implementation of the Cinema4D importer class.
|
||||||
|
*/
|
||||||
|
#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
|
|
||||||
|
// no #ifdefing here, Cinema4D support is carried out in a branch of assimp
|
||||||
|
// where it is turned on in the CMake settings.
|
||||||
|
|
||||||
|
#ifndef _MSC_VER
|
||||||
|
# error C4D support is currently MSVC only
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "C4DImporter.h"
|
||||||
|
#include "TinyFormatter.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
|
|
||||||
|
#if defined(_M_X64) || defined(__amd64__)
|
||||||
|
# define __C4D_64BIT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define __PC
|
||||||
|
#include "c4d_file.h"
|
||||||
|
#include "default_alien_overloads.h"
|
||||||
|
|
||||||
|
using namespace melange;
|
||||||
|
|
||||||
|
// overload this function and fill in your own unique data
|
||||||
|
void GetWriterInfo(int &id, String &appname)
|
||||||
|
{
|
||||||
|
id = 2424226;
|
||||||
|
appname = "Open Asset Import Library";
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
template<> const std::string LogFunctions<C4DImporter>::log_prefix = "C4D: ";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const aiImporterDesc desc = {
|
||||||
|
"Cinema4D Importer",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
aiImporterFlags_SupportBinaryFlavour,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
"c4d"
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
C4DImporter::C4DImporter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
C4DImporter::~C4DImporter()
|
||||||
|
{}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||||
|
{
|
||||||
|
const std::string& extension = GetExtension(pFile);
|
||||||
|
if (extension == "c4d") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if ((!extension.length() || checkSig) && pIOHandler) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
const aiImporterDesc* C4DImporter::GetInfo () const
|
||||||
|
{
|
||||||
|
return &desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void C4DImporter::SetupProperties(const Importer* /*pImp*/)
|
||||||
|
{
|
||||||
|
// nothing to be done for the moment
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Imports the given file into the given scene structure.
|
||||||
|
void C4DImporter::InternReadFile( const std::string& pFile,
|
||||||
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
|
{
|
||||||
|
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
|
||||||
|
|
||||||
|
if( file.get() == NULL) {
|
||||||
|
ThrowException("failed to open file " + pFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t file_size = file->FileSize();
|
||||||
|
|
||||||
|
std::vector<uint8_t> mBuffer(file_size);
|
||||||
|
file->Read(&mBuffer[0], 1, file_size);
|
||||||
|
|
||||||
|
Filename f;
|
||||||
|
f.SetMemoryReadMode(&mBuffer[0], file_size);
|
||||||
|
|
||||||
|
// open document first
|
||||||
|
BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
|
||||||
|
if(doc == NULL) {
|
||||||
|
ThrowException("failed to read document " + pFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
pScene->mRootNode = new aiNode("<C4DRoot>");
|
||||||
|
|
||||||
|
// first convert all materials
|
||||||
|
ReadMaterials(doc->GetFirstMaterial());
|
||||||
|
|
||||||
|
// process C4D scenegraph recursively
|
||||||
|
try {
|
||||||
|
RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
|
||||||
|
}
|
||||||
|
catch(...) {
|
||||||
|
for(aiMesh* mesh : meshes) {
|
||||||
|
delete mesh;
|
||||||
|
}
|
||||||
|
BaseDocument::Free(doc);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
BaseDocument::Free(doc);
|
||||||
|
|
||||||
|
// copy meshes over
|
||||||
|
pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
|
||||||
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
|
||||||
|
std::copy(meshes.begin(), meshes.end(), pScene->mMeshes);
|
||||||
|
|
||||||
|
// copy materials over, adding a default material if necessary
|
||||||
|
unsigned int mat_count = static_cast<unsigned int>(materials.size());
|
||||||
|
for(aiMesh* mesh : meshes) {
|
||||||
|
ai_assert(mesh->mMaterialIndex <= mat_count);
|
||||||
|
if(mesh->mMaterialIndex >= mat_count) {
|
||||||
|
++mat_count;
|
||||||
|
|
||||||
|
ScopeGuard<aiMaterial> def_material(new aiMaterial());
|
||||||
|
const aiString name(AI_DEFAULT_MATERIAL_NAME);
|
||||||
|
def_material->AddProperty(&name, AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
materials.push_back(def_material.dismiss());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
|
||||||
|
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
|
||||||
|
std::copy(materials.begin(), materials.end(), pScene->mMaterials);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
|
||||||
|
{
|
||||||
|
// based on Melange sample code (C4DImportExport.cpp)
|
||||||
|
while(shader) {
|
||||||
|
if(shader->GetType() == Xlayer) {
|
||||||
|
BaseContainer* container = shader->GetDataInstance();
|
||||||
|
GeData blend = container->GetData(SLA_LAYER_BLEND);
|
||||||
|
iBlendDataType* blend_list = reinterpret_cast<iBlendDataType*>(blend.GetCustomDataType(CUSTOMDATA_BLEND_LIST));
|
||||||
|
if (!blend_list)
|
||||||
|
{
|
||||||
|
LogWarn("ignoring XLayer shader: no blend list given");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
LayerShaderLayer *lsl = dynamic_cast<LayerShaderLayer*>(blend_list->m_BlendLayers.GetObject(0));
|
||||||
|
|
||||||
|
// Ignore the actual layer blending - models for real-time rendering should not
|
||||||
|
// use them in a non-trivial way. Just try to find textures that we can apply
|
||||||
|
// to the model.
|
||||||
|
while (lsl)
|
||||||
|
{
|
||||||
|
if (lsl->GetType() == TypeFolder)
|
||||||
|
{
|
||||||
|
BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
|
||||||
|
LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
|
||||||
|
|
||||||
|
while (subLsl)
|
||||||
|
{
|
||||||
|
if (subLsl->GetType() == TypeShader) {
|
||||||
|
BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
|
||||||
|
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
subLsl = subLsl->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (lsl->GetType() == TypeShader) {
|
||||||
|
BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
|
||||||
|
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lsl = lsl->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( shader->GetType() == Xbitmap )
|
||||||
|
{
|
||||||
|
aiString path;
|
||||||
|
shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
|
||||||
|
path.length = ::strlen(path.data);
|
||||||
|
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
|
||||||
|
}
|
||||||
|
shader = shader->GetNext();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
|
||||||
|
{
|
||||||
|
// based on Melange sample code
|
||||||
|
while (mat)
|
||||||
|
{
|
||||||
|
const String& name = mat->GetName();
|
||||||
|
if (mat->GetType() == Mmaterial)
|
||||||
|
{
|
||||||
|
aiMaterial* out = new aiMaterial();
|
||||||
|
material_mapping[mat] = static_cast<unsigned int>(materials.size());
|
||||||
|
materials.push_back(out);
|
||||||
|
|
||||||
|
aiString ai_name;
|
||||||
|
name.GetCString(ai_name.data, MAXLEN-1);
|
||||||
|
ai_name.length = ::strlen(ai_name.data);
|
||||||
|
out->AddProperty(&ai_name, AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
Material& m = dynamic_cast<Material&>(*mat);
|
||||||
|
|
||||||
|
if (m.GetChannelState(CHANNEL_COLOR))
|
||||||
|
{
|
||||||
|
GeData data;
|
||||||
|
mat->GetParameter(MATERIAL_COLOR_COLOR, data);
|
||||||
|
Vector color = data.GetVector();
|
||||||
|
mat->GetParameter(MATERIAL_COLOR_BRIGHTNESS, data);
|
||||||
|
const Float brightness = data.GetFloat();
|
||||||
|
|
||||||
|
color *= brightness;
|
||||||
|
|
||||||
|
aiVector3D v;
|
||||||
|
v.x = color.x;
|
||||||
|
v.y = color.y;
|
||||||
|
v.z = color.z;
|
||||||
|
out->AddProperty(&v, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseShader* const shader = m.GetShader(MATERIAL_COLOR_SHADER);
|
||||||
|
if(shader) {
|
||||||
|
ReadShader(out, shader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
|
||||||
|
}
|
||||||
|
mat = mat->GetNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
|
||||||
|
{
|
||||||
|
ai_assert(parent != NULL);
|
||||||
|
std::vector<aiNode*> nodes;
|
||||||
|
|
||||||
|
// based on Melange sample code
|
||||||
|
while (object)
|
||||||
|
{
|
||||||
|
const String& name = object->GetName();
|
||||||
|
const LONG type = object->GetType();
|
||||||
|
const Matrix& ml = object->GetMl();
|
||||||
|
|
||||||
|
aiString string;
|
||||||
|
name.GetCString(string.data, MAXLEN-1);
|
||||||
|
string.length = ::strlen(string.data);
|
||||||
|
aiNode* const nd = new aiNode();
|
||||||
|
|
||||||
|
nd->mParent = parent;
|
||||||
|
nd->mName = string;
|
||||||
|
|
||||||
|
nd->mTransformation.a1 = ml.v1.x;
|
||||||
|
nd->mTransformation.b1 = ml.v1.y;
|
||||||
|
nd->mTransformation.c1 = ml.v1.z;
|
||||||
|
|
||||||
|
nd->mTransformation.a2 = ml.v2.x;
|
||||||
|
nd->mTransformation.b2 = ml.v2.y;
|
||||||
|
nd->mTransformation.c2 = ml.v2.z;
|
||||||
|
|
||||||
|
nd->mTransformation.a3 = ml.v3.x;
|
||||||
|
nd->mTransformation.b3 = ml.v3.y;
|
||||||
|
nd->mTransformation.c3 = ml.v3.z;
|
||||||
|
|
||||||
|
nd->mTransformation.a4 = ml.off.x;
|
||||||
|
nd->mTransformation.b4 = ml.off.y;
|
||||||
|
nd->mTransformation.c4 = ml.off.z;
|
||||||
|
|
||||||
|
nodes.push_back(nd);
|
||||||
|
|
||||||
|
GeData data;
|
||||||
|
if (type == Ocamera)
|
||||||
|
{
|
||||||
|
object->GetParameter(CAMERAOBJECT_FOV, data);
|
||||||
|
// TODO: read camera
|
||||||
|
}
|
||||||
|
else if (type == Olight)
|
||||||
|
{
|
||||||
|
// TODO: read light
|
||||||
|
}
|
||||||
|
else if (type == Opolygon)
|
||||||
|
{
|
||||||
|
aiMesh* const mesh = ReadMesh(object);
|
||||||
|
if(mesh != NULL) {
|
||||||
|
nd->mNumMeshes = 1;
|
||||||
|
nd->mMeshes = new unsigned int[1];
|
||||||
|
nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
|
||||||
|
meshes.push_back(mesh);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
|
||||||
|
}
|
||||||
|
|
||||||
|
RecurseHierarchy(object->GetDown(), nd);
|
||||||
|
object = object->GetNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy nodes over to parent
|
||||||
|
parent->mNumChildren = static_cast<unsigned int>(nodes.size());
|
||||||
|
parent->mChildren = new aiNode*[parent->mNumChildren]();
|
||||||
|
std::copy(nodes.begin(), nodes.end(), parent->mChildren);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
aiMesh* C4DImporter::ReadMesh(BaseObject* object)
|
||||||
|
{
|
||||||
|
assert(object != NULL && object->GetType() == Opolygon);
|
||||||
|
|
||||||
|
// based on Melange sample code
|
||||||
|
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
||||||
|
ai_assert(polyObject != NULL);
|
||||||
|
|
||||||
|
const LONG pointCount = polyObject->GetPointCount();
|
||||||
|
const LONG polyCount = polyObject->GetPolygonCount();
|
||||||
|
if(!polyObject || !pointCount) {
|
||||||
|
LogWarn("ignoring mesh with zero vertices or faces");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector* points = polyObject->GetPointR();
|
||||||
|
ai_assert(points != NULL);
|
||||||
|
|
||||||
|
const CPolygon* polys = polyObject->GetPolygonR();
|
||||||
|
ai_assert(polys != NULL);
|
||||||
|
|
||||||
|
ScopeGuard<aiMesh> mesh(new aiMesh());
|
||||||
|
mesh->mNumFaces = static_cast<unsigned int>(polyCount);
|
||||||
|
aiFace* face = mesh->mFaces = new aiFace[mesh->mNumFaces]();
|
||||||
|
|
||||||
|
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
|
||||||
|
mesh->mMaterialIndex = 0;
|
||||||
|
|
||||||
|
unsigned int vcount = 0;
|
||||||
|
|
||||||
|
// first count vertices
|
||||||
|
for (LONG i = 0; i < polyCount; i++)
|
||||||
|
{
|
||||||
|
vcount += 3;
|
||||||
|
|
||||||
|
// TODO: do we also need to handle lines or points with similar checks?
|
||||||
|
if (polys[i].c != polys[i].d)
|
||||||
|
{
|
||||||
|
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
|
++vcount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_assert(vcount > 0);
|
||||||
|
|
||||||
|
mesh->mNumVertices = vcount;
|
||||||
|
aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||||
|
aiVector3D* normals, *uvs, *tangents, *bitangents;
|
||||||
|
unsigned int n = 0;
|
||||||
|
|
||||||
|
// check if there are normals, tangents or UVW coordinates
|
||||||
|
BaseTag* tag = object->GetTag(Tnormal);
|
||||||
|
NormalTag* normals_src = NULL;
|
||||||
|
if(tag) {
|
||||||
|
normals_src = dynamic_cast<NormalTag*>(tag);
|
||||||
|
normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = object->GetTag(Ttangent);
|
||||||
|
TangentTag* tangents_src = NULL;
|
||||||
|
if(tag) {
|
||||||
|
tangents_src = dynamic_cast<TangentTag*>(tag);
|
||||||
|
tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
|
||||||
|
bitangents = mesh->mBitangents = new aiVector3D[mesh->mNumVertices]();
|
||||||
|
}
|
||||||
|
|
||||||
|
tag = object->GetTag(Tuvw);
|
||||||
|
UVWTag* uvs_src = NULL;
|
||||||
|
if(tag) {
|
||||||
|
uvs_src = dynamic_cast<UVWTag*>(tag);
|
||||||
|
uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy vertices and extra channels over and populate faces
|
||||||
|
for (LONG i = 0; i < polyCount; ++i, ++face)
|
||||||
|
{
|
||||||
|
ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
|
||||||
|
const Vector& pointA = points[polys[i].a];
|
||||||
|
verts->x = pointA.x;
|
||||||
|
verts->y = pointA.y;
|
||||||
|
verts->z = pointA.z;
|
||||||
|
++verts;
|
||||||
|
|
||||||
|
ai_assert(polys[i].b < pointCount && polys[i].b >= 0);
|
||||||
|
const Vector& pointB = points[polys[i].b];
|
||||||
|
verts->x = pointB.x;
|
||||||
|
verts->y = pointB.y;
|
||||||
|
verts->z = pointB.z;
|
||||||
|
++verts;
|
||||||
|
|
||||||
|
ai_assert(polys[i].c < pointCount && polys[i].c >= 0);
|
||||||
|
const Vector& pointC = points[polys[i].c];
|
||||||
|
verts->x = pointC.x;
|
||||||
|
verts->y = pointC.y;
|
||||||
|
verts->z = pointC.z;
|
||||||
|
++verts;
|
||||||
|
|
||||||
|
// TODO: do we also need to handle lines or points with similar checks?
|
||||||
|
if (polys[i].c != polys[i].d)
|
||||||
|
{
|
||||||
|
ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
|
||||||
|
|
||||||
|
face->mNumIndices = 4;
|
||||||
|
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
|
const Vector& pointD = points[polys[i].d];
|
||||||
|
verts->x = pointD.x;
|
||||||
|
verts->y = pointD.y;
|
||||||
|
verts->z = pointD.z;
|
||||||
|
++verts;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
face->mNumIndices = 3;
|
||||||
|
}
|
||||||
|
face->mIndices = new unsigned int[face->mNumIndices];
|
||||||
|
for(unsigned int j = 0; j < face->mNumIndices; ++j) {
|
||||||
|
face->mIndices[j] = n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy normals
|
||||||
|
if (normals_src) {
|
||||||
|
if(i >= normals_src->GetDataCount()) {
|
||||||
|
LogError("unexpected number of normals, ignoring");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
|
||||||
|
NormalStruct nor;
|
||||||
|
NormalTag::Get(normal_handle, i, nor);
|
||||||
|
normals->x = nor.a.x;
|
||||||
|
normals->y = nor.a.y;
|
||||||
|
normals->z = nor.a.z;
|
||||||
|
++normals;
|
||||||
|
|
||||||
|
normals->x = nor.b.x;
|
||||||
|
normals->y = nor.b.y;
|
||||||
|
normals->z = nor.b.z;
|
||||||
|
++normals;
|
||||||
|
|
||||||
|
normals->x = nor.c.x;
|
||||||
|
normals->y = nor.c.y;
|
||||||
|
normals->z = nor.c.z;
|
||||||
|
++normals;
|
||||||
|
|
||||||
|
if(face->mNumIndices == 4) {
|
||||||
|
normals->x = nor.d.x;
|
||||||
|
normals->y = nor.d.y;
|
||||||
|
normals->z = nor.d.z;
|
||||||
|
++normals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy tangents and bitangents
|
||||||
|
if (tangents_src) {
|
||||||
|
|
||||||
|
for(unsigned int k = 0; k < face->mNumIndices; ++k) {
|
||||||
|
LONG l;
|
||||||
|
switch(k) {
|
||||||
|
case 0:
|
||||||
|
l = polys[i].a;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
l = polys[i].b;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
l = polys[i].c;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
l = polys[i].d;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ai_assert(false);
|
||||||
|
}
|
||||||
|
if(l >= tangents_src->GetDataCount()) {
|
||||||
|
LogError("unexpected number of tangents, ignoring");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Tangent tan = tangents_src->GetDataR()[l];
|
||||||
|
tangents->x = tan.vl.x;
|
||||||
|
tangents->y = tan.vl.y;
|
||||||
|
tangents->z = tan.vl.z;
|
||||||
|
++tangents;
|
||||||
|
|
||||||
|
bitangents->x = tan.vr.x;
|
||||||
|
bitangents->y = tan.vr.y;
|
||||||
|
bitangents->z = tan.vr.z;
|
||||||
|
++bitangents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy UVs
|
||||||
|
if (uvs_src) {
|
||||||
|
if(i >= uvs_src->GetDataCount()) {
|
||||||
|
LogError("unexpected number of UV coordinates, ignoring");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UVWStruct uvw;
|
||||||
|
uvs_src->Get(uvs_src->GetDataAddressR(),i,uvw);
|
||||||
|
|
||||||
|
uvs->x = uvw.a.x;
|
||||||
|
uvs->y = 1.0f-uvw.a.y;
|
||||||
|
uvs->z = uvw.a.z;
|
||||||
|
++uvs;
|
||||||
|
|
||||||
|
uvs->x = uvw.b.x;
|
||||||
|
uvs->y = 1.0f-uvw.b.y;
|
||||||
|
uvs->z = uvw.b.z;
|
||||||
|
++uvs;
|
||||||
|
|
||||||
|
uvs->x = uvw.c.x;
|
||||||
|
uvs->y = 1.0f-uvw.c.y;
|
||||||
|
uvs->z = uvw.c.z;
|
||||||
|
++uvs;
|
||||||
|
|
||||||
|
if(face->mNumIndices == 4) {
|
||||||
|
uvs->x = uvw.d.x;
|
||||||
|
uvs->y = 1.0f-uvw.d.y;
|
||||||
|
uvs->z = uvw.d.z;
|
||||||
|
++uvs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mesh->mMaterialIndex = ResolveMaterial(polyObject);
|
||||||
|
return mesh.dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
|
||||||
|
{
|
||||||
|
ai_assert(obj != NULL);
|
||||||
|
|
||||||
|
const unsigned int mat_count = static_cast<unsigned int>(materials.size());
|
||||||
|
|
||||||
|
BaseTag* tag = obj->GetTag(Ttexture);
|
||||||
|
if(tag == NULL) {
|
||||||
|
return mat_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
|
||||||
|
|
||||||
|
BaseMaterial* const mat = ttag.GetMaterial();
|
||||||
|
assert(mat != NULL);
|
||||||
|
|
||||||
|
const MaterialMap::const_iterator it = material_mapping.find(mat);
|
||||||
|
if(it == material_mapping.end()) {
|
||||||
|
return mat_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
ai_assert((*it).second < mat_count);
|
||||||
|
return (*it).second;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
|
|
|
@ -0,0 +1,123 @@
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (assimp)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2012, assimp team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the assimp team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the assimp team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file C4DImporter.h
|
||||||
|
* @brief Declaration of the Cinema4D (*.c4d) importer class.
|
||||||
|
*/
|
||||||
|
#ifndef INCLUDED_AI_CINEMA_4D_LOADER_H
|
||||||
|
#define INCLUDED_AI_CINEMA_4D_LOADER_H
|
||||||
|
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include "LogAux.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
struct aiNode;
|
||||||
|
struct aiMesh;
|
||||||
|
struct aiMaterial;
|
||||||
|
|
||||||
|
struct aiImporterDesc;
|
||||||
|
|
||||||
|
namespace melange {
|
||||||
|
class BaseObject; // c4d_file.h
|
||||||
|
class PolygonObject;
|
||||||
|
class BaseMaterial;
|
||||||
|
class BaseShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Assimp {
|
||||||
|
|
||||||
|
// TinyFormatter.h
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
/** Importer class to load Cinema4D files using the Melange library to be obtained from
|
||||||
|
* www.plugincafe.com
|
||||||
|
*
|
||||||
|
* Note that Melange is not free software. */
|
||||||
|
// -------------------------------------------------------------------------------------------
|
||||||
|
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
C4DImporter();
|
||||||
|
~C4DImporter();
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
||||||
|
bool checkSig) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
const aiImporterDesc* GetInfo () const;
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void ReadMaterials(melange::BaseMaterial* mat);
|
||||||
|
void RecurseHierarchy(melange::BaseObject* object, aiNode* parent);
|
||||||
|
aiMesh* ReadMesh(melange::BaseObject* object);
|
||||||
|
unsigned int ResolveMaterial(melange::PolygonObject* obj);
|
||||||
|
|
||||||
|
bool ReadShader(aiMaterial* out, melange::BaseShader* shader);
|
||||||
|
|
||||||
|
std::vector<aiMesh*> meshes;
|
||||||
|
std::vector<aiMaterial*> materials;
|
||||||
|
|
||||||
|
typedef std::map<melange::BaseMaterial*, unsigned int> MaterialMap;
|
||||||
|
MaterialMap material_mapping;
|
||||||
|
|
||||||
|
}; // !class C4DImporter
|
||||||
|
|
||||||
|
} // end of namespace Assimp
|
||||||
|
#endif // INCLUDED_AI_CINEMA_4D_LOADER_H
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue