2
0
Эх сурвалжийг харах

Merge pull request #10 from assimp/master

Update fork
Madrich 9 жил өмнө
parent
commit
406d9a10cb
100 өөрчлөгдсөн 1189 нэмэгдсэн , 393 устгасан
  1. 12 0
      .gitignore
  2. 3 3
      .travis.sh
  3. 30 12
      CHANGES
  4. 33 5
      CMakeLists.txt
  5. 7 8
      INSTALL
  6. 12 18
      LICENSE
  7. 28 27
      Readme.md
  8. 23 4
      appveyor.yml
  9. 3 1
      assimp-config.cmake.in
  10. 12 6
      cmake-modules/AddGTest.cmake
  11. 2 1
      cmake-modules/FindPkgMacros.cmake
  12. 78 22
      cmake-modules/Findassimp.cmake
  13. 8 7
      code/3DSConverter.cpp
  14. 1 1
      code/3DSExporter.cpp
  15. 1 1
      code/3DSExporter.h
  16. 11 10
      code/3DSHelper.h
  17. 3 3
      code/3DSLoader.cpp
  18. 1 1
      code/3DSLoader.h
  19. 6 6
      code/ACLoader.cpp
  20. 1 1
      code/ACLoader.h
  21. 1 1
      code/ASELoader.cpp
  22. 1 1
      code/ASELoader.h
  23. 11 11
      code/ASEParser.cpp
  24. 5 5
      code/ASEParser.h
  25. 2 2
      code/AssbinExporter.cpp
  26. 1 1
      code/AssbinExporter.h
  27. 1 1
      code/AssbinLoader.cpp
  28. 1 1
      code/AssbinLoader.h
  29. 61 15
      code/Assimp.cpp
  30. 29 4
      code/AssimpCExport.cpp
  31. 3 3
      code/AssxmlExporter.cpp
  32. 1 1
      code/AssxmlExporter.h
  33. 3 2
      code/B3DImporter.cpp
  34. 1 1
      code/B3DImporter.h
  35. 1 1
      code/BVHLoader.cpp
  36. 2 2
      code/BVHLoader.h
  37. 13 8
      code/BaseImporter.cpp
  38. 29 4
      code/BaseImporter.h
  39. 1 1
      code/BaseProcess.cpp
  40. 3 3
      code/BaseProcess.h
  41. 6 1
      code/Bitmap.cpp
  42. 1 1
      code/Bitmap.h
  43. 1 1
      code/BlenderDNA.cpp
  44. 1 1
      code/BlenderDNA.h
  45. 1 1
      code/BlenderDNA.inl
  46. 1 1
      code/BlenderIntermediate.h
  47. 10 3
      code/BlenderLoader.cpp
  48. 1 1
      code/BlenderLoader.h
  49. 1 1
      code/BlenderModifier.cpp
  50. 1 1
      code/BlenderModifier.h
  51. 4 1
      code/BlenderScene.cpp
  52. 4 12
      code/BlenderScene.h
  53. 1 1
      code/BlobIOSystem.h
  54. 1 1
      code/ByteSwapper.h
  55. 3 3
      code/CInterfaceIOWrapper.h
  56. 29 3
      code/CMakeLists.txt
  57. 1 1
      code/COBLoader.cpp
  58. 1 1
      code/COBLoader.h
  59. 1 1
      code/COBScene.h
  60. 1 1
      code/CSMLoader.cpp
  61. 1 1
      code/CSMLoader.h
  62. 1 1
      code/CalcTangentsProcess.cpp
  63. 1 1
      code/CalcTangentsProcess.h
  64. 28 7
      code/ColladaExporter.cpp
  65. 1 1
      code/ColladaExporter.h
  66. 46 2
      code/ColladaHelper.h
  67. 46 12
      code/ColladaLoader.cpp
  68. 1 2
      code/ColladaLoader.h
  69. 205 24
      code/ColladaParser.cpp
  70. 16 1
      code/ColladaParser.h
  71. 2 2
      code/ComputeUVMappingProcess.cpp
  72. 2 2
      code/ComputeUVMappingProcess.h
  73. 1 1
      code/ConvertToLHProcess.cpp
  74. 1 1
      code/ConvertToLHProcess.h
  75. 3 1
      code/DXFHelper.h
  76. 1 1
      code/DXFLoader.cpp
  77. 1 1
      code/DXFLoader.h
  78. 2 2
      code/DeboneProcess.cpp
  79. 1 1
      code/DeboneProcess.h
  80. 1 1
      code/DefaultIOStream.cpp
  81. 1 1
      code/DefaultIOStream.h
  82. 1 2
      code/DefaultIOSystem.cpp
  83. 1 1
      code/DefaultIOSystem.h
  84. 20 17
      code/DefaultLogger.cpp
  85. 1 1
      code/DefaultProgressHandler.h
  86. 10 1
      code/Exporter.cpp
  87. 1 1
      code/FBXAnimation.cpp
  88. 1 1
      code/FBXBinaryTokenizer.cpp
  89. 1 1
      code/FBXCompileConfig.h
  90. 78 34
      code/FBXConverter.cpp
  91. 1 1
      code/FBXConverter.h
  92. 2 2
      code/FBXDeformer.cpp
  93. 9 1
      code/FBXDocument.cpp
  94. 62 1
      code/FBXDocument.h
  95. 1 1
      code/FBXDocumentUtil.cpp
  96. 5 1
      code/FBXImportSettings.h
  97. 2 1
      code/FBXImporter.cpp
  98. 1 1
      code/FBXImporter.h
  99. 82 1
      code/FBXMaterial.cpp
  100. 33 16
      code/FBXMeshGeometry.cpp

+ 12 - 0
.gitignore

@@ -60,3 +60,15 @@ 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

+ 3 - 3
.travis.sh

@@ -3,7 +3,7 @@ function generate()
     cmake -G "Unix Makefiles" -DASSIMP_ENABLE_BOOST_WORKAROUND=YES -DASSIMP_NO_EXPORT=$TRAVIS_NO_EXPORT -DBUILD_SHARED_LIBS=$SHARED_BUILD
 }
 
-if [ $ANDROID ]; then 
+if [ $ANDROID ]; then
     ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
 else
     generate \
@@ -11,6 +11,6 @@ else
     && sudo make install \
     && sudo ldconfig \
     && (cd test/unit; ../../bin/unit) \
-    && (cd test/regression; chmod 755 run.py; ./run.py; \
-	chmod 755 result_checker.py; ./result_checker.py)
+    #&& (cd test/regression; chmod 755 run.py; ./run.py; \
+	  #chmod 755 result_checker.py; ./result_checker.py)
 fi

+ 30 - 12
CHANGES

@@ -2,6 +2,24 @@
 CHANGELOG
 ----------------------------------------------------------------------
 
+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)
 
 FEATURES:
@@ -18,18 +36,18 @@ FEATURES:
 FIXES/HOUSEKEEPING:
     - Hundreds of bugfixes in all parts of the library
     - CMake is now the primary build system
-    
+
 API COMPATIBILITY:
     - 3.1.1 is not binary compatible to 3.0 due to aiNode::mMetaData
       and aiMesh::mName
     - Export interface has been cleaned up and unified
     - Other than that no relevant changes
-   
+
 
 3.0 (2012-07-07)
 
 FEATURES:
-   - new export interface similar to the import API. 
+   - new export interface similar to the import API.
    - Supported export formats: Collada, OBJ, PLY and STL
    - added new import formats: XGL/ZGL, M3 (experimental)
    - new postprocessing steps: Debone
@@ -46,11 +64,11 @@ FIXES/HOUSEKEEPING:
    - improved CMake build system
    - templatized math library
    - reduce dependency on boost.thread, only remaining spot
-     is synchronization for the C logging API 
+     is synchronization for the C logging API
 
 API COMPATIBILITY:
    - renamed headers, export interface, C API properties and meta data
-     prevent compatibility with code written for 2.0, but in 
+     prevent compatibility with code written for 2.0, but in
      most cases these can be easily resolved
    - Note: 3.0 is not binary compatible with 2.0
 
@@ -68,9 +86,9 @@ FEATURES:
      spatial structure) in some expensive postprocessing steps
    - AssimpView now uses a reworked layout which leaves more space
      to the scene hierarchy window
-     
+
    - Add C# bindings ('Assimp.NET')
-   - Keep BSD-licensed and otherwise free test files in separate 
+   - Keep BSD-licensed and otherwise free test files in separate
      folders (./test/models and ./test/models-nonbsd).
 
 FIXES:
@@ -80,20 +98,20 @@ FIXES:
    - OpenGL-sample now works with MinGW
    - Fix Importer::FindLoader failing on uppercase file extensions
    - Fix flawed path handling when locating external files
-   - Limit the maximum number of vertices, faces, face indices and 
+   - Limit the maximum number of vertices, faces, face indices and
      weights that Assimp is able to handle. This is to avoid
      crashes due to overflowing counters.
-   
+
    - Updated XCode project files
    - Further CMAKE build improvements
-   
+
 
 API CHANGES:
    - Add data structures for vertex-based animations (These are not
      currently used, however ...)
    - Some Assimp::Importer methods are const now.
- 
- 
+
+
 
 
 

+ 33 - 5
CMakeLists.txt

@@ -10,8 +10,8 @@ endif(NOT BUILD_SHARED_LIBS)
 
 # Define here the needed parameters
 set (ASSIMP_VERSION_MAJOR 3)
-set (ASSIMP_VERSION_MINOR 1)
-set (ASSIMP_VERSION_PATCH 1) # subversion revision?
+set (ASSIMP_VERSION_MINOR 2)
+set (ASSIMP_VERSION_PATCH 0) # subversion revision?
 set (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VERSION_PATCH})
 set (ASSIMP_SOVERSION 3)
 set (PROJECT_VERSION "${ASSIMP_VERSION}")
@@ -98,10 +98,10 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
 SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
   "Path the tool executables are installed to." )
 
-IF (CMAKE_BUILD_TYPE STREQUAL "Release")
-  SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
-ELSE()
+IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
   SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools")
+ELSE()
+  SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
 ENDIF()
 
 # Only generate this target if no higher-level project already has
@@ -340,3 +340,31 @@ if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
   include(CPack)
   include(DebSourcePPA)
 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)

+ 7 - 8
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
 http://www.cmake.org/. 
 
-Building Assimp with CMake is 'business as usual' if you've used CMake
-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. 
+For Unix:
 
+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

+ 12 - 18
LICENSE

@@ -1,10 +1,10 @@
 Open Asset Import Library (assimp)
 
-Copyright (c) 2006-2015, assimp team
+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 
+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
@@ -21,16 +21,16 @@ following conditions are met:
   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 
+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 
+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 
+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 
+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.
 
 
@@ -41,9 +41,9 @@ AN EXCEPTION applies to all files in the ./test/models-nonbsd folder.
 These are 3d models for testing purposes, from various free sources
 on the internet. They are - unless otherwise stated - copyright of
 their respective creators, which may impose additional requirements
-on the use of their work. For any of these models, see 
+on the use of their work. For any of these models, see
 <model-name>.source.txt for more legal information. Contact us if you
-are a copyright holder and believe that we credited you inproperly or 
+are a copyright holder and believe that we credited you inproperly or
 if you don't want your files to appear in the repository.
 
 
@@ -76,9 +76,3 @@ 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.
-
-
-
-
-
-

+ 28 - 27
Readme.md

@@ -1,6 +1,5 @@
-Open Asset Import Library (assimp) 
-========
-
+Open Asset Import Library (assimp)
+==================================
 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.
 
 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.
@@ -28,28 +27,28 @@ __Importers__:
 - BLEND (Blender)
 - DAE/Collada
 - FBX
-- IFC-STEP 
+- IFC-STEP
 - ASE
 - DXF
 - HMP
 - MD2
-- MD3 
+- MD3
 - MD5
 - MDC
 - MDL
 - NFF
 - PLY
 - STL
-- X 
+- X
 - OBJ
 - OpenGEX
 - SMD
-- LWO 
-- LXO 
+- LWO
+- LXO
 - LWS  
-- TER 
-- AC3D 
-- MS3D 
+- TER
+- AC3D
+- MS3D
 - COB
 - Q3BSP
 - XGL
@@ -61,7 +60,8 @@ __Importers__:
 - Ogre XML
 - Q3D
 - ASSBIN (Assimp custom format)
- 
+- glTF
+
 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)
@@ -76,16 +76,18 @@ __Exporters__:
 - 3DS
 - JSON (for WebGl, via https://github.com/acgessler/assimp2json)
 - ASSBIN
-	
-### Building ###
-
+- glTF
 
+### 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)
 
 #### Repository structure ####
-
-
 Open Asset Import Library is implemented in C++. The directory structure is:
 
 	/code		Source code
@@ -96,35 +98,34 @@ Open Asset Import Library is implemented in C++. The directory structure is:
 	/port		Ports to other languages and scripts to maintain those.
 	/test		Unit- and regression tests, test suite of models
 	/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
 	/workspaces	Build enviroments for vc,xcode,... (deprecated,
 			CMake has superseeded all legacy build options!)
 
 
 ### Where to get help ###
-
-
 For more information, visit [our website](http://assimp.sourceforge.net/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
 (CHMs for Windows are included in some release packages and should be located right here in the root folder).
 
 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.
 
 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)
 
 And we also have an IRC-channel at freenode: #assetimporterlib . You can easily join us via: [KiwiIRC/freenote](https://kiwiirc.com/client/irc.freenode.net), choose your nickname and type
 > /join #assetimporterlib
 
 ### 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.
 
 ### License ###
+Our license is based on the modified, __3-clause BSD__-License.
 
-Our license is based on the modified, __3-clause BSD__-License. 
-
-An _informal_ summary is: do whatever you want, but include Assimp's license text with your product - 
+An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
 and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
-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 ...

+ 23 - 4
appveyor.yml

@@ -10,12 +10,31 @@ branches:
   only:
     - master
 
-platform: x64
-configuration: Release
+platform:
+    - x86
+    - x64
 
-build:
+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
- - cmake CMakeLists.txt -G "Visual Studio 11" 
+ - cmake CMakeLists.txt -G "Visual Studio %Configuration%"
  - 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

+ 3 - 1
assimp-config.cmake.in

@@ -29,8 +29,10 @@ if( MSVC )
     set(MSVC_PREFIX "vc110")
   elseif( MSVC12 )
     set(MSVC_PREFIX "vc120")
+  elseif( MSVC14 )
+    set(MSVC_PREFIX "vc140")
   else()
-    set(MSVC_PREFIX "vc130")
+    set(MSVC_PREFIX "vc150")
   endif()
   set(ASSIMP_LIBRARY_SUFFIX "@ASSIMP_LIBRARY_SUFFIX@-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library" FORCE)
 else()

+ 12 - 6
cmake-modules/AddGTest.cmake

@@ -10,6 +10,9 @@ endif()
 if (MSVC)
   set(RELEASE_LIB_DIR ReleaseLibs)
   set(DEBUG_LIB_DIR DebugLibs)
+elseif(XCODE_VERSION)
+  set(RELEASE_LIB_DIR Release)
+  set(DEBUG_LIB_DIR Debug)
 else()
   set(RELEASE_LIB_DIR "")
   set(DEBUG_LIB_DIR "")
@@ -18,7 +21,8 @@ endif()
 set(GTEST_CMAKE_ARGS
   "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}"
   "-Dgtest_force_shared_crt=ON"
-  "-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}")
+  "-Dgtest_disable_pthreads:BOOL=${DISABLE_PTHREADS}"
+  "-DBUILD_GTEST=ON")
 set(GTEST_RELEASE_LIB_DIR "")
 set(GTEST_DEBUGLIB_DIR "")
 if (MSVC)
@@ -38,7 +42,7 @@ else(NOT GIT_FOUND)
   set(AddGTest_FOUND true CACHE BOOL "Was gtest setup correctly?")
 
   ExternalProject_Add(gtest
-    GIT_REPOSITORY https://chromium.googlesource.com/external/googletest
+    GIT_REPOSITORY https://github.com/google/googletest.git
     TIMEOUT 10
     PREFIX "${GTEST_PREFIX}"
     CMAKE_ARGS "${GTEST_CMAKE_ARGS}"
@@ -53,10 +57,10 @@ else(NOT GIT_FOUND)
   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}"
+    "${LIB_PREFIX}gtest${LIB_SUFFIX}"
     "${CMAKE_THREAD_LIBS_INIT}")
   SET(GTEST_RELEASE_LIBRARIES
-    "${GTEST_LOCATION}/${RELEASE_LIB_DIR}/${LIB_PREFIX}gtest${LIB_SUFFIX}"
+    "${LIB_PREFIX}gtest${LIB_SUFFIX}"
     "${CMAKE_THREAD_LIBS_INIT}")
 
   if(MSVC_VERSION EQUAL 1700)
@@ -64,9 +68,11 @@ else(NOT GIT_FOUND)
   endif()
 
   ExternalProject_Get_Property(gtest source_dir)
-  include_directories(${source_dir}/include)
+  include_directories(${source_dir}/googletest/include)
   include_directories(${source_dir}/gtest/include)
 
   ExternalProject_Get_Property(gtest binary_dir)
-  link_directories(${binary_dir})
+  link_directories(${binary_dir}/googlemock/gtest)
+  link_directories(${binary_dir}/googlemock/gtest/${RELEASE_LIB_DIR})
+  link_directories(${binary_dir}/googlemock/gtest/${DEBUG_LIB_DIR})
 endif(NOT GIT_FOUND)

+ 2 - 1
cmake-modules/FindPkgMacros.cmake

@@ -85,7 +85,7 @@ macro(get_debug_names PREFIX)
   endforeach(i)
 endmacro(get_debug_names)
 
-# Add the parent dir from DIR to VAR 
+# Add the parent dir from DIR to VAR
 macro(add_parent_dir VAR DIR)
   get_filename_component(${DIR}_TEMP "${${DIR}}/.." ABSOLUTE)
   set(${VAR} ${${VAR}} ${${DIR}_TEMP})
@@ -127,6 +127,7 @@ MACRO(findpkg_framework fwk)
       /System/Library/Frameworks
       /Network/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})
       SET(fwkpath ${dir}/${fwk}.framework)

+ 78 - 22
cmake-modules/Findassimp.cmake

@@ -1,25 +1,81 @@
-FIND_PATH(
-  assimp_INCLUDE_DIRS
-  NAMES postprocess.h scene.h version.h config.h cimport.h
-  PATHS /usr/local/include/
-)
+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_LIBRARY(
-  assimp_LIBRARIES
-  NAMES assimp
-  PATHS /usr/local/lib/
-)
+	# Find path of each library
+	find_path(ASSIMP_INCLUDE_DIR
+		NAMES
+			assimp/anim.h
+		HINTS
+			${ASSIMP_ROOT_DIR}/include
+	)
 
-IF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
-  SET(assimp_FOUND TRUE)
-ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
+	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)
 
-IF (assimp_FOUND)
-  IF (NOT assimp_FIND_QUIETLY)
-    MESSAGE(STATUS "Found asset importer library: ${assimp_LIBRARIES}")
-  ENDIF (NOT assimp_FIND_QUIETLY)
-ELSE (assimp_FOUND)
-  IF (assimp_FIND_REQUIRED)
-    MESSAGE(FATAL_ERROR "Could not find asset importer library")
-  ENDIF (assimp_FIND_REQUIRED)
-ENDIF (assimp_FOUND)
+	find_path(
+	  assimp_INCLUDE_DIRS
+	  NAMES postprocess.h scene.h version.h config.h cimport.h
+	  PATHS /usr/local/include/
+	)
+
+	find_library(
+	  assimp_LIBRARIES
+	  NAMES assimp
+	  PATHS /usr/local/lib/
+	)
+
+	if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
+	  SET(assimp_FOUND TRUE)
+	ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES)
+
+	if (assimp_FOUND)
+	  if (NOT assimp_FIND_QUIETLY)
+		message(STATUS "Found asset importer library: ${assimp_LIBRARIES}")
+	  endif (NOT assimp_FIND_QUIETLY)
+	else (assimp_FOUND)
+	  if (assimp_FIND_REQUIRED)
+		message(FATAL_ERROR "Could not find asset importer library")
+	  endif (assimp_FIND_REQUIRED)
+	endif (assimp_FOUND)
+	
+endif(WIN32)

+ 8 - 7
code/3DSConverter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -70,8 +70,9 @@ void Discreet3DSImporter::ReplaceDefaultMaterial()
     for (unsigned int i = 0; i < mScene->mMaterials.size();++i)
     {
         std::string s = mScene->mMaterials[i].mName;
-        for (std::string::iterator it = s.begin(); it != s.end(); ++it)
-            *it = ::tolower(*it);
+        for ( std::string::iterator it = s.begin(); it != s.end(); ++it ) {
+            *it = static_cast< char >( ::tolower( *it ) );
+        }
 
         if (std::string::npos == s.find("default"))continue;
 
@@ -663,14 +664,14 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene* pcSOut,aiNode* pcOut,
             nda->mRotationKeys = new aiQuatKey[nda->mNumRotationKeys];
 
             // Rotations are quaternion offsets
-            aiQuaternion abs;
+            aiQuaternion abs1;
             for (unsigned int n = 0; n < nda->mNumRotationKeys;++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].mValue = abs.Normalize();
+                nda->mRotationKeys[n].mValue = abs1.Normalize();
             }
         }
 
@@ -757,7 +758,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene* pcOut)
             pcNode->mNumMeshes = 1;
 
             // Build a name for the node
-            pcNode->mName.length = sprintf(pcNode->mName.data,"3DSMesh_%u",i);
+            pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u",i);
         }
 
         // Build dummy nodes for all cameras

+ 1 - 1
code/3DSExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/3DSExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 11 - 10
code/3DSHelper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "SpatialSort.h"
 #include "SmoothingGroups.h"
+#include "StringUtils.h"
 #include "qnan.h"
 #include "./../include/assimp/material.h"
 #include "./../include/assimp/camera.h"
@@ -379,7 +380,7 @@ struct Material
         static int iCnt = 0;
 
         char szTemp[128];
-        sprintf(szTemp,"UNNAMED_%i",iCnt++);
+        ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
     }
 
@@ -435,7 +436,7 @@ struct Mesh : public MeshWithSmoothingGroups<D3DS::Face>
 
         // Generate a default name for the mesh
         char szTemp[128];
-        ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
+        ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
     }
 
@@ -484,18 +485,18 @@ struct aiFloatKey
 /** Helper structure to represent a 3ds file node */
 struct Node
 {
-    Node()
-        : mParent()
-        , mInstanceNumber()
-        ,   mHierarchyPos       (0)
-        ,   mHierarchyIndex     (0)
-        ,   mInstanceCount      (1)
+    Node():
+    	mParent(NULL)
+		,	mInstanceNumber(0)
+		,	mHierarchyPos		(0)
+		,	mHierarchyIndex		(0)
+		,	mInstanceCount		(1)
     {
         static int iCnt = 0;
 
         // Generate a default name for the node
         char szTemp[128];
-        ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
 
         aRotationKeys.reserve (20);

+ 3 - 3
code/3DSLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -86,8 +86,8 @@ static const aiImporterDesc desc = {
     int chunkSize = chunk.Size-sizeof(Discreet3DS::Chunk);               \
     if(chunkSize <= 0)                                                   \
         continue;                                                        \
-    const int oldReadLimit = stream->GetReadLimit();                     \
-    stream->SetReadLimit(stream->GetCurrentPos() + chunkSize);           \
+    const unsigned int oldReadLimit = stream->SetReadLimit(              \
+        stream->GetCurrentPos() + chunkSize);                            \
 
 
 // ------------------------------------------------------------------------------------------------

+ 1 - 1
code/3DSLoader.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 6 - 6
code/ACLoader.cpp

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -211,7 +211,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
 
         // 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.
-        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 );
 
         DefaultLogger::get()->debug("AC3D: Light source encountered");
@@ -733,18 +733,18 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
         switch (object.type)
         {
         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;
         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;
         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;
 
             // there shouldn't be more than one world, but we don't care
         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;
         }
     }

+ 1 - 1
code/ACLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/ASELoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/ASELoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 11 - 11
code/ASEParser.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -143,9 +143,9 @@ void Parser::LogWarning(const char* szWarn)
 
     char szTemp[1024];
 #if _MSC_VER >= 1400
-    sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
+    sprintf_s(szTemp, "Line %u: %s",iLineNumber,szWarn);
 #else
-    snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
+    ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
 #endif
 
     // output the warning to the logger ...
@@ -161,7 +161,7 @@ void Parser::LogInfo(const char* szWarn)
 #if _MSC_VER >= 1400
     sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
 #else
-    snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
+    ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
 #endif
 
     // output the information to the logger ...
@@ -177,7 +177,7 @@ AI_WONT_RETURN void Parser::LogError(const char* szWarn)
 #if _MSC_VER >= 1400
     sprintf_s(szTemp,"Line %u: %s",iLineNumber,szWarn);
 #else
-    snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
+    ai_snprintf(szTemp,1024,"Line %u: %s",iLineNumber,szWarn);
 #endif
 
     // throw an exception
@@ -825,7 +825,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
     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);
         return false;
     }
@@ -833,7 +833,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
     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);
         LogWarning(szBuffer);
         return false;
@@ -845,7 +845,7 @@ bool Parser::ParseString(std::string& out,const char* szName)
         if ('\"' == *sz)break;
         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 "
                 "a closing quotation mark was encountered",szName);
             LogWarning(szBuffer);
@@ -1134,7 +1134,7 @@ void Parser::ParseLV3ScaleAnimationBlock(ASE::Animation& anim)
             bool b = false;
 
             // For the moment we're just reading the three floats -
-            // we ignore the ádditional information for bezier's and TCBs
+            // we ignore the �dditional information for bezier's and TCBs
 
             // simple scaling keyframe
             if (TokenMatch(filePtr,"CONTROL_SCALE_SAMPLE" ,20))
@@ -1180,7 +1180,7 @@ void Parser::ParseLV3PosAnimationBlock(ASE::Animation& anim)
             bool b = false;
 
             // For the moment we're just reading the three floats -
-            // we ignore the ádditional information for bezier's and TCBs
+            // we ignore the �dditional information for bezier's and TCBs
 
             // simple scaling keyframe
             if (TokenMatch(filePtr,"CONTROL_POS_SAMPLE" ,18))
@@ -1226,7 +1226,7 @@ void Parser::ParseLV3RotAnimationBlock(ASE::Animation& anim)
             bool b = false;
 
             // For the moment we're just reading the  floats -
-            // we ignore the ádditional information for bezier's and TCBs
+            // we ignore the �dditional information for bezier's and TCBs
 
             // simple scaling keyframe
             if (TokenMatch(filePtr,"CONTROL_ROT_SAMPLE" ,18))

+ 5 - 5
code/ASEParser.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -133,12 +133,12 @@ struct Bone
 
         // Generate a default name for the bone
         char szTemp[128];
-        ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
     }
 
     //! Construction from an existing name
-    Bone( const std::string& name)
+    explicit Bone( const std::string& name)
         :   mName   (name)
     {}
 
@@ -216,14 +216,14 @@ struct BaseNode
     enum Type {Light, Camera, Mesh, Dummy} mType;
 
     //! Constructor. Creates a default name for the node
-    BaseNode(Type _mType)
+    explicit BaseNode(Type _mType)
         : mType         (_mType)
         , mProcessed    (false)
     {
         // generate a default name for the  node
         static int iCnt = 0;
         char szTemp[128]; // should be sufficiently large
-        ::sprintf(szTemp,"UNNAMED_%i",iCnt++);
+        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
         mName = szTemp;
 
         // Set mTargetPosition to qnan

+ 2 - 2
code/AssbinExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -702,7 +702,7 @@ inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
 #if _MSC_VER >= 1400
             sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
 #else
-            snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
+            ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
 #endif
             out->Write( s, 44, 1 );
             // == 44 bytes

+ 1 - 1
code/AssbinExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/AssbinLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/AssbinLoader.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 61 - 15
code/Assimp.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -96,11 +96,13 @@ namespace Assimp
     /** 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
-/** 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;
 #endif
 
@@ -110,7 +112,7 @@ static boost::mutex gLogStreamMutex;
 class LogToCallbackRedirector : public LogStream
 {
 public:
-    LogToCallbackRedirector(const aiLogStream& s)
+    explicit LogToCallbackRedirector(const aiLogStream& s)
         : stream (s)    {
             ai_assert(NULL != s.callback);
     }
@@ -228,7 +230,8 @@ const aiScene* aiImportFileFromMemoryWithProperties(
     const char* pHint,
     const aiPropertyStore* props)
 {
-    ai_assert(NULL != pBuffer && 0 != pLength);
+    ai_assert( NULL != pBuffer );
+    ai_assert( 0 != pLength );
 
     const aiScene* scene = NULL;
     ASSIMP_BEGIN_EXCEPTION_REGION();
@@ -317,10 +320,38 @@ ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene* pScene,
     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)
 {
-    ai_assert(NULL != msg && NULL != dt);
+    ai_assert( NULL != msg );
+    ai_assert( NULL != dt );
     LogStream* s = (LogStream*)dt;
 
     s->write(msg);
@@ -373,7 +404,7 @@ ASSIMP_API aiReturn aiDetachLogStream( const aiLogStream* stream)
 #ifndef ASSIMP_BUILD_SINGLETHREADED
     boost::mutex::scoped_lock lock(gLogStreamMutex);
 #endif
-    // find the logstream associated with this data
+    // find the log-stream associated with this data
     LogStreamMap::iterator it = gActiveLogStreams.find( *stream);
     // it should be there... else the user is playing fools with us
     if( it == gActiveLogStreams.end())  {
@@ -398,12 +429,18 @@ ASSIMP_API void aiDetachAllLogStreams(void)
 #ifndef ASSIMP_BUILD_SINGLETHREADED
     boost::mutex::scoped_lock lock(gLogStreamMutex);
 #endif
+    Logger *logger( DefaultLogger::get() );
+    if ( NULL == logger ) {
+        return;
+    }
+
     for (LogStreamMap::iterator it = gActiveLogStreams.begin(); it != gActiveLogStreams.end(); ++it) {
-        DefaultLogger::get()->detatchStream( it->second );
+        logger->detatchStream( it->second );
         delete it->second;
     }
     gActiveLogStreams.clear();
     DefaultLogger::kill();
+    
     ASSIMP_END_EXCEPTION_REGION(void);
 }
 
@@ -437,7 +474,6 @@ size_t aiGetImportFormatCount(void)
     return Importer().GetImporterCount();
 }
 
-
 // ------------------------------------------------------------------------------------------------
 // Returns the error text of the last failed import process.
 aiBool aiIsExtensionSupported(const char* szExtension)
@@ -492,7 +528,6 @@ ASSIMP_API aiPropertyStore* aiCreatePropertyStore(void)
     return reinterpret_cast<aiPropertyStore*>( new PropertyMap() );
 }
 
-
 // ------------------------------------------------------------------------------------------------
 ASSIMP_API void aiReleasePropertyStore(aiPropertyStore* p)
 {
@@ -551,7 +586,8 @@ ASSIMP_API void aiSetImportPropertyMatrix(aiPropertyStore* p, const char* szName
 // Rotation matrix to quaternion
 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);
 }
 
@@ -561,7 +597,10 @@ ASSIMP_API void aiDecomposeMatrix(const aiMatrix4x4* mat,aiVector3D* scaling,
     aiQuaternion* rotation,
     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);
 }
 
@@ -585,7 +624,8 @@ ASSIMP_API void aiTransposeMatrix4(aiMatrix4x4* mat)
 ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
     const aiMatrix3x3* mat)
 {
-    ai_assert(NULL != mat && NULL != vec);
+    ai_assert( NULL != mat );
+    ai_assert( NULL != vec);
     *vec *= (*mat);
 }
 
@@ -593,7 +633,9 @@ ASSIMP_API void aiTransformVecByMatrix3(aiVector3D* vec,
 ASSIMP_API void aiTransformVecByMatrix4(aiVector3D* vec,
     const aiMatrix4x4* mat)
 {
-    ai_assert(NULL != mat && NULL != vec);
+    ai_assert( NULL != mat );
+    ai_assert( NULL != vec );
+
     *vec *= (*mat);
 }
 
@@ -603,7 +645,8 @@ ASSIMP_API void aiMultiplyMatrix4(
     aiMatrix4x4* dst,
     const aiMatrix4x4* src)
 {
-    ai_assert(NULL != dst && NULL != src);
+    ai_assert( NULL != dst );
+    ai_assert( NULL != src );
     *dst = (*dst) * (*src);
 }
 
@@ -612,7 +655,8 @@ ASSIMP_API void aiMultiplyMatrix3(
     aiMatrix3x3* dst,
     const aiMatrix3x3* src)
 {
-    ai_assert(NULL != dst && NULL != src);
+    ai_assert( NULL != dst );
+    ai_assert( NULL != src );
     *dst = (*dst) * (*src);
 }
 
@@ -648,6 +692,8 @@ ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extensi
         }
     }
 
+    DeleteImporterInstanceList(out);
+
     return desc;
 }
 

+ 29 - 4
code/AssimpCExport.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -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.
-    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)

+ 3 - 3
code/AssxmlExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -70,8 +70,8 @@ int ioprintf( IOStream * io, const char * format, ... )
     char sz[4096];
     va_list va;
     va_start( va, format );
-    int nSize = vsnprintf( sz, 4096, format, va );
-  ai_assert( nSize < 4096 );
+    int nSize = ai_snprintf( sz, 4096, format, va );
+   ai_assert( nSize < 4096 );
     va_end( va );
 
     io->Write( sz, sizeof(char), nSize );

+ 1 - 1
code/AssxmlExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 3 - 2
code/B3DImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "B3DImporter.h"
 #include "TextureTransform.h"
 #include "ConvertToLHProcess.h"
+#include "StringUtils.h"
 #include <boost/scoped_ptr.hpp>
 #include "../include/assimp/IOSystem.hpp"
 #include "../include/assimp/anim.h"
@@ -571,7 +572,7 @@ void B3DImporter::ReadBB3D( aiScene *scene ){
         
         if (!DefaultLogger::isNullLogger()) {
             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);
         }
 

+ 1 - 1
code/B3DImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/BVHLoader.cpp

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 2 - 2
code/BVHLoader.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -83,7 +83,7 @@ class BVHLoader : public BaseImporter
         std::vector<float> mChannelValues; // motion data values for that node. Of size NumChannels * NumFrames
 
         Node() { }
-        Node( const aiNode* pNode) : mNode( pNode) { }
+        explicit Node( const aiNode* pNode) : mNode( pNode) { }
     };
 
 public:

+ 13 - 8
code/BaseImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -435,22 +435,27 @@ void BaseImporter::ConvertUTF8toISO8859_1(std::string& data)
 
 // ------------------------------------------------------------------------------------------------
 void BaseImporter::TextFileToBuffer(IOStream* stream,
-    std::vector<char>& data)
+    std::vector<char>& data,
+    TextFileMode mode)
 {
     ai_assert(NULL != stream);
 
     const size_t fileSize = stream->FileSize();
-    if(!fileSize) {
-        throw DeadlyImportError("File is empty");
+    if (mode == FORBID_EMPTY) {
+        if(!fileSize) {
+            throw DeadlyImportError("File is empty");
+        }
     }
 
     data.reserve(fileSize+1);
     data.resize(fileSize);
-    if(fileSize != stream->Read( &data[0], 1, fileSize)) {
-        throw DeadlyImportError("File read error");
-    }
+    if(fileSize > 0) {
+        if(fileSize != stream->Read( &data[0], 1, fileSize)) {
+            throw DeadlyImportError("File read error");
+        }
 
-    ConvertToUTF8(data);
+        ConvertToUTF8(data);
+    }
 
     // append a binary zero to simplify string parsing
     data.push_back(0);

+ 29 - 4
code/BaseImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -70,7 +70,7 @@ class IOStream;
 template <typename T>
 struct ScopeGuard
 {
-    ScopeGuard(T* obj) : obj(obj), mdismiss() {}
+    explicit ScopeGuard(T* obj) : obj(obj), mdismiss() {}
     ~ScopeGuard () throw() {
         if (!mdismiss) {
             delete obj;
@@ -347,6 +347,8 @@ public: // static utilities
     static void ConvertUTF8toISO8859_1(
         std::string& data);
 
+	enum TextFileMode { ALLOW_EMPTY, FORBID_EMPTY };
+
     // -------------------------------------------------------------------
     /** Utility for text file loaders which copies the contents of the
      *  file into a memory buffer and converts it to our UTF8
@@ -354,10 +356,33 @@ public: // static utilities
      *  @param stream Stream to read from.
      *  @param data Output buffer to be resized and filled with the
      *   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(
         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 = vec.size();
+        if (outLength) {
+            out = new T[outLength];
+            std::swap_ranges(vec.begin(), vec.end(), out);
+        }
+    }
+
+    
 
 protected:
 

+ 1 - 1
code/BaseProcess.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 3 - 3
code/BaseProcess.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -74,7 +74,7 @@ public:
     template <typename T>
     struct THeapData : public Base
     {
-        THeapData(T* in)
+        explicit THeapData(T* in)
             : data (in)
         {}
 
@@ -89,7 +89,7 @@ public:
     template <typename T>
     struct TStaticData : public Base
     {
-        TStaticData(T in)
+        explicit TStaticData(T in)
             : data (in)
         {}
 

+ 6 - 1
code/Bitmap.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -84,7 +84,12 @@ namespace Assimp {
 
     template<typename T>
     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);
+#endif
     }
 
     void Bitmap::WriteHeader(Header& header, IOStream* file) {

+ 1 - 1
code/Bitmap.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/BlenderDNA.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/BlenderDNA.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/BlenderDNA.inl

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms, 

+ 1 - 1
code/BlenderIntermediate.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 10 - 3
code/BlenderLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "BlenderIntermediate.h"
 #include "BlenderModifier.h"
 #include "BlenderBMesh.h"
+#include "StringUtils.h"
 #include "../include/assimp/scene.h"
 #include "StringComparison.h"
 
@@ -496,7 +497,7 @@ void BlenderImporter::AddSentinelTexture(aiMaterial* out, const Material* mat, c
     (void)mat; (void)tex; (void)conv_data;
 
     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)
     );
     out->AddProperty(&name,AI_MATKEY_TEXTURE_DIFFUSE(
@@ -1010,13 +1011,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());
     out->mName = obj->id.name+2;
     out->mPosition = aiVector3D(0.f, 0.f, 0.f);
     out->mUp = aiVector3D(0.f, 1.f, 0.f);
     out->mLookAt = aiVector3D(0.f, 0.f, -1.f);
+    if (cam->sensor_x && cam->lens) {
+        out->mHorizontalFOV = atan2(cam->sensor_x,  2.f * cam->lens);
+    }
+    out->mClipPlaneNear = cam->clipsta;
+    out->mClipPlaneFar = cam->clipend;
+
     return out.dismiss();
 }
 

+ 1 - 1
code/BlenderLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/BlenderModifier.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/BlenderModifier.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 4 - 1
code/BlenderScene.cpp

@@ -620,7 +620,10 @@ template <> void Structure :: Convert<Camera> (
     ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
     ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",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);
 }

+ 4 - 12
code/BlenderScene.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -312,18 +312,10 @@ struct Camera : ElemBase {
 
     ID id FAIL;
 
-    // struct AnimData *adt;
-
     Type type,flag WARN;
-    float angle WARN;
-    //float passepartalpha, angle;
-    //float clipsta, clipend;
-    //float lens, ortho_scale, drawsize;
-    //float shiftx, shifty;
-
-    //float YF_dofdist, YF_aperture;
-    //short YF_bkhtype, YF_bkhbias;
-    //float YF_bkhrot;
+    float lens WARN;
+    float sensor_x WARN;
+    float clipsta, clipend;
 };
 
 

+ 1 - 1
code/BlobIOSystem.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/ByteSwapper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 3 - 3
code/CInterfaceIOWrapper.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -57,7 +57,7 @@ class CIOStreamWrapper : public IOStream
     friend class CIOSystemWrapper;
 public:
 
-    CIOStreamWrapper(aiFile* pFile)
+    explicit CIOStreamWrapper(aiFile* pFile)
         : mFile(pFile)
     {}
 
@@ -110,7 +110,7 @@ private:
 class CIOSystemWrapper : public IOSystem
 {
 public:
-    CIOSystemWrapper(aiFileIO* pFile)
+    explicit CIOSystemWrapper(aiFileIO* pFile)
         : mFileSystem(pFile)
     {}
 

+ 29 - 3
code/CMakeLists.txt

@@ -113,6 +113,7 @@ SET( Common_SRCS
   StreamReader.h
   StreamWriter.h
   StringComparison.h
+  StringUtils.h
   SGSpatialSort.cpp
   SGSpatialSort.h
   VertexTriangleAdjacency.cpp
@@ -530,6 +531,11 @@ ADD_ASSIMP_IMPORTER(RAW
   RawLoader.h
 )
 
+ADD_ASSIMP_IMPORTER(SIB
+  SIBImporter.cpp
+  SIBImporter.h
+)
+
 ADD_ASSIMP_IMPORTER(SMD
   SMDLoader.cpp
   SMDLoader.h
@@ -562,6 +568,19 @@ ADD_ASSIMP_IMPORTER(X
   XFileExporter.cpp
 )
 
+ADD_ASSIMP_IMPORTER(GLTF
+  glTFAsset.h
+  glTFAsset.inl
+  glTFAssetWriter.h
+  glTFAssetWriter.inl
+
+  glTFImporter.cpp
+  glTFImporter.h
+  
+  glTFExporter.h
+  glTFExporter.cpp
+)
+
 SET( Step_SRCS
   StepExporter.h
   StepExporter.cpp
@@ -632,15 +651,20 @@ SOURCE_GROUP( unzip FILES ${unzip_SRCS})
 SET ( openddl_parser_SRCS
   ../contrib/openddlparser/code/OpenDDLParser.cpp
   ../contrib/openddlparser/code/DDLNode.cpp
+  ../contrib/openddlparser/code/OpenDDLCommon.cpp
+  ../contrib/openddlparser/code/OpenDDLExport.cpp
   ../contrib/openddlparser/code/Value.cpp
   ../contrib/openddlparser/include/openddlparser/OpenDDLParser.h
   ../contrib/openddlparser/include/openddlparser/OpenDDLParserUtils.h
   ../contrib/openddlparser/include/openddlparser/OpenDDLCommon.h
+  ../contrib/openddlparser/include/openddlparser/OpenDDLExport.h
   ../contrib/openddlparser/include/openddlparser/DDLNode.h
   ../contrib/openddlparser/include/openddlparser/Value.h
 )
 SOURCE_GROUP( openddl_parser FILES ${openddl_parser_SRCS})
 
+INCLUDE_DIRECTORIES( "../contrib/rapidjson/include" )
+
 # VC2010 fixes
 if(MSVC10)
   option( VC10_STDINT_FIX "Fix for VC10 Compiler regarding pstdint.h redefinition errors" OFF )
@@ -733,8 +757,10 @@ if( MSVC )
     set(MSVC_PREFIX "vc110")
   elseif( MSVC12 )
     set(MSVC_PREFIX "vc120")
+  elseif( MSVC14 )
+    set(MSVC_PREFIX "vc140")
   else()
-    set(MSVC_PREFIX "vc130")
+    set(MSVC_PREFIX "vc150")
   endif()
   set(LIBRARY_SUFFIX "${ASSIMP_LIBRARY_SUFFIX}-${MSVC_PREFIX}-mt" CACHE STRING "the suffix for the assimp windows library")
 endif()
@@ -766,13 +792,13 @@ INSTALL( TARGETS assimp
 INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)
 INSTALL( FILES ${COMPILER_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp/Compiler COMPONENT assimp-dev)
 if (ASSIMP_ANDROID_JNIIOSYSTEM)
-  INSTALL(FILES ${HEADER_PATH}/../${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
+  INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h
     DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
     COMPONENT assimp-dev)
 endif(ASSIMP_ANDROID_JNIIOSYSTEM)
 
 if(MSVC AND ASSIMP_INSTALL_PDB)
-  install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${CMAKE_DEBUG_POSTFIX}.pdb
+  install(FILES ${Assimp_BINARY_DIR}/code/Debug/assimp${LIBRARY_SUFFIX}${CMAKE_DEBUG_POSTFIX}.pdb
     DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
     CONFIGURATIONS Debug
   )

+ 1 - 1
code/COBLoader.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/COBLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/COBScene.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/CSMLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/CSMLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/CalcTangentsProcess.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/CalcTangentsProcess.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 28 - 7
code/ColladaExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -526,6 +526,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
   }
 }
 
+// ------------------------------------------------------------------------------------------------
+// Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
+static bool isalnum_C(char c)
+{
+  return strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c);
+}
+
 // ------------------------------------------------------------------------------------------------
 // Writes an image entry for the given surface
 void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd)
@@ -540,7 +547,7 @@ void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::strin
     std::stringstream imageUrlEncoded;
     for( std::string::const_iterator it = pSurface.texture.begin(); it != pSurface.texture.end(); ++it )
     {
-      if( isalnum( *it) || *it == '_' || *it == '.' || *it == '/' || *it == '\\' )
+      if( isalnum_C( (unsigned char) *it) || *it == ':' || *it == '_' || *it == '.' || *it == '/' || *it == '\\' )
         imageUrlEncoded << *it;
       else
         imageUrlEncoded << '%' << std::hex << size_t( (unsigned char) *it) << std::dec;
@@ -631,9 +638,7 @@ void ColladaExporter::WriteMaterials()
       name = "mat";
     materials[a].name = std::string( "m") + boost::lexical_cast<std::string> (a) + name.C_Str();
     for( std::string::iterator it = materials[a].name.begin(); it != materials[a].name.end(); ++it ) {
-        // isalnum on MSVC asserts for code points outside [0,255]. Thus prevent unwanted promotion
-        // of char to signed int and take the unsigned char value.
-      if( !isalnum( static_cast<uint8_t>(*it) ) ) {
+      if( !isalnum_C( *it ) ) {
         *it = '_';
       }
     }
@@ -875,6 +880,11 @@ void ColladaExporter::WriteGeometry( size_t pIndex)
         mOutput << startstr << "<polylist count=\"" << countPoly << "\" material=\"defaultMaterial\">" << endstr;
         PushTag();
         mOutput << startstr << "<input offset=\"0\" semantic=\"VERTEX\" source=\"#" << idstrEscaped << "-vertices\" />" << endstr;
+        for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
+        {
+            if( mesh->HasTextureCoords( a) )
+                mOutput << startstr << "<input offset=\"0\" semantic=\"TEXCOORD\" source=\"#" << idstrEscaped << "-tex" << a << "\" set=\"" << a << "\" />" << endstr;
+        }
 
         mOutput << startstr << "<vcount>";
         for( size_t a = 0; a < mesh->mNumFaces; ++a )
@@ -1070,8 +1080,19 @@ void ColladaExporter::WriteNode(aiNode* pNode)
     PushTag();
     mOutput << startstr << "<technique_common>" << endstr;
     PushTag();
-    mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLEscape(materials[mesh->mMaterialIndex].name) << "\" />" << endstr;
-        PopTag();
+    mOutput << startstr << "<instance_material symbol=\"defaultMaterial\" target=\"#" << XMLEscape(materials[mesh->mMaterialIndex].name) << "\">" << endstr;
+    PushTag();
+    for( size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a )
+    {
+        if( mesh->HasTextureCoords( a) )
+            // semantic       as in <texture texcoord=...>
+            // input_semantic as in <input semantic=...>
+            // input_set      as in <input set=...>
+            mOutput << startstr << "<bind_vertex_input semantic=\"CHANNEL" << a << "\" input_semantic=\"TEXCOORD\" input_set=\"" << a << "\"/>" << endstr;
+    }
+    PopTag();
+    mOutput << startstr << "</instance_material>" << endstr;
+    PopTag();
     mOutput << startstr << "</technique_common>" << endstr;
     PopTag();
     mOutput << startstr << "</bind_material>" << endstr;

+ 1 - 1
code/ColladaExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 46 - 2
code/ColladaHelper.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -517,6 +517,7 @@ struct Effect
     float mTransparency;
     bool mHasTransparency;
     bool mRGBTransparency;
+    bool mInvertTransparency;
 
     // local params referring to each other by their SID
     typedef std::map<std::string, Collada::EffectParam> ParamLibrary;
@@ -536,10 +537,11 @@ struct Effect
         , mTransparent  ( 0, 0, 0, 1)
         , mShininess    (10.0f)
         , mRefractIndex (1.f)
-        , mReflectivity (1.f)
+        , mReflectivity (0.f)
         , mTransparency (1.f)
         , mHasTransparency (false)
         , mRGBTransparency(false)
+        , mInvertTransparency(false)
         , mDoubleSided  (false)
         , mWireframe    (false)
         , mFaceted      (false)
@@ -595,6 +597,48 @@ struct Animation
         for( std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
             delete *it;
     }
+
+	/** Collect all channels in the animation hierarchy into a single channel list. */
+	void CollectChannelsRecursively(std::vector<AnimationChannel> &channels)
+	{
+		channels.insert(channels.end(), mChannels.begin(), mChannels.end());
+
+		for (std::vector<Animation*>::iterator it = mSubAnims.begin(); it != mSubAnims.end(); ++it)
+		{
+			Animation *pAnim = (*it);
+
+			pAnim->CollectChannelsRecursively(channels);
+		}
+	}
+
+	/** Combine all single-channel animations' channel into the same (parent) animation channel list. */
+	void CombineSingleChannelAnimations()
+	{
+		CombineSingleChannelAnimationsRecursively(this);
+	}
+
+	void CombineSingleChannelAnimationsRecursively(Animation *pParent)
+	{
+		for (std::vector<Animation*>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();)
+		{
+			Animation *anim = *it;
+
+			CombineSingleChannelAnimationsRecursively(anim);
+
+			if (anim->mChannels.size() == 1)
+			{
+				pParent->mChannels.push_back(anim->mChannels[0]);
+
+				it = pParent->mSubAnims.erase(it);
+
+				delete anim;
+			}
+			else
+			{
+				++it;
+			}
+		}
+	}
 };
 
 /** Description of a collada animation channel which has been determined to affect the current node */

+ 46 - 12
code/ColladaLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "Defines.h"
 
 #include "time.h"
+#include "math.h"
 #include <boost/foreach.hpp>
 #include "../include/assimp/DefaultLogger.hpp"
 #include "../include/assimp/Importer.hpp"
@@ -77,14 +78,21 @@ static const aiImporterDesc desc = {
     "dae"
 };
 
-
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 ColladaLoader::ColladaLoader()
-    : noSkeletonMesh()
+    : mFileName()
+	, mMeshIndexByID()
+	, mMaterialIndexByName()
+	, mMeshes()
+	, newMats()
+	, mCameras()
+	, mLights()
+	, mTextures()
+	, mAnims()
+	, noSkeletonMesh( false )
     , ignoreUpDirection(false)
-    , invertTransparency(false)
-    , mNodeNameCounter()
+    , mNodeNameCounter( 0 )
 {}
 
 // ------------------------------------------------------------------------------------------------
@@ -120,7 +128,6 @@ void ColladaLoader::SetupProperties(const Importer* pImp)
 {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION,0) != 0;
-    invertTransparency = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_INVERT_TRANSPARENCY,0) != 0;
 }
 
 
@@ -1163,6 +1170,25 @@ void ColladaLoader::CreateAnimation( aiScene* pScene, const ColladaParser& pPars
                       }
                       ++pos;
                   }
+				  
+				  // https://github.com/assimp/assimp/issues/458
+			  	  // Sub-sample axis-angle channels if the delta between two consecutive
+                  // key-frame angles is >= 180 degrees.
+				  if (transforms[e.mTransformIndex].mType == Collada::TF_ROTATE && e.mSubElement == 3 && pos > 0 && pos < e.mTimeAccessor->mCount) {
+					  float cur_key_angle = ReadFloat(*e.mValueAccessor, *e.mValueData, pos, 0);
+					  float last_key_angle = ReadFloat(*e.mValueAccessor, *e.mValueData, pos - 1, 0);
+					  float cur_key_time = ReadFloat(*e.mTimeAccessor, *e.mTimeData, pos, 0);
+					  float last_key_time = ReadFloat(*e.mTimeAccessor, *e.mTimeData, pos - 1, 0);
+					  float last_eval_angle = last_key_angle + (cur_key_angle - last_key_angle) * (time - last_key_time) / (cur_key_time - last_key_time); 
+					  float delta = std::fabs(cur_key_angle - last_eval_angle);
+				      if (delta >= 180.0f) {
+						int subSampleCount = static_cast<int>(floorf(delta / 90.0f));
+						if (cur_key_time != time) {
+							float nextSampleTime = time + (cur_key_time - time) / subSampleCount;
+							nextTime = std::min(nextTime, nextSampleTime);
+						  }
+					  }
+				  }
               }
 
               // no more keys on any channel after the current time -> we're done
@@ -1341,7 +1367,6 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
         mat.AddProperty( &effect.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
         mat.AddProperty( &effect.mSpecular, 1,AI_MATKEY_COLOR_SPECULAR);
         mat.AddProperty( &effect.mEmissive, 1,  AI_MATKEY_COLOR_EMISSIVE);
-        mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
         mat.AddProperty( &effect.mReflective, 1, AI_MATKEY_COLOR_REFLECTIVE);
 
         // scalar properties
@@ -1354,20 +1379,29 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
         // therefore, we let the opportunity for the user to manually invert
         // the transparency if necessary and we add preliminary support for RGB_ZERO mode
         if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {
-            // Trying some support for RGB_ZERO mode
+            // handle RGB transparency completely, cf Collada specs 1.5.0 pages 249 and 304
             if(effect.mRGBTransparency) {
-                effect.mTransparency = 1.f - effect.mTransparent.a;
+				// use luminance as defined by ISO/CIE color standards (see ITU-R Recommendation BT.709-4)
+                effect.mTransparency *= (
+                    0.212671f * effect.mTransparent.r +
+                    0.715160f * effect.mTransparent.g +
+                    0.072169f * effect.mTransparent.b
+                );
+
+                effect.mTransparent.a = 1.f;
+
+                mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
+            } else {
+                effect.mTransparency *=  effect.mTransparent.a;
             }
 
-            // Global option
-            if(invertTransparency) {
+            if(effect.mInvertTransparency) {
                 effect.mTransparency = 1.f - effect.mTransparency;
             }
 
             // Is the material finally transparent ?
             if (effect.mHasTransparency || effect.mTransparency < 1.f) {
                 mat.AddProperty( &effect.mTransparency, 1, AI_MATKEY_OPACITY );
-                mat.AddProperty( &effect.mTransparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
             }
         }
 

+ 1 - 2
code/ColladaLoader.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -241,7 +241,6 @@ protected:
 
     bool noSkeletonMesh;
     bool ignoreUpDirection;
-    bool invertTransparency;
 
     /** Used by FindNameForNode() to generate unique node names */
     unsigned int mNodeNameCounter;

+ 205 - 24
code/ColladaParser.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -64,25 +64,41 @@ using namespace Assimp::Collada;
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
-    : mFileName( pFile)
+    : mFileName( pFile )
+    , mReader( NULL )
+    , mDataLibrary()
+    , mAccessorLibrary()
+    , mMeshLibrary()
+    , mNodeLibrary()
+    , mImageLibrary()
+    , mEffectLibrary()
+    , mMaterialLibrary()
+    , mLightLibrary()
+    , mCameraLibrary()
+    , mControllerLibrary()
+    , mRootNode( NULL )
+    , mAnims()
+    , mUnitSize( 1.0f )
+    , mUpDirection( UP_Y )
+    , mFormat(FV_1_5_n )    // We assume the newest file format by default
 {
-    mRootNode = NULL;
-    mUnitSize = 1.0f;
-    mUpDirection = UP_Y;
-
-    // We assume the newest file format by default
-    mFormat = FV_1_5_n;
+    // validate io-handler instance
+    if ( NULL == pIOHandler ) {
+        throw DeadlyImportError("IOSystem is NULL." );
+    }
 
-  // open the file
-  boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
-  if( file.get() == NULL)
-    throw DeadlyImportError( "Failed to open file " + pFile + ".");
+    // open the file
+    boost::scoped_ptr<IOStream> file( pIOHandler->Open(pFile ) );
+    if (file.get() == NULL) {
+        throw DeadlyImportError( "Failed to open file " + pFile + "." );
+    }
 
     // generate a XML reader for it
-  boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
+    boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper(new CIrrXML_IOStreamReader(file.get()));
     mReader = irr::io::createIrrXMLReader( mIOWrapper.get());
-    if( !mReader)
-        ThrowException( "Collada: Unable to open file.");
+    if (!mReader) {
+        ThrowException("Collada: Unable to open file.");
+    }
 
     // start reading
     ReadContents();
@@ -171,6 +187,8 @@ void ColladaParser::ReadStructure()
                 ReadAssetInfo();
             else if( IsElement( "library_animations"))
                 ReadAnimationLibrary();
+			else if (IsElement("library_animation_clips"))
+				ReadAnimationClipLibrary();
             else if( IsElement( "library_controllers"))
                 ReadControllerLibrary();
             else if( IsElement( "library_images"))
@@ -199,6 +217,8 @@ void ColladaParser::ReadStructure()
             break;
         }
     }
+
+	PostProcessRootAnimations();
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -255,6 +275,131 @@ void ColladaParser::ReadAssetInfo()
     }
 }
 
+// ------------------------------------------------------------------------------------------------
+// Reads the animation clips
+void ColladaParser::ReadAnimationClipLibrary()
+{
+	if (mReader->isEmptyElement())
+		return;
+
+	while (mReader->read())
+	{
+		if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
+		{
+			if (IsElement("animation_clip"))
+			{
+				// optional name given as an attribute
+				std::string animName;
+				int indexName = TestAttribute("name");
+				int indexID = TestAttribute("id");
+				if (indexName >= 0)
+					animName = mReader->getAttributeValue(indexName);
+				else if (indexID >= 0)
+					animName = mReader->getAttributeValue(indexID);
+				else
+					animName = "animation_" + mAnimationClipLibrary.size();
+
+				std::pair<std::string, std::vector<std::string> > clip;
+
+				clip.first = animName;
+
+				while (mReader->read())
+				{
+					if (mReader->getNodeType() == irr::io::EXN_ELEMENT)
+					{
+						if (IsElement("instance_animation"))
+						{
+							int indexUrl = TestAttribute("url");
+							if (indexUrl >= 0)
+							{
+								const char* url = mReader->getAttributeValue(indexUrl);
+								if (url[0] != '#')
+									ThrowException("Unknown reference format");
+
+								url++;
+
+								clip.second.push_back(url);
+							}
+						}
+						else
+						{
+							// ignore the rest
+							SkipElement();
+						}
+					}
+					else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
+					{
+						if (strcmp(mReader->getNodeName(), "animation_clip") != 0)
+							ThrowException("Expected end of <animation_clip> element.");
+
+						break;
+					}
+				}
+
+				if (clip.second.size() > 0)
+				{
+					mAnimationClipLibrary.push_back(clip);
+				}
+			}
+			else
+			{
+				// ignore the rest
+				SkipElement();
+			}
+		}
+		else if (mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
+		{
+			if (strcmp(mReader->getNodeName(), "library_animation_clips") != 0)
+				ThrowException("Expected end of <library_animation_clips> element.");
+
+			break;
+		}
+	}
+}
+
+// ------------------------------------------------------------------------------------------------
+// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
+void ColladaParser::PostProcessRootAnimations()
+{
+	if (mAnimationClipLibrary.size() > 0)
+	{
+		Animation temp;
+
+		for (AnimationClipLibrary::iterator it = mAnimationClipLibrary.begin(); it != mAnimationClipLibrary.end(); ++it)
+		{
+			std::string clipName = it->first;
+
+			Animation *clip = new Animation();
+			clip->mName = clipName;
+
+			temp.mSubAnims.push_back(clip);
+
+			for (std::vector<std::string>::iterator a = it->second.begin(); a != it->second.end(); ++a)
+			{
+				std::string animationID = *a;
+
+				AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
+
+				if (animation != mAnimationLibrary.end())
+				{
+					Animation *pSourceAnimation = animation->second;
+
+					pSourceAnimation->CollectChannelsRecursively(clip->mChannels);
+				}
+			}
+		}
+
+		mAnims = temp;
+
+		// Ensure no double deletes.
+		temp.mSubAnims.clear();
+	}
+	else
+	{
+		mAnims.CombineSingleChannelAnimations();
+	}
+}
+
 // ------------------------------------------------------------------------------------------------
 // Reads the animation library
 void ColladaParser::ReadAnimationLibrary()
@@ -302,12 +447,17 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
 
     // optional name given as an attribute
     std::string animName;
+	std::string animID;
     int indexName = TestAttribute( "name");
     int indexID = TestAttribute( "id");
+
+	if (indexID >= 0)
+		animID = mReader->getAttributeValue(indexID);
+
     if( indexName >= 0)
         animName = mReader->getAttributeValue( indexName);
     else if( indexID >= 0)
-        animName = mReader->getAttributeValue( indexID);
+        animName = animID;
     else
         animName = "animation";
 
@@ -379,11 +529,19 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
     // it turned out to have channels - add them
     if( !channels.empty())
     {
+		// FIXME: Is this essentially doing the same as "single-anim-node" codepath in 
+		//        ColladaLoader::StoreAnimations? For now, this has been deferred to after
+		//        all animations and all clips have been read. Due to handling of 
+		//        <library_animation_clips> this cannot be done here, as the channel owner 
+		//        is lost, and some exporters make up animations by referring to multiple
+		//        single-channel animations from an <instance_animation>.
+/*
         // special filtering for stupid exporters packing each channel into a separate animation
         if( channels.size() == 1)
         {
             pParent->mChannels.push_back( channels.begin()->second);
         } else
+*/
         {
             // else create the animation, if not done yet, and store the channels
             if( !anim)
@@ -394,6 +552,11 @@ void ColladaParser::ReadAnimation( Collada::Animation* pParent)
             }
             for( ChannelMap::const_iterator it = channels.begin(); it != channels.end(); ++it)
                 anim->mChannels.push_back( it->second);
+
+			if (indexID >= 0)
+			{
+				mAnimationLibrary[animID] = anim;
+			}
         }
     }
 }
@@ -832,7 +995,7 @@ void ColladaParser::ReadMaterialLibrary()
         {
             if( IsElement( "material"))
             {
-                // read ID. By now you propably know my opinion about this "specification"
+                // read ID. By now you probably know my opinion about this "specification"
                 int attrID = GetAttribute( "id");
                 std::string id = mReader->getAttributeValue( attrID);
 
@@ -890,7 +1053,7 @@ void ColladaParser::ReadLightLibrary()
         if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
             if( IsElement( "light"))
             {
-                // read ID. By now you propably know my opinion about this "specification"
+                // read ID. By now you probably know my opinion about this "specification"
                 int attrID = GetAttribute( "id");
                 std::string id = mReader->getAttributeValue( attrID);
 
@@ -924,7 +1087,7 @@ void ColladaParser::ReadCameraLibrary()
         if( mReader->getNodeType() == irr::io::EXN_ELEMENT) {
             if( IsElement( "camera"))
             {
-                // read ID. By now you propably know my opinion about this "specification"
+                // read ID. By now you probably know my opinion about this "specification"
                 int attrID = GetAttribute( "id");
                 std::string id = mReader->getAttributeValue( attrID);
 
@@ -1240,12 +1403,17 @@ void ColladaParser::ReadEffectProfileCommon( Collada::Effect& pEffect)
             else if( IsElement( "transparent")) {
                 pEffect.mHasTransparency = true;
 
-                // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure...
-                if(::strcmp(mReader->getAttributeValueSafe("opaque"), "RGB_ZERO") == 0) {
-                    // TODO: handle RGB_ZERO mode completely
+                const char* opaque = mReader->getAttributeValueSafe("opaque");
+ 
+                if(::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "RGB_ONE") == 0) {
                     pEffect.mRGBTransparency = true;
                 }
 
+                // In RGB_ZERO mode, the transparency is interpreted in reverse, go figure...
+				if(::strcmp(opaque, "RGB_ZERO") == 0 || ::strcmp(opaque, "A_ZERO") == 0) {
+					pEffect.mInvertTransparency = true;
+				}
+
                 ReadEffectColor( pEffect.mTransparent,pEffect.mTexTransparent);
             }
             else if( IsElement( "shininess"))
@@ -1509,7 +1677,7 @@ void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
                 // don't care for remaining stuff
                 SkipElement( "surface");
             }
-            else if( IsElement( "sampler2D"))
+            else if( IsElement( "sampler2D") && (FV_1_4_n == mFormat || FV_1_3_n == mFormat))
             {
                 // surface ID is given inside <source> tags
                 TestOpening( "source");
@@ -1520,6 +1688,19 @@ void ColladaParser::ReadEffectParam( Collada::EffectParam& pParam)
 
                 // don't care for remaining stuff
                 SkipElement( "sampler2D");
+            }
+            else if( IsElement( "sampler2D"))
+            {
+                // surface ID is given inside <instance_image> tags
+                TestOpening( "instance_image");
+                int attrURL = GetAttribute("url");
+                const char* url = mReader->getAttributeValue( attrURL);
+                if( url[0] != '#')
+                    ThrowException( "Unsupported URL format in instance_image");
+                url++;
+                pParam.mType = Param_Sampler;
+                pParam.mReference = url;
+                SkipElement( "sampler2D");
             } else
             {
                 // ignore unknown element
@@ -1947,7 +2128,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
 
     ai_assert( primType != Prim_Invalid);
 
-    // also a number of <input> elements, but in addition a <p> primitive collection and propably index counts for all primitives
+    // also a number of <input> elements, but in addition a <p> primitive collection and probably index counts for all primitives
     while( mReader->read())
     {
         if( mReader->getNodeType() == irr::io::EXN_ELEMENT)

+ 16 - 1
code/ColladaParser.h

@@ -2,7 +2,7 @@
  Open Asset Import Library (assimp)
  ----------------------------------------------------------------------
  
- Copyright (c) 2006-2015, assimp team
+ Copyright (c) 2006-2016, assimp team
  All rights reserved.
  
  Redistribution and use of this software in source and binary forms,
@@ -49,6 +49,7 @@
 #include "ColladaHelper.h"
 #include "../include/assimp/ai_assert.h"
 #include <boost/format.hpp>
+#include <boost/scoped_ptr.hpp>
 
 namespace Assimp
 {
@@ -81,6 +82,12 @@ namespace Assimp
         
         /** Reads the animation library */
         void ReadAnimationLibrary();
+
+		/** Reads the animation clip library */
+		void ReadAnimationClipLibrary();
+
+		/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
+		void PostProcessRootAnimations();
         
         /** Reads an animation into the given parent structure */
         void ReadAnimation( Collada::Animation* pParent);
@@ -311,6 +318,14 @@ namespace Assimp
         /** Controller library: joint controllers by ID */
         typedef std::map<std::string, Collada::Controller> ControllerLibrary;
         ControllerLibrary mControllerLibrary;
+
+		/** Animation library: animation references by ID */
+		typedef std::map<std::string, Collada::Animation*> AnimationLibrary;
+		AnimationLibrary mAnimationLibrary;
+
+		/** Animation clip library: clip animation references by ID */
+		typedef std::vector<std::pair<std::string, std::vector<std::string> > > AnimationClipLibrary;
+		AnimationClipLibrary mAnimationClipLibrary;
         
         /** Pointer to the root node. Don't delete, it just points to one of
          the nodes in the node library. */

+ 2 - 2
code/ComputeUVMappingProcess.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -412,7 +412,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
                 {
                     if (!DefaultLogger::isNullLogger())
                     {
-                        sprintf(buffer, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
+                        ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
                             TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex,
                             MappingTypeToString(mapping));
 

+ 2 - 2
code/ComputeUVMappingProcess.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -125,7 +125,7 @@ private:
     // temporary structure to describe a mapping
     struct MappingInfo
     {
-        MappingInfo(aiTextureMapping _type)
+        explicit MappingInfo(aiTextureMapping _type)
             : type  (_type)
             , axis  (0.f,1.f,0.f)
             , uv    (0u)

+ 1 - 1
code/ConvertToLHProcess.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/ConvertToLHProcess.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 3 - 1
code/DXFHelper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -66,6 +66,8 @@ public:
     LineReader(StreamReaderLE& reader)
          // do NOT skip empty lines. In DXF files, they count as valid data.
         : splitter(reader,false,true)
+        , groupcode( 0 )
+        , value()
         , end()
     {
     }

+ 1 - 1
code/DXFLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/DXFLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 2 - 2
code/DeboneProcess.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -147,7 +147,7 @@ void DeboneProcess::Execute( aiScene* pScene)
 
                 if(!DefaultLogger::isNullLogger()) {
                     char buffer[1024];
-                    ::sprintf(buffer,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
+                    ::ai_snprintf(buffer,1024,"Removed %u bones. Input bones: %u. Output bones: %u",in-out,in,out);
                     DefaultLogger::get()->info(buffer);
                 }
 

+ 1 - 1
code/DeboneProcess.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/DefaultIOStream.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 

+ 1 - 1
code/DefaultIOStream.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 2
code/DefaultIOSystem.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -176,7 +176,6 @@ std::string DefaultIOSystem::fileName( const std::string &path )
     return ret;
 }
 
-
 // ------------------------------------------------------------------------------------------------
 std::string DefaultIOSystem::completeBaseName( const std::string &path )
 {

+ 1 - 1
code/DefaultIOSystem.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 20 - 17
code/DefaultLogger.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "Win32DebugLogStream.h"
 #include "StdOStreamLogStream.h"
 #include "FileLogStream.h"
+#include "StringUtils.h"
 #include "../include/assimp/NullLogger.hpp"
 #include "../include/assimp/DefaultLogger.hpp"
 #include "../include/assimp/ai_assert.h"
@@ -226,9 +227,7 @@ bool DefaultLogger::isNullLogger()
 }
 
 // ----------------------------------------------------------------------------------
-//  Singleton getter
-Logger *DefaultLogger::get()
-{
+Logger *DefaultLogger::get() {
     return m_pLogger;
 }
 
@@ -241,7 +240,9 @@ void DefaultLogger::kill()
     boost::mutex::scoped_lock lock(loggerMutex);
 #endif
 
-    if (m_pLogger == &s_pNullLogger)return;
+	if ( m_pLogger == &s_pNullLogger ) {
+		return;
+	}
     delete m_pLogger;
     m_pLogger = &s_pNullLogger;
 }
@@ -253,8 +254,9 @@ void DefaultLogger::OnDebug( const char* message )
     if ( m_Severity == Logger::NORMAL )
         return;
 
-    char msg[MAX_LOG_MESSAGE_LENGTH + 16];
-    ::sprintf(msg,"Debug, T%u: %s", GetThreadID(), message );
+	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
+	char msg[Size];
+	ai_snprintf(msg, Size, "Debug, T%u: %s", GetThreadID(), message);
 
     WriteToStreams( msg, Logger::Debugging );
 }
@@ -263,8 +265,9 @@ void DefaultLogger::OnDebug( const char* message )
 //  Logs an info
 void DefaultLogger::OnInfo( const char* message )
 {
-    char msg[MAX_LOG_MESSAGE_LENGTH + 16];
-    ::sprintf(msg,"Info,  T%u: %s", GetThreadID(), message );
+	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
+	char msg[Size];
+    ai_snprintf(msg, Size, "Info,  T%u: %s", GetThreadID(), message );
 
     WriteToStreams( msg , Logger::Info );
 }
@@ -273,8 +276,9 @@ void DefaultLogger::OnInfo( const char* message )
 //  Logs a warning
 void DefaultLogger::OnWarn( const char* message )
 {
-    char msg[MAX_LOG_MESSAGE_LENGTH + 16];
-    ::sprintf(msg,"Warn,  T%u: %s", GetThreadID(), message );
+	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
+	char msg[Size];
+	ai_snprintf(msg, Size, "Warn,  T%u: %s", GetThreadID(), message );
 
     WriteToStreams( msg, Logger::Warn );
 }
@@ -283,8 +287,9 @@ void DefaultLogger::OnWarn( const char* message )
 //  Logs an error
 void DefaultLogger::OnError( const char* message )
 {
-    char msg[MAX_LOG_MESSAGE_LENGTH + 16];
-    ::sprintf(msg,"Error, T%u: %s", GetThreadID(), message );
+	static const size_t Size = MAX_LOG_MESSAGE_LENGTH + 16;
+	char msg[ Size ];
+    ai_snprintf(msg, Size, "Error, T%u: %s", GetThreadID(), message );
 
     WriteToStreams( msg, Logger::Err );
 }
@@ -317,7 +322,7 @@ bool DefaultLogger::attachStream( LogStream *pStream, unsigned int severity )
 }
 
 // ----------------------------------------------------------------------------------
-//  Detatch a stream
+//  Detach a stream
 bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
 {
     if (!pStream)
@@ -351,7 +356,6 @@ bool DefaultLogger::detatchStream( LogStream *pStream, unsigned int severity )
 // ----------------------------------------------------------------------------------
 //  Constructor
 DefaultLogger::DefaultLogger(LogSeverity severity)
-
     :   Logger  ( severity )
     ,   noRepeatMsg (false)
     ,   lastLen( 0 )
@@ -371,8 +375,7 @@ DefaultLogger::~DefaultLogger()
 
 // ----------------------------------------------------------------------------------
 //  Writes message to stream
-void DefaultLogger::WriteToStreams(const char *message,
-    ErrorSeverity ErrorSev )
+void DefaultLogger::WriteToStreams(const char *message, ErrorSeverity ErrorSev )
 {
     ai_assert(NULL != message);
 

+ 1 - 1
code/DefaultProgressHandler.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 10 - 1
code/Exporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 
 All rights reserved.
 
@@ -87,6 +87,8 @@ void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*, const ExportPro
 void ExportScenePly(const char*,IOSystem*, const aiScene*, const ExportProperties*);
 void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportScene3DS(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneGLTF(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneGLB(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneAssbin(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneAssxml(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 
@@ -135,6 +137,13 @@ Exporter::ExportFormatEntry gExporters[] =
         aiProcess_Triangulate | aiProcess_SortByPType | aiProcess_JoinIdenticalVertices),
 #endif
 
+#ifndef ASSIMP_BUILD_NO_GLTF_EXPORTER
+    Exporter::ExportFormatEntry( "gltf", "GL Transmission Format", "gltf", &ExportSceneGLTF,
+        aiProcess_JoinIdenticalVertices /*| aiProcess_SortByPType*/),
+    Exporter::ExportFormatEntry( "glb", "GL Transmission Format (binary)", "glb", &ExportSceneGLB,
+        aiProcess_JoinIdenticalVertices /*| aiProcess_SortByPType*/),
+#endif
+
 #ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER
     Exporter::ExportFormatEntry( "assbin", "Assimp Binary", "assbin" , &ExportSceneAssbin, 0),
 #endif

+ 1 - 1
code/FBXAnimation.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/FBXBinaryTokenizer.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 1 - 1
code/FBXCompileConfig.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 78 - 34
code/FBXConverter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXUtil.h"
 #include "FBXProperties.h"
 #include "FBXImporter.h"
+#include "StringComparison.h"
 #include "../include/assimp/scene.h"
 #include <boost/foreach.hpp>
 #include <boost/scoped_array.hpp>
@@ -148,6 +149,7 @@ public:
         std::for_each(animations.begin(),animations.end(),Util::delete_fun<aiAnimation>());
         std::for_each(lights.begin(),lights.end(),Util::delete_fun<aiLight>());
         std::for_each(cameras.begin(),cameras.end(),Util::delete_fun<aiCamera>());
+        std::for_each(textures.begin(),textures.end(),Util::delete_fun<aiTexture>());
     }
 
 
@@ -1449,6 +1451,36 @@ private:
         return static_cast<unsigned int>(materials.size() - 1);
     }
 
+    // ------------------------------------------------------------------------------------------------
+    // Video -> aiTexture
+    unsigned int ConvertVideo(const Video& video)
+    {
+        // generate empty output texture
+        aiTexture* out_tex = new aiTexture();
+        textures.push_back(out_tex);
+
+        // assuming the texture is compressed
+        out_tex->mWidth = static_cast<unsigned int>(video.ContentLength()); // total data size
+        out_tex->mHeight = 0; // fixed to 0
+
+        // steal the data from the Video to avoid an additional copy
+        out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>(video).RelinquishContent() );
+
+        // try to extract a hint from the file extension
+        const std::string& filename = video.FileName().empty() ? video.RelativeFilename() : video.FileName();
+        std::string ext = BaseImporter::GetExtension(filename);
+
+        if(ext == "jpeg") {
+            ext = "jpg";
+        }
+
+        if(ext.size() <= 3) {
+            memcpy(out_tex->achFormatHint, ext.c_str(), ext.size());
+        }
+
+        return static_cast<unsigned int>(textures.size() - 1);
+    }
+
 
     // ------------------------------------------------------------------------------------------------
     void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
@@ -1466,6 +1498,24 @@ private:
             aiString path;
             path.Set(tex->RelativeFilename());
 
+            const Video* media = tex->Media();
+            if(media != 0 && media->ContentLength() > 0) {
+                unsigned int index;
+
+                VideoMap::const_iterator it = textures_converted.find(media);
+                if(it != textures_converted.end()) {
+                    index = (*it).second;
+                }
+                else {
+                    index = ConvertVideo(*media);
+                    textures_converted[media] = index;
+                }
+
+                // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
+                path.data[0] = '*';
+                path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
+            }
+
             out_mat->AddProperty(&path,_AI_MATKEY_TEXTURE_BASE,target,0);
 
             aiUVTransform uvTrafo;
@@ -2496,8 +2546,9 @@ private:
         // need to convert from TRS order to SRT?
         if(reverse_order) {
 
-            aiVector3D def_scale, def_translate;
-            aiQuaternion def_rot;
+            aiVector3D def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
+            aiVector3D def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
+            aiVector3D def_rot = PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f));
 
             KeyFrameListList scaling;
             KeyFrameListList translation;
@@ -2506,24 +2557,14 @@ private:
             if(chain[TransformationComp_Scaling] != iter_end) {
                 scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
             }
-            else {
-                def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
-            }
 
             if(chain[TransformationComp_Translation] != iter_end) {
                 translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
             }
-            else {
-                def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
-            }
 
             if(chain[TransformationComp_Rotation] != iter_end) {
                 rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
             }
-            else {
-                def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
-                    target.RotationOrder());
-            }
 
             KeyFrameListList joined;
             joined.insert(joined.end(), scaling.begin(), scaling.end());
@@ -2740,7 +2781,7 @@ private:
 
     // ------------------------------------------------------------------------------------------------
     void InterpolateKeys(aiVectorKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs,
-        const bool geom,
+        const aiVector3D& def_value,
         double& max_time,
         double& min_time)
 
@@ -2754,10 +2795,7 @@ private:
         next_pos.resize(inputs.size(),0);
 
         BOOST_FOREACH(KeyTimeList::value_type time, keys) {
-            float result[3] = {0.0f, 0.0f, 0.0f};
-            if(geom) {
-                result[0] = result[1] = result[2] = 1.0f;
-            }
+            float result[3] = {def_value.x, def_value.y, def_value.z};
 
             for (size_t i = 0; i < count; ++i) {
                 const KeyFrameList& kfl = inputs[i];
@@ -2782,12 +2820,7 @@ private:
                 const double factor = timeB == timeA ? 0. : static_cast<double>((time - timeA) / (timeB - timeA));
                 const float interpValue = static_cast<float>(valueA + (valueB - valueA) * factor);
 
-                if(geom) {
-                    result[kfl.get<2>()] *= interpValue;
-                }
-                else {
-                    result[kfl.get<2>()] += interpValue;
-                }
+                result[kfl.get<2>()] = interpValue;
             }
 
             // magic value to convert fbx times to seconds
@@ -2807,7 +2840,7 @@ private:
 
     // ------------------------------------------------------------------------------------------------
     void InterpolateKeys(aiQuatKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs,
-        const bool geom,
+        const aiVector3D& def_value,
         double& maxTime,
         double& minTime,
         Model::RotOrder order)
@@ -2816,7 +2849,7 @@ private:
         ai_assert(valOut);
 
         boost::scoped_array<aiVectorKey> temp(new aiVectorKey[keys.size()]);
-        InterpolateKeys(temp.get(),keys,inputs,geom,maxTime, minTime);
+        InterpolateKeys(temp.get(), keys, inputs, def_value, maxTime, minTime);
 
         aiMatrix4x4 m;
 
@@ -2858,20 +2891,20 @@ private:
         Model::RotOrder order,
         const aiVector3D& def_scale,
         const aiVector3D& def_translate,
-        const aiQuaternion& def_rotation)
+        const aiVector3D& def_rotation)
     {
         if (rotation.size()) {
-            InterpolateKeys(out_quat, times, rotation, false, maxTime, minTime, order);
+            InterpolateKeys(out_quat, times, rotation, def_rotation, maxTime, minTime, order);
         }
         else {
             for (size_t i = 0; i < times.size(); ++i) {
                 out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
-                out_quat[i].mValue = def_rotation;
+                out_quat[i].mValue = EulerToQuaternion(def_rotation, order);
             }
         }
 
         if (scaling.size()) {
-            InterpolateKeys(out_scale, times, scaling, true, maxTime, minTime);
+            InterpolateKeys(out_scale, times, scaling, def_scale, maxTime, minTime);
         }
         else {
             for (size_t i = 0; i < times.size(); ++i) {
@@ -2881,7 +2914,7 @@ private:
         }
 
         if (translation.size()) {
-            InterpolateKeys(out_translation, times, translation, false, maxTime, minTime);
+            InterpolateKeys(out_translation, times, translation, def_translate, maxTime, minTime);
         }
         else {
             for (size_t i = 0; i < times.size(); ++i) {
@@ -2935,7 +2968,7 @@ private:
         na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
         na->mScalingKeys = new aiVectorKey[keys.size()];
         if (keys.size() > 0)
-            InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
+            InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
     }
 
 
@@ -2955,7 +2988,7 @@ private:
         na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
         na->mPositionKeys = new aiVectorKey[keys.size()];
         if (keys.size() > 0)
-            InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
+            InterpolateKeys(na->mPositionKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime);
     }
 
 
@@ -2976,7 +3009,7 @@ private:
         na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
         na->mRotationKeys = new aiQuatKey[keys.size()];
         if (keys.size() > 0)
-            InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
+            InterpolateKeys(na->mRotationKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime, order);
     }
 
 
@@ -3024,6 +3057,13 @@ private:
 
             std::swap_ranges(cameras.begin(),cameras.end(),out->mCameras);
         }
+
+        if(textures.size()) {
+            out->mTextures = new aiTexture*[textures.size()]();
+            out->mNumTextures = static_cast<unsigned int>(textures.size());
+
+            std::swap_ranges(textures.begin(),textures.end(),out->mTextures);
+        }
     }
 
 
@@ -3037,10 +3077,14 @@ private:
     std::vector<aiAnimation*> animations;
     std::vector<aiLight*> lights;
     std::vector<aiCamera*> cameras;
+    std::vector<aiTexture*> textures;
 
     typedef std::map<const Material*, unsigned int> MaterialMap;
     MaterialMap materials_converted;
 
+    typedef std::map<const Video*, unsigned int> VideoMap;
+    VideoMap textures_converted;
+
     typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
     MeshMap meshes_converted;
 

+ 1 - 1
code/FBXConverter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 2 - 2
code/FBXDeformer.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -131,7 +131,7 @@ Cluster::~Cluster()
 // ------------------------------------------------------------------------------------------------
 Skin::Skin(uint64_t id, const Element& element, const Document& doc, const std::string& name)
 : Deformer(id,element,doc,name)
-{
+, accuracy( 0.0f ) {
     const Scope& sc = GetRequiredScope(element);
 
     const Element* const Link_DeformAcuracy = sc["Link_DeformAcuracy"];

+ 9 - 1
code/FBXDocument.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -180,6 +180,9 @@ const Object* LazyObject::Get(bool dieOnError)
         else if (!strncmp(obtype,"LayeredTexture",length)) {
             object.reset(new LayeredTexture(id,element,doc,name));
         }
+        else if (!strncmp(obtype,"Video",length)) {
+            object.reset(new Video(id,element,doc,name));
+        }
         else if (!strncmp(obtype,"AnimationStack",length)) {
             object.reset(new AnimationStack(id,element,name,doc));
         }
@@ -483,6 +486,11 @@ void Document::ReadConnections()
     for(ElementMap::const_iterator it = conns.first; it != conns.second; ++it) {
         const Element& el = *(*it).second;
         const std::string& type = ParseTokenAsString(GetRequiredToken(el,0));
+
+        // PP = property-property connection, ignored for now
+        // (tokens: "PP", ID1, "Property1", ID2, "Property2")
+        if(type == "PP") continue;
+
         const uint64_t src = ParseTokenAsID(GetRequiredToken(el,1));
         const uint64_t dest = ParseTokenAsID(GetRequiredToken(el,2));
 

+ 62 - 1
code/FBXDocument.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -73,6 +73,8 @@ namespace FBX {
     class Material;
     class Geometry;
 
+    class Video;
+
     class AnimationCurve;
     class AnimationCurveNode;
     class AnimationLayer;
@@ -571,6 +573,10 @@ public:
         return crop;
     }
 
+    const Video* Media() const {
+        return media;
+    }
+
 private:
 
     aiVector2D uvTrans;
@@ -583,6 +589,8 @@ private:
     boost::shared_ptr<const PropertyTable> props;
 
     unsigned int crop[4];
+
+    const Video* media;
 };
 
 /** DOM class for layered FBX textures */
@@ -654,6 +662,59 @@ typedef std::fbx_unordered_map<std::string, const Texture*> TextureMap;
 typedef std::fbx_unordered_map<std::string, const LayeredTexture*> LayeredTextureMap;
 
 
+/** DOM class for generic FBX videos */
+class Video : public Object
+{
+public:
+
+    Video(uint64_t id, const Element& element, const Document& doc, const std::string& name);
+    ~Video();
+
+public:
+
+    const std::string& Type() const {
+        return type;
+    }
+
+    const std::string& FileName() const {
+        return fileName;
+    }
+
+    const std::string& RelativeFilename() const {
+        return relativeFileName;
+    }
+
+    const PropertyTable& Props() const {
+        ai_assert(props.get());
+        return *props.get();
+    }
+
+    const uint8_t* Content() const {
+        ai_assert(content);
+        return content;
+    }
+
+    const uint32_t ContentLength() const {
+        return contentLength;
+    }
+
+    uint8_t* RelinquishContent() {
+        uint8_t* ptr = content;
+        content = 0;
+        return ptr;
+    }
+
+private:
+
+    std::string type;
+    std::string relativeFileName;
+    std::string fileName;
+    boost::shared_ptr<const PropertyTable> props;
+
+    uint32_t contentLength;
+    uint8_t* content;
+};
+
 /** DOM class for generic FBX materials */
 class Material : public Object
 {

+ 1 - 1
code/FBXDocumentUtil.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 5 - 1
code/FBXImportSettings.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -55,6 +55,7 @@ struct ImportSettings
         , readAllLayers(true)
         , readAllMaterials(false)
         , readMaterials(true)
+        , readTextures(true)
         , readCameras(true)
         , readLights(true)
         , readAnimations(true)
@@ -92,6 +93,9 @@ struct ImportSettings
      *  material. The default value is true.*/
     bool readMaterials;
 
+    /** import embedded textures? Default value is true.*/
+    bool readTextures;
+
     /** import cameras? Default value is true.*/
     bool readCameras;
 

+ 2 - 1
code/FBXImporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -126,6 +126,7 @@ void FBXImporter::SetupProperties(const Importer* pImp)
     settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
     settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
     settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
+    settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
     settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
     settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
     settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);

+ 1 - 1
code/FBXImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,

+ 82 - 1
code/FBXMaterial.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXImportSettings.h"
 #include "FBXDocumentUtil.h"
 #include "FBXProperties.h"
+#include "ByteSwapper.h"
 #include <boost/foreach.hpp>
 
 namespace Assimp {
@@ -147,6 +148,7 @@ Material::~Material()
 Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name)
 : Object(id,element,name)
 , uvScaling(1.0f,1.0f)
+, media(0)
 {
     const Scope& sc = GetRequiredScope(element);
 
@@ -199,6 +201,23 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
     }
 
     props = GetPropertyTable(doc,"Texture.FbxFileTexture",element,sc);
+
+    // resolve video links
+    if(doc.Settings().readTextures) {
+        const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
+        BOOST_FOREACH(const Connection* con, conns) {
+            const Object* const ob = con->SourceObject();
+            if(!ob) {
+                DOMWarning("failed to read source object for texture link, ignoring",&element);
+                continue;
+            }
+
+            const Video* const video = dynamic_cast<const Video*>(ob);
+            if(video) {
+                media = video;
+            }
+        }
+    }
 }
 
 
@@ -253,6 +272,68 @@ void LayeredTexture::fillTexture(const Document& doc)
     }
 }
 
+
+// ------------------------------------------------------------------------------------------------
+Video::Video(uint64_t id, const Element& element, const Document& doc, const std::string& name)
+: Object(id,element,name)
+, contentLength(0)
+, content(0)
+{
+    const Scope& sc = GetRequiredScope(element);
+
+    const Element* const Type = sc["Type"];
+    const Element* const FileName = sc["FileName"];
+    const Element* const RelativeFilename = sc["RelativeFilename"];
+    const Element* const Content = sc["Content"];
+
+    if(Type) {
+        type = ParseTokenAsString(GetRequiredToken(*Type,0));
+    }
+
+    if(FileName) {
+        fileName = ParseTokenAsString(GetRequiredToken(*FileName,0));
+    }
+
+    if(RelativeFilename) {
+        relativeFileName = ParseTokenAsString(GetRequiredToken(*RelativeFilename,0));
+    }
+
+    if(Content) {
+        const Token& token = GetRequiredToken(*Content, 0);
+        const char* data = token.begin();
+        if(!token.IsBinary()) {
+            DOMWarning("video content is not binary data, ignoring", &element);
+        }
+        else if(static_cast<size_t>(token.end() - data) < 5) {
+            DOMError("binary data array is too short, need five (5) bytes for type signature and element count", &element);
+        }
+        else if(*data != 'R') {
+            DOMWarning("video content is not raw binary data, ignoring", &element);
+        }
+        else {
+            // read number of elements
+            uint32_t len = 0;
+            ::memcpy(&len, data + 1, sizeof(len));
+            AI_SWAP4(len);
+
+            contentLength = len;
+
+            content = new uint8_t[len];
+            ::memcpy(content, data + 5, len);
+        }
+    }
+
+    props = GetPropertyTable(doc,"Video.FbxVideo",element,sc);
+}
+
+
+Video::~Video()
+{
+    if(content) {
+        delete[] content;
+    }
+}
+
 } //!FBX
 } //!Assimp
 

+ 33 - 16
code/FBXMeshGeometry.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 
-Copyright (c) 2006-2015, assimp team
+Copyright (c) 2006-2016, assimp team
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -347,23 +347,28 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
     const std::vector<unsigned int>& mapping_offsets,
     const std::vector<unsigned int>& mappings)
 {
-    std::vector<T> tempUV;
-    ParseVectorDataArray(tempUV,GetRequiredElement(source,dataElementName));
+
 
     // handle permutations of Mapping and Reference type - it would be nice to
     // deal with this more elegantly and with less redundancy, but right
     // now it seems unavoidable.
     if (MappingInformationType == "ByVertice" && ReferenceInformationType == "Direct") {
+		std::vector<T> tempData;
+		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
+
         data_out.resize(vertex_count);
-        for (size_t i = 0, e = tempUV.size(); i < e; ++i) {
+		for (size_t i = 0, e = tempData.size(); i < e; ++i) {
 
             const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
             for (unsigned int j = istart; j < iend; ++j) {
-                data_out[mappings[j]] = tempUV[i];
+				data_out[mappings[j]] = tempData[i];
             }
         }
     }
     else if (MappingInformationType == "ByVertice" && ReferenceInformationType == "IndexToDirect") {
+		std::vector<T> tempData;
+		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
+
         data_out.resize(vertex_count);
 
         std::vector<int> uvIndices;
@@ -373,24 +378,30 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
 
             const unsigned int istart = mapping_offsets[i], iend = istart + mapping_counts[i];
             for (unsigned int j = istart; j < iend; ++j) {
-                if(static_cast<size_t>(uvIndices[i]) >= tempUV.size()) {
+				if (static_cast<size_t>(uvIndices[i]) >= tempData.size()) {
                     DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
                 }
-                data_out[mappings[j]] = tempUV[uvIndices[i]];
+				data_out[mappings[j]] = tempData[uvIndices[i]];
             }
         }
     }
     else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "Direct") {
-        if (tempUV.size() != vertex_count) {
+		std::vector<T> tempData;
+		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
+
+		if (tempData.size() != vertex_count) {
             FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
-                << tempUV.size() << ", expected " << vertex_count
+				<< tempData.size() << ", expected " << vertex_count
             );
             return;
         }
 
-        data_out.swap(tempUV);
+		data_out.swap(tempData);
     }
     else if (MappingInformationType == "ByPolygonVertex" && ReferenceInformationType == "IndexToDirect") {
+		std::vector<T> tempData;
+		ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
+
         data_out.resize(vertex_count);
 
         std::vector<int> uvIndices;
@@ -403,11 +414,11 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
 
         unsigned int next = 0;
         BOOST_FOREACH(int i, uvIndices) {
-            if(static_cast<size_t>(i) >= tempUV.size()) {
+			if (static_cast<size_t>(i) >= tempData.size()) {
                 DOMError("index out of range",&GetRequiredElement(source,indexDataElementName));
             }
 
-            data_out[next++] = tempUV[i];
+			data_out[next++] = tempData[i];
         }
     }
     else {
@@ -460,32 +471,38 @@ void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D>& colors_out, cons
         mappings);
 }
 
-
 // ------------------------------------------------------------------------------------------------
+static const std::string TangentIndexToken = "TangentIndex";
+static const std::string TangentsIndexToken = "TangentsIndex";
+
 void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D>& tangents_out, const Scope& source,
     const std::string& MappingInformationType,
     const std::string& ReferenceInformationType)
 {
     const char * str = source.Elements().count( "Tangents" ) > 0 ? "Tangents" : "Tangent";
+    const char * strIdx = source.Elements().count( "Tangents" ) > 0 ? TangentsIndexToken.c_str() : TangentIndexToken.c_str();
     ResolveVertexDataArray(tangents_out,source,MappingInformationType,ReferenceInformationType,
         str,
-        "TangentIndex",
+        strIdx,
         vertices.size(),
         mapping_counts,
         mapping_offsets,
         mappings);
 }
 
-
 // ------------------------------------------------------------------------------------------------
+static const std::string BinormalIndexToken = "BinormalIndex";
+static const std::string BinormalsIndexToken = "BinormalsIndex";
+
 void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_out, const Scope& source,
     const std::string& MappingInformationType,
     const std::string& ReferenceInformationType)
 {
     const char * str = source.Elements().count( "Binormals" ) > 0 ? "Binormals" : "Binormal";
+    const char * strIdx = source.Elements().count( "Binormals" ) > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str();
     ResolveVertexDataArray(binormals_out,source,MappingInformationType,ReferenceInformationType,
         str,
-        "BinormalIndex",
+        strIdx,
         vertices.size(),
         mapping_counts,
         mapping_offsets,

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно