浏览代码

Restored polyimport functionality using new Polycode branch, upgraded to latest assimp, added a DummyCore for non-graphical use of Polycode, added polyimport Xcode project to workspace, updated Studio to use new location of polyimport, fixed indexed mesh import in polyimport

Ivan Safrin 9 年之前
父节点
当前提交
4865727e2d
共有 57 个文件被更改,包括 14412 次插入38 次删除
  1. 3 0
      .gitignore
  2. 1 0
      bin/README.md
  3. 3 0
      build/osx/Polycode.xcworkspace/contents.xcworkspacedata
  4. 1 5
      build/osx/PolycodeStudio/PolycodeStudio.xcodeproj/project.pbxproj
  5. 0 4
      build/osx/TemplateApp/TemplateApp.xcodeproj/project.pbxproj
  6. 337 0
      build/osx/polyimport/polyimport.xcodeproj/project.pbxproj
  7. 8 0
      include/assimp/.editorconfig
  8. 22 0
      include/assimp/Compiler/poppack1.h
  9. 729 0
      include/assimp/Compiler/pstdint.h
  10. 46 0
      include/assimp/Compiler/pushpack1.h
  11. 190 0
      include/assimp/DefaultLogger.hpp
  12. 504 0
      include/assimp/Exporter.hpp
  13. 138 0
      include/assimp/IOStream.hpp
  14. 290 0
      include/assimp/IOSystem.hpp
  15. 654 0
      include/assimp/Importer.hpp
  16. 96 0
      include/assimp/LogStream.hpp
  17. 265 0
      include/assimp/Logger.hpp
  18. 95 0
      include/assimp/NullLogger.hpp
  19. 122 0
      include/assimp/ProgressHandler.hpp
  20. 14 0
      include/assimp/ai_assert.h
  21. 484 0
      include/assimp/anim.h
  22. 223 0
      include/assimp/camera.h
  23. 255 0
      include/assimp/cexport.h
  24. 135 0
      include/assimp/cfileio.h
  25. 561 0
      include/assimp/cimport.h
  26. 104 0
      include/assimp/color4.h
  27. 182 0
      include/assimp/color4.inl
  28. 908 0
      include/assimp/config.h
  29. 287 0
      include/assimp/defs.h
  30. 143 0
      include/assimp/importerdesc.h
  31. 240 0
      include/assimp/light.h
  32. 1542 0
      include/assimp/material.h
  33. 350 0
      include/assimp/material.inl
  34. 185 0
      include/assimp/matrix3x3.h
  35. 332 0
      include/assimp/matrix3x3.inl
  36. 249 0
      include/assimp/matrix4x4.h
  37. 535 0
      include/assimp/matrix4x4.inl
  38. 739 0
      include/assimp/mesh.h
  39. 248 0
      include/assimp/metadata.h
  40. 92 0
      include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h
  41. 633 0
      include/assimp/postprocess.h
  42. 126 0
      include/assimp/quaternion.h
  43. 283 0
      include/assimp/quaternion.inl
  44. 426 0
      include/assimp/scene.h
  45. 197 0
      include/assimp/texture.h
  46. 515 0
      include/assimp/types.h
  47. 113 0
      include/assimp/vector2.h
  48. 224 0
      include/assimp/vector2.inl
  49. 149 0
      include/assimp/vector3.h
  50. 228 0
      include/assimp/vector3.inl
  51. 105 0
      include/assimp/version.h
  52. 33 0
      include/polycode/core/PolyCore.h
  53. 5 6
      include/polycode/tools/polyimport.h
  54. 42 2
      src/core/PolyCore.cpp
  55. 0 2
      src/core/PolyResourceManager.cpp
  56. 4 4
      src/ide/PolycodeToolLauncher.cpp
  57. 17 15
      src/tools/polyimport.cpp

+ 3 - 0
.gitignore

@@ -1,5 +1,8 @@
 # Created by https://www.gitignore.io
 
+bin/polyimport
+bin/polybuild
+
 *.o
 *.do
 *.io

+ 1 - 0
bin/README.md

@@ -0,0 +1 @@
+Binary tool executables.

+ 3 - 0
build/osx/Polycode.xcworkspace/contents.xcworkspacedata

@@ -1,6 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Workspace
    version = "1.0">
+   <FileRef
+      location = "group:polyimport/polyimport.xcodeproj">
+   </FileRef>
    <FileRef
       location = "group:Polycode3DPhsyics/Polycode3DPhsyics.xcodeproj">
    </FileRef>

+ 1 - 5
build/osx/PolycodeStudio/PolycodeStudio.xcodeproj/project.pbxproj

@@ -57,7 +57,6 @@
 		8A36D31F1B8E6FD5009897D0 /* liblibvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D3151B8E6FD5009897D0 /* liblibvorbisfile.a */; };
 		8A36D3201B8E6FD5009897D0 /* liblua5.1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D3161B8E6FD5009897D0 /* liblua5.1.a */; };
 		8A36D3211B8E6FD5009897D0 /* libphysfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D3171B8E6FD5009897D0 /* libphysfs.a */; };
-		8A36D3221B8E6FD5009897D0 /* libpng15.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D3181B8E6FD5009897D0 /* libpng15.a */; };
 		8A36D3231B8E6FD5009897D0 /* libPolycore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D3191B8E6FD5009897D0 /* libPolycore.a */; };
 		8A36D3241B8E6FD5009897D0 /* libz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D31A1B8E6FD5009897D0 /* libz.a */; };
 		8A36D3261B8E6FE7009897D0 /* libPolycodeUI.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A36D3251B8E6FE7009897D0 /* libPolycodeUI.a */; };
@@ -154,7 +153,6 @@
 		8A36D3151B8E6FD5009897D0 /* liblibvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibvorbisfile.a; path = /Users/isafrin/Desktop/Workshop/PolycodeNoCmake/build/osx/TemplateApp/TemplateApp/../../../../lib/osx/liblibvorbisfile.a; sourceTree = "<absolute>"; };
 		8A36D3161B8E6FD5009897D0 /* liblua5.1.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua5.1.a; path = /Users/isafrin/Desktop/Workshop/PolycodeNoCmake/build/osx/TemplateApp/TemplateApp/../../../../lib/osx/liblua5.1.a; sourceTree = "<absolute>"; };
 		8A36D3171B8E6FD5009897D0 /* libphysfs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libphysfs.a; path = /Users/isafrin/Desktop/Workshop/PolycodeNoCmake/build/osx/TemplateApp/TemplateApp/../../../../lib/osx/libphysfs.a; sourceTree = "<absolute>"; };
-		8A36D3181B8E6FD5009897D0 /* libpng15.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng15.a; path = /Users/isafrin/Desktop/Workshop/PolycodeNoCmake/build/osx/TemplateApp/TemplateApp/../../../../lib/osx/libpng15.a; sourceTree = "<absolute>"; };
 		8A36D3191B8E6FD5009897D0 /* libPolycore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPolycore.a; path = /Users/isafrin/Desktop/Workshop/PolycodeNoCmake/build/osx/TemplateApp/TemplateApp/../../../../lib/osx/libPolycore.a; sourceTree = "<absolute>"; };
 		8A36D31A1B8E6FD5009897D0 /* libz.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libz.a; path = /Users/isafrin/Desktop/Workshop/PolycodeNoCmake/build/osx/TemplateApp/TemplateApp/../../../../lib/osx/libz.a; sourceTree = "<absolute>"; };
 		8A36D3251B8E6FE7009897D0 /* libPolycodeUI.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPolycodeUI.a; path = ../../../../lib/osx/libPolycodeUI.a; sourceTree = "<group>"; };
@@ -172,7 +170,6 @@
 				8A22D92B1BCC67DE009EF0A6 /* OpenGL.framework in Frameworks */,
 				8A36D31D1B8E6FD5009897D0 /* liblibvorbis.a in Frameworks */,
 				8A36D3231B8E6FD5009897D0 /* libPolycore.a in Frameworks */,
-				8A36D3221B8E6FD5009897D0 /* libpng15.a in Frameworks */,
 				8A36D3201B8E6FD5009897D0 /* liblua5.1.a in Frameworks */,
 				8A36D31F1B8E6FD5009897D0 /* liblibvorbisfile.a in Frameworks */,
 				8A36D31E1B8E6FD5009897D0 /* libportaudio.a in Frameworks */,
@@ -235,7 +232,6 @@
 				8A36D3161B8E6FD5009897D0 /* liblua5.1.a */,
 				8A36D3171B8E6FD5009897D0 /* libphysfs.a */,
 				8A36D3251B8E6FE7009897D0 /* libPolycodeUI.a */,
-				8A36D3181B8E6FD5009897D0 /* libpng15.a */,
 				8A36D3191B8E6FD5009897D0 /* libPolycore.a */,
 				8A36D31A1B8E6FD5009897D0 /* libz.a */,
 				8A36D20D1B8E5751009897D0 /* Info.plist */,
@@ -405,7 +401,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "cp -R \"$PROJECT_DIR/../../../assets/ide/\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"";
+			shellScript = "cp -R \"$PROJECT_DIR/../../../assets/ide/\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"\ncp -R \"$PROJECT_DIR/../../../bin\" \"$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Resources\"";
 		};
 /* End PBXShellScriptBuildPhase section */
 

+ 0 - 4
build/osx/TemplateApp/TemplateApp.xcodeproj/project.pbxproj

@@ -24,7 +24,6 @@
 		8A86535F1B72949F009F94DD /* liblibvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653561B72949F009F94DD /* liblibvorbisfile.a */; };
 		8A8653601B72949F009F94DD /* liblua5.1.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653571B72949F009F94DD /* liblua5.1.a */; };
 		8A8653611B72949F009F94DD /* libphysfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653581B72949F009F94DD /* libphysfs.a */; };
-		8A8653621B72949F009F94DD /* libpng15.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653591B72949F009F94DD /* libpng15.a */; };
 		8A8653631B72949F009F94DD /* libPolycore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A86535A1B72949F009F94DD /* libPolycore.a */; };
 		8A8653641B72949F009F94DD /* libz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A86535B1B72949F009F94DD /* libz.a */; };
 		8A8653681B7294B7009F94DD /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8A8653671B7294B7009F94DD /* OpenGL.framework */; };
@@ -55,7 +54,6 @@
 		8A8653561B72949F009F94DD /* liblibvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibvorbisfile.a; path = ../../../../lib/osx/liblibvorbisfile.a; sourceTree = "<group>"; };
 		8A8653571B72949F009F94DD /* liblua5.1.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblua5.1.a; path = ../../../../lib/osx/liblua5.1.a; sourceTree = "<group>"; };
 		8A8653581B72949F009F94DD /* libphysfs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libphysfs.a; path = ../../../../lib/osx/libphysfs.a; sourceTree = "<group>"; };
-		8A8653591B72949F009F94DD /* libpng15.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libpng15.a; path = ../../../../lib/osx/libpng15.a; sourceTree = "<group>"; };
 		8A86535A1B72949F009F94DD /* libPolycore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPolycore.a; path = ../../../../lib/osx/libPolycore.a; sourceTree = "<group>"; };
 		8A86535B1B72949F009F94DD /* libz.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libz.a; path = ../../../../lib/osx/libz.a; sourceTree = "<group>"; };
 		8A8653671B7294B7009F94DD /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
@@ -80,7 +78,6 @@
 				8A825F271B82A2680039E823 /* libportaudio.a in Frameworks */,
 				8A8653631B72949F009F94DD /* libPolycore.a in Frameworks */,
 				8A86535F1B72949F009F94DD /* liblibvorbisfile.a in Frameworks */,
-				8A8653621B72949F009F94DD /* libpng15.a in Frameworks */,
 				8A86535E1B72949F009F94DD /* liblibvorbis.a in Frameworks */,
 				8A86535C1B72949F009F94DD /* libfreetype.a in Frameworks */,
 				8A8653601B72949F009F94DD /* liblua5.1.a in Frameworks */,
@@ -144,7 +141,6 @@
 				8A8653571B72949F009F94DD /* liblua5.1.a */,
 				6DD2D0B51BEEDC150026D85C /* libportaudio.a */,
 				8A8653581B72949F009F94DD /* libphysfs.a */,
-				8A8653591B72949F009F94DD /* libpng15.a */,
 				8A86535A1B72949F009F94DD /* libPolycore.a */,
 				8A86535B1B72949F009F94DD /* libz.a */,
 				8A8653341B72931C009F94DD /* Info.plist */,

+ 337 - 0
build/osx/polyimport/polyimport.xcodeproj/project.pbxproj

@@ -0,0 +1,337 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		8AE1F6B61CB82FDF0001557D /* polyimport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8AE1F6B51CB82FDF0001557D /* polyimport.cpp */; };
+		8AE1F6B91CB837050001557D /* libassimp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6B71CB837050001557D /* libassimp.a */; };
+		8AE1F6D41CB8391D0001557D /* libz.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6D31CB8391D0001557D /* libz.a */; };
+		8AE1F6EA1CB83C640001557D /* libPolycore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6E91CB83C640001557D /* libPolycore.a */; };
+		8AE1F6EC1CB83C720001557D /* libfreetype.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6EB1CB83C720001557D /* libfreetype.a */; };
+		8AE1F6EE1CB83C850001557D /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6ED1CB83C850001557D /* Cocoa.framework */; };
+		8AE1F6F01CB83C8B0001557D /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6EF1CB83C8B0001557D /* OpenGL.framework */; };
+		8AE1F6F21CB83C990001557D /* libphysfs.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6F11CB83C990001557D /* libphysfs.a */; };
+		8AE1F6F41CB83CC20001557D /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6F31CB83CC20001557D /* IOKit.framework */; };
+		8AE1F6F61CB83CD00001557D /* libportaudio.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6F51CB83CD00001557D /* libportaudio.a */; };
+		8AE1F6F81CB83CD80001557D /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6F71CB83CD80001557D /* CoreAudio.framework */; };
+		8AE1F6FA1CB83CE10001557D /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6F91CB83CE10001557D /* AudioUnit.framework */; };
+		8AE1F6FC1CB83CF00001557D /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6FB1CB83CF00001557D /* AudioToolbox.framework */; };
+		8AE1F7001CB83CFE0001557D /* liblibogg.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6FD1CB83CFE0001557D /* liblibogg.a */; };
+		8AE1F7011CB83CFE0001557D /* liblibvorbis.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6FE1CB83CFE0001557D /* liblibvorbis.a */; };
+		8AE1F7021CB83CFE0001557D /* liblibvorbisfile.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8AE1F6FF1CB83CFE0001557D /* liblibvorbisfile.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		8AE1F6A91CB82FBD0001557D /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		8AE1F6AB1CB82FBD0001557D /* polyimport */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = polyimport; sourceTree = BUILT_PRODUCTS_DIR; };
+		8AE1F6B51CB82FDF0001557D /* polyimport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = polyimport.cpp; path = ../../../../src/tools/polyimport.cpp; sourceTree = "<group>"; };
+		8AE1F6B71CB837050001557D /* libassimp.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libassimp.a; path = ../../../../lib/osx/libassimp.a; sourceTree = "<group>"; };
+		8AE1F6D31CB8391D0001557D /* libz.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libz.a; path = ../../../../lib/osx/libz.a; sourceTree = "<group>"; };
+		8AE1F6E91CB83C640001557D /* libPolycore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPolycore.a; path = ../../../../lib/osx/libPolycore.a; sourceTree = "<group>"; };
+		8AE1F6EB1CB83C720001557D /* libfreetype.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfreetype.a; path = ../../../../lib/osx/libfreetype.a; sourceTree = "<group>"; };
+		8AE1F6ED1CB83C850001557D /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
+		8AE1F6EF1CB83C8B0001557D /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
+		8AE1F6F11CB83C990001557D /* libphysfs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libphysfs.a; path = ../../../../lib/osx/libphysfs.a; sourceTree = "<group>"; };
+		8AE1F6F31CB83CC20001557D /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
+		8AE1F6F51CB83CD00001557D /* libportaudio.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libportaudio.a; path = ../../../../lib/osx/libportaudio.a; sourceTree = "<group>"; };
+		8AE1F6F71CB83CD80001557D /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; };
+		8AE1F6F91CB83CE10001557D /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; };
+		8AE1F6FB1CB83CF00001557D /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
+		8AE1F6FD1CB83CFE0001557D /* liblibogg.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibogg.a; path = ../../../../lib/osx/liblibogg.a; sourceTree = "<group>"; };
+		8AE1F6FE1CB83CFE0001557D /* liblibvorbis.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibvorbis.a; path = ../../../../lib/osx/liblibvorbis.a; sourceTree = "<group>"; };
+		8AE1F6FF1CB83CFE0001557D /* liblibvorbisfile.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = liblibvorbisfile.a; path = ../../../../lib/osx/liblibvorbisfile.a; sourceTree = "<group>"; };
+		8AE1F71D1CB844370001557D /* polyimport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = polyimport.h; path = ../../../../include/polycode/tools/polyimport.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8AE1F6A81CB82FBD0001557D /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8AE1F7011CB83CFE0001557D /* liblibvorbis.a in Frameworks */,
+				8AE1F6FC1CB83CF00001557D /* AudioToolbox.framework in Frameworks */,
+				8AE1F6FA1CB83CE10001557D /* AudioUnit.framework in Frameworks */,
+				8AE1F7021CB83CFE0001557D /* liblibvorbisfile.a in Frameworks */,
+				8AE1F6F81CB83CD80001557D /* CoreAudio.framework in Frameworks */,
+				8AE1F6F61CB83CD00001557D /* libportaudio.a in Frameworks */,
+				8AE1F6F41CB83CC20001557D /* IOKit.framework in Frameworks */,
+				8AE1F6F01CB83C8B0001557D /* OpenGL.framework in Frameworks */,
+				8AE1F6EE1CB83C850001557D /* Cocoa.framework in Frameworks */,
+				8AE1F6D41CB8391D0001557D /* libz.a in Frameworks */,
+				8AE1F6B91CB837050001557D /* libassimp.a in Frameworks */,
+				8AE1F7001CB83CFE0001557D /* liblibogg.a in Frameworks */,
+				8AE1F6EA1CB83C640001557D /* libPolycore.a in Frameworks */,
+				8AE1F6F21CB83C990001557D /* libphysfs.a in Frameworks */,
+				8AE1F6EC1CB83C720001557D /* libfreetype.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		8AE1F6A21CB82FBD0001557D = {
+			isa = PBXGroup;
+			children = (
+				8AE1F6FB1CB83CF00001557D /* AudioToolbox.framework */,
+				8AE1F6F91CB83CE10001557D /* AudioUnit.framework */,
+				8AE1F6F71CB83CD80001557D /* CoreAudio.framework */,
+				8AE1F6F31CB83CC20001557D /* IOKit.framework */,
+				8AE1F6EF1CB83C8B0001557D /* OpenGL.framework */,
+				8AE1F6ED1CB83C850001557D /* Cocoa.framework */,
+				8AE1F6AD1CB82FBD0001557D /* polyimport */,
+				8AE1F6AC1CB82FBD0001557D /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		8AE1F6AC1CB82FBD0001557D /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8AE1F6AB1CB82FBD0001557D /* polyimport */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		8AE1F6AD1CB82FBD0001557D /* polyimport */ = {
+			isa = PBXGroup;
+			children = (
+				8AE1F6B71CB837050001557D /* libassimp.a */,
+				8AE1F6F51CB83CD00001557D /* libportaudio.a */,
+				8AE1F6FD1CB83CFE0001557D /* liblibogg.a */,
+				8AE1F6FE1CB83CFE0001557D /* liblibvorbis.a */,
+				8AE1F6FF1CB83CFE0001557D /* liblibvorbisfile.a */,
+				8AE1F6F11CB83C990001557D /* libphysfs.a */,
+				8AE1F6EB1CB83C720001557D /* libfreetype.a */,
+				8AE1F6D31CB8391D0001557D /* libz.a */,
+				8AE1F6E91CB83C640001557D /* libPolycore.a */,
+				8AE1F71D1CB844370001557D /* polyimport.h */,
+				8AE1F6B51CB82FDF0001557D /* polyimport.cpp */,
+			);
+			path = polyimport;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		8AE1F6AA1CB82FBD0001557D /* polyimport */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 8AE1F6B21CB82FBD0001557D /* Build configuration list for PBXNativeTarget "polyimport" */;
+			buildPhases = (
+				8AE1F6A71CB82FBD0001557D /* Sources */,
+				8AE1F6A81CB82FBD0001557D /* Frameworks */,
+				8AE1F6A91CB82FBD0001557D /* CopyFiles */,
+				8AE1F71C1CB840B10001557D /* ShellScript */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = polyimport;
+			productName = polyimport;
+			productReference = 8AE1F6AB1CB82FBD0001557D /* polyimport */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		8AE1F6A31CB82FBD0001557D /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0730;
+				ORGANIZATIONNAME = Polycode;
+				TargetAttributes = {
+					8AE1F6AA1CB82FBD0001557D = {
+						CreatedOnToolsVersion = 7.3;
+					};
+				};
+			};
+			buildConfigurationList = 8AE1F6A61CB82FBD0001557D /* Build configuration list for PBXProject "polyimport" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 8AE1F6A21CB82FBD0001557D;
+			productRefGroup = 8AE1F6AC1CB82FBD0001557D /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8AE1F6AA1CB82FBD0001557D /* polyimport */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		8AE1F71C1CB840B10001557D /* ShellScript */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "cp $TARGET_BUILD_DIR//$EXECUTABLE_NAME ../../../bin";
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8AE1F6A71CB82FBD0001557D /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				8AE1F6B61CB82FDF0001557D /* polyimport.cpp in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		8AE1F6B01CB82FBD0001557D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)/../../../include\"",
+					"\"$(SRCROOT)/../../../include/assimp\"",
+				);
+				LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../lib/osx\"";
+				MACOSX_DEPLOYMENT_TARGET = 10.11;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		8AE1F6B11CB82FBD0001557D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_ANALYZER_NONNULL = YES;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				HEADER_SEARCH_PATHS = (
+					"\"$(SRCROOT)/../../../include\"",
+					"\"$(SRCROOT)/../../../include/assimp\"",
+				);
+				LIBRARY_SEARCH_PATHS = "\"$(SRCROOT)/../../../lib/osx\"";
+				MACOSX_DEPLOYMENT_TARGET = 10.11;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		8AE1F6B31CB82FBD0001557D /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SYMROOT = build;
+			};
+			name = Debug;
+		};
+		8AE1F6B41CB82FBD0001557D /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SYMROOT = build;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		8AE1F6A61CB82FBD0001557D /* Build configuration list for PBXProject "polyimport" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				8AE1F6B01CB82FBD0001557D /* Debug */,
+				8AE1F6B11CB82FBD0001557D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		8AE1F6B21CB82FBD0001557D /* Build configuration list for PBXNativeTarget "polyimport" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				8AE1F6B31CB82FBD0001557D /* Debug */,
+				8AE1F6B41CB82FBD0001557D /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 8AE1F6A31CB82FBD0001557D /* Project object */;
+}

+ 8 - 0
include/assimp/.editorconfig

@@ -0,0 +1,8 @@
+# See <http://EditorConfig.org> for details
+
+[*.{h,hpp,inl}]
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_size = 4
+indent_style = space

+ 22 - 0
include/assimp/Compiler/poppack1.h

@@ -0,0 +1,22 @@
+
+// ===============================================================================
+// May be included multiple times - resets structure packing to the defaults 
+// for all supported compilers. Reverts the changes made by #include <pushpack1.h> 
+//
+// Currently this works on the following compilers:
+// MSVC 7,8,9
+// GCC
+// BORLAND (complains about 'pack state changed but not reverted', but works)
+// ===============================================================================
+
+#ifndef AI_PUSHPACK_IS_DEFINED
+#	error pushpack1.h must be included after poppack1.h
+#endif
+
+// reset packing to the original value
+#if defined(_MSC_VER) ||  defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
+#	pragma pack( pop )
+#endif
+#undef PACK_STRUCT
+
+#undef AI_PUSHPACK_IS_DEFINED

+ 729 - 0
include/assimp/Compiler/pstdint.h

@@ -0,0 +1,729 @@
+/*  A portable stdint.h
+ ****************************************************************************
+ *  BSD License:
+ ****************************************************************************
+ *
+ *  Copyright (c) 2005-2007 Paul Hsieh
+ *  All rights reserved.
+ *
+ *  Redistribution and use in source and binary forms, with or without
+ *  modification, are permitted provided that the following conditions
+ *  are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************
+ *
+ *  Version 0.1.10
+ *
+ *  The ANSI C standard committee, for the C99 standard, specified the
+ *  inclusion of a new standard include file called stdint.h.  This is
+ *  a very useful and long desired include file which contains several
+ *  very precise definitions for integer scalar types that is
+ *  critically important for making portable several classes of
+ *  applications including cryptography, hashing, variable length
+ *  integer libraries and so on.  But for most developers its likely
+ *  useful just for programming sanity.
+ *
+ *  The problem is that most compiler vendors have decided not to
+ *  implement the C99 standard, and the next C++ language standard
+ *  (which has a lot more mindshare these days) will be a long time in
+ *  coming and its unknown whether or not it will include stdint.h or
+ *  how much adoption it will have.  Either way, it will be a long time
+ *  before all compilers come with a stdint.h and it also does nothing
+ *  for the extremely large number of compilers available today which
+ *  do not include this file, or anything comparable to it.
+ *
+ *  So that's what this file is all about.  Its an attempt to build a
+ *  single universal include file that works on as many platforms as
+ *  possible to deliver what stdint.h is supposed to.  A few things
+ *  that should be noted about this file:
+ *
+ *    1) It is not guaranteed to be portable and/or present an identical
+ *       interface on all platforms.  The extreme variability of the
+ *       ANSI C standard makes this an impossibility right from the
+ *       very get go. Its really only meant to be useful for the vast
+ *       majority of platforms that possess the capability of
+ *       implementing usefully and precisely defined, standard sized
+ *       integer scalars.  Systems which are not intrinsically 2s
+ *       complement may produce invalid constants.
+ *
+ *    2) There is an unavoidable use of non-reserved symbols.
+ *
+ *    3) Other standard include files are invoked.
+ *
+ *    4) This file may come in conflict with future platforms that do
+ *       include stdint.h.  The hope is that one or the other can be
+ *       used with no real difference.
+ *
+ *    5) In the current verison, if your platform can't represent
+ *       int32_t, int16_t and int8_t, it just dumps out with a compiler
+ *       error.
+ *
+ *    6) 64 bit integers may or may not be defined.  Test for their
+ *       presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
+ *       Note that this is different from the C99 specification which
+ *       requires the existence of 64 bit support in the compiler.  If
+ *       this is not defined for your platform, yet it is capable of
+ *       dealing with 64 bits then it is because this file has not yet
+ *       been extended to cover all of your system's capabilities.
+ *
+ *    7) (u)intptr_t may or may not be defined.  Test for its presence
+ *       with the test: #ifdef PTRDIFF_MAX.  If this is not defined
+ *       for your platform, then it is because this file has not yet
+ *       been extended to cover all of your system's capabilities, not
+ *       because its optional.
+ *
+ *    8) The following might not been defined even if your platform is
+ *       capable of defining it:
+ *
+ *       WCHAR_MIN
+ *       WCHAR_MAX
+ *       (u)int64_t
+ *       PTRDIFF_MIN
+ *       PTRDIFF_MAX
+ *       (u)intptr_t
+ *
+ *    9) The following have not been defined:
+ *
+ *       WINT_MIN
+ *       WINT_MAX
+ *
+ *   10) The criteria for defining (u)int_least(*)_t isn't clear,
+ *       except for systems which don't have a type that precisely
+ *       defined 8, 16, or 32 bit types (which this include file does
+ *       not support anyways). Default definitions have been given.
+ *
+ *   11) The criteria for defining (u)int_fast(*)_t isn't something I
+ *       would trust to any particular compiler vendor or the ANSI C
+ *       committee.  It is well known that "compatible systems" are
+ *       commonly created that have very different performance
+ *       characteristics from the systems they are compatible with,
+ *       especially those whose vendors make both the compiler and the
+ *       system.  Default definitions have been given, but its strongly
+ *       recommended that users never use these definitions for any
+ *       reason (they do *NOT* deliver any serious guarantee of
+ *       improved performance -- not in this file, nor any vendor's
+ *       stdint.h).
+ *
+ *   12) The following macros:
+ *
+ *       PRINTF_INTMAX_MODIFIER
+ *       PRINTF_INT64_MODIFIER
+ *       PRINTF_INT32_MODIFIER
+ *       PRINTF_INT16_MODIFIER
+ *       PRINTF_LEAST64_MODIFIER
+ *       PRINTF_LEAST32_MODIFIER
+ *       PRINTF_LEAST16_MODIFIER
+ *       PRINTF_INTPTR_MODIFIER
+ *
+ *       are strings which have been defined as the modifiers required
+ *       for the "d", "u" and "x" printf formats to correctly output
+ *       (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
+ *       (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
+ *       PRINTF_INTPTR_MODIFIER is not defined for some systems which
+ *       provide their own stdint.h.  PRINTF_INT64_MODIFIER is not
+ *       defined if INT64_MAX is not defined.  These are an extension
+ *       beyond what C99 specifies must be in stdint.h.
+ *
+ *       In addition, the following macros are defined:
+ *
+ *       PRINTF_INTMAX_HEX_WIDTH
+ *       PRINTF_INT64_HEX_WIDTH
+ *       PRINTF_INT32_HEX_WIDTH
+ *       PRINTF_INT16_HEX_WIDTH
+ *       PRINTF_INT8_HEX_WIDTH
+ *       PRINTF_INTMAX_DEC_WIDTH
+ *       PRINTF_INT64_DEC_WIDTH
+ *       PRINTF_INT32_DEC_WIDTH
+ *       PRINTF_INT16_DEC_WIDTH
+ *       PRINTF_INT8_DEC_WIDTH
+ *
+ *       Which specifies the maximum number of characters required to
+ *       print the number of that type in either hexadecimal or decimal.
+ *       These are an extension beyond what C99 specifies must be in
+ *       stdint.h.
+ *
+ *  Compilers tested (all with 0 warnings at their highest respective
+ *  settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
+ *  bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
+ *  .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
+ *
+ *  This file should be considered a work in progress.  Suggestions for
+ *  improvements, especially those which increase coverage are strongly
+ *  encouraged.
+ *
+ *  Acknowledgements
+ *
+ *  The following people have made significant contributions to the
+ *  development and testing of this file:
+ *
+ *  Chris Howie
+ *  John Steele Scott
+ *  Dave Thorup
+ *
+ */
+
+#include <stddef.h>
+#include <limits.h>
+#include <signal.h>
+
+/*
+ *  For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
+ *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
+ */
+
+#if ((defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)))) && !defined (_PSTDINT_H_INCLUDED) && !defined(_STDINT)
+#include <stdint.h>
+#define _PSTDINT_H_INCLUDED
+# ifndef PRINTF_INT64_MODIFIER
+#  define PRINTF_INT64_MODIFIER "ll"
+# endif
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER "l"
+# endif
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+# ifndef PRINTF_INTMAX_MODIFIER
+#  define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
+# endif
+# ifndef PRINTF_INT64_HEX_WIDTH
+#  define PRINTF_INT64_HEX_WIDTH "16"
+# endif
+# ifndef PRINTF_INT32_HEX_WIDTH
+#  define PRINTF_INT32_HEX_WIDTH "8"
+# endif
+# ifndef PRINTF_INT16_HEX_WIDTH
+#  define PRINTF_INT16_HEX_WIDTH "4"
+# endif
+# ifndef PRINTF_INT8_HEX_WIDTH
+#  define PRINTF_INT8_HEX_WIDTH "2"
+# endif
+# ifndef PRINTF_INT64_DEC_WIDTH
+#  define PRINTF_INT64_DEC_WIDTH "20"
+# endif
+# ifndef PRINTF_INT32_DEC_WIDTH
+#  define PRINTF_INT32_DEC_WIDTH "10"
+# endif
+# ifndef PRINTF_INT16_DEC_WIDTH
+#  define PRINTF_INT16_DEC_WIDTH "5"
+# endif
+# ifndef PRINTF_INT8_DEC_WIDTH
+#  define PRINTF_INT8_DEC_WIDTH "3"
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
+# endif
+
+/*
+ *  Something really weird is going on with Open Watcom.  Just pull some of
+ *  these duplicated definitions from Open Watcom's stdint.h file for now.
+ */
+
+# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
+#  if !defined (INT64_C)
+#   define INT64_C(x)   (x + (INT64_MAX - INT64_MAX))
+#  endif
+#  if !defined (UINT64_C)
+#   define UINT64_C(x)  (x + (UINT64_MAX - UINT64_MAX))
+#  endif
+#  if !defined (INT32_C)
+#   define INT32_C(x)   (x + (INT32_MAX - INT32_MAX))
+#  endif
+#  if !defined (UINT32_C)
+#   define UINT32_C(x)  (x + (UINT32_MAX - UINT32_MAX))
+#  endif
+#  if !defined (INT16_C)
+#   define INT16_C(x)   (x)
+#  endif
+#  if !defined (UINT16_C)
+#   define UINT16_C(x)  (x)
+#  endif
+#  if !defined (INT8_C)
+#   define INT8_C(x)   (x)
+#  endif
+#  if !defined (UINT8_C)
+#   define UINT8_C(x)  (x)
+#  endif
+#  if !defined (UINT64_MAX)
+#   define UINT64_MAX  18446744073709551615ULL
+#  endif
+#  if !defined (INT64_MAX)
+#   define INT64_MAX  9223372036854775807LL
+#  endif
+#  if !defined (UINT32_MAX)
+#   define UINT32_MAX  4294967295UL
+#  endif
+#  if !defined (INT32_MAX)
+#   define INT32_MAX  2147483647L
+#  endif
+#  if !defined (INTMAX_MAX)
+#   define INTMAX_MAX INT64_MAX
+#  endif
+#  if !defined (INTMAX_MIN)
+#   define INTMAX_MIN INT64_MIN
+#  endif
+# endif
+#endif
+
+#ifndef _PSTDINT_H_INCLUDED
+#define _PSTDINT_H_INCLUDED
+
+#ifndef SIZE_MAX
+# define SIZE_MAX (~(size_t)0)
+#endif
+
+/*
+ *  Deduce the type assignments from limits.h under the assumption that
+ *  integer sizes in bits are powers of 2, and follow the ANSI
+ *  definitions.
+ */
+
+#ifndef UINT8_MAX
+# define UINT8_MAX 0xff
+#endif
+#ifndef uint8_t
+# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
+    typedef unsigned char uint8_t;
+#   define UINT8_C(v) ((uint8_t) v)
+# else
+#   error "Platform not supported"
+# endif
+#endif
+
+#ifndef INT8_MAX
+# define INT8_MAX 0x7f
+#endif
+#ifndef INT8_MIN
+# define INT8_MIN INT8_C(0x80)
+#endif
+#ifndef int8_t
+# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
+    typedef signed char int8_t;
+#   define INT8_C(v) ((int8_t) v)
+# else
+#   error "Platform not supported"
+# endif
+#endif
+
+#ifndef UINT16_MAX
+# define UINT16_MAX 0xffff
+#endif
+#ifndef uint16_t
+#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
+  typedef unsigned int uint16_t;
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER ""
+# endif
+# define UINT16_C(v) ((uint16_t) (v))
+#elif (USHRT_MAX == UINT16_MAX)
+  typedef unsigned short uint16_t;
+# define UINT16_C(v) ((uint16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef INT16_MAX
+# define INT16_MAX 0x7fff
+#endif
+#ifndef INT16_MIN
+# define INT16_MIN INT16_C(0x8000)
+#endif
+#ifndef int16_t
+#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
+  typedef signed int int16_t;
+# define INT16_C(v) ((int16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER ""
+# endif
+#elif (SHRT_MAX == INT16_MAX)
+  typedef signed short int16_t;
+# define INT16_C(v) ((int16_t) (v))
+# ifndef PRINTF_INT16_MODIFIER
+#  define PRINTF_INT16_MODIFIER "h"
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef UINT32_MAX
+# define UINT32_MAX (0xffffffffUL)
+#endif
+#ifndef uint32_t
+#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
+  typedef unsigned long uint32_t;
+# define UINT32_C(v) v ## UL
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER "l"
+# endif
+#elif (UINT_MAX == UINT32_MAX)
+  typedef unsigned int uint32_t;
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+# define UINT32_C(v) v ## U
+#elif (USHRT_MAX == UINT32_MAX)
+  typedef unsigned short uint32_t;
+# define UINT32_C(v) ((unsigned short) (v))
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+#ifndef INT32_MAX
+# define INT32_MAX (0x7fffffffL)
+#endif
+#ifndef INT32_MIN
+# define INT32_MIN INT32_C(0x80000000)
+#endif
+#ifndef int32_t
+#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
+  typedef signed long int32_t;
+# define INT32_C(v) v ## L
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER "l"
+# endif
+#elif (INT_MAX == INT32_MAX)
+  typedef signed int int32_t;
+# define INT32_C(v) v
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+#elif (SHRT_MAX == INT32_MAX)
+  typedef signed short int32_t;
+# define INT32_C(v) ((short) (v))
+# ifndef PRINTF_INT32_MODIFIER
+#  define PRINTF_INT32_MODIFIER ""
+# endif
+#else
+#error "Platform not supported"
+#endif
+#endif
+
+/*
+ *  The macro stdint_int64_defined is temporarily used to record
+ *  whether or not 64 integer support is available.  It must be
+ *  defined for any 64 integer extensions for new platforms that are
+ *  added.
+ */
+
+#undef stdint_int64_defined
+#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
+# if (__STDC__ && __STDC_VERSION >= 199901L) || defined (S_SPLINT_S)
+#  define stdint_int64_defined
+   typedef long long int64_t;
+   typedef unsigned long long uint64_t;
+#  define UINT64_C(v) v ## ULL
+#  define  INT64_C(v) v ## LL
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+# endif
+#endif
+
+#if !defined (stdint_int64_defined)
+# if defined(__GNUC__)
+#  define stdint_int64_defined
+   __extension__ typedef long long int64_t;
+   __extension__ typedef unsigned long long uint64_t;
+#  define UINT64_C(v) v ## ULL
+#  define  INT64_C(v) v ## LL
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
+#  define stdint_int64_defined
+   typedef long long int64_t;
+   typedef unsigned long long uint64_t;
+#  define UINT64_C(v) v ## ULL
+#  define  INT64_C(v) v ## LL
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "ll"
+#  endif
+# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
+#  define stdint_int64_defined
+   typedef __int64 int64_t;
+   typedef unsigned __int64 uint64_t;
+#  define UINT64_C(v) v ## UI64
+#  define  INT64_C(v) v ## I64
+#  ifndef PRINTF_INT64_MODIFIER
+#   define PRINTF_INT64_MODIFIER "I64"
+#  endif
+# endif
+#endif
+
+#if !defined (LONG_LONG_MAX) && defined (INT64_C)
+# define LONG_LONG_MAX INT64_C (9223372036854775807)
+#endif
+#ifndef ULONG_LONG_MAX
+# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
+#endif
+
+#if !defined (INT64_MAX) && defined (INT64_C)
+# define INT64_MAX INT64_C (9223372036854775807)
+#endif
+#if !defined (INT64_MIN) && defined (INT64_C)
+# define INT64_MIN INT64_C (-9223372036854775808)
+#endif
+#if !defined (UINT64_MAX) && defined (INT64_C)
+# define UINT64_MAX UINT64_C (18446744073709551615)
+#endif
+
+/*
+ *  Width of hexadecimal for number field.
+ */
+
+#ifndef PRINTF_INT64_HEX_WIDTH
+# define PRINTF_INT64_HEX_WIDTH "16"
+#endif
+#ifndef PRINTF_INT32_HEX_WIDTH
+# define PRINTF_INT32_HEX_WIDTH "8"
+#endif
+#ifndef PRINTF_INT16_HEX_WIDTH
+# define PRINTF_INT16_HEX_WIDTH "4"
+#endif
+#ifndef PRINTF_INT8_HEX_WIDTH
+# define PRINTF_INT8_HEX_WIDTH "2"
+#endif
+
+#ifndef PRINTF_INT64_DEC_WIDTH
+# define PRINTF_INT64_DEC_WIDTH "20"
+#endif
+#ifndef PRINTF_INT32_DEC_WIDTH
+# define PRINTF_INT32_DEC_WIDTH "10"
+#endif
+#ifndef PRINTF_INT16_DEC_WIDTH
+# define PRINTF_INT16_DEC_WIDTH "5"
+#endif
+#ifndef PRINTF_INT8_DEC_WIDTH
+# define PRINTF_INT8_DEC_WIDTH "3"
+#endif
+
+/*
+ *  Ok, lets not worry about 128 bit integers for now.  Moore's law says
+ *  we don't need to worry about that until about 2040 at which point
+ *  we'll have bigger things to worry about.
+ */
+
+#ifdef stdint_int64_defined
+  typedef int64_t intmax_t;
+  typedef uint64_t uintmax_t;
+# define  INTMAX_MAX   INT64_MAX
+# define  INTMAX_MIN   INT64_MIN
+# define UINTMAX_MAX  UINT64_MAX
+# define UINTMAX_C(v) UINT64_C(v)
+# define  INTMAX_C(v)  INT64_C(v)
+# ifndef PRINTF_INTMAX_MODIFIER
+#   define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
+# endif
+#else
+  typedef int32_t intmax_t;
+  typedef uint32_t uintmax_t;
+# define  INTMAX_MAX   INT32_MAX
+# define UINTMAX_MAX  UINT32_MAX
+# define UINTMAX_C(v) UINT32_C(v)
+# define  INTMAX_C(v)  INT32_C(v)
+# ifndef PRINTF_INTMAX_MODIFIER
+#   define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
+# endif
+# ifndef PRINTF_INTMAX_HEX_WIDTH
+#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
+# endif
+# ifndef PRINTF_INTMAX_DEC_WIDTH
+#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
+# endif
+#endif
+
+/*
+ *  Because this file currently only supports platforms which have
+ *  precise powers of 2 as bit sizes for the default integers, the
+ *  least definitions are all trivial.  Its possible that a future
+ *  version of this file could have different definitions.
+ */
+
+#ifndef stdint_least_defined
+  typedef   int8_t   int_least8_t;
+  typedef  uint8_t  uint_least8_t;
+  typedef  int16_t  int_least16_t;
+  typedef uint16_t uint_least16_t;
+  typedef  int32_t  int_least32_t;
+  typedef uint32_t uint_least32_t;
+# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
+# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
+# define  UINT_LEAST8_MAX  UINT8_MAX
+# define   INT_LEAST8_MAX   INT8_MAX
+# define UINT_LEAST16_MAX UINT16_MAX
+# define  INT_LEAST16_MAX  INT16_MAX
+# define UINT_LEAST32_MAX UINT32_MAX
+# define  INT_LEAST32_MAX  INT32_MAX
+# define   INT_LEAST8_MIN   INT8_MIN
+# define  INT_LEAST16_MIN  INT16_MIN
+# define  INT_LEAST32_MIN  INT32_MIN
+# ifdef stdint_int64_defined
+    typedef  int64_t  int_least64_t;
+    typedef uint64_t uint_least64_t;
+#   define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
+#   define UINT_LEAST64_MAX UINT64_MAX
+#   define  INT_LEAST64_MAX  INT64_MAX
+#   define  INT_LEAST64_MIN  INT64_MIN
+# endif
+#endif
+#undef stdint_least_defined
+
+/*
+ *  The ANSI C committee pretending to know or specify anything about
+ *  performance is the epitome of misguided arrogance.  The mandate of
+ *  this file is to *ONLY* ever support that absolute minimum
+ *  definition of the fast integer types, for compatibility purposes.
+ *  No extensions, and no attempt to suggest what may or may not be a
+ *  faster integer type will ever be made in this file.  Developers are
+ *  warned to stay away from these types when using this or any other
+ *  stdint.h.
+ */
+
+typedef   int_least8_t   int_fast8_t;
+typedef  uint_least8_t  uint_fast8_t;
+typedef  int_least16_t  int_fast16_t;
+typedef uint_least16_t uint_fast16_t;
+typedef  int_least32_t  int_fast32_t;
+typedef uint_least32_t uint_fast32_t;
+#define  UINT_FAST8_MAX  UINT_LEAST8_MAX
+#define   INT_FAST8_MAX   INT_LEAST8_MAX
+#define UINT_FAST16_MAX UINT_LEAST16_MAX
+#define  INT_FAST16_MAX  INT_LEAST16_MAX
+#define UINT_FAST32_MAX UINT_LEAST32_MAX
+#define  INT_FAST32_MAX  INT_LEAST32_MAX
+#define   INT_FAST8_MIN   INT_LEAST8_MIN
+#define  INT_FAST16_MIN  INT_LEAST16_MIN
+#define  INT_FAST32_MIN  INT_LEAST32_MIN
+#ifdef stdint_int64_defined
+  typedef  int_least64_t  int_fast64_t;
+  typedef uint_least64_t uint_fast64_t;
+# define UINT_FAST64_MAX UINT_LEAST64_MAX
+# define  INT_FAST64_MAX  INT_LEAST64_MAX
+# define  INT_FAST64_MIN  INT_LEAST64_MIN
+#endif
+
+#undef stdint_int64_defined
+
+/*
+ *  Whatever piecemeal, per compiler thing we can do about the wchar_t
+ *  type limits.
+ */
+
+#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__)
+# include <wchar.h>
+# ifndef WCHAR_MIN
+#  define WCHAR_MIN 0
+# endif
+# ifndef WCHAR_MAX
+#  define WCHAR_MAX ((wchar_t)-1)
+# endif
+#endif
+
+/*
+ *  Whatever piecemeal, per compiler/platform thing we can do about the
+ *  (u)intptr_t types and limits.
+ */
+
+#if defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)
+# define STDINT_H_UINTPTR_T_DEFINED
+#endif
+
+#ifndef STDINT_H_UINTPTR_T_DEFINED
+# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64)
+#  define stdint_intptr_bits 64
+# elif defined (__WATCOMC__) || defined (__TURBOC__)
+#  if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
+#    define stdint_intptr_bits 16
+#  else
+#    define stdint_intptr_bits 32
+#  endif
+# elif defined (__i386__) || defined (_WIN32) || defined (WIN32)
+#  define stdint_intptr_bits 32
+# elif defined (__INTEL_COMPILER)
+/* TODO -- what will Intel do about x86-64? */
+# endif
+
+# ifdef stdint_intptr_bits
+#  define stdint_intptr_glue3_i(a,b,c)  a##b##c
+#  define stdint_intptr_glue3(a,b,c)    stdint_intptr_glue3_i(a,b,c)
+#  ifndef PRINTF_INTPTR_MODIFIER
+#    define PRINTF_INTPTR_MODIFIER      stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
+#  endif
+#  ifndef PTRDIFF_MAX
+#    define PTRDIFF_MAX                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
+#  endif
+#  ifndef PTRDIFF_MIN
+#    define PTRDIFF_MIN                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
+#  endif
+#  ifndef UINTPTR_MAX
+#    define UINTPTR_MAX                 stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
+#  endif
+#  ifndef INTPTR_MAX
+#    define INTPTR_MAX                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
+#  endif
+#  ifndef INTPTR_MIN
+#    define INTPTR_MIN                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
+#  endif
+#  ifndef INTPTR_C
+#    define INTPTR_C(x)                 stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
+#  endif
+#  ifndef UINTPTR_C
+#    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
+#  endif
+  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
+  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
+# else
+/* TODO -- This following is likely wrong for some platforms, and does
+   nothing for the definition of uintptr_t. */
+  typedef ptrdiff_t intptr_t;
+# endif
+# define STDINT_H_UINTPTR_T_DEFINED
+#endif
+
+/*
+ *  Assumes sig_atomic_t is signed and we have a 2s complement machine.
+ */
+
+#ifndef SIG_ATOMIC_MAX
+# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
+#endif
+
+#endif
+

+ 46 - 0
include/assimp/Compiler/pushpack1.h

@@ -0,0 +1,46 @@
+
+
+// ===============================================================================
+// May be included multiple times - sets structure packing to 1 
+// for all supported compilers. #include <poppack1.h> reverts the changes.
+//
+// Currently this works on the following compilers:
+// MSVC 7,8,9
+// GCC
+// BORLAND (complains about 'pack state changed but not reverted', but works)
+// Clang
+//
+//
+// USAGE:
+//
+// struct StructToBePacked {
+// } PACK_STRUCT;
+//
+// ===============================================================================
+
+#ifdef AI_PUSHPACK_IS_DEFINED
+#	error poppack1.h must be included after pushpack1.h
+#endif
+
+#if defined(_MSC_VER) ||  defined(__BORLANDC__) ||	defined (__BCPLUSPLUS__)
+#	pragma pack(push,1)
+#	define PACK_STRUCT
+#elif defined( __GNUC__ )
+#	if !defined(HOST_MINGW)
+#		define PACK_STRUCT	__attribute__((__packed__))
+#	else
+#		define PACK_STRUCT	__attribute__((gcc_struct, __packed__))
+#	endif
+#else
+#	error Compiler not supported
+#endif
+
+#if defined(_MSC_VER)
+
+// C4103: Packing was changed after the inclusion of the header, propably missing #pragma pop
+#	pragma warning (disable : 4103) 
+#endif
+
+#define AI_PUSHPACK_IS_DEFINED
+
+

+ 190 - 0
include/assimp/DefaultLogger.hpp

@@ -0,0 +1,190 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+/** @file DefaultLogger.hpp
+*/
+
+#ifndef INCLUDED_AI_DEFAULTLOGGER
+#define INCLUDED_AI_DEFAULTLOGGER
+
+#include "Logger.hpp"
+#include "LogStream.hpp"
+#include "NullLogger.hpp"
+#include <vector>
+
+namespace Assimp    {
+// ------------------------------------------------------------------------------------
+class IOStream;
+struct LogStreamInfo;
+
+/** default name of logfile */
+#define ASSIMP_DEFAULT_LOG_NAME "AssimpLog.txt"
+
+// ------------------------------------------------------------------------------------
+/** @brief CPP-API: Primary logging facility of Assimp.
+ *
+ *  The library stores its primary #Logger as a static member of this class.
+ *  #get() returns this primary logger. By default the underlying implementation is
+ *  just a #NullLogger which rejects all log messages. By calling #create(), logging
+ *  is turned on. To capture the log output multiple log streams (#LogStream) can be
+ *  attach to the logger. Some default streams for common streaming locations (such as
+ *  a file, std::cout, OutputDebugString()) are also provided.
+ *
+ *  If you wish to customize the logging at an even deeper level supply your own
+ *  implementation of #Logger to #set().
+ *  @note The whole logging stuff causes a small extra overhead for all imports. */
+class ASSIMP_API DefaultLogger :
+    public Logger   {
+
+public:
+
+    // ----------------------------------------------------------------------
+    /** @brief Creates a logging instance.
+     *  @param name Name for log file. Only valid in combination
+     *    with the aiDefaultLogStream_FILE flag.
+     *  @param severity Log severity, VERBOSE turns on debug messages
+     *  @param defStreams  Default log streams to be attached. Any bitwise
+     *    combination of the aiDefaultLogStream enumerated values.
+     *    If #aiDefaultLogStream_FILE is specified but an empty string is
+     *    passed for 'name', no log file is created at all.
+     *  @param  io IOSystem to be used to open external files (such as the
+     *   log file). Pass NULL to rely on the default implementation.
+     *  This replaces the default #NullLogger with a #DefaultLogger instance. */
+    static Logger *create(const char* name = ASSIMP_DEFAULT_LOG_NAME,
+        LogSeverity severity    = NORMAL,
+        unsigned int defStreams = aiDefaultLogStream_DEBUGGER | aiDefaultLogStream_FILE,
+        IOSystem* io            = NULL);
+
+    // ----------------------------------------------------------------------
+    /** @brief Setup a custom #Logger implementation.
+     *
+     *  Use this if the provided #DefaultLogger class doesn't fit into
+     *  your needs. If the provided message formatting is OK for you,
+     *  it's much easier to use #create() and to attach your own custom
+     *  output streams to it.
+     *  @param logger Pass NULL to setup a default NullLogger*/
+    static void set (Logger *logger);
+
+    // ----------------------------------------------------------------------
+    /** @brief  Getter for singleton instance
+     *   @return Only instance. This is never null, but it could be a
+     *  NullLogger. Use isNullLogger to check this.*/
+    static Logger *get();
+
+    // ----------------------------------------------------------------------
+    /** @brief  Return whether a #NullLogger is currently active
+     *  @return true if the current logger is a #NullLogger.
+     *  Use create() or set() to setup a logger that does actually do
+     *  something else than just rejecting all log messages. */
+    static bool isNullLogger();
+
+    // ----------------------------------------------------------------------
+    /** @brief  Kills the current singleton logger and replaces it with a
+     *  #NullLogger instance. */
+    static void kill();
+
+    // ----------------------------------------------------------------------
+    /** @copydoc Logger::attachStream   */
+    bool attachStream(LogStream *pStream,
+        unsigned int severity);
+
+    // ----------------------------------------------------------------------
+    /** @copydoc Logger::detatchStream */
+    bool detatchStream(LogStream *pStream,
+        unsigned int severity);
+
+
+private:
+
+    // ----------------------------------------------------------------------
+    /** @briefPrivate construction for internal use by create().
+     *  @param severity Logging granularity  */
+    explicit DefaultLogger(LogSeverity severity);
+
+    // ----------------------------------------------------------------------
+    /** @briefDestructor    */
+    ~DefaultLogger();
+
+private:
+
+    /** @brief  Logs debug infos, only been written when severity level VERBOSE is set */
+    void OnDebug(const char* message);
+
+    /** @brief  Logs an info message */
+    void OnInfo(const char*  message);
+
+    /** @brief  Logs a warning message */
+    void OnWarn(const char*  message);
+
+    /** @brief  Logs an error message */
+    void OnError(const char* message);
+
+    // ----------------------------------------------------------------------
+    /** @brief Writes a message to all streams */
+    void WriteToStreams(const char* message, ErrorSeverity ErrorSev );
+
+    // ----------------------------------------------------------------------
+    /** @brief Returns the thread id.
+     *  @note This is an OS specific feature, if not supported, a
+     *    zero will be returned.
+     */
+    unsigned int GetThreadID();
+
+private:
+    //  Aliases for stream container
+    typedef std::vector<LogStreamInfo*> StreamArray;
+    typedef std::vector<LogStreamInfo*>::iterator StreamIt;
+    typedef std::vector<LogStreamInfo*>::const_iterator ConstStreamIt;
+
+    //! only logging instance
+    static Logger *m_pLogger;
+    static NullLogger s_pNullLogger;
+
+    //! Attached streams
+    StreamArray m_StreamArray;
+
+    bool noRepeatMsg;
+    char lastMsg[MAX_LOG_MESSAGE_LENGTH*2];
+    size_t lastLen;
+};
+// ------------------------------------------------------------------------------------
+
+} // Namespace Assimp
+
+#endif // !! INCLUDED_AI_DEFAULTLOGGER

+ 504 - 0
include/assimp/Exporter.hpp

@@ -0,0 +1,504 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2011, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  Exporter.hpp
+*  @brief Defines the CPP-API for the Assimp export interface
+*/
+#ifndef AI_EXPORT_HPP_INC
+#define AI_EXPORT_HPP_INC
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+#include "cexport.h"
+#include <map>
+
+namespace Assimp    {
+    class ExporterPimpl;
+    class IOSystem;
+
+
+// ----------------------------------------------------------------------------------
+/** CPP-API: The Exporter class forms an C++ interface to the export functionality
+ * of the Open Asset Import Library. Note that the export interface is available
+ * only if Assimp has been built with ASSIMP_BUILD_NO_EXPORT not defined.
+ *
+ * The interface is modelled after the importer interface and mostly
+ * symmetric. The same rules for threading etc. apply.
+ *
+ * In a nutshell, there are two export interfaces: #Export, which writes the
+ * output file(s) either to the regular file system or to a user-supplied
+ * #IOSystem, and #ExportToBlob which returns a linked list of memory
+ * buffers (blob), each referring to one output file (in most cases
+ * there will be only one output file of course, but this extra complexity is
+ * needed since Assimp aims at supporting a wide range of file formats).
+ *
+ * #ExportToBlob is especially useful if you intend to work
+ * with the data in-memory.
+*/
+
+class ASSIMP_API ExportProperties;
+
+class ASSIMP_API Exporter
+    // TODO: causes good ol' base class has no dll interface warning
+//#ifdef __cplusplus
+//  : public boost::noncopyable
+//#endif // __cplusplus
+{
+public:
+
+    /** Function pointer type of a Export worker function */
+    typedef void (*fpExportFunc)(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+
+    /** Internal description of an Assimp export format option */
+    struct ExportFormatEntry
+    {
+        /// Public description structure to be returned by aiGetExportFormatDescription()
+        aiExportFormatDesc mDescription;
+
+        // Worker function to do the actual exporting
+        fpExportFunc mExportFunction;
+
+        // Postprocessing steps to be executed PRIOR to invoking mExportFunction
+        unsigned int mEnforcePP;
+
+        // Constructor to fill all entries
+        ExportFormatEntry( const char* pId, const char* pDesc, const char* pExtension, fpExportFunc pFunction, unsigned int pEnforcePP = 0u)
+        {
+            mDescription.id = pId;
+            mDescription.description = pDesc;
+            mDescription.fileExtension = pExtension;
+            mExportFunction = pFunction;
+            mEnforcePP = pEnforcePP;
+        }
+
+        ExportFormatEntry() :
+            mExportFunction()
+          , mEnforcePP()
+        {
+            mDescription.id = NULL;
+            mDescription.description = NULL;
+            mDescription.fileExtension = NULL;
+        }
+    };
+
+
+public:
+
+
+    Exporter();
+    ~Exporter();
+
+public:
+
+
+    // -------------------------------------------------------------------
+    /** Supplies a custom IO handler to the exporter to use to open and
+     * access files.
+     *
+     * If you need #Export to use custom IO logic to access the files,
+     * you need to supply a custom implementation of IOSystem and
+     * IOFile to the exporter.
+     *
+     * #Exporter takes ownership of the object and will destroy it
+     * afterwards. The previously assigned handler will be deleted.
+     * Pass NULL to take again ownership of your IOSystem and reset Assimp
+     * to use its default implementation, which uses plain file IO.
+     *
+     * @param pIOHandler The IO handler to be used in all file accesses
+     *   of the Importer. */
+    void SetIOHandler( IOSystem* pIOHandler);
+
+    // -------------------------------------------------------------------
+    /** Retrieves the IO handler that is currently set.
+     * You can use #IsDefaultIOHandler() to check whether the returned
+     * interface is the default IO handler provided by ASSIMP. The default
+     * handler is active as long the application doesn't supply its own
+     * custom IO handler via #SetIOHandler().
+     * @return A valid IOSystem interface, never NULL. */
+    IOSystem* GetIOHandler() const;
+
+    // -------------------------------------------------------------------
+    /** Checks whether a default IO handler is active
+     * A default handler is active as long the application doesn't
+     * supply its own custom IO handler via #SetIOHandler().
+     * @return true by default */
+    bool IsDefaultIOHandler() const;
+
+
+
+    // -------------------------------------------------------------------
+    /** Exports the given scene to a chosen file format. Returns the exported
+    * data as a binary blob which you can write into a file or something.
+    * When you're done with the data, simply let the #Exporter instance go
+    * out of scope to have it released automatically.
+    * @param pScene The scene to export. Stays in possession of the caller,
+    *   is not changed by the function.
+    * @param pFormatId ID string to specify to which format you want to
+    *   export to. Use
+    * #GetExportFormatCount / #GetExportFormatDescription to learn which
+    *   export formats are available.
+    * @param pPreprocessing See the documentation for #Export
+    * @return the exported data or NULL in case of error.
+    * @note If the Exporter instance did already hold a blob from
+    *   a previous call to #ExportToBlob, it will be disposed.
+    *   Any IO handlers set via #SetIOHandler are ignored here.
+    * @note Use aiCopyScene() to get a modifiable copy of a previously
+    *   imported scene. */
+    const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+    inline const aiExportDataBlob* ExportToBlob(  const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+
+
+    // -------------------------------------------------------------------
+    /** Convenience function to export directly to a file. Use
+     *  #SetIOSystem to supply a custom IOSystem to gain fine-grained control
+     *  about the output data flow of the export process.
+     * @param pBlob A data blob obtained from a previous call to #aiExportScene. Must not be NULL.
+     * @param pPath Full target file name. Target must be accessible.
+     * @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
+     *   flags, but in reality only a subset of them makes sense here. Specifying
+     *   'preprocessing' flags is useful if the input scene does not conform to
+     *   Assimp's default conventions as specified in the @link data Data Structures Page @endlink.
+     *   In short, this means the geometry data should use a right-handed coordinate systems, face
+     *   winding should be counter-clockwise and the UV coordinate origin is assumed to be in
+     *   the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
+     *   #aiProcess_FlipWindingOrder flags are used in the import side to allow users
+     *   to have those defaults automatically adapted to their conventions. Specifying those flags
+     *   for exporting has the opposite effect, respectively. Some other of the
+     *   #aiPostProcessSteps enumerated values may be useful as well, but you'll need
+     *   to try out what their effect on the exported file is. Many formats impose
+     *   their own restrictions on the structure of the geometry stored therein,
+     *   so some preprocessing may have little or no effect at all, or may be
+     *   redundant as exporters would apply them anyhow. A good example
+     *   is triangulation - whilst you can enforce it by specifying
+     *   the #aiProcess_Triangulate flag, most export formats support only
+     *   triangulate data so they would run the step even if it wasn't requested.
+     *
+     *   If assimp detects that the input scene was directly taken from the importer side of
+     *   the library (i.e. not copied using aiCopyScene and potetially modified afterwards),
+     *   any postprocessing steps already applied to the scene will not be applied again, unless
+     *   they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
+     *   #aiProcess_FlipWindingOrder).
+     * @return AI_SUCCESS if everything was fine.
+     * @note Use aiCopyScene() to get a modifiable copy of a previously
+     *   imported scene.*/
+    aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+    inline aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,  unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
+
+
+    // -------------------------------------------------------------------
+    /** Returns an error description of an error that occurred in #Export
+     *    or #ExportToBlob
+     *
+     * Returns an empty string if no error occurred.
+     * @return A description of the last error, an empty string if no
+     *   error occurred. The string is never NULL.
+     *
+     * @note The returned function remains valid until one of the
+     * following methods is called: #Export, #ExportToBlob, #FreeBlob */
+    const char* GetErrorString() const;
+
+
+    // -------------------------------------------------------------------
+    /** Return the blob obtained from the last call to #ExportToBlob */
+    const aiExportDataBlob* GetBlob() const;
+
+
+    // -------------------------------------------------------------------
+    /** Orphan the blob from the last call to #ExportToBlob. This means
+     *  the caller takes ownership and is thus responsible for calling
+     *  the C API function #aiReleaseExportBlob to release it. */
+    const aiExportDataBlob* GetOrphanedBlob() const;
+
+
+    // -------------------------------------------------------------------
+    /** Frees the current blob.
+     *
+     *  The function does nothing if no blob has previously been
+     *  previously produced via #ExportToBlob. #FreeBlob is called
+     *  automatically by the destructor. The only reason to call
+     *  it manually would be to reclain as much storage as possible
+     *  without giving up the #Exporter instance yet. */
+    void FreeBlob( );
+
+
+    // -------------------------------------------------------------------
+    /** Returns the number of export file formats available in the current
+     *  Assimp build. Use #Exporter::GetExportFormatDescription to
+     *  retrieve infos of a specific export format.
+     *
+     *  This includes built-in exporters as well as exporters registered
+     *  using #RegisterExporter.
+     **/
+    size_t GetExportFormatCount() const;
+
+
+    // -------------------------------------------------------------------
+    /** Returns a description of the nth export file format. Use #
+     *  #Exporter::GetExportFormatCount to learn how many export
+     *  formats are supported.
+     *
+     * The returned pointer is of static storage duration iff the
+     * pIndex pertains to a built-in exporter (i.e. one not registered
+     * via #RegistrerExporter). It is restricted to the life-time of the
+     * #Exporter instance otherwise.
+     *
+     * @param pIndex Index of the export format to retrieve information
+     *  for. Valid range is 0 to #Exporter::GetExportFormatCount
+     * @return A description of that specific export format.
+     *  NULL if pIndex is out of range. */
+    const aiExportFormatDesc* GetExportFormatDescription( size_t pIndex ) const;
+
+
+    // -------------------------------------------------------------------
+    /** Register a custom exporter. Custom export formats are limited to
+     *    to the current #Exporter instance and do not affect the
+     *    library globally. The indexes under which the format's
+     *    export format description can be queried are assigned
+     *    monotonously.
+     *  @param desc Exporter description.
+     *  @return aiReturn_SUCCESS if the export format was successfully
+     *    registered. A common cause that would prevent an exporter
+     *    from being registered is that its format id is already
+     *    occupied by another format. */
+    aiReturn RegisterExporter(const ExportFormatEntry& desc);
+
+
+    // -------------------------------------------------------------------
+    /** Remove an export format previously registered with #RegisterExporter
+     *  from the #Exporter instance (this can also be used to drop
+     *  builtin exporters because those are implicitly registered
+     *  using #RegisterExporter).
+     *  @param id Format id to be unregistered, this refers to the
+     *    'id' field of #aiExportFormatDesc.
+     *  @note Calling this method on a format description not yet registered
+     *    has no effect.*/
+    void UnregisterExporter(const char* id);
+
+
+protected:
+
+    // Just because we don't want you to know how we're hacking around.
+    ExporterPimpl* pimpl;
+};
+
+
+class ASSIMP_API ExportProperties
+{
+public:
+    // Data type to store the key hash
+    typedef unsigned int KeyType;
+
+    // typedefs for our four configuration maps.
+    // We don't need more, so there is no need for a generic solution
+    typedef std::map<KeyType, int> IntPropertyMap;
+    typedef std::map<KeyType, float> FloatPropertyMap;
+    typedef std::map<KeyType, std::string> StringPropertyMap;
+    typedef std::map<KeyType, aiMatrix4x4> MatrixPropertyMap;
+
+public:
+
+    /** Standard constructor
+    * @see ExportProperties()
+    */
+
+    ExportProperties();
+
+    // -------------------------------------------------------------------
+    /** Copy constructor.
+     *
+     * This copies the configuration properties of another ExportProperties.
+     * @see ExportProperties(const ExportProperties& other)
+     */
+    ExportProperties(const ExportProperties& other);
+
+    // -------------------------------------------------------------------
+    /** Set an integer configuration property.
+     * @param szName Name of the property. All supported properties
+     *   are defined in the aiConfig.g header (all constants share the
+     *   prefix AI_CONFIG_XXX and are simple strings).
+     * @param iValue New value of the property
+     * @return true if the property was set before. The new value replaces
+     *   the previous value in this case.
+     * @note Property of different types (float, int, string ..) are kept
+     *   on different stacks, so calling SetPropertyInteger() for a
+     *   floating-point property has no effect - the loader will call
+     *   GetPropertyFloat() to read the property, but it won't be there.
+     */
+    bool SetPropertyInteger(const char* szName, int iValue);
+
+    // -------------------------------------------------------------------
+    /** Set a boolean configuration property. Boolean properties
+     *  are stored on the integer stack internally so it's possible
+     *  to set them via #SetPropertyBool and query them with
+     *  #GetPropertyBool and vice versa.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyBool(const char* szName, bool value)    {
+        return SetPropertyInteger(szName,value);
+    }
+
+    // -------------------------------------------------------------------
+    /** Set a floating-point configuration property.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyFloat(const char* szName, float fValue);
+
+    // -------------------------------------------------------------------
+    /** Set a string configuration property.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyString(const char* szName, const std::string& sValue);
+
+    // -------------------------------------------------------------------
+    /** Set a matrix configuration property.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);
+
+    // -------------------------------------------------------------------
+    /** Get a configuration property.
+     * @param szName Name of the property. All supported properties
+     *   are defined in the aiConfig.g header (all constants share the
+     *   prefix AI_CONFIG_XXX).
+     * @param iErrorReturn Value that is returned if the property
+     *   is not found.
+     * @return Current value of the property
+     * @note Property of different types (float, int, string ..) are kept
+     *   on different lists, so calling SetPropertyInteger() for a
+     *   floating-point property has no effect - the loader will call
+     *   GetPropertyFloat() to read the property, but it won't be there.
+     */
+    int GetPropertyInteger(const char* szName,
+        int iErrorReturn = 0xffffffff) const;
+
+    // -------------------------------------------------------------------
+    /** Get a boolean configuration property. Boolean properties
+     *  are stored on the integer stack internally so it's possible
+     *  to set them via #SetPropertyBool and query them with
+     *  #GetPropertyBool and vice versa.
+     * @see GetPropertyInteger()
+     */
+    bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
+        return GetPropertyInteger(szName,bErrorReturn)!=0;
+    }
+
+    // -------------------------------------------------------------------
+    /** Get a floating-point configuration property
+     * @see GetPropertyInteger()
+     */
+    float GetPropertyFloat(const char* szName,
+        float fErrorReturn = 10e10f) const;
+
+    // -------------------------------------------------------------------
+    /** Get a string configuration property
+     *
+     *  The return value remains valid until the property is modified.
+     * @see GetPropertyInteger()
+     */
+    const std::string GetPropertyString(const char* szName,
+        const std::string& sErrorReturn = "") const;
+
+    // -------------------------------------------------------------------
+    /** Get a matrix configuration property
+     *
+     *  The return value remains valid until the property is modified.
+     * @see GetPropertyInteger()
+     */
+    const aiMatrix4x4 GetPropertyMatrix(const char* szName,
+        const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
+
+    // -------------------------------------------------------------------
+    /** Determine a integer configuration property has been set.
+    * @see HasPropertyInteger()
+     */
+    bool HasPropertyInteger(const char* szName) const;
+
+    /** Determine a boolean configuration property has been set.
+    * @see HasPropertyBool()
+     */
+    bool HasPropertyBool(const char* szName) const;
+
+    /** Determine a boolean configuration property has been set.
+    * @see HasPropertyFloat()
+     */
+    bool HasPropertyFloat(const char* szName) const;
+
+    /** Determine a String configuration property has been set.
+    * @see HasPropertyString()
+     */
+    bool HasPropertyString(const char* szName) const;
+
+    /** Determine a Matrix configuration property has been set.
+    * @see HasPropertyMatrix()
+     */
+    bool HasPropertyMatrix(const char* szName) const;
+
+protected:
+
+    /** List of integer properties */
+    IntPropertyMap mIntProperties;
+
+    /** List of floating-point properties */
+    FloatPropertyMap mFloatProperties;
+
+    /** List of string properties */
+    StringPropertyMap mStringProperties;
+
+    /** List of Matrix properties */
+    MatrixPropertyMap mMatrixProperties;
+};
+
+
+// ----------------------------------------------------------------------------------
+inline const aiExportDataBlob* Exporter :: ExportToBlob(  const aiScene* pScene, const std::string& pFormatId,unsigned int pPreprocessing, const ExportProperties* pProperties)
+{
+    return ExportToBlob(pScene,pFormatId.c_str(),pPreprocessing, pProperties);
+}
+
+// ----------------------------------------------------------------------------------
+inline aiReturn Exporter :: Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing, const ExportProperties* pProperties)
+{
+    return Export(pScene,pFormatId.c_str(),pPath.c_str(),pPreprocessing, pProperties);
+}
+
+} // namespace Assimp
+#endif // ASSIMP_BUILD_NO_EXPORT
+#endif // AI_EXPORT_HPP_INC

+ 138 - 0
include/assimp/IOStream.hpp

@@ -0,0 +1,138 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+/** @file IOStream.hpp
+ *  @brief File I/O wrappers for C++.
+ */
+
+#ifndef AI_IOSTREAM_H_INC
+#define AI_IOSTREAM_H_INC
+
+#include "types.h"
+
+#ifndef __cplusplus
+#   error This header requires C++ to be used. aiFileIO.h is the \
+    corresponding C interface.
+#endif
+
+namespace Assimp    {
+
+// ----------------------------------------------------------------------------------
+/** @brief CPP-API: Class to handle file I/O for C++
+ *
+ *  Derive an own implementation from this interface to provide custom IO handling
+ *  to the Importer. If you implement this interface, be sure to also provide an
+ *  implementation for IOSystem that creates instances of your custom IO class.
+*/
+class ASSIMP_API IOStream
+#ifndef SWIG
+    : public Intern::AllocateFromAssimpHeap
+#endif
+{
+protected:
+    /** Constructor protected, use IOSystem::Open() to create an instance. */
+    IOStream(void);
+
+public:
+    // -------------------------------------------------------------------
+    /** @brief Destructor. Deleting the object closes the underlying file,
+     * alternatively you may use IOSystem::Close() to release the file.
+     */
+    virtual ~IOStream();
+
+    // -------------------------------------------------------------------
+    /** @brief Read from the file
+     *
+     * See fread() for more details
+     * This fails for write-only files */
+    virtual size_t Read(void* pvBuffer,
+        size_t pSize,
+        size_t pCount) = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Write to the file
+    *
+    * See fwrite() for more details
+    * This fails for read-only files */
+    virtual size_t Write(const void* pvBuffer,
+        size_t pSize,
+        size_t pCount) = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Set the read/write cursor of the file
+     *
+     * Note that the offset is _negative_ for aiOrigin_END.
+     * See fseek() for more details */
+    virtual aiReturn Seek(size_t pOffset,
+        aiOrigin pOrigin) = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Get the current position of the read/write cursor
+     *
+     * See ftell() for more details */
+    virtual size_t Tell() const = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Returns filesize
+     *  Returns the filesize. */
+    virtual size_t FileSize() const = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Flush the contents of the file buffer (for writers)
+     *  See fflush() for more details.
+     */
+    virtual void Flush() = 0;
+}; //! class IOStream
+
+// ----------------------------------------------------------------------------------
+inline IOStream::IOStream()
+{
+    // empty
+}
+
+// ----------------------------------------------------------------------------------
+inline IOStream::~IOStream()
+{
+    // empty
+}
+// ----------------------------------------------------------------------------------
+} //!namespace Assimp
+
+#endif //!!AI_IOSTREAM_H_INC

+ 290 - 0
include/assimp/IOSystem.hpp

@@ -0,0 +1,290 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file IOSystem.hpp
+ *  @brief File system wrapper for C++. Inherit this class to supply
+ *  custom file handling logic to the Import library.
+*/
+
+#ifndef AI_IOSYSTEM_H_INC
+#define AI_IOSYSTEM_H_INC
+
+#ifndef __cplusplus
+#   error This header requires C++ to be used. aiFileIO.h is the \
+    corresponding C interface.
+#endif
+
+#include "types.h"
+
+#include <vector>
+
+namespace Assimp    {
+class IOStream;
+
+// ---------------------------------------------------------------------------
+/** @brief CPP-API: Interface to the file system.
+ *
+ *  Derive an own implementation from this interface to supply custom file handling
+ *  to the importer library. If you implement this interface, you also want to
+ *  supply a custom implementation for IOStream.
+ *
+ *  @see Importer::SetIOHandler() */
+class ASSIMP_API IOSystem
+#ifndef SWIG
+    : public Intern::AllocateFromAssimpHeap
+#endif
+{
+public:
+
+    // -------------------------------------------------------------------
+    /** @brief Default constructor.
+     *
+     *  Create an instance of your derived class and assign it to an
+     *  #Assimp::Importer instance by calling Importer::SetIOHandler().
+     */
+    IOSystem();
+
+    // -------------------------------------------------------------------
+    /** @brief Virtual destructor.
+     *
+     *  It is safe to be called from within DLL Assimp, we're constructed
+     *  on Assimp's heap.
+     */
+    virtual ~IOSystem();
+
+
+public:
+
+    // -------------------------------------------------------------------
+    /** @brief For backward compatibility
+     *  @see Exists(const char*)
+     */
+    AI_FORCE_INLINE bool Exists( const std::string& pFile) const;
+
+    // -------------------------------------------------------------------
+    /** @brief Tests for the existence of a file at the given path.
+     *
+     * @param pFile Path to the file
+     * @return true if there is a file with this path, else false.
+     */
+    virtual bool Exists( const char* pFile) const = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Returns the system specific directory separator
+     *  @return System specific directory separator
+     */
+    virtual char getOsSeparator() const = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Open a new file with a given path.
+     *
+     *  When the access to the file is finished, call Close() to release
+     *  all associated resources (or the virtual dtor of the IOStream).
+     *
+     *  @param pFile Path to the file
+     *  @param pMode Desired file I/O mode. Required are: "wb", "w", "wt",
+     *         "rb", "r", "rt".
+     *
+     *  @return New IOStream interface allowing the lib to access
+     *         the underlying file.
+     *  @note When implementing this class to provide custom IO handling,
+     *  you probably have to supply an own implementation of IOStream as well.
+     */
+    virtual IOStream* Open(const char* pFile,
+        const char* pMode = "rb") = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief For backward compatibility
+     *  @see Open(const char*, const char*)
+     */
+    inline IOStream* Open(const std::string& pFile,
+        const std::string& pMode = std::string("rb"));
+
+    // -------------------------------------------------------------------
+    /** @brief Closes the given file and releases all resources
+     *    associated with it.
+     *  @param pFile The file instance previously created by Open().
+     */
+    virtual void Close( IOStream* pFile) = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Compares two paths and check whether the point to
+     *         identical files.
+     *
+     * The dummy implementation of this virtual member performs a
+     * case-insensitive comparison of the given strings. The default IO
+     * system implementation uses OS mechanisms to convert relative into
+     * absolute paths, so the result can be trusted.
+     * @param one First file
+     * @param second Second file
+     * @return true if the paths point to the same file. The file needn't
+     *   be existing, however.
+     */
+    virtual bool ComparePaths (const char* one,
+        const char* second) const;
+
+    // -------------------------------------------------------------------
+    /** @brief For backward compatibility
+     *  @see ComparePaths(const char*, const char*)
+     */
+    inline bool ComparePaths (const std::string& one,
+        const std::string& second) const;
+
+    // -------------------------------------------------------------------
+    /** @brief Pushes a new directory onto the directory stack.
+     *  @param path Path to push onto the stack.
+     *  @return True, when push was successful, false if path is empty.
+     */
+    virtual bool PushDirectory( const std::string &path );
+
+    // -------------------------------------------------------------------
+    /** @brief Returns the top directory from the stack.
+     *  @return The directory on the top of the stack.
+     *          Returns empty when no directory was pushed to the stack.
+     */
+    virtual const std::string &CurrentDirectory() const;
+
+    // -------------------------------------------------------------------
+    /** @brief Returns the number of directories stored on the stack.
+     *  @return The number of directories of the stack.
+     */
+    virtual size_t StackSize() const;
+
+    // -------------------------------------------------------------------
+    /** @brief Pops the top directory from the stack.
+     *  @return True, when a directory was on the stack. False if no
+     *          directory was on the stack.
+     */
+    virtual bool PopDirectory();
+
+private:
+    std::vector<std::string> m_pathStack;
+};
+
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE IOSystem::IOSystem() :
+    m_pathStack()
+{
+    // empty
+}
+
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE IOSystem::~IOSystem()
+{
+    // empty
+}
+
+// ----------------------------------------------------------------------------
+// For compatibility, the interface of some functions taking a std::string was
+// changed to const char* to avoid crashes between binary incompatible STL
+// versions. This code her is inlined,  so it shouldn't cause any problems.
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE IOStream* IOSystem::Open(const std::string& pFile,
+    const std::string& pMode)
+{
+    // NOTE:
+    // For compatibility, interface was changed to const char* to
+    // avoid crashes between binary incompatible STL versions
+    return Open(pFile.c_str(),pMode.c_str());
+}
+
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE bool IOSystem::Exists( const std::string& pFile) const
+{
+    // NOTE:
+    // For compatibility, interface was changed to const char* to
+    // avoid crashes between binary incompatible STL versions
+    return Exists(pFile.c_str());
+}
+
+// ----------------------------------------------------------------------------
+inline bool IOSystem::ComparePaths (const std::string& one,
+    const std::string& second) const
+{
+    // NOTE:
+    // For compatibility, interface was changed to const char* to
+    // avoid crashes between binary incompatible STL versions
+    return ComparePaths(one.c_str(),second.c_str());
+}
+
+// ----------------------------------------------------------------------------
+inline bool IOSystem::PushDirectory( const std::string &path ) {
+    if ( path.empty() ) {
+        return false;
+    }
+
+    m_pathStack.push_back( path );
+
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+inline const std::string &IOSystem::CurrentDirectory() const {
+    if ( m_pathStack.empty() ) {
+        static const std::string Dummy("");
+        return Dummy;
+    }
+    return m_pathStack[ m_pathStack.size()-1 ];
+}
+
+// ----------------------------------------------------------------------------
+inline size_t IOSystem::StackSize() const {
+    return m_pathStack.size();
+}
+
+// ----------------------------------------------------------------------------
+inline bool IOSystem::PopDirectory() {
+    if ( m_pathStack.empty() ) {
+        return false;
+    }
+
+    m_pathStack.pop_back();
+
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+
+} //!ns Assimp
+
+#endif //AI_IOSYSTEM_H_INC

+ 654 - 0
include/assimp/Importer.hpp

@@ -0,0 +1,654 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  Importer.hpp
+ *  @brief Defines the C++-API to the Open Asset Import Library.
+ */
+#ifndef INCLUDED_AI_ASSIMP_HPP
+#define INCLUDED_AI_ASSIMP_HPP
+
+#ifndef __cplusplus
+#   error This header requires C++ to be used. Use assimp.h for plain C.
+#endif
+
+// Public ASSIMP data structures
+#include "types.h"
+#include "config.h"
+
+namespace Assimp    {
+    // =======================================================================
+    // Public interface to Assimp
+    class Importer;
+    class Exporter; // export.hpp
+    class IOStream;
+    class IOSystem;
+    class ProgressHandler;
+
+    // =======================================================================
+    // Plugin development
+    //
+    // Include the following headers for the declarations:
+    // BaseImporter.h
+    // BaseProcess.h
+    class BaseImporter;
+    class BaseProcess;
+    class SharedPostProcessInfo;
+    class BatchLoader;
+
+    // =======================================================================
+    // Holy stuff, only for members of the high council of the Jedi.
+    class ImporterPimpl;
+    class ExporterPimpl; // export.hpp
+} //! namespace Assimp
+
+#define AI_PROPERTY_WAS_NOT_EXISTING 0xffffffff
+
+struct aiScene;
+
+// importerdesc.h
+struct aiImporterDesc;
+
+/** @namespace Assimp Assimp's CPP-API and all internal APIs */
+namespace Assimp    {
+
+// ----------------------------------------------------------------------------------
+/** CPP-API: The Importer class forms an C++ interface to the functionality of the
+*   Open Asset Import Library.
+*
+* Create an object of this class and call ReadFile() to import a file.
+* If the import succeeds, the function returns a pointer to the imported data.
+* The data remains property of the object, it is intended to be accessed
+* read-only. The imported data will be destroyed along with the Importer
+* object. If the import fails, ReadFile() returns a NULL pointer. In this
+* case you can retrieve a human-readable error description be calling
+* GetErrorString(). You can call ReadFile() multiple times with a single Importer
+* instance. Actually, constructing Importer objects involves quite many
+* allocations and may take some time, so it's better to reuse them as often as
+* possible.
+*
+* If you need the Importer to do custom file handling to access the files,
+* implement IOSystem and IOStream and supply an instance of your custom
+* IOSystem implementation by calling SetIOHandler() before calling ReadFile().
+* If you do not assign a custion IO handler, a default handler using the
+* standard C++ IO logic will be used.
+*
+* @note One Importer instance is not thread-safe. If you use multiple
+* threads for loading, each thread should maintain its own Importer instance.
+*/
+class ASSIMP_API Importer   {
+
+public:
+
+    // -------------------------------------------------------------------
+    /** Constructor. Creates an empty importer object.
+     *
+     * Call ReadFile() to start the import process. The configuration
+     * property table is initially empty.
+     */
+    Importer();
+
+    // -------------------------------------------------------------------
+    /** Copy constructor.
+     *
+     * This copies the configuration properties of another Importer.
+     * If this Importer owns a scene it won't be copied.
+     * Call ReadFile() to start the import process.
+     */
+    Importer(const Importer& other);
+
+    // -------------------------------------------------------------------
+    /** Destructor. The object kept ownership of the imported data,
+     * which now will be destroyed along with the object.
+     */
+    ~Importer();
+
+
+    // -------------------------------------------------------------------
+    /** Registers a new loader.
+     *
+     * @param pImp Importer to be added. The Importer instance takes
+     *   ownership of the pointer, so it will be automatically deleted
+     *   with the Importer instance.
+     * @return AI_SUCCESS if the loader has been added. The registration
+     *   fails if there is already a loader for a specific file extension.
+     */
+    aiReturn RegisterLoader(BaseImporter* pImp);
+
+    // -------------------------------------------------------------------
+    /** Unregisters a loader.
+     *
+     * @param pImp Importer to be unregistered.
+     * @return AI_SUCCESS if the loader has been removed. The function
+     *   fails if the loader is currently in use (this could happen
+     *   if the #Importer instance is used by more than one thread) or
+     *   if it has not yet been registered.
+     */
+    aiReturn UnregisterLoader(BaseImporter* pImp);
+
+    // -------------------------------------------------------------------
+    /** Registers a new post-process step.
+     *
+     * At the moment, there's a small limitation: new post processing
+     * steps are added to end of the list, or in other words, executed
+     * last, after all built-in steps.
+     * @param pImp Post-process step to be added. The Importer instance
+     *   takes ownership of the pointer, so it will be automatically
+     *   deleted with the Importer instance.
+     * @return AI_SUCCESS if the step has been added correctly.
+     */
+    aiReturn RegisterPPStep(BaseProcess* pImp);
+
+    // -------------------------------------------------------------------
+    /** Unregisters a post-process step.
+     *
+     * @param pImp Step to be unregistered.
+     * @return AI_SUCCESS if the step has been removed. The function
+     *   fails if the step is currently in use (this could happen
+     *   if the #Importer instance is used by more than one thread) or
+     *   if it has not yet been registered.
+     */
+    aiReturn UnregisterPPStep(BaseProcess* pImp);
+
+
+    // -------------------------------------------------------------------
+    /** Set an integer configuration property.
+     * @param szName Name of the property. All supported properties
+     *   are defined in the aiConfig.g header (all constants share the
+     *   prefix AI_CONFIG_XXX and are simple strings).
+     * @param iValue New value of the property
+     * @return true if the property was set before. The new value replaces
+     *   the previous value in this case.
+     * @note Property of different types (float, int, string ..) are kept
+     *   on different stacks, so calling SetPropertyInteger() for a
+     *   floating-point property has no effect - the loader will call
+     *   GetPropertyFloat() to read the property, but it won't be there.
+     */
+    bool SetPropertyInteger(const char* szName, int iValue);
+
+    // -------------------------------------------------------------------
+    /** Set a boolean configuration property. Boolean properties
+     *  are stored on the integer stack internally so it's possible
+     *  to set them via #SetPropertyBool and query them with
+     *  #GetPropertyBool and vice versa.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyBool(const char* szName, bool value)    {
+        return SetPropertyInteger(szName,value);
+    }
+
+    // -------------------------------------------------------------------
+    /** Set a floating-point configuration property.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyFloat(const char* szName, float fValue);
+
+    // -------------------------------------------------------------------
+    /** Set a string configuration property.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyString(const char* szName, const std::string& sValue);
+
+    // -------------------------------------------------------------------
+    /** Set a matrix configuration property.
+     * @see SetPropertyInteger()
+     */
+    bool SetPropertyMatrix(const char* szName, const aiMatrix4x4& sValue);
+
+    // -------------------------------------------------------------------
+    /** Get a configuration property.
+     * @param szName Name of the property. All supported properties
+     *   are defined in the aiConfig.g header (all constants share the
+     *   prefix AI_CONFIG_XXX).
+     * @param iErrorReturn Value that is returned if the property
+     *   is not found.
+     * @return Current value of the property
+     * @note Property of different types (float, int, string ..) are kept
+     *   on different lists, so calling SetPropertyInteger() for a
+     *   floating-point property has no effect - the loader will call
+     *   GetPropertyFloat() to read the property, but it won't be there.
+     */
+    int GetPropertyInteger(const char* szName,
+        int iErrorReturn = 0xffffffff) const;
+
+    // -------------------------------------------------------------------
+    /** Get a boolean configuration property. Boolean properties
+     *  are stored on the integer stack internally so it's possible
+     *  to set them via #SetPropertyBool and query them with
+     *  #GetPropertyBool and vice versa.
+     * @see GetPropertyInteger()
+     */
+    bool GetPropertyBool(const char* szName, bool bErrorReturn = false) const {
+        return GetPropertyInteger(szName,bErrorReturn)!=0;
+    }
+
+    // -------------------------------------------------------------------
+    /** Get a floating-point configuration property
+     * @see GetPropertyInteger()
+     */
+    float GetPropertyFloat(const char* szName,
+        float fErrorReturn = 10e10f) const;
+
+    // -------------------------------------------------------------------
+    /** Get a string configuration property
+     *
+     *  The return value remains valid until the property is modified.
+     * @see GetPropertyInteger()
+     */
+    const std::string GetPropertyString(const char* szName,
+        const std::string& sErrorReturn = "") const;
+
+    // -------------------------------------------------------------------
+    /** Get a matrix configuration property
+     *
+     *  The return value remains valid until the property is modified.
+     * @see GetPropertyInteger()
+     */
+    const aiMatrix4x4 GetPropertyMatrix(const char* szName,
+        const aiMatrix4x4& sErrorReturn = aiMatrix4x4()) const;
+
+    // -------------------------------------------------------------------
+    /** Supplies a custom IO handler to the importer to use to open and
+     * access files. If you need the importer to use custion IO logic to
+     * access the files, you need to provide a custom implementation of
+     * IOSystem and IOFile to the importer. Then create an instance of
+     * your custion IOSystem implementation and supply it by this function.
+     *
+     * The Importer takes ownership of the object and will destroy it
+     * afterwards. The previously assigned handler will be deleted.
+     * Pass NULL to take again ownership of your IOSystem and reset Assimp
+     * to use its default implementation.
+     *
+     * @param pIOHandler The IO handler to be used in all file accesses
+     *   of the Importer.
+     */
+    void SetIOHandler( IOSystem* pIOHandler);
+
+    // -------------------------------------------------------------------
+    /** Retrieves the IO handler that is currently set.
+     * You can use #IsDefaultIOHandler() to check whether the returned
+     * interface is the default IO handler provided by ASSIMP. The default
+     * handler is active as long the application doesn't supply its own
+     * custom IO handler via #SetIOHandler().
+     * @return A valid IOSystem interface, never NULL.
+     */
+    IOSystem* GetIOHandler() const;
+
+    // -------------------------------------------------------------------
+    /** Checks whether a default IO handler is active
+     * A default handler is active as long the application doesn't
+     * supply its own custom IO handler via #SetIOHandler().
+     * @return true by default
+     */
+    bool IsDefaultIOHandler() const;
+
+    // -------------------------------------------------------------------
+    /** Supplies a custom progress handler to the importer. This
+     *  interface exposes a #Update() callback, which is called
+     *  more or less periodically (please don't sue us if it
+     *  isn't as periodically as you'd like it to have ...).
+     *  This can be used to implement progress bars and loading
+     *  timeouts.
+     *  @param pHandler Progress callback interface. Pass NULL to
+     *    disable progress reporting.
+     *  @note Progress handlers can be used to abort the loading
+     *    at almost any time.*/
+    void SetProgressHandler ( ProgressHandler* pHandler );
+
+    // -------------------------------------------------------------------
+    /** Retrieves the progress handler that is currently set.
+     * You can use #IsDefaultProgressHandler() to check whether the returned
+     * interface is the default handler provided by ASSIMP. The default
+     * handler is active as long the application doesn't supply its own
+     * custom handler via #SetProgressHandler().
+     * @return A valid ProgressHandler interface, never NULL.
+     */
+    ProgressHandler* GetProgressHandler() const;
+
+    // -------------------------------------------------------------------
+    /** Checks whether a default progress handler is active
+     * A default handler is active as long the application doesn't
+     * supply its own custom progress handler via #SetProgressHandler().
+     * @return true by default
+     */
+    bool IsDefaultProgressHandler() const;
+
+    // -------------------------------------------------------------------
+    /** @brief Check whether a given set of postprocessing flags
+     *  is supported.
+     *
+     *  Some flags are mutually exclusive, others are probably
+     *  not available because your excluded them from your
+     *  Assimp builds. Calling this function is recommended if
+     *  you're unsure.
+     *
+     *  @param pFlags Bitwise combination of the aiPostProcess flags.
+     *  @return true if this flag combination is fine.
+     */
+    bool ValidateFlags(unsigned int pFlags) const;
+
+    // -------------------------------------------------------------------
+    /** Reads the given file and returns its contents if successful.
+     *
+     * If the call succeeds, the contents of the file are returned as a
+     * pointer to an aiScene object. The returned data is intended to be
+     * read-only, the importer object keeps ownership of the data and will
+     * destroy it upon destruction. If the import fails, NULL is returned.
+     * A human-readable error description can be retrieved by calling
+     * GetErrorString(). The previous scene will be deleted during this call.
+     * @param pFile Path and filename to the file to be imported.
+     * @param pFlags Optional post processing steps to be executed after
+     *   a successful import. Provide a bitwise combination of the
+     *   #aiPostProcessSteps flags. If you wish to inspect the imported
+     *   scene first in order to fine-tune your post-processing setup,
+     *   consider to use #ApplyPostProcessing().
+     * @return A pointer to the imported data, NULL if the import failed.
+     *   The pointer to the scene remains in possession of the Importer
+     *   instance. Use GetOrphanedScene() to take ownership of it.
+     *
+     * @note Assimp is able to determine the file format of a file
+     * automatically.
+     */
+    const aiScene* ReadFile(
+        const char* pFile,
+        unsigned int pFlags);
+
+    // -------------------------------------------------------------------
+    /** Reads the given file from a memory buffer and returns its
+     *  contents if successful.
+     *
+     * If the call succeeds, the contents of the file are returned as a
+     * pointer to an aiScene object. The returned data is intended to be
+     * read-only, the importer object keeps ownership of the data and will
+     * destroy it upon destruction. If the import fails, NULL is returned.
+     * A human-readable error description can be retrieved by calling
+     * GetErrorString(). The previous scene will be deleted during this call.
+     * Calling this method doesn't affect the active IOSystem.
+     * @param pBuffer Pointer to the file data
+     * @param pLength Length of pBuffer, in bytes
+     * @param pFlags Optional post processing steps to be executed after
+     *   a successful import. Provide a bitwise combination of the
+     *   #aiPostProcessSteps flags. If you wish to inspect the imported
+     *   scene first in order to fine-tune your post-processing setup,
+     *   consider to use #ApplyPostProcessing().
+     * @param pHint An additional hint to the library. If this is a non
+     *   empty string, the library looks for a loader to support
+     *   the file extension specified by pHint and passes the file to
+     *   the first matching loader. If this loader is unable to completely
+     *   the request, the library continues and tries to determine the
+     *   file format on its own, a task that may or may not be successful.
+     *   Check the return value, and you'll know ...
+     * @return A pointer to the imported data, NULL if the import failed.
+     *   The pointer to the scene remains in possession of the Importer
+     *   instance. Use GetOrphanedScene() to take ownership of it.
+     *
+     * @note This is a straightforward way to decode models from memory
+     * buffers, but it doesn't handle model formats that spread their
+     * data across multiple files or even directories. Examples include
+     * OBJ or MD3, which outsource parts of their material info into
+     * external scripts. If you need full functionality, provide
+     * a custom IOSystem to make Assimp find these files and use
+     * the regular ReadFile() API.
+     */
+    const aiScene* ReadFileFromMemory(
+        const void* pBuffer,
+        size_t pLength,
+        unsigned int pFlags,
+        const char* pHint = "");
+
+    // -------------------------------------------------------------------
+    /** Apply post-processing to an already-imported scene.
+     *
+     *  This is strictly equivalent to calling #ReadFile() with the same
+     *  flags. However, you can use this separate function to inspect
+     *  the imported scene first to fine-tune your post-processing setup.
+     *  @param pFlags Provide a bitwise combination of the
+     *   #aiPostProcessSteps flags.
+     *  @return A pointer to the post-processed data. This is still the
+     *   same as the pointer returned by #ReadFile(). However, if
+     *   post-processing fails, the scene could now be NULL.
+     *   That's quite a rare case, post processing steps are not really
+     *   designed to 'fail'. To be exact, the #aiProcess_ValidateDS
+     *   flag is currently the only post processing step which can actually
+     *   cause the scene to be reset to NULL.
+     *
+     *  @note The method does nothing if no scene is currently bound
+     *    to the #Importer instance.  */
+    const aiScene* ApplyPostProcessing(unsigned int pFlags);
+
+    // -------------------------------------------------------------------
+    /** @brief Reads the given file and returns its contents if successful.
+     *
+     * This function is provided for backward compatibility.
+     * See the const char* version for detailled docs.
+     * @see ReadFile(const char*, pFlags)  */
+    const aiScene* ReadFile(
+        const std::string& pFile,
+        unsigned int pFlags);
+
+    // -------------------------------------------------------------------
+    /** Frees the current scene.
+     *
+     *  The function does nothing if no scene has previously been
+     *  read via ReadFile(). FreeScene() is called automatically by the
+     *  destructor and ReadFile() itself.  */
+    void FreeScene( );
+
+    // -------------------------------------------------------------------
+    /** Returns an error description of an error that occurred in ReadFile().
+     *
+     * Returns an empty string if no error occurred.
+     * @return A description of the last error, an empty string if no
+     *   error occurred. The string is never NULL.
+     *
+     * @note The returned function remains valid until one of the
+     * following methods is called: #ReadFile(), #FreeScene(). */
+    const char* GetErrorString() const;
+
+    // -------------------------------------------------------------------
+    /** Returns the scene loaded by the last successful call to ReadFile()
+     *
+     * @return Current scene or NULL if there is currently no scene loaded */
+    const aiScene* GetScene() const;
+
+    // -------------------------------------------------------------------
+    /** Returns the scene loaded by the last successful call to ReadFile()
+     *  and releases the scene from the ownership of the Importer
+     *  instance. The application is now responsible for deleting the
+     *  scene. Any further calls to GetScene() or GetOrphanedScene()
+     *  will return NULL - until a new scene has been loaded via ReadFile().
+     *
+     * @return Current scene or NULL if there is currently no scene loaded
+     * @note Use this method with maximal caution, and only if you have to.
+     *   By design, aiScene's are exclusively maintained, allocated and
+     *   deallocated by Assimp and no one else. The reasoning behind this
+     *   is the golden rule that deallocations should always be done
+     *   by the module that did the original allocation because heaps
+     *   are not necessarily shared. GetOrphanedScene() enforces you
+     *   to delete the returned scene by yourself, but this will only
+     *   be fine if and only if you're using the same heap as assimp.
+     *   On Windows, it's typically fine provided everything is linked
+     *   against the multithreaded-dll version of the runtime library.
+     *   It will work as well for static linkage with Assimp.*/
+    aiScene* GetOrphanedScene();
+
+
+
+
+    // -------------------------------------------------------------------
+    /** Returns whether a given file extension is supported by ASSIMP.
+     *
+     * @param szExtension Extension to be checked.
+     *   Must include a trailing dot '.'. Example: ".3ds", ".md3".
+     *   Cases-insensitive.
+     * @return true if the extension is supported, false otherwise */
+    bool IsExtensionSupported(const char* szExtension) const;
+
+    // -------------------------------------------------------------------
+    /** @brief Returns whether a given file extension is supported by ASSIMP.
+     *
+     * This function is provided for backward compatibility.
+     * See the const char* version for detailed and up-to-date docs.
+     * @see IsExtensionSupported(const char*) */
+    inline bool IsExtensionSupported(const std::string& szExtension) const;
+
+    // -------------------------------------------------------------------
+    /** Get a full list of all file extensions supported by ASSIMP.
+     *
+     * If a file extension is contained in the list this does of course not
+     * mean that ASSIMP is able to load all files with this extension ---
+     * it simply means there is an importer loaded which claims to handle
+     * files with this file extension.
+     * @param szOut String to receive the extension list.
+     *   Format of the list: "*.3ds;*.obj;*.dae". This is useful for
+     *   use with the WinAPI call GetOpenFileName(Ex). */
+    void GetExtensionList(aiString& szOut) const;
+
+    // -------------------------------------------------------------------
+    /** @brief Get a full list of all file extensions supported by ASSIMP.
+     *
+     * This function is provided for backward compatibility.
+     * See the aiString version for detailed and up-to-date docs.
+     * @see GetExtensionList(aiString&)*/
+    inline void GetExtensionList(std::string& szOut) const;
+
+    // -------------------------------------------------------------------
+    /** Get the number of importrs currently registered with Assimp. */
+    size_t GetImporterCount() const;
+
+    // -------------------------------------------------------------------
+    /** Get meta data for the importer corresponding to a specific index..
+    *
+    *  For the declaration of #aiImporterDesc, include <assimp/importerdesc.h>.
+    *  @param index Index to query, must be within [0,GetImporterCount())
+    *  @return Importer meta data structure, NULL if the index does not
+    *     exist or if the importer doesn't offer meta information (
+    *     importers may do this at the cost of being hated by their peers).*/
+    const aiImporterDesc* GetImporterInfo(size_t index) const;
+
+    // -------------------------------------------------------------------
+    /** Find the importer corresponding to a specific index.
+    *
+    *  @param index Index to query, must be within [0,GetImporterCount())
+    *  @return Importer instance. NULL if the index does not
+    *     exist. */
+    BaseImporter* GetImporter(size_t index) const;
+
+    // -------------------------------------------------------------------
+    /** Find the importer corresponding to a specific file extension.
+    *
+    *  This is quite similar to #IsExtensionSupported except a
+    *  BaseImporter instance is returned.
+    *  @param szExtension Extension to check for. The following formats
+    *    are recognized (BAH being the file extension): "BAH" (comparison
+    *    is case-insensitive), ".bah", "*.bah" (wild card and dot
+    *    characters at the beginning of the extension are skipped).
+    *  @return NULL if no importer is found*/
+    BaseImporter* GetImporter (const char* szExtension) const;
+
+    // -------------------------------------------------------------------
+    /** Find the importer index corresponding to a specific file extension.
+    *
+    *  @param szExtension Extension to check for. The following formats
+    *    are recognized (BAH being the file extension): "BAH" (comparison
+    *    is case-insensitive), ".bah", "*.bah" (wild card and dot
+    *    characters at the beginning of the extension are skipped).
+    *  @return (size_t)-1 if no importer is found */
+    size_t GetImporterIndex (const char* szExtension) const;
+
+
+
+
+    // -------------------------------------------------------------------
+    /** Returns the storage allocated by ASSIMP to hold the scene data
+     * in memory.
+     *
+     * This refers to the currently loaded file, see #ReadFile().
+     * @param in Data structure to be filled.
+     * @note The returned memory statistics refer to the actual
+     *   size of the use data of the aiScene. Heap-related overhead
+     *   is (naturally) not included.*/
+    void GetMemoryRequirements(aiMemoryInfo& in) const;
+
+    // -------------------------------------------------------------------
+    /** Enables "extra verbose" mode.
+     *
+     * 'Extra verbose' means the data structure is validated after *every*
+     * single post processing step to make sure everyone modifies the data
+     * structure in a well-defined manner. This is a debug feature and not
+     * intended for use in production environments. */
+    void SetExtraVerbose(bool bDo);
+
+
+    // -------------------------------------------------------------------
+    /** Private, do not use. */
+    ImporterPimpl* Pimpl() { return pimpl; }
+    const ImporterPimpl* Pimpl() const { return pimpl; }
+
+protected:
+
+    // Just because we don't want you to know how we're hacking around.
+    ImporterPimpl* pimpl;
+}; //! class Importer
+
+
+// ----------------------------------------------------------------------------
+// For compatibility, the interface of some functions taking a std::string was
+// changed to const char* to avoid crashes between binary incompatible STL
+// versions. This code her is inlined,  so it shouldn't cause any problems.
+// ----------------------------------------------------------------------------
+
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE const aiScene* Importer::ReadFile( const std::string& pFile,unsigned int pFlags){
+    return ReadFile(pFile.c_str(),pFlags);
+}
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE void Importer::GetExtensionList(std::string& szOut) const   {
+    aiString s;
+    GetExtensionList(s);
+    szOut = s.data;
+}
+// ----------------------------------------------------------------------------
+AI_FORCE_INLINE bool Importer::IsExtensionSupported(const std::string& szExtension) const   {
+    return IsExtensionSupported(szExtension.c_str());
+}
+
+} // !namespace Assimp
+#endif // INCLUDED_AI_ASSIMP_HPP

+ 96 - 0
include/assimp/LogStream.hpp

@@ -0,0 +1,96 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file LogStream.hpp
+ *  @brief Abstract base class 'LogStream', representing an output log stream.
+ */
+#ifndef INCLUDED_AI_LOGSTREAM_H
+#define INCLUDED_AI_LOGSTREAM_H
+#include "types.h"
+namespace Assimp    {
+class IOSystem;
+
+// ------------------------------------------------------------------------------------
+/** @brief CPP-API: Abstract interface for log stream implementations.
+ *
+ *  Several default implementations are provided, see #aiDefaultLogStream for more
+ *  details. Writing your own implementation of LogStream is just necessary if these
+ *  are not enough for your purpose. */
+class ASSIMP_API LogStream
+#ifndef SWIG
+    : public Intern::AllocateFromAssimpHeap
+#endif
+{
+protected:
+    /** @brief  Default constructor */
+    LogStream() {
+    }
+public:
+    /** @brief  Virtual destructor  */
+    virtual ~LogStream() {
+    }
+
+    // -------------------------------------------------------------------
+    /** @brief  Overwrite this for your own output methods
+     *
+     *  Log messages *may* consist of multiple lines and you shouldn't
+     *  expect a consistent formatting. If you want custom formatting
+     *  (e.g. generate HTML), supply a custom instance of Logger to
+     *  #DefaultLogger:set(). Usually you can *expect* that a log message
+     *  is exactly one line and terminated with a single \n character.
+     *  @param message Message to be written */
+    virtual void write(const char* message) = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Creates a default log stream
+     *  @param streams Type of the default stream
+     *  @param name For aiDefaultLogStream_FILE: name of the output file
+     *  @param io For aiDefaultLogStream_FILE: IOSystem to be used to open the output
+     *   file. Pass NULL for the default implementation.
+     *  @return New LogStream instance.  */
+    static LogStream* createDefaultStream(aiDefaultLogStream stream,
+        const char* name = "AssimpLog.txt",
+        IOSystem* io = NULL);
+
+}; // !class LogStream
+// ------------------------------------------------------------------------------------
+} // Namespace Assimp
+
+#endif

+ 265 - 0
include/assimp/Logger.hpp

@@ -0,0 +1,265 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file Logger.hpp
+ *  @brief Abstract base class 'Logger', base of the logging system.
+ */
+#ifndef INCLUDED_AI_LOGGER_H
+#define INCLUDED_AI_LOGGER_H
+
+#include "types.h"
+namespace Assimp    {
+class LogStream;
+
+// Maximum length of a log message. Longer messages are rejected.
+#define MAX_LOG_MESSAGE_LENGTH 1024u
+
+// ----------------------------------------------------------------------------------
+/** @brief CPP-API: Abstract interface for logger implementations.
+ *  Assimp provides a default implementation and uses it for almost all
+ *  logging stuff ('DefaultLogger'). This class defines just basic logging
+ *  behaviour and is not of interest for you. Instead, take a look at #DefaultLogger. */
+class ASSIMP_API Logger
+#ifndef SWIG
+    : public Intern::AllocateFromAssimpHeap
+#endif
+{
+public:
+
+    // ----------------------------------------------------------------------
+    /** @enum   LogSeverity
+     *  @brief  Log severity to describe the granularity of logging.
+     */
+    enum LogSeverity
+    {
+        NORMAL,     //!< Normal granularity of logging
+        VERBOSE     //!< Debug infos will be logged, too
+    };
+
+    // ----------------------------------------------------------------------
+    /** @enum   ErrorSeverity
+     *  @brief  Description for severity of a log message.
+     *
+     *  Every LogStream has a bitwise combination of these flags.
+     *  A LogStream doesn't receive any messages of a specific type
+     *  if it doesn't specify the corresponding ErrorSeverity flag.
+     */
+    enum ErrorSeverity
+    {
+        Debugging   = 1,    //!< Debug log message
+        Info        = 2,    //!< Info log message
+        Warn        = 4,    //!< Warn log message
+        Err         = 8     //!< Error log message
+    };
+
+public:
+
+    /** @brief  Virtual destructor */
+    virtual ~Logger();
+
+    // ----------------------------------------------------------------------
+    /** @brief  Writes a debug message
+     *   @param message Debug message*/
+    void debug(const char* message);
+    inline void debug(const std::string &message);
+
+    // ----------------------------------------------------------------------
+    /** @brief  Writes a info message
+     *  @param  message Info message*/
+    void info(const char* message);
+    inline void info(const std::string &message);
+
+    // ----------------------------------------------------------------------
+    /** @brief  Writes a warning message
+     *  @param  message Warn message*/
+    void warn(const char* message);
+    inline void warn(const std::string &message);
+
+    // ----------------------------------------------------------------------
+    /** @brief  Writes an error message
+     *  @param  message Error message*/
+    void error(const char* message);
+    inline void error(const std::string &message);
+
+    // ----------------------------------------------------------------------
+    /** @brief  Set a new log severity.
+     *  @param  log_severity New severity for logging*/
+    void setLogSeverity(LogSeverity log_severity);
+
+    // ----------------------------------------------------------------------
+    /** @brief Get the current log severity*/
+    LogSeverity getLogSeverity() const;
+
+    // ----------------------------------------------------------------------
+    /** @brief  Attach a new log-stream
+     *
+     *  The logger takes ownership of the stream and is responsible
+     *  for its destruction (which is done using ::delete when the logger
+     *  itself is destroyed). Call detachStream to detach a stream and to
+     *  gain ownership of it again.
+     *   @param pStream  Log-stream to attach
+     *  @param severity  Message filter, specified which types of log
+     *    messages are dispatched to the stream. Provide a bitwise
+     *    combination of the ErrorSeverity flags.
+     *  @return true if the stream has been attached, false otherwise.*/
+    virtual bool attachStream(LogStream *pStream,
+        unsigned int severity = Debugging | Err | Warn | Info) = 0;
+
+    // ----------------------------------------------------------------------
+    /** @brief  Detach a still attached stream from the logger (or
+     *          modify the filter flags bits)
+     *   @param pStream Log-stream instance for detaching
+     *  @param severity Provide a bitwise combination of the ErrorSeverity
+     *    flags. This value is &~ed with the current flags of the stream,
+     *    if the result is 0 the stream is detached from the Logger and
+     *    the caller retakes the possession of the stream.
+     *  @return true if the stream has been detached, false otherwise.*/
+    virtual bool detatchStream(LogStream *pStream,
+        unsigned int severity = Debugging | Err | Warn | Info) = 0;
+
+protected:
+
+    /** Default constructor */
+    Logger();
+
+    /** Construction with a given log severity */
+    explicit Logger(LogSeverity severity);
+
+    // ----------------------------------------------------------------------
+    /** @brief Called as a request to write a specific debug message
+     *  @param  message Debug message. Never longer than
+     *    MAX_LOG_MESSAGE_LENGTH characters (excluding the '0').
+     *  @note  The message string is only valid until the scope of
+     *    the function is left.
+     */
+    virtual void OnDebug(const char* message)= 0;
+
+    // ----------------------------------------------------------------------
+    /** @brief Called as a request to write a specific info message
+     *  @param  message Info message. Never longer than
+     *    MAX_LOG_MESSAGE_LENGTH characters (ecxluding the '0').
+     *  @note  The message string is only valid until the scope of
+     *    the function is left.
+     */
+    virtual void OnInfo(const char* message) = 0;
+
+    // ----------------------------------------------------------------------
+    /** @brief Called as a request to write a specific warn message
+     *  @param  message Warn message. Never longer than
+     *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
+     *  @note  The message string is only valid until the scope of
+     *    the function is left.
+     */
+    virtual void OnWarn(const char* essage) = 0;
+
+    // ----------------------------------------------------------------------
+    /** @brief Called as a request to write a specific error message
+     *  @param  message Error message. Never longer than
+     *    MAX_LOG_MESSAGE_LENGTH characters (exluding the '0').
+     *  @note  The message string is only valid until the scope of
+     *    the function is left.
+     */
+    virtual void OnError(const char* message) = 0;
+
+protected:
+
+    //! Logger severity
+    LogSeverity m_Severity;
+};
+
+// ----------------------------------------------------------------------------------
+//  Default constructor
+inline Logger::Logger() {
+    setLogSeverity(NORMAL);
+}
+
+// ----------------------------------------------------------------------------------
+//  Virtual destructor
+inline  Logger::~Logger()
+{
+}
+
+// ----------------------------------------------------------------------------------
+// Construction with given logging severity
+inline Logger::Logger(LogSeverity severity) {
+    setLogSeverity(severity);
+}
+
+// ----------------------------------------------------------------------------------
+// Log severity setter
+inline void Logger::setLogSeverity(LogSeverity log_severity){
+    m_Severity = log_severity;
+}
+
+// ----------------------------------------------------------------------------------
+// Log severity getter
+inline Logger::LogSeverity Logger::getLogSeverity() const {
+    return m_Severity;
+}
+
+// ----------------------------------------------------------------------------------
+inline void Logger::debug(const std::string &message)
+{
+    return debug(message.c_str());
+}
+
+// ----------------------------------------------------------------------------------
+inline void Logger::error(const std::string &message)
+{
+    return error(message.c_str());
+}
+
+// ----------------------------------------------------------------------------------
+inline void Logger::warn(const std::string &message)
+{
+    return warn(message.c_str());
+}
+
+// ----------------------------------------------------------------------------------
+inline void Logger::info(const std::string &message)
+{
+    return info(message.c_str());
+}
+
+// ----------------------------------------------------------------------------------
+
+} // Namespace Assimp
+
+#endif // !! INCLUDED_AI_LOGGER_H

+ 95 - 0
include/assimp/NullLogger.hpp

@@ -0,0 +1,95 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file  NullLogger.hpp
+ *  @brief Dummy logger
+*/
+
+#ifndef INCLUDED_AI_NULLLOGGER_H
+#define INCLUDED_AI_NULLLOGGER_H
+
+#include "Logger.hpp"
+namespace Assimp    {
+// ---------------------------------------------------------------------------
+/** @brief CPP-API: Empty logging implementation.
+ *
+ * Does nothing! Used by default if the application hasn't requested a
+ * custom logger via #DefaultLogger::set() or #DefaultLogger::create(); */
+class ASSIMP_API NullLogger
+    : public Logger {
+
+public:
+
+    /** @brief  Logs a debug message */
+    void OnDebug(const char* message) {
+        (void)message; //this avoids compiler warnings
+    }
+
+    /** @brief  Logs an info message */
+    void OnInfo(const char* message) {
+        (void)message; //this avoids compiler warnings
+    }
+
+    /** @brief  Logs a warning message */
+    void OnWarn(const char* message) {
+        (void)message; //this avoids compiler warnings
+    }
+
+    /** @brief  Logs an error message */
+    void OnError(const char* message) {
+        (void)message; //this avoids compiler warnings
+    }
+
+    /** @brief  Detach a still attached stream from logger */
+    bool attachStream(LogStream *pStream, unsigned int severity) {
+        (void)pStream; (void)severity; //this avoids compiler warnings
+        return false;
+    }
+
+    /** @brief  Detach a still attached stream from logger */
+    bool detatchStream(LogStream *pStream, unsigned int severity) {
+        (void)pStream; (void)severity; //this avoids compiler warnings
+        return false;
+    }
+
+private:
+};
+}
+#endif // !! AI_NULLLOGGER_H_INCLUDED

+ 122 - 0
include/assimp/ProgressHandler.hpp

@@ -0,0 +1,122 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file ProgressHandler.hpp
+ *  @brief Abstract base class 'ProgressHandler'.
+ */
+#ifndef INCLUDED_AI_PROGRESSHANDLER_H
+#define INCLUDED_AI_PROGRESSHANDLER_H
+#include "types.h"
+namespace Assimp    {
+
+// ------------------------------------------------------------------------------------
+/** @brief CPP-API: Abstract interface for custom progress report receivers.
+ *
+ *  Each #Importer instance maintains its own #ProgressHandler. The default
+ *  implementation provided by Assimp doesn't do anything at all. */
+class ASSIMP_API ProgressHandler
+#ifndef SWIG
+    : public Intern::AllocateFromAssimpHeap
+#endif
+{
+protected:
+    /** @brief  Default constructor */
+    ProgressHandler () {
+    }
+public:
+    /** @brief  Virtual destructor  */
+    virtual ~ProgressHandler () {
+    }
+
+    // -------------------------------------------------------------------
+    /** @brief Progress callback.
+     *  @param percentage An estimate of the current loading progress,
+     *    in percent. Or -1.f if such an estimate is not available.
+     *
+     *  There are restriction on what you may do from within your
+     *  implementation of this method: no exceptions may be thrown and no
+     *  non-const #Importer methods may be called. It is
+     *  not generally possible to predict the number of callbacks
+     *  fired during a single import.
+     *
+     *  @return Return false to abort loading at the next possible
+     *   occasion (loaders and Assimp are generally allowed to perform
+     *   all needed cleanup tasks prior to returning control to the
+     *   caller). If the loading is aborted, #Importer::ReadFile()
+     *   returns always NULL.
+     *   */
+    virtual bool Update(float percentage = -1.f) = 0;
+
+    // -------------------------------------------------------------------
+    /** @brief Progress callback for file loading steps
+     *  @param numberOfSteps The number of total post-processing
+     *   steps
+     *  @param currentStep The index of the current post-processing
+     *   step that will run, or equal to numberOfSteps if all of
+     *   them has finished. This number is always strictly monotone
+     *   increasing, although not necessarily linearly.
+     *
+     *  @note This is currently only used at the start and the end
+     *   of the file parsing.
+     *   */
+    virtual void UpdateFileRead(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
+        float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
+        Update( f * 0.5f );
+    }
+
+    // -------------------------------------------------------------------
+    /** @brief Progress callback for post-processing steps
+     *  @param numberOfSteps The number of total post-processing
+     *   steps
+     *  @param currentStep The index of the current post-processing
+     *   step that will run, or equal to numberOfSteps if all of
+     *   them has finished. This number is always strictly monotone
+     *   increasing, although not necessarily linearly.
+     *   */
+    virtual void UpdatePostProcess(int currentStep /*= 0*/, int numberOfSteps /*= 0*/) {
+        float f = numberOfSteps ? currentStep / (float)numberOfSteps : 1.0f;
+        Update( f * 0.5f + 0.5f );
+    }
+
+}; // !class ProgressHandler
+// ------------------------------------------------------------------------------------
+} // Namespace Assimp
+
+#endif

+ 14 - 0
include/assimp/ai_assert.h

@@ -0,0 +1,14 @@
+/** @file ai_assert.h
+ */
+#ifndef AI_DEBUG_H_INC
+#define AI_DEBUG_H_INC
+
+#ifdef ASSIMP_BUILD_DEBUG
+#   include <assert.h>
+#   define  ai_assert(expression) assert(expression)
+#else
+#   define  ai_assert(expression)
+#endif
+
+
+#endif

+ 484 - 0
include/assimp/anim.h

@@ -0,0 +1,484 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file anim.h
+ *  @brief Defines the data structures in which the imported animations
+ *  are returned.
+ */
+#ifndef AI_ANIM_H_INC
+#define AI_ANIM_H_INC
+
+#include "types.h"
+#include "quaternion.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+/** A time-value pair specifying a certain 3D vector for the given time. */
+struct aiVectorKey
+{
+    /** The time of this key */
+    double mTime;
+
+    /** The value of this key */
+    C_STRUCT aiVector3D mValue;
+
+#ifdef __cplusplus
+
+    //! Default constructor
+    aiVectorKey(){}
+
+    //! Construction from a given time and key value
+    aiVectorKey(double time, const aiVector3D& value)
+        :   mTime   (time)
+        ,   mValue  (value)
+    {}
+
+
+    typedef aiVector3D elem_type;
+
+    // Comparison operators. For use with std::find();
+    bool operator == (const aiVectorKey& o) const {
+        return o.mValue == this->mValue;
+    }
+    bool operator != (const aiVectorKey& o) const {
+        return o.mValue != this->mValue;
+    }
+
+    // Relational operators. For use with std::sort();
+    bool operator < (const aiVectorKey& o) const {
+        return mTime < o.mTime;
+    }
+    bool operator > (const aiVectorKey& o) const {
+        return mTime > o.mTime;
+    }
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** A time-value pair specifying a rotation for the given time.
+ *  Rotations are expressed with quaternions. */
+struct aiQuatKey
+{
+    /** The time of this key */
+    double mTime;
+
+    /** The value of this key */
+    C_STRUCT aiQuaternion mValue;
+
+#ifdef __cplusplus
+    aiQuatKey(){
+    }
+
+    /** Construction from a given time and key value */
+    aiQuatKey(double time, const aiQuaternion& value)
+        :   mTime   (time)
+        ,   mValue  (value)
+    {}
+
+    typedef aiQuaternion elem_type;
+
+    // Comparison operators. For use with std::find();
+    bool operator == (const aiQuatKey& o) const {
+        return o.mValue == this->mValue;
+    }
+    bool operator != (const aiQuatKey& o) const {
+        return o.mValue != this->mValue;
+    }
+
+    // Relational operators. For use with std::sort();
+    bool operator < (const aiQuatKey& o) const {
+        return mTime < o.mTime;
+    }
+    bool operator > (const aiQuatKey& o) const {
+        return mTime > o.mTime;
+    }
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** Binds a anim mesh to a specific point in time. */
+struct aiMeshKey
+{
+    /** The time of this key */
+    double mTime;
+
+    /** Index into the aiMesh::mAnimMeshes array of the
+     *  mesh coresponding to the #aiMeshAnim hosting this
+     *  key frame. The referenced anim mesh is evaluated
+     *  according to the rules defined in the docs for #aiAnimMesh.*/
+    unsigned int mValue;
+
+#ifdef __cplusplus
+
+    aiMeshKey() {
+    }
+
+    /** Construction from a given time and key value */
+    aiMeshKey(double time, const unsigned int value)
+        :   mTime   (time)
+        ,   mValue  (value)
+    {}
+
+    typedef unsigned int elem_type;
+
+    // Comparison operators. For use with std::find();
+    bool operator == (const aiMeshKey& o) const {
+        return o.mValue == this->mValue;
+    }
+    bool operator != (const aiMeshKey& o) const {
+        return o.mValue != this->mValue;
+    }
+
+    // Relational operators. For use with std::sort();
+    bool operator < (const aiMeshKey& o) const {
+        return mTime < o.mTime;
+    }
+    bool operator > (const aiMeshKey& o) const {
+        return mTime > o.mTime;
+    }
+
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** Defines how an animation channel behaves outside the defined time
+ *  range. This corresponds to aiNodeAnim::mPreState and
+ *  aiNodeAnim::mPostState.*/
+enum aiAnimBehaviour
+{
+    /** The value from the default node transformation is taken*/
+    aiAnimBehaviour_DEFAULT  = 0x0,
+
+    /** The nearest key value is used without interpolation */
+    aiAnimBehaviour_CONSTANT = 0x1,
+
+    /** The value of the nearest two keys is linearly
+     *  extrapolated for the current time value.*/
+    aiAnimBehaviour_LINEAR   = 0x2,
+
+    /** The animation is repeated.
+     *
+     *  If the animation key go from n to m and the current
+     *  time is t, use the value at (t-n) % (|m-n|).*/
+    aiAnimBehaviour_REPEAT   = 0x3,
+
+
+
+    /** This value is not used, it is just here to force the
+     *  the compiler to map this enum to a 32 Bit integer  */
+#ifndef SWIG
+    _aiAnimBehaviour_Force32Bit = INT_MAX
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** Describes the animation of a single node. The name specifies the
+ *  bone/node which is affected by this animation channel. The keyframes
+ *  are given in three separate series of values, one each for position,
+ *  rotation and scaling. The transformation matrix computed from these
+ *  values replaces the node's original transformation matrix at a
+ *  specific time.
+ *  This means all keys are absolute and not relative to the bone default pose.
+ *  The order in which the transformations are applied is
+ *  - as usual - scaling, rotation, translation.
+ *
+ *  @note All keys are returned in their correct, chronological order.
+ *  Duplicate keys don't pass the validation step. Most likely there
+ *  will be no negative time values, but they are not forbidden also ( so
+ *  implementations need to cope with them! ) */
+struct aiNodeAnim
+{
+    /** The name of the node affected by this animation. The node
+     *  must exist and it must be unique.*/
+    C_STRUCT aiString mNodeName;
+
+    /** The number of position keys */
+    unsigned int mNumPositionKeys;
+
+    /** The position keys of this animation channel. Positions are
+     * specified as 3D vector. The array is mNumPositionKeys in size.
+     *
+     * If there are position keys, there will also be at least one
+     * scaling and one rotation key.*/
+    C_STRUCT aiVectorKey* mPositionKeys;
+
+    /** The number of rotation keys */
+    unsigned int mNumRotationKeys;
+
+    /** The rotation keys of this animation channel. Rotations are
+     *  given as quaternions,  which are 4D vectors. The array is
+     *  mNumRotationKeys in size.
+     *
+     * If there are rotation keys, there will also be at least one
+     * scaling and one position key. */
+    C_STRUCT aiQuatKey* mRotationKeys;
+
+
+    /** The number of scaling keys */
+    unsigned int mNumScalingKeys;
+
+    /** The scaling keys of this animation channel. Scalings are
+     *  specified as 3D vector. The array is mNumScalingKeys in size.
+     *
+     * If there are scaling keys, there will also be at least one
+     * position and one rotation key.*/
+    C_STRUCT aiVectorKey* mScalingKeys;
+
+
+    /** Defines how the animation behaves before the first
+     *  key is encountered.
+     *
+     *  The default value is aiAnimBehaviour_DEFAULT (the original
+     *  transformation matrix of the affected node is used).*/
+    C_ENUM aiAnimBehaviour mPreState;
+
+    /** Defines how the animation behaves after the last
+     *  key was processed.
+     *
+     *  The default value is aiAnimBehaviour_DEFAULT (the original
+     *  transformation matrix of the affected node is taken).*/
+    C_ENUM aiAnimBehaviour mPostState;
+
+#ifdef __cplusplus
+    aiNodeAnim()
+    {
+        mNumPositionKeys = 0; mPositionKeys = NULL;
+        mNumRotationKeys = 0; mRotationKeys = NULL;
+        mNumScalingKeys  = 0; mScalingKeys  = NULL;
+
+        mPreState = mPostState = aiAnimBehaviour_DEFAULT;
+    }
+
+    ~aiNodeAnim()
+    {
+        delete [] mPositionKeys;
+        delete [] mRotationKeys;
+        delete [] mScalingKeys;
+    }
+#endif // __cplusplus
+};
+
+// ---------------------------------------------------------------------------
+/** Describes vertex-based animations for a single mesh or a group of
+ *  meshes. Meshes carry the animation data for each frame in their
+ *  aiMesh::mAnimMeshes array. The purpose of aiMeshAnim is to
+ *  define keyframes linking each mesh attachment to a particular
+ *  point in time. */
+struct aiMeshAnim
+{
+    /** Name of the mesh to be animated. An empty string is not allowed,
+     *  animated meshes need to be named (not necessarily uniquely,
+     *  the name can basically serve as wildcard to select a group
+     *  of meshes with similar animation setup)*/
+    C_STRUCT aiString mName;
+
+    /** Size of the #mKeys array. Must be 1, at least. */
+    unsigned int mNumKeys;
+
+    /** Key frames of the animation. May not be NULL. */
+    C_STRUCT aiMeshKey* mKeys;
+
+#ifdef __cplusplus
+
+    aiMeshAnim()
+        : mNumKeys()
+        , mKeys()
+    {}
+
+    ~aiMeshAnim()
+    {
+        delete[] mKeys;
+    }
+
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** An animation consists of keyframe data for a number of nodes. For
+ *  each node affected by the animation a separate series of data is given.*/
+struct aiAnimation
+{
+    /** The name of the animation. If the modeling package this data was
+     *  exported from does support only a single animation channel, this
+     *  name is usually empty (length is zero). */
+    C_STRUCT aiString mName;
+
+    /** Duration of the animation in ticks.  */
+    double mDuration;
+
+    /** Ticks per second. 0 if not specified in the imported file */
+    double mTicksPerSecond;
+
+    /** The number of bone animation channels. Each channel affects
+     *  a single node. */
+    unsigned int mNumChannels;
+
+    /** The node animation channels. Each channel affects a single node.
+     *  The array is mNumChannels in size. */
+    C_STRUCT aiNodeAnim** mChannels;
+
+
+    /** The number of mesh animation channels. Each channel affects
+     *  a single mesh and defines vertex-based animation. */
+    unsigned int mNumMeshChannels;
+
+    /** The mesh animation channels. Each channel affects a single mesh.
+     *  The array is mNumMeshChannels in size. */
+    C_STRUCT aiMeshAnim** mMeshChannels;
+
+#ifdef __cplusplus
+    aiAnimation()
+        : mDuration(-1.)
+        , mTicksPerSecond()
+        , mNumChannels()
+        , mChannels()
+        , mNumMeshChannels()
+        , mMeshChannels()
+    {
+    }
+
+    ~aiAnimation()
+    {
+        // DO NOT REMOVE THIS ADDITIONAL CHECK
+        if (mNumChannels && mChannels)  {
+            for( unsigned int a = 0; a < mNumChannels; a++) {
+                delete mChannels[a];
+            }
+
+        delete [] mChannels;
+        }
+        if (mNumMeshChannels && mMeshChannels)  {
+            for( unsigned int a = 0; a < mNumMeshChannels; a++) {
+                delete mMeshChannels[a];
+            }
+
+        delete [] mMeshChannels;
+        }
+    }
+#endif // __cplusplus
+};
+
+#ifdef __cplusplus
+}
+
+
+// some C++ utilities for inter- and extrapolation
+namespace Assimp {
+
+// ---------------------------------------------------------------------------
+/** @brief CPP-API: Utility class to simplify interpolations of various data types.
+ *
+ *  The type of interpolation is choosen automatically depending on the
+ *  types of the arguments. */
+template <typename T>
+struct Interpolator
+{
+    // ------------------------------------------------------------------
+    /** @brief Get the result of the interpolation between a,b.
+     *
+     *  The interpolation algorithm depends on the type of the operands.
+     *  aiQuaternion's and aiQuatKey's SLERP, the rest does a simple
+     *  linear interpolation. */
+    void operator () (T& out,const T& a, const T& b, float d) const {
+        out = a + (b-a)*d;
+    }
+}; // ! Interpolator <T>
+
+//! @cond Never
+
+template <>
+struct Interpolator <aiQuaternion>  {
+    void operator () (aiQuaternion& out,const aiQuaternion& a,
+        const aiQuaternion& b, float d) const
+    {
+        aiQuaternion::Interpolate(out,a,b,d);
+    }
+}; // ! Interpolator <aiQuaternion>
+
+template <>
+struct Interpolator <unsigned int>  {
+    void operator () (unsigned int& out,unsigned int a,
+        unsigned int b, float d) const
+    {
+        out = d>0.5f ? b : a;
+    }
+}; // ! Interpolator <aiQuaternion>
+
+template <>
+struct Interpolator  <aiVectorKey>  {
+    void operator () (aiVector3D& out,const aiVectorKey& a,
+        const aiVectorKey& b, float d) const
+    {
+        Interpolator<aiVector3D> ipl;
+        ipl(out,a.mValue,b.mValue,d);
+    }
+}; // ! Interpolator <aiVectorKey>
+
+template <>
+struct Interpolator <aiQuatKey>     {
+    void operator () (aiQuaternion& out, const aiQuatKey& a,
+        const aiQuatKey& b, float d) const
+    {
+        Interpolator<aiQuaternion> ipl;
+        ipl(out,a.mValue,b.mValue,d);
+    }
+}; // ! Interpolator <aiQuatKey>
+
+template <>
+struct Interpolator <aiMeshKey>     {
+    void operator () (unsigned int& out, const aiMeshKey& a,
+        const aiMeshKey& b, float d) const
+    {
+        Interpolator<unsigned int> ipl;
+        ipl(out,a.mValue,b.mValue,d);
+    }
+}; // ! Interpolator <aiQuatKey>
+
+//! @endcond
+} //  ! end namespace Assimp
+
+
+
+#endif // __cplusplus
+#endif // AI_ANIM_H_INC

+ 223 - 0
include/assimp/camera.h

@@ -0,0 +1,223 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file camera.h
+ *  @brief Defines the aiCamera data structure
+ */
+
+#ifndef AI_CAMERA_H_INC
+#define AI_CAMERA_H_INC
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+/** Helper structure to describe a virtual camera.
+ *
+ * Cameras have a representation in the node graph and can be animated.
+ * An important aspect is that the camera itself is also part of the
+ * scenegraph. This means, any values such as the look-at vector are not
+ * *absolute*, they're <b>relative</b> to the coordinate system defined
+ * by the node which corresponds to the camera. This allows for camera
+ * animations. For static cameras parameters like the 'look-at' or 'up' vectors
+ * are usually specified directly in aiCamera, but beware, they could also
+ * be encoded in the node transformation. The following (pseudo)code sample
+ * shows how to do it: <br><br>
+ * @code
+ * // Get the camera matrix for a camera at a specific time
+ * // if the node hierarchy for the camera does not contain
+ * // at least one animated node this is a static computation
+ * get-camera-matrix (node sceneRoot, camera cam) : matrix
+ * {
+ *    node   cnd = find-node-for-camera(cam)
+ *    matrix cmt = identity()
+ *
+ *    // as usual - get the absolute camera transformation for this frame
+ *    for each node nd in hierarchy from sceneRoot to cnd
+ *      matrix cur
+ *      if (is-animated(nd))
+ *         cur = eval-animation(nd)
+ *      else cur = nd->mTransformation;
+ *      cmt = mult-matrices( cmt, cur )
+ *    end for
+ *
+ *    // now multiply with the camera's own local transform
+ *    cam = mult-matrices (cam, get-camera-matrix(cmt) )
+ * }
+ * @endcode
+ *
+ * @note some file formats (such as 3DS, ASE) export a "target point" -
+ * the point the camera is looking at (it can even be animated). Assimp
+ * writes the target point as a subnode of the camera's main node,
+ * called "<camName>.Target". However this is just additional information
+ * then the transformation tracks of the camera main node make the
+ * camera already look in the right direction.
+ *
+*/
+struct aiCamera
+{
+    /** The name of the camera.
+     *
+     *  There must be a node in the scenegraph with the same name.
+     *  This node specifies the position of the camera in the scene
+     *  hierarchy and can be animated.
+     */
+    C_STRUCT aiString mName;
+
+    /** Position of the camera relative to the coordinate space
+     *  defined by the corresponding node.
+     *
+     *  The default value is 0|0|0.
+     */
+    C_STRUCT aiVector3D mPosition;
+
+
+    /** 'Up' - vector of the camera coordinate system relative to
+     *  the coordinate space defined by the corresponding node.
+     *
+     *  The 'right' vector of the camera coordinate system is
+     *  the cross product of  the up and lookAt vectors.
+     *  The default value is 0|1|0. The vector
+     *  may be normalized, but it needn't.
+     */
+    C_STRUCT aiVector3D mUp;
+
+
+    /** 'LookAt' - vector of the camera coordinate system relative to
+     *  the coordinate space defined by the corresponding node.
+     *
+     *  This is the viewing direction of the user.
+     *  The default value is 0|0|1. The vector
+     *  may be normalized, but it needn't.
+     */
+    C_STRUCT aiVector3D mLookAt;
+
+
+    /** Half horizontal field of view angle, in radians.
+     *
+     *  The field of view angle is the angle between the center
+     *  line of the screen and the left or right border.
+     *  The default value is 1/4PI.
+     */
+    float mHorizontalFOV;
+
+    /** Distance of the near clipping plane from the camera.
+     *
+     * The value may not be 0.f (for arithmetic reasons to prevent
+     * a division through zero). The default value is 0.1f.
+     */
+    float mClipPlaneNear;
+
+    /** Distance of the far clipping plane from the camera.
+     *
+     * The far clipping plane must, of course, be further away than the
+     * near clipping plane. The default value is 1000.f. The ratio
+     * between the near and the far plane should not be too
+     * large (between 1000-10000 should be ok) to avoid floating-point
+     * inaccuracies which could lead to z-fighting.
+     */
+    float mClipPlaneFar;
+
+
+    /** Screen aspect ratio.
+     *
+     * This is the ration between the width and the height of the
+     * screen. Typical values are 4/3, 1/2 or 1/1. This value is
+     * 0 if the aspect ratio is not defined in the source file.
+     * 0 is also the default value.
+     */
+    float mAspect;
+
+#ifdef __cplusplus
+
+    aiCamera()
+        : mUp               (0.f,1.f,0.f)
+        , mLookAt           (0.f,0.f,1.f)
+        , mHorizontalFOV    (0.25f * (float)AI_MATH_PI)
+        , mClipPlaneNear    (0.1f)
+        , mClipPlaneFar     (1000.f)
+        , mAspect           (0.f)
+    {}
+
+    /** @brief Get a *right-handed* camera matrix from me
+     *  @param out Camera matrix to be filled
+     */
+    void GetCameraMatrix (aiMatrix4x4& out) const
+    {
+        /** todo: test ... should work, but i'm not absolutely sure */
+
+        /** We don't know whether these vectors are already normalized ...*/
+        aiVector3D zaxis = mLookAt;     zaxis.Normalize();
+        aiVector3D yaxis = mUp;         yaxis.Normalize();
+        aiVector3D xaxis = mUp^mLookAt; xaxis.Normalize();
+
+        out.a4 = -(xaxis * mPosition);
+        out.b4 = -(yaxis * mPosition);
+        out.c4 = -(zaxis * mPosition);
+
+        out.a1 = xaxis.x;
+        out.a2 = xaxis.y;
+        out.a3 = xaxis.z;
+
+        out.b1 = yaxis.x;
+        out.b2 = yaxis.y;
+        out.b3 = yaxis.z;
+
+        out.c1 = zaxis.x;
+        out.c2 = zaxis.y;
+        out.c3 = zaxis.z;
+
+        out.d1 = out.d2 = out.d3 = 0.f;
+        out.d4 = 1.f;
+    }
+
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // AI_CAMERA_H_INC

+ 255 - 0
include/assimp/cexport.h

@@ -0,0 +1,255 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2011, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  cexport.h
+*  @brief Defines the C-API for the Assimp export interface
+*/
+#ifndef AI_EXPORT_H_INC
+#define AI_EXPORT_H_INC
+
+#ifndef ASSIMP_BUILD_NO_EXPORT
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct aiScene;  // aiScene.h
+struct aiFileIO; // aiFileIO.h
+
+// --------------------------------------------------------------------------------
+/** Describes an file format which Assimp can export to. Use #aiGetExportFormatCount() to
+* learn how many export formats the current Assimp build supports and #aiGetExportFormatDescription()
+* to retrieve a description of an export format option.
+*/
+struct aiExportFormatDesc
+{
+    /// a short string ID to uniquely identify the export format. Use this ID string to
+    /// specify which file format you want to export to when calling #aiExportScene().
+    /// Example: "dae" or "obj"
+    const char* id;
+
+    /// A short description of the file format to present to users. Useful if you want
+    /// to allow the user to select an export format.
+    const char* description;
+
+    /// Recommended file extension for the exported file in lower case.
+    const char* fileExtension;
+};
+
+
+// --------------------------------------------------------------------------------
+/** Returns the number of export file formats available in the current Assimp build.
+ * Use aiGetExportFormatDescription() to retrieve infos of a specific export format.
+ */
+ASSIMP_API size_t aiGetExportFormatCount(void);
+
+
+// --------------------------------------------------------------------------------
+/** Returns a description of the nth export file format. Use #aiGetExportFormatCount()
+ * to learn how many export formats are supported.
+ * @param pIndex Index of the export format to retrieve information for. Valid range is
+ *    0 to #aiGetExportFormatCount()
+ * @return A description of that specific export format. NULL if pIndex is out of range.
+ */
+ASSIMP_API const C_STRUCT aiExportFormatDesc* aiGetExportFormatDescription( size_t pIndex);
+
+
+// --------------------------------------------------------------------------------
+/** Create a modifiable copy of a scene.
+ *  This is useful to import files via Assimp, change their topology and
+ *  export them again. Since the scene returned by the various importer functions
+ *  is const, a modifiable copy is needed.
+ *  @param pIn Valid scene to be copied
+ *  @param pOut Receives a modifyable copy of the scene. Use aiFreeScene() to
+ *    delete it again.
+ */
+ASSIMP_API void aiCopyScene(const C_STRUCT aiScene* pIn,
+    C_STRUCT aiScene** pOut);
+
+
+// --------------------------------------------------------------------------------
+/** Frees a scene copy created using aiCopyScene() */
+ASSIMP_API void aiFreeScene(const C_STRUCT aiScene* pIn);
+
+// --------------------------------------------------------------------------------
+/** Exports the given scene to a chosen file format and writes the result file(s) to disk.
+* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
+*   The scene is expected to conform to Assimp's Importer output format as specified
+*   in the @link data Data Structures Page @endlink. In short, this means the model data
+*   should use a right-handed coordinate systems, face winding should be counter-clockwise
+*   and the UV coordinate origin is assumed to be in the upper left. If your input data
+*   uses different conventions, have a look at the last parameter.
+* @param pFormatId ID string to specify to which format you want to export to. Use
+* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
+* @param pFileName Output file to write
+* @param pPreprocessing Accepts any choice of the #aiPostProcessSteps enumerated
+*   flags, but in reality only a subset of them makes sense here. Specifying
+*   'preprocessing' flags is useful if the input scene does not conform to
+*   Assimp's default conventions as specified in the @link data Data Structures Page @endlink.
+*   In short, this means the geometry data should use a right-handed coordinate systems, face
+*   winding should be counter-clockwise and the UV coordinate origin is assumed to be in
+*   the upper left. The #aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
+*   #aiProcess_FlipWindingOrder flags are used in the import side to allow users
+*   to have those defaults automatically adapted to their conventions. Specifying those flags
+*   for exporting has the opposite effect, respectively. Some other of the
+*   #aiPostProcessSteps enumerated values may be useful as well, but you'll need
+*   to try out what their effect on the exported file is. Many formats impose
+*   their own restrictions on the structure of the geometry stored therein,
+*   so some preprocessing may have little or no effect at all, or may be
+*   redundant as exporters would apply them anyhow. A good example
+*   is triangulation - whilst you can enforce it by specifying
+*   the #aiProcess_Triangulate flag, most export formats support only
+*   triangulate data so they would run the step anyway.
+*
+*   If assimp detects that the input scene was directly taken from the importer side of
+*   the library (i.e. not copied using aiCopyScene and potetially modified afterwards),
+*   any postprocessing steps already applied to the scene will not be applied again, unless
+*   they show non-idempotent behaviour (#aiProcess_MakeLeftHanded, #aiProcess_FlipUVs and
+*   #aiProcess_FlipWindingOrder).
+* @return a status code indicating the result of the export
+* @note Use aiCopyScene() to get a modifiable copy of a previously
+*   imported scene.
+*/
+ASSIMP_API aiReturn aiExportScene( const C_STRUCT aiScene* pScene,
+    const char* pFormatId,
+    const char* pFileName,
+    unsigned int pPreprocessing);
+
+
+// --------------------------------------------------------------------------------
+/** Exports the given scene to a chosen file format using custom IO logic supplied by you.
+* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
+* @param pFormatId ID string to specify to which format you want to export to. Use
+* aiGetExportFormatCount() / aiGetExportFormatDescription() to learn which export formats are available.
+* @param pFileName Output file to write
+* @param pIO custom IO implementation to be used. Use this if you use your own storage methods.
+*   If none is supplied, a default implementation using standard file IO is used. Note that
+*   #aiExportSceneToBlob is provided as convenience function to export to memory buffers.
+* @param pPreprocessing Please see the documentation for #aiExportScene
+* @return a status code indicating the result of the export
+* @note Include <aiFileIO.h> for the definition of #aiFileIO.
+* @note Use aiCopyScene() to get a modifiable copy of a previously
+*   imported scene.
+*/
+ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene,
+    const char* pFormatId,
+    const char* pFileName,
+    C_STRUCT aiFileIO* pIO,
+    unsigned int pPreprocessing );
+
+
+// --------------------------------------------------------------------------------
+/** Describes a blob of exported scene data. Use #aiExportSceneToBlob() to create a blob containing an
+* exported scene. The memory referred by this structure is owned by Assimp.
+* to free its resources. Don't try to free the memory on your side - it will crash for most build configurations
+* due to conflicting heaps.
+*
+* Blobs can be nested - each blob may reference another blob, which may in turn reference another blob and so on.
+* This is used when exporters write more than one output file for a given #aiScene. See the remarks for
+* #aiExportDataBlob::name for more information.
+*/
+struct aiExportDataBlob
+{
+    /// Size of the data in bytes
+    size_t size;
+
+    /// The data.
+    void* data;
+
+    /** Name of the blob. An empty string always
+        indicates the first (and primary) blob,
+        which contains the actual file data.
+        Any other blobs are auxiliary files produced
+        by exporters (i.e. material files). Existence
+        of such files depends on the file format. Most
+        formats don't split assets across multiple files.
+
+        If used, blob names usually contain the file
+        extension that should be used when writing
+        the data to disc.
+     */
+    C_STRUCT aiString name;
+
+    /** Pointer to the next blob in the chain or NULL if there is none. */
+    C_STRUCT aiExportDataBlob * next;
+
+#ifdef __cplusplus
+    /// Default constructor
+    aiExportDataBlob() { size = 0; data = next = NULL; }
+    /// Releases the data
+    ~aiExportDataBlob() { delete [] static_cast<unsigned char*>( data ); delete next; }
+
+private:
+    // no copying
+    aiExportDataBlob(const aiExportDataBlob& );
+    aiExportDataBlob& operator= (const aiExportDataBlob& );
+#endif // __cplusplus
+};
+
+// --------------------------------------------------------------------------------
+/** Exports the given scene to a chosen file format. Returns the exported data as a binary blob which
+* you can write into a file or something. When you're done with the data, use #aiReleaseExportBlob()
+* to free the resources associated with the export.
+* @param pScene The scene to export. Stays in possession of the caller, is not changed by the function.
+* @param pFormatId ID string to specify to which format you want to export to. Use
+* #aiGetExportFormatCount() / #aiGetExportFormatDescription() to learn which export formats are available.
+* @param pPreprocessing Please see the documentation for #aiExportScene
+* @return the exported data or NULL in case of error
+*/
+ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId,  unsigned int pPreprocessing );
+
+
+// --------------------------------------------------------------------------------
+/** Releases the memory associated with the given exported data. Use this function to free a data blob
+* returned by aiExportScene().
+* @param pData the data blob returned by #aiExportSceneToBlob
+*/
+ASSIMP_API void aiReleaseExportBlob( const C_STRUCT aiExportDataBlob* pData );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ASSIMP_BUILD_NO_EXPORT
+#endif // AI_EXPORT_H_INC
+

+ 135 - 0
include/assimp/cfileio.h

@@ -0,0 +1,135 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file cfileio.h
+ *  @brief Defines generic C routines to access memory-mapped files
+ */
+#ifndef AI_FILEIO_H_INC
+#define AI_FILEIO_H_INC
+
+#include "types.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+struct aiFileIO;
+struct aiFile;
+
+// aiFile callbacks
+typedef size_t   (*aiFileWriteProc) (C_STRUCT aiFile*,   const char*, size_t, size_t);
+typedef size_t   (*aiFileReadProc)  (C_STRUCT aiFile*,   char*, size_t,size_t);
+typedef size_t   (*aiFileTellProc)  (C_STRUCT aiFile*);
+typedef void     (*aiFileFlushProc) (C_STRUCT aiFile*);
+typedef aiReturn (*aiFileSeek)(C_STRUCT aiFile*, size_t, aiOrigin);
+
+// aiFileIO callbacks
+typedef aiFile* (*aiFileOpenProc)  (C_STRUCT aiFileIO*, const char*, const char*);
+typedef void    (*aiFileCloseProc) (C_STRUCT aiFileIO*, C_STRUCT aiFile*);
+
+// Represents user-defined data
+typedef char* aiUserData;
+
+// ----------------------------------------------------------------------------------
+/** @brief C-API: File system callbacks
+ *
+ *  Provided are functions to open and close files. Supply a custom structure to
+ *  the import function. If you don't, a default implementation is used. Use custom
+ *  file systems to enable reading from other sources, such as ZIPs
+ *  or memory locations. */
+struct aiFileIO
+{
+    /** Function used to open a new file
+     */
+    aiFileOpenProc OpenProc;
+
+    /** Function used to close an existing file
+     */
+    aiFileCloseProc CloseProc;
+
+    /** User-defined, opaque data */
+    aiUserData UserData;
+};
+
+// ----------------------------------------------------------------------------------
+/** @brief C-API: File callbacks
+ *
+ *  Actually, it's a data structure to wrap a set of fXXXX (e.g fopen)
+ *  replacement functions.
+ *
+ *  The default implementation of the functions utilizes the fXXX functions from
+ *  the CRT. However, you can supply a custom implementation to Assimp by
+ *  delivering a custom aiFileIO. Use this to enable reading from other sources,
+ *  such as ZIP archives or memory locations. */
+struct aiFile
+{
+    /** Callback to read from a file */
+    aiFileReadProc ReadProc;
+
+    /** Callback to write to a file */
+    aiFileWriteProc WriteProc;
+
+    /** Callback to retrieve the current position of
+     *  the file cursor (ftell())
+     */
+    aiFileTellProc TellProc;
+
+    /** Callback to retrieve the size of the file,
+     *  in bytes
+     */
+    aiFileTellProc FileSizeProc;
+
+    /** Callback to set the current position
+     * of the file cursor (fseek())
+     */
+    aiFileSeek SeekProc;
+
+    /** Callback to flush the file contents
+     */
+    aiFileFlushProc FlushProc;
+
+    /** User-defined, opaque data
+     */
+    aiUserData UserData;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif // AI_FILEIO_H_INC

+ 561 - 0
include/assimp/cimport.h

@@ -0,0 +1,561 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  cimport.h
+ *  @brief Defines the C-API to the Open Asset Import Library.
+ */
+#ifndef AI_ASSIMP_H_INC
+#define AI_ASSIMP_H_INC
+#include "types.h"
+#include <assimp/importerdesc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct aiScene;  // aiScene.h
+struct aiFileIO; // aiFileIO.h
+typedef void (*aiLogStreamCallback)(const char* /* message */, char* /* user */);
+
+// --------------------------------------------------------------------------------
+/** C-API: Represents a log stream. A log stream receives all log messages and
+ *  streams them _somewhere_.
+ *  @see aiGetPredefinedLogStream
+ *  @see aiAttachLogStream
+ *  @see aiDetachLogStream */
+// --------------------------------------------------------------------------------
+struct aiLogStream
+{
+    /** callback to be called */
+    aiLogStreamCallback callback;
+
+    /** user data to be passed to the callback */
+    char* user;
+};
+
+
+// --------------------------------------------------------------------------------
+/** C-API: Represents an opaque set of settings to be used during importing.
+ *  @see aiCreatePropertyStore
+ *  @see aiReleasePropertyStore
+ *  @see aiImportFileExWithProperties
+ *  @see aiSetPropertyInteger
+ *  @see aiSetPropertyFloat
+ *  @see aiSetPropertyString
+ *  @see aiSetPropertyMatrix
+ */
+// --------------------------------------------------------------------------------
+struct aiPropertyStore { char sentinel; };
+
+/** Our own C boolean type */
+typedef int aiBool;
+
+#define AI_FALSE 0
+#define AI_TRUE 1
+
+// --------------------------------------------------------------------------------
+/** Reads the given file and returns its content.
+ *
+ * If the call succeeds, the imported data is returned in an aiScene structure.
+ * The data is intended to be read-only, it stays property of the ASSIMP
+ * library and will be stable until aiReleaseImport() is called. After you're
+ * done with it, call aiReleaseImport() to free the resources associated with
+ * this file. If the import fails, NULL is returned instead. Call
+ * aiGetErrorString() to retrieve a human-readable error text.
+ * @param pFile Path and filename of the file to be imported,
+ *   expected to be a null-terminated c-string. NULL is not a valid value.
+ * @param pFlags Optional post processing steps to be executed after
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags.
+ * @return Pointer to the imported data or NULL if the import failed.
+ */
+ASSIMP_API const C_STRUCT aiScene* aiImportFile(
+    const char* pFile,
+    unsigned int pFlags);
+
+// --------------------------------------------------------------------------------
+/** Reads the given file using user-defined I/O functions and returns
+ *   its content.
+ *
+ * If the call succeeds, the imported data is returned in an aiScene structure.
+ * The data is intended to be read-only, it stays property of the ASSIMP
+ * library and will be stable until aiReleaseImport() is called. After you're
+ * done with it, call aiReleaseImport() to free the resources associated with
+ * this file. If the import fails, NULL is returned instead. Call
+ * aiGetErrorString() to retrieve a human-readable error text.
+ * @param pFile Path and filename of the file to be imported,
+ *   expected to be a null-terminated c-string. NULL is not a valid value.
+ * @param pFlags Optional post processing steps to be executed after
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags.
+ * @param pFS aiFileIO structure. Will be used to open the model file itself
+ *   and any other files the loader needs to open.  Pass NULL to use the default
+ *   implementation.
+ * @return Pointer to the imported data or NULL if the import failed.
+ * @note Include <aiFileIO.h> for the definition of #aiFileIO.
+ */
+ASSIMP_API const C_STRUCT aiScene* aiImportFileEx(
+    const char* pFile,
+    unsigned int pFlags,
+    C_STRUCT aiFileIO* pFS);
+
+// --------------------------------------------------------------------------------
+/** Same as #aiImportFileEx, but adds an extra parameter containing importer settings.
+ *
+ * @param pFile Path and filename of the file to be imported,
+ *   expected to be a null-terminated c-string. NULL is not a valid value.
+ * @param pFlags Optional post processing steps to be executed after
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags.
+ * @param pFS aiFileIO structure. Will be used to open the model file itself
+ *   and any other files the loader needs to open.  Pass NULL to use the default
+ *   implementation.
+ * @param pProps #aiPropertyStore instance containing import settings.
+ * @return Pointer to the imported data or NULL if the import failed.
+ * @note Include <aiFileIO.h> for the definition of #aiFileIO.
+ * @see aiImportFileEx
+ */
+ASSIMP_API const C_STRUCT aiScene* aiImportFileExWithProperties(
+    const char* pFile,
+    unsigned int pFlags,
+    C_STRUCT aiFileIO* pFS,
+    const C_STRUCT aiPropertyStore* pProps);
+
+// --------------------------------------------------------------------------------
+/** Reads the given file from a given memory buffer,
+ *
+ * If the call succeeds, the contents of the file are returned as a pointer to an
+ * aiScene object. The returned data is intended to be read-only, the importer keeps
+ * ownership of the data and will destroy it upon destruction. If the import fails,
+ * NULL is returned.
+ * A human-readable error description can be retrieved by calling aiGetErrorString().
+ * @param pBuffer Pointer to the file data
+ * @param pLength Length of pBuffer, in bytes
+ * @param pFlags Optional post processing steps to be executed after
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags. If you wish to inspect the imported
+ *   scene first in order to fine-tune your post-processing setup,
+ *   consider to use #aiApplyPostProcessing().
+ * @param pHint An additional hint to the library. If this is a non empty string,
+ *   the library looks for a loader to support the file extension specified by pHint
+ *   and passes the file to the first matching loader. If this loader is unable to
+ *   completely the request, the library continues and tries to determine the file
+ *   format on its own, a task that may or may not be successful.
+ *   Check the return value, and you'll know ...
+ * @return A pointer to the imported data, NULL if the import failed.
+ *
+ * @note This is a straightforward way to decode models from memory
+ * buffers, but it doesn't handle model formats that spread their
+ * data across multiple files or even directories. Examples include
+ * OBJ or MD3, which outsource parts of their material info into
+ * external scripts. If you need full functionality, provide
+ * a custom IOSystem to make Assimp find these files and use
+ * the regular aiImportFileEx()/aiImportFileExWithProperties() API.
+ */
+ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemory(
+    const char* pBuffer,
+    unsigned int pLength,
+    unsigned int pFlags,
+    const char* pHint);
+
+// --------------------------------------------------------------------------------
+/** Same as #aiImportFileFromMemory, but adds an extra parameter containing importer settings.
+ *
+ * @param pBuffer Pointer to the file data
+ * @param pLength Length of pBuffer, in bytes
+ * @param pFlags Optional post processing steps to be executed after
+ *   a successful import. Provide a bitwise combination of the
+ *   #aiPostProcessSteps flags. If you wish to inspect the imported
+ *   scene first in order to fine-tune your post-processing setup,
+ *   consider to use #aiApplyPostProcessing().
+ * @param pHint An additional hint to the library. If this is a non empty string,
+ *   the library looks for a loader to support the file extension specified by pHint
+ *   and passes the file to the first matching loader. If this loader is unable to
+ *   completely the request, the library continues and tries to determine the file
+ *   format on its own, a task that may or may not be successful.
+ *   Check the return value, and you'll know ...
+ * @param pProps #aiPropertyStore instance containing import settings.
+ * @return A pointer to the imported data, NULL if the import failed.
+ *
+ * @note This is a straightforward way to decode models from memory
+ * buffers, but it doesn't handle model formats that spread their
+ * data across multiple files or even directories. Examples include
+ * OBJ or MD3, which outsource parts of their material info into
+ * external scripts. If you need full functionality, provide
+ * a custom IOSystem to make Assimp find these files and use
+ * the regular aiImportFileEx()/aiImportFileExWithProperties() API.
+ * @see aiImportFileFromMemory
+ */
+ASSIMP_API const C_STRUCT aiScene* aiImportFileFromMemoryWithProperties(
+    const char* pBuffer,
+    unsigned int pLength,
+    unsigned int pFlags,
+    const char* pHint,
+    const C_STRUCT aiPropertyStore* pProps);
+
+// --------------------------------------------------------------------------------
+/** Apply post-processing to an already-imported scene.
+ *
+ * This is strictly equivalent to calling #aiImportFile()/#aiImportFileEx with the
+ * same flags. However, you can use this separate function to inspect the imported
+ * scene first to fine-tune your post-processing setup.
+ * @param pScene Scene to work on.
+ * @param pFlags Provide a bitwise combination of the #aiPostProcessSteps flags.
+ * @return A pointer to the post-processed data. Post processing is done in-place,
+ *   meaning this is still the same #aiScene which you passed for pScene. However,
+ *   _if_ post-processing failed, the scene could now be NULL. That's quite a rare
+ *   case, post processing steps are not really designed to 'fail'. To be exact,
+ *   the #aiProcess_ValidateDataStructure flag is currently the only post processing step
+ *   which can actually cause the scene to be reset to NULL.
+ */
+ASSIMP_API const C_STRUCT aiScene* aiApplyPostProcessing(
+    const C_STRUCT aiScene* pScene,
+    unsigned int pFlags);
+
+// --------------------------------------------------------------------------------
+/** Get one of the predefine log streams. This is the quick'n'easy solution to
+ *  access Assimp's log system. Attaching a log stream can slightly reduce Assimp's
+ *  overall import performance.
+ *
+ *  Usage is rather simple (this will stream the log to a file, named log.txt, and
+ *  the stdout stream of the process:
+ *  @code
+ *    struct aiLogStream c;
+ *    c = aiGetPredefinedLogStream(aiDefaultLogStream_FILE,"log.txt");
+ *    aiAttachLogStream(&c);
+ *    c = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
+ *    aiAttachLogStream(&c);
+ *  @endcode
+ *
+ *  @param pStreams One of the #aiDefaultLogStream enumerated values.
+ *  @param file Solely for the #aiDefaultLogStream_FILE flag: specifies the file to write to.
+ *    Pass NULL for all other flags.
+ *  @return The log stream. callback is set to NULL if something went wrong.
+ */
+ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream(
+    C_ENUM aiDefaultLogStream pStreams,
+    const char* file);
+
+// --------------------------------------------------------------------------------
+/** Attach a custom log stream to the libraries' logging system.
+ *
+ *  Attaching a log stream can slightly reduce Assimp's overall import
+ *  performance. Multiple log-streams can be attached.
+ *  @param stream Describes the new log stream.
+ *  @note To ensure proper destruction of the logging system, you need to manually
+ *    call aiDetachLogStream() on every single log stream you attach.
+ *    Alternatively (for the lazy folks) #aiDetachAllLogStreams is provided.
+ */
+ASSIMP_API void aiAttachLogStream(
+    const C_STRUCT aiLogStream* stream);
+
+// --------------------------------------------------------------------------------
+/** Enable verbose logging. Verbose logging includes debug-related stuff and
+ *  detailed import statistics. This can have severe impact on import performance
+ *  and memory consumption. However, it might be useful to find out why a file
+ *  didn't read correctly.
+ *  @param d AI_TRUE or AI_FALSE, your decision.
+ */
+ASSIMP_API void aiEnableVerboseLogging(aiBool d);
+
+// --------------------------------------------------------------------------------
+/** Detach a custom log stream from the libraries' logging system.
+ *
+ *  This is the counterpart of #aiAttachLogStream. If you attached a stream,
+ *  don't forget to detach it again.
+ *  @param stream The log stream to be detached.
+ *  @return AI_SUCCESS if the log stream has been detached successfully.
+ *  @see aiDetachAllLogStreams
+ */
+ASSIMP_API C_ENUM aiReturn aiDetachLogStream(
+    const C_STRUCT aiLogStream* stream);
+
+// --------------------------------------------------------------------------------
+/** Detach all active log streams from the libraries' logging system.
+ *  This ensures that the logging system is terminated properly and all
+ *  resources allocated by it are actually freed. If you attached a stream,
+ *  don't forget to detach it again.
+ *  @see aiAttachLogStream
+ *  @see aiDetachLogStream
+ */
+ASSIMP_API void aiDetachAllLogStreams(void);
+
+// --------------------------------------------------------------------------------
+/** Releases all resources associated with the given import process.
+ *
+ * Call this function after you're done with the imported data.
+ * @param pScene The imported data to release. NULL is a valid value.
+ */
+ASSIMP_API void aiReleaseImport(
+    const C_STRUCT aiScene* pScene);
+
+// --------------------------------------------------------------------------------
+/** Returns the error text of the last failed import process.
+ *
+ * @return A textual description of the error that occurred at the last
+ * import process. NULL if there was no error. There can't be an error if you
+ * got a non-NULL #aiScene from #aiImportFile/#aiImportFileEx/#aiApplyPostProcessing.
+ */
+ASSIMP_API const char* aiGetErrorString();
+
+// --------------------------------------------------------------------------------
+/** Returns whether a given file extension is supported by ASSIMP
+ *
+ * @param szExtension Extension for which the function queries support for.
+ * Must include a leading dot '.'. Example: ".3ds", ".md3"
+ * @return AI_TRUE if the file extension is supported.
+ */
+ASSIMP_API aiBool aiIsExtensionSupported(
+    const char* szExtension);
+
+// --------------------------------------------------------------------------------
+/** Get a list of all file extensions supported by ASSIMP.
+ *
+ * If a file extension is contained in the list this does, of course, not
+ * mean that ASSIMP is able to load all files with this extension.
+ * @param szOut String to receive the extension list.
+ * Format of the list: "*.3ds;*.obj;*.dae". NULL is not a valid parameter.
+ */
+ASSIMP_API void aiGetExtensionList(
+    C_STRUCT aiString* szOut);
+
+// --------------------------------------------------------------------------------
+/** Get the approximated storage required by an imported asset
+ * @param pIn Input asset.
+ * @param in Data structure to be filled.
+ */
+ASSIMP_API void aiGetMemoryRequirements(
+    const C_STRUCT aiScene* pIn,
+    C_STRUCT aiMemoryInfo* in);
+
+
+
+// --------------------------------------------------------------------------------
+/** Create an empty property store. Property stores are used to collect import
+ *  settings.
+ * @return New property store. Property stores need to be manually destroyed using
+ *   the #aiReleasePropertyStore API function.
+ */
+ASSIMP_API C_STRUCT aiPropertyStore* aiCreatePropertyStore(void);
+
+// --------------------------------------------------------------------------------
+/** Delete a property store.
+ * @param p Property store to be deleted.
+ */
+ASSIMP_API void aiReleasePropertyStore(C_STRUCT aiPropertyStore* p);
+
+// --------------------------------------------------------------------------------
+/** Set an integer property.
+ *
+ *  This is the C-version of #Assimp::Importer::SetPropertyInteger(). In the C
+ *  interface, properties are always shared by all imports. It is not possible to
+ *  specify them per import.
+ *
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
+ * @param szName Name of the configuration property to be set. All supported
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
+ * @param value New value for the property
+ */
+ASSIMP_API void aiSetImportPropertyInteger(
+    C_STRUCT aiPropertyStore* store,
+    const char* szName,
+    int value);
+
+// --------------------------------------------------------------------------------
+/** Set a floating-point property.
+ *
+ *  This is the C-version of #Assimp::Importer::SetPropertyFloat(). In the C
+ *  interface, properties are always shared by all imports. It is not possible to
+ *  specify them per import.
+ *
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
+ * @param szName Name of the configuration property to be set. All supported
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
+ * @param value New value for the property
+ */
+ASSIMP_API void aiSetImportPropertyFloat(
+    C_STRUCT aiPropertyStore* store,
+    const char* szName,
+    float value);
+
+// --------------------------------------------------------------------------------
+/** Set a string property.
+ *
+ *  This is the C-version of #Assimp::Importer::SetPropertyString(). In the C
+ *  interface, properties are always shared by all imports. It is not possible to
+ *  specify them per import.
+ *
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
+ * @param szName Name of the configuration property to be set. All supported
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
+ * @param st New value for the property
+ */
+ASSIMP_API void aiSetImportPropertyString(
+    C_STRUCT aiPropertyStore* store,
+    const char* szName,
+    const C_STRUCT aiString* st);
+
+// --------------------------------------------------------------------------------
+/** Set a matrix property.
+ *
+ *  This is the C-version of #Assimp::Importer::SetPropertyMatrix(). In the C
+ *  interface, properties are always shared by all imports. It is not possible to
+ *  specify them per import.
+ *
+ * @param store Store to modify. Use #aiCreatePropertyStore to obtain a store.
+ * @param szName Name of the configuration property to be set. All supported
+ *   public properties are defined in the config.h header file (AI_CONFIG_XXX).
+ * @param mat New value for the property
+ */
+ASSIMP_API void aiSetImportPropertyMatrix(
+    C_STRUCT aiPropertyStore* store,
+    const char* szName,
+    const C_STRUCT aiMatrix4x4* mat);
+
+// --------------------------------------------------------------------------------
+/** Construct a quaternion from a 3x3 rotation matrix.
+ *  @param quat Receives the output quaternion.
+ *  @param mat Matrix to 'quaternionize'.
+ *  @see aiQuaternion(const aiMatrix3x3& pRotMatrix)
+ */
+ASSIMP_API void aiCreateQuaternionFromMatrix(
+    C_STRUCT aiQuaternion* quat,
+    const C_STRUCT aiMatrix3x3* mat);
+
+// --------------------------------------------------------------------------------
+/** Decompose a transformation matrix into its rotational, translational and
+ *  scaling components.
+ *
+ * @param mat Matrix to decompose
+ * @param scaling Receives the scaling component
+ * @param rotation Receives the rotational component
+ * @param position Receives the translational component.
+ * @see aiMatrix4x4::Decompose (aiVector3D&, aiQuaternion&, aiVector3D&) const;
+ */
+ASSIMP_API void aiDecomposeMatrix(
+    const C_STRUCT aiMatrix4x4* mat,
+    C_STRUCT aiVector3D* scaling,
+    C_STRUCT aiQuaternion* rotation,
+    C_STRUCT aiVector3D* position);
+
+// --------------------------------------------------------------------------------
+/** Transpose a 4x4 matrix.
+ *  @param mat Pointer to the matrix to be transposed
+ */
+ASSIMP_API void aiTransposeMatrix4(
+    C_STRUCT aiMatrix4x4* mat);
+
+// --------------------------------------------------------------------------------
+/** Transpose a 3x3 matrix.
+ *  @param mat Pointer to the matrix to be transposed
+ */
+ASSIMP_API void aiTransposeMatrix3(
+    C_STRUCT aiMatrix3x3* mat);
+
+// --------------------------------------------------------------------------------
+/** Transform a vector by a 3x3 matrix
+ *  @param vec Vector to be transformed.
+ *  @param mat Matrix to transform the vector with.
+ */
+ASSIMP_API void aiTransformVecByMatrix3(
+    C_STRUCT aiVector3D* vec,
+    const C_STRUCT aiMatrix3x3* mat);
+
+// --------------------------------------------------------------------------------
+/** Transform a vector by a 4x4 matrix
+ *  @param vec Vector to be transformed.
+ *  @param mat Matrix to transform the vector with.
+ */
+ASSIMP_API void aiTransformVecByMatrix4(
+    C_STRUCT aiVector3D* vec,
+    const C_STRUCT aiMatrix4x4* mat);
+
+// --------------------------------------------------------------------------------
+/** Multiply two 4x4 matrices.
+ *  @param dst First factor, receives result.
+ *  @param src Matrix to be multiplied with 'dst'.
+ */
+ASSIMP_API void aiMultiplyMatrix4(
+    C_STRUCT aiMatrix4x4* dst,
+    const C_STRUCT aiMatrix4x4* src);
+
+// --------------------------------------------------------------------------------
+/** Multiply two 3x3 matrices.
+ *  @param dst First factor, receives result.
+ *  @param src Matrix to be multiplied with 'dst'.
+ */
+ASSIMP_API void aiMultiplyMatrix3(
+    C_STRUCT aiMatrix3x3* dst,
+    const C_STRUCT aiMatrix3x3* src);
+
+// --------------------------------------------------------------------------------
+/** Get a 3x3 identity matrix.
+ *  @param mat Matrix to receive its personal identity
+ */
+ASSIMP_API void aiIdentityMatrix3(
+    C_STRUCT aiMatrix3x3* mat);
+
+// --------------------------------------------------------------------------------
+/** Get a 4x4 identity matrix.
+ *  @param mat Matrix to receive its personal identity
+ */
+ASSIMP_API void aiIdentityMatrix4(
+    C_STRUCT aiMatrix4x4* mat);
+
+// --------------------------------------------------------------------------------
+/** Returns the number of import file formats available in the current Assimp build.
+ * Use aiGetImportFormatDescription() to retrieve infos of a specific import format.
+ */
+ASSIMP_API size_t aiGetImportFormatCount(void);
+
+// --------------------------------------------------------------------------------
+/** Returns a description of the nth import file format. Use #aiGetImportFormatCount()
+ * to learn how many import formats are supported.
+ * @param pIndex Index of the import format to retrieve information for. Valid range is
+ *    0 to #aiGetImportFormatCount()
+ * @return A description of that specific import format. NULL if pIndex is out of range.
+ */
+ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImportFormatDescription( size_t pIndex);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // AI_ASSIMP_H_INC

+ 104 - 0
include/assimp/color4.h

@@ -0,0 +1,104 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+/** @file color4.h
+ *  @brief RGBA color structure, including operators when compiling in C++
+ */
+#ifndef AI_COLOR4D_H_INC
+#define AI_COLOR4D_H_INC
+
+#include "./Compiler/pushpack1.h"
+
+#ifdef __cplusplus
+
+// ----------------------------------------------------------------------------------
+/** Represents a color in Red-Green-Blue space including an
+*   alpha component. Color values range from 0 to 1. */
+// ----------------------------------------------------------------------------------
+template <typename TReal>
+class aiColor4t
+{
+public:
+    aiColor4t () : r(), g(), b(), a() {}
+    aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a)
+        : r(_r), g(_g), b(_b), a(_a) {}
+    explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
+    aiColor4t (const aiColor4t& o)
+        : r(o.r), g(o.g), b(o.b), a(o.a) {}
+
+public:
+    // combined operators
+    const aiColor4t& operator += (const aiColor4t& o);
+    const aiColor4t& operator -= (const aiColor4t& o);
+    const aiColor4t& operator *= (TReal f);
+    const aiColor4t& operator /= (TReal f);
+
+public:
+    // comparison
+    bool operator == (const aiColor4t& other) const;
+    bool operator != (const aiColor4t& other) const;
+    bool operator <  (const aiColor4t& other) const;
+
+    // color tuple access, rgba order
+    inline TReal operator[](unsigned int i) const;
+    inline TReal& operator[](unsigned int i);
+
+    /** check whether a color is (close to) black */
+    inline bool IsBlack() const;
+
+public:
+
+    // Red, green, blue and alpha color values
+    TReal r, g, b, a;
+} PACK_STRUCT;  // !struct aiColor4D
+
+typedef aiColor4t<float> aiColor4D;
+
+#else
+
+struct aiColor4D {
+    float r, g, b, a;
+} PACK_STRUCT;
+
+#endif // __cplusplus
+
+#include "./Compiler/poppack1.h"
+
+#endif // AI_COLOR4D_H_INC

+ 182 - 0
include/assimp/color4.inl

@@ -0,0 +1,182 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  color4.inl
+ *  @brief Inline implementation of aiColor4t<TReal> operators
+ */
+#ifndef AI_COLOR4D_INL_INC
+#define AI_COLOR4D_INL_INC
+
+#ifdef __cplusplus
+#include "color4.h"
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator += (const aiColor4t<TReal>& o) {
+    r += o.r; g += o.g; b += o.b; a += o.a;
+    return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator -= (const aiColor4t<TReal>& o) {
+    r -= o.r; g -= o.g; b -= o.b; a -= o.a;
+    return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator *= (TReal f) {
+    r *= f; g *= f; b *= f; a *= f;
+    return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiColor4t<TReal>& aiColor4t<TReal>::operator /= (TReal f) {
+    r /= f; g /= f; b /= f; a /= f;
+    return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
+    return *(&r + i);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
+    return *(&r + i);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
+    return r == other.r && g == other.g && b == other.b && a == other.a;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE bool aiColor4t<TReal>::operator!= (const aiColor4t<TReal>& other) const {
+    return r != other.r || g != other.g || b != other.b || a != other.a;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
+    return r < other.r || (
+        r == other.r && (
+            g < other.g || (
+                g == other.g && (
+                    b < other.b || (
+                        b == other.b && (
+                            a < other.a
+                        )
+                    )
+                )
+            )
+        )
+    );
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)    {
+    return aiColor4t<TReal>( v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiColor4t<TReal> operator - (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)    {
+    return aiColor4t<TReal>( v1.r - v2.r, v1.g - v2.g, v1.b - v2.b, v1.a - v2.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)    {
+    return aiColor4t<TReal>( v1.r * v2.r, v1.g * v2.g, v1.b * v2.b, v1.a * v2.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)    {
+    return aiColor4t<TReal>( v1.r / v2.r, v1.g / v2.g, v1.b / v2.b, v1.a / v2.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiColor4t<TReal> operator * ( TReal f, const aiColor4t<TReal>& v)   {
+    return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator * ( const aiColor4t<TReal>& v, TReal f)  {
+    return aiColor4t<TReal>( f*v.r, f*v.g, f*v.b, f*v.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator / ( const aiColor4t<TReal>& v, TReal f)  {
+    return v * (1/f);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator / ( TReal f,const aiColor4t<TReal>& v)   {
+    return aiColor4t<TReal>(f,f,f,f)/v;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator + ( const aiColor4t<TReal>& v, TReal f)  {
+    return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator - ( const aiColor4t<TReal>& v, TReal f)  {
+    return aiColor4t<TReal>( v.r-f, v.g-f, v.b-f, v.a-f);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator + ( TReal f, const aiColor4t<TReal>& v)  {
+    return aiColor4t<TReal>( f+v.r, f+v.g, f+v.b, f+v.a);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE  aiColor4t<TReal> operator - ( TReal f, const aiColor4t<TReal>& v)  {
+    return aiColor4t<TReal>( f-v.r, f-v.g, f-v.b, f-v.a);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline bool aiColor4t<TReal> :: IsBlack() const {
+    // The alpha component doesn't care here. black is black.
+    static const TReal epsilon = 10e-3f;
+    return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
+}
+
+#endif // __cplusplus
+#endif // AI_VECTOR3D_INL_INC

+ 908 - 0
include/assimp/config.h

@@ -0,0 +1,908 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file config.h
+ *  @brief Defines constants for configurable properties for the library
+ *
+ *  Typically these properties are set via
+ *  #Assimp::Importer::SetPropertyFloat,
+ *  #Assimp::Importer::SetPropertyInteger or
+ *  #Assimp::Importer::SetPropertyString,
+ *  depending on the data type of a property. All properties have a
+ *  default value. See the doc for the mentioned methods for more details.
+ *
+ *  <br><br>
+ *  The corresponding functions for use with the plain-c API are:
+ *  #aiSetImportPropertyInteger,
+ *  #aiSetImportPropertyFloat,
+ *  #aiSetImportPropertyString
+ */
+#ifndef INCLUDED_AI_CONFIG_H
+#define INCLUDED_AI_CONFIG_H
+
+
+// ###########################################################################
+// LIBRARY SETTINGS
+// General, global settings
+// ###########################################################################
+
+// ---------------------------------------------------------------------------
+/** @brief Enables time measurements.
+ *
+ *  If enabled, measures the time needed for each part of the loading
+ *  process (i.e. IO time, importing, postprocessing, ..) and dumps
+ *  these timings to the DefaultLogger. See the @link perf Performance
+ *  Page@endlink for more information on this topic.
+ *
+ * Property type: bool. Default value: false.
+ */
+#define AI_CONFIG_GLOB_MEASURE_TIME  \
+    "GLOB_MEASURE_TIME"
+
+
+// ---------------------------------------------------------------------------
+/** @brief Global setting to disable generation of skeleton dummy meshes
+ *
+ * Skeleton dummy meshes are generated as a visualization aid in cases which
+ * the input data contains no geometry, but only animation data.
+ * Property data type: bool. Default value: false
+ */
+// ---------------------------------------------------------------------------
+#define AI_CONFIG_IMPORT_NO_SKELETON_MESHES \
+    "IMPORT_NO_SKELETON_MESHES"
+
+
+
+# if 0 // not implemented yet
+// ---------------------------------------------------------------------------
+/** @brief Set Assimp's multithreading policy.
+ *
+ * This setting is ignored if Assimp was built without boost.thread
+ * support (ASSIMP_BUILD_NO_THREADING, which is implied by ASSIMP_BUILD_BOOST_WORKAROUND).
+ * Possible values are: -1 to let Assimp decide what to do, 0 to disable
+ * multithreading entirely and any number larger than 0 to force a specific
+ * number of threads. Assimp is always free to ignore this settings, which is
+ * merely a hint. Usually, the default value (-1) will be fine. However, if
+ * Assimp is used concurrently from multiple user threads, it might be useful
+ * to limit each Importer instance to a specific number of cores.
+ *
+ * For more information, see the @link threading Threading page@endlink.
+ * Property type: int, default value: -1.
+ */
+#define AI_CONFIG_GLOB_MULTITHREADING  \
+    "GLOB_MULTITHREADING"
+#endif
+
+// ###########################################################################
+// POST PROCESSING SETTINGS
+// Various stuff to fine-tune the behavior of a specific post processing step.
+// ###########################################################################
+
+
+// ---------------------------------------------------------------------------
+/** @brief Maximum bone count per mesh for the SplitbyBoneCount step.
+ *
+ * Meshes are split until the maximum number of bones is reached. The default
+ * value is AI_SBBC_DEFAULT_MAX_BONES, which may be altered at
+ * compile-time.
+ * Property data type: integer.
+ */
+// ---------------------------------------------------------------------------
+#define AI_CONFIG_PP_SBBC_MAX_BONES \
+    "PP_SBBC_MAX_BONES"
+
+
+// default limit for bone count
+#if (!defined AI_SBBC_DEFAULT_MAX_BONES)
+#   define AI_SBBC_DEFAULT_MAX_BONES        60
+#endif
+
+
+// ---------------------------------------------------------------------------
+/** @brief  Specifies the maximum angle that may be between two vertex tangents
+ *         that their tangents and bi-tangents are smoothed.
+ *
+ * This applies to the CalcTangentSpace-Step. The angle is specified
+ * in degrees. The maximum value is 175.
+ * Property type: float. Default value: 45 degrees
+ */
+#define AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE \
+    "PP_CT_MAX_SMOOTHING_ANGLE"
+
+// ---------------------------------------------------------------------------
+/** @brief Source UV channel for tangent space computation.
+ *
+ * The specified channel must exist or an error will be raised.
+ * Property type: integer. Default value: 0
+ */
+// ---------------------------------------------------------------------------
+#define AI_CONFIG_PP_CT_TEXTURE_CHANNEL_INDEX \
+    "PP_CT_TEXTURE_CHANNEL_INDEX"
+
+// ---------------------------------------------------------------------------
+/** @brief  Specifies the maximum angle that may be between two face normals
+ *          at the same vertex position that their are smoothed together.
+ *
+ * Sometimes referred to as 'crease angle'.
+ * This applies to the GenSmoothNormals-Step. The angle is specified
+ * in degrees, so 180 is PI. The default value is 175 degrees (all vertex
+ * normals are smoothed). The maximum value is 175, too. Property type: float.
+ * Warning: setting this option may cause a severe loss of performance. The
+ * performance is unaffected if the #AI_CONFIG_FAVOUR_SPEED flag is set but
+ * the output quality may be reduced.
+ */
+#define AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE \
+    "PP_GSN_MAX_SMOOTHING_ANGLE"
+
+
+// ---------------------------------------------------------------------------
+/** @brief Sets the colormap (= palette) to be used to decode embedded
+ *         textures in MDL (Quake or 3DGS) files.
+ *
+ * This must be a valid path to a file. The file is 768 (256*3) bytes
+ * large and contains RGB triplets for each of the 256 palette entries.
+ * The default value is colormap.lmp. If the file is not found,
+ * a default palette (from Quake 1) is used.
+ * Property type: string.
+ */
+#define AI_CONFIG_IMPORT_MDL_COLORMAP       \
+    "IMPORT_MDL_COLORMAP"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_RemoveRedundantMaterials step to
+ *  keep materials matching a name in a given list.
+ *
+ * This is a list of 1 to n strings, ' ' serves as delimiter character.
+ * Identifiers containing whitespaces must be enclosed in *single*
+ * quotation marks. For example:<tt>
+ * "keep-me and_me_to anotherMaterialToBeKept \'name with whitespace\'"</tt>.
+ * If a material matches on of these names, it will not be modified or
+ * removed by the postprocessing step nor will other materials be replaced
+ * by a reference to it. <br>
+ * This option might be useful if you are using some magic material names
+ * to pass additional semantics through the content pipeline. This ensures
+ * they won't be optimized away, but a general optimization is still
+ * performed for materials not contained in the list.
+ * Property type: String. Default value: n/a
+ * @note Linefeeds, tabs or carriage returns are treated as whitespace.
+ *   Material names are case sensitive.
+ */
+#define AI_CONFIG_PP_RRM_EXCLUDE_LIST   \
+    "PP_RRM_EXCLUDE_LIST"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_PreTransformVertices step to
+ *  keep the scene hierarchy. Meshes are moved to worldspace, but
+ *  no optimization is performed (read: meshes with equal materials are not
+ *  joined. The total number of meshes won't change).
+ *
+ * This option could be of use for you if the scene hierarchy contains
+ * important additional information which you intend to parse.
+ * For rendering, you can still render all meshes in the scene without
+ * any transformations.
+ * Property type: bool. Default value: false.
+ */
+#define AI_CONFIG_PP_PTV_KEEP_HIERARCHY     \
+    "PP_PTV_KEEP_HIERARCHY"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_PreTransformVertices step to normalize
+ *  all vertex components into the [-1,1] range. That is, a bounding box
+ *  for the whole scene is computed, the maximum component is taken and all
+ *  meshes are scaled appropriately (uniformly of course!).
+ *  This might be useful if you don't know the spatial dimension of the input
+ *  data*/
+#define AI_CONFIG_PP_PTV_NORMALIZE  \
+    "PP_PTV_NORMALIZE"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_PreTransformVertices step to use
+ *  a users defined matrix as the scene root node transformation before
+ *  transforming vertices.
+ *  Property type: bool. Default value: false.
+ */
+#define AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION    \
+    "PP_PTV_ADD_ROOT_TRANSFORMATION"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_PreTransformVertices step to use
+ *  a users defined matrix as the scene root node transformation before
+ *  transforming vertices. This property correspond to the 'a1' component
+ *  of the transformation matrix.
+ *  Property type: aiMatrix4x4.
+ */
+#define AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION    \
+    "PP_PTV_ROOT_TRANSFORMATION"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_FindDegenerates step to
+ *  remove degenerated primitives from the import - immediately.
+ *
+ * The default behaviour converts degenerated triangles to lines and
+ * degenerated lines to points. See the documentation to the
+ * #aiProcess_FindDegenerates step for a detailed example of the various ways
+ * to get rid of these lines and points if you don't want them.
+ * Property type: bool. Default value: false.
+ */
+#define AI_CONFIG_PP_FD_REMOVE \
+    "PP_FD_REMOVE"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
+ * matching a name in a given list.
+ *
+ * This is a list of 1 to n strings, ' ' serves as delimiter character.
+ * Identifiers containing whitespaces must be enclosed in *single*
+ * quotation marks. For example:<tt>
+ * "keep-me and_me_to anotherNodeToBeKept \'name with whitespace\'"</tt>.
+ * If a node matches on of these names, it will not be modified or
+ * removed by the postprocessing step.<br>
+ * This option might be useful if you are using some magic node names
+ * to pass additional semantics through the content pipeline. This ensures
+ * they won't be optimized away, but a general optimization is still
+ * performed for nodes not contained in the list.
+ * Property type: String. Default value: n/a
+ * @note Linefeeds, tabs or carriage returns are treated as whitespace.
+ *   Node names are case sensitive.
+ */
+#define AI_CONFIG_PP_OG_EXCLUDE_LIST    \
+    "PP_OG_EXCLUDE_LIST"
+
+// ---------------------------------------------------------------------------
+/** @brief  Set the maximum number of triangles in a mesh.
+ *
+ * This is used by the "SplitLargeMeshes" PostProcess-Step to determine
+ * whether a mesh must be split or not.
+ * @note The default value is AI_SLM_DEFAULT_MAX_TRIANGLES
+ * Property type: integer.
+ */
+#define AI_CONFIG_PP_SLM_TRIANGLE_LIMIT \
+    "PP_SLM_TRIANGLE_LIMIT"
+
+// default value for AI_CONFIG_PP_SLM_TRIANGLE_LIMIT
+#if (!defined AI_SLM_DEFAULT_MAX_TRIANGLES)
+#   define AI_SLM_DEFAULT_MAX_TRIANGLES     1000000
+#endif
+
+// ---------------------------------------------------------------------------
+/** @brief  Set the maximum number of vertices in a mesh.
+ *
+ * This is used by the "SplitLargeMeshes" PostProcess-Step to determine
+ * whether a mesh must be split or not.
+ * @note The default value is AI_SLM_DEFAULT_MAX_VERTICES
+ * Property type: integer.
+ */
+#define AI_CONFIG_PP_SLM_VERTEX_LIMIT \
+    "PP_SLM_VERTEX_LIMIT"
+
+// default value for AI_CONFIG_PP_SLM_VERTEX_LIMIT
+#if (!defined AI_SLM_DEFAULT_MAX_VERTICES)
+#   define AI_SLM_DEFAULT_MAX_VERTICES      1000000
+#endif
+
+// ---------------------------------------------------------------------------
+/** @brief Set the maximum number of bones affecting a single vertex
+ *
+ * This is used by the #aiProcess_LimitBoneWeights PostProcess-Step.
+ * @note The default value is AI_LBW_MAX_WEIGHTS
+ * Property type: integer.*/
+#define AI_CONFIG_PP_LBW_MAX_WEIGHTS    \
+    "PP_LBW_MAX_WEIGHTS"
+
+// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
+#if (!defined AI_LMW_MAX_WEIGHTS)
+#   define AI_LMW_MAX_WEIGHTS   0x4
+#endif // !! AI_LMW_MAX_WEIGHTS
+
+// ---------------------------------------------------------------------------
+/** @brief Lower the deboning threshold in order to remove more bones.
+ *
+ * This is used by the #aiProcess_Debone PostProcess-Step.
+ * @note The default value is AI_DEBONE_THRESHOLD
+ * Property type: float.*/
+#define AI_CONFIG_PP_DB_THRESHOLD \
+    "PP_DB_THRESHOLD"
+
+// default value for AI_CONFIG_PP_LBW_MAX_WEIGHTS
+#if (!defined AI_DEBONE_THRESHOLD)
+#   define AI_DEBONE_THRESHOLD  1.0f
+#endif // !! AI_DEBONE_THRESHOLD
+
+// ---------------------------------------------------------------------------
+/** @brief Require all bones qualify for deboning before removing any
+ *
+ * This is used by the #aiProcess_Debone PostProcess-Step.
+ * @note The default value is 0
+ * Property type: bool.*/
+#define AI_CONFIG_PP_DB_ALL_OR_NONE \
+    "PP_DB_ALL_OR_NONE"
+
+/** @brief Default value for the #AI_CONFIG_PP_ICL_PTCACHE_SIZE property
+ */
+#ifndef PP_ICL_PTCACHE_SIZE
+#   define PP_ICL_PTCACHE_SIZE 12
+#endif
+
+// ---------------------------------------------------------------------------
+/** @brief Set the size of the post-transform vertex cache to optimize the
+ *    vertices for. This configures the #aiProcess_ImproveCacheLocality step.
+ *
+ * The size is given in vertices. Of course you can't know how the vertex
+ * format will exactly look like after the import returns, but you can still
+ * guess what your meshes will probably have.
+ * @note The default value is #PP_ICL_PTCACHE_SIZE. That results in slight
+ * performance improvements for most nVidia/AMD cards since 2002.
+ * Property type: integer.
+ */
+#define AI_CONFIG_PP_ICL_PTCACHE_SIZE   "PP_ICL_PTCACHE_SIZE"
+
+// ---------------------------------------------------------------------------
+/** @brief Enumerates components of the aiScene and aiMesh data structures
+ *  that can be excluded from the import using the #aiProcess_RemoveComponent step.
+ *
+ *  See the documentation to #aiProcess_RemoveComponent for more details.
+ */
+enum aiComponent
+{
+    /** Normal vectors */
+#ifdef SWIG
+    aiComponent_NORMALS = 0x2,
+#else
+    aiComponent_NORMALS = 0x2u,
+#endif
+
+    /** Tangents and bitangents go always together ... */
+#ifdef SWIG
+    aiComponent_TANGENTS_AND_BITANGENTS = 0x4,
+#else
+    aiComponent_TANGENTS_AND_BITANGENTS = 0x4u,
+#endif
+
+    /** ALL color sets
+     * Use aiComponent_COLORn(N) to specify the N'th set */
+    aiComponent_COLORS = 0x8,
+
+    /** ALL texture UV sets
+     * aiComponent_TEXCOORDn(N) to specify the N'th set  */
+    aiComponent_TEXCOORDS = 0x10,
+
+    /** Removes all bone weights from all meshes.
+     * The scenegraph nodes corresponding to the bones are NOT removed.
+     * use the #aiProcess_OptimizeGraph step to do this */
+    aiComponent_BONEWEIGHTS = 0x20,
+
+    /** Removes all node animations (aiScene::mAnimations).
+     * The corresponding scenegraph nodes are NOT removed.
+     * use the #aiProcess_OptimizeGraph step to do this */
+    aiComponent_ANIMATIONS = 0x40,
+
+    /** Removes all embedded textures (aiScene::mTextures) */
+    aiComponent_TEXTURES = 0x80,
+
+    /** Removes all light sources (aiScene::mLights).
+     * The corresponding scenegraph nodes are NOT removed.
+     * use the #aiProcess_OptimizeGraph step to do this */
+    aiComponent_LIGHTS = 0x100,
+
+    /** Removes all cameras (aiScene::mCameras).
+     * The corresponding scenegraph nodes are NOT removed.
+     * use the #aiProcess_OptimizeGraph step to do this */
+    aiComponent_CAMERAS = 0x200,
+
+    /** Removes all meshes (aiScene::mMeshes). */
+    aiComponent_MESHES = 0x400,
+
+    /** Removes all materials. One default material will
+     * be generated, so aiScene::mNumMaterials will be 1. */
+    aiComponent_MATERIALS = 0x800,
+
+
+    /** This value is not used. It is just there to force the
+     *  compiler to map this enum to a 32 Bit integer. */
+#ifndef SWIG
+    _aiComponent_Force32Bit = 0x9fffffff
+#endif
+};
+
+// Remove a specific color channel 'n'
+#define aiComponent_COLORSn(n) (1u << (n+20u))
+
+// Remove a specific UV channel 'n'
+#define aiComponent_TEXCOORDSn(n) (1u << (n+25u))
+
+// ---------------------------------------------------------------------------
+/** @brief Input parameter to the #aiProcess_RemoveComponent step:
+ *  Specifies the parts of the data structure to be removed.
+ *
+ * See the documentation to this step for further details. The property
+ * is expected to be an integer, a bitwise combination of the
+ * #aiComponent flags defined above in this header. The default
+ * value is 0. Important: if no valid mesh is remaining after the
+ * step has been executed (e.g you thought it was funny to specify ALL
+ * of the flags defined above) the import FAILS. Mainly because there is
+ * no data to work on anymore ...
+ */
+#define AI_CONFIG_PP_RVC_FLAGS              \
+    "PP_RVC_FLAGS"
+
+// ---------------------------------------------------------------------------
+/** @brief Input parameter to the #aiProcess_SortByPType step:
+ *  Specifies which primitive types are removed by the step.
+ *
+ *  This is a bitwise combination of the aiPrimitiveType flags.
+ *  Specifying all of them is illegal, of course. A typical use would
+ *  be to exclude all line and point meshes from the import. This
+ *  is an integer property, its default value is 0.
+ */
+#define AI_CONFIG_PP_SBP_REMOVE             \
+    "PP_SBP_REMOVE"
+
+// ---------------------------------------------------------------------------
+/** @brief Input parameter to the #aiProcess_FindInvalidData step:
+ *  Specifies the floating-point accuracy for animation values. The step
+ *  checks for animation tracks where all frame values are absolutely equal
+ *  and removes them. This tweakable controls the epsilon for floating-point
+ *  comparisons - two keys are considered equal if the invariant
+ *  abs(n0-n1)>epsilon holds true for all vector respectively quaternion
+ *  components. The default value is 0.f - comparisons are exact then.
+ */
+#define AI_CONFIG_PP_FID_ANIM_ACCURACY              \
+    "PP_FID_ANIM_ACCURACY"
+
+
+// TransformUVCoords evaluates UV scalings
+#define AI_UVTRAFO_SCALING 0x1
+
+// TransformUVCoords evaluates UV rotations
+#define AI_UVTRAFO_ROTATION 0x2
+
+// TransformUVCoords evaluates UV translation
+#define AI_UVTRAFO_TRANSLATION 0x4
+
+// Everything baked together -> default value
+#define AI_UVTRAFO_ALL (AI_UVTRAFO_SCALING | AI_UVTRAFO_ROTATION | AI_UVTRAFO_TRANSLATION)
+
+// ---------------------------------------------------------------------------
+/** @brief Input parameter to the #aiProcess_TransformUVCoords step:
+ *  Specifies which UV transformations are evaluated.
+ *
+ *  This is a bitwise combination of the AI_UVTRAFO_XXX flags (integer
+ *  property, of course). By default all transformations are enabled
+ * (AI_UVTRAFO_ALL).
+ */
+#define AI_CONFIG_PP_TUV_EVALUATE               \
+    "PP_TUV_EVALUATE"
+
+// ---------------------------------------------------------------------------
+/** @brief A hint to assimp to favour speed against import quality.
+ *
+ * Enabling this option may result in faster loading, but it needn't.
+ * It represents just a hint to loaders and post-processing steps to use
+ * faster code paths, if possible.
+ * This property is expected to be an integer, != 0 stands for true.
+ * The default value is 0.
+ */
+#define AI_CONFIG_FAVOUR_SPEED              \
+ "FAVOUR_SPEED"
+
+
+// ###########################################################################
+// IMPORTER SETTINGS
+// Various stuff to fine-tune the behaviour of specific importer plugins.
+// ###########################################################################
+
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will merge all geometry layers present
+ *    in the source file or take only the first.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS \
+    "IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will read all materials present in the
+ *    source file or take only the referenced materials.
+ *
+ * This is void unless IMPORT_FBX_READ_MATERIALS=1.
+ *
+ * The default value is false (0)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS \
+    "IMPORT_FBX_READ_ALL_MATERIALS"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will read materials.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_READ_MATERIALS \
+    "IMPORT_FBX_READ_MATERIALS"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will read cameras.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_READ_CAMERAS \
+    "IMPORT_FBX_READ_CAMERAS"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will read light sources.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_READ_LIGHTS \
+    "IMPORT_FBX_READ_LIGHTS"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will read animations.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS \
+    "IMPORT_FBX_READ_ANIMATIONS"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will act in strict mode in which only
+ *    FBX 2013 is supported and any other sub formats are rejected. FBX 2013
+ *    is the primary target for the importer, so this format is best
+ *    supported and well-tested.
+ *
+ * The default value is false (0)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_STRICT_MODE \
+    "IMPORT_FBX_STRICT_MODE"
+
+// ---------------------------------------------------------------------------
+/** @brief Set whether the fbx importer will preserve pivot points for
+ *    transformations (as extra nodes). If set to false, pivots and offsets
+ *    will be evaluated whenever possible.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS \
+    "IMPORT_FBX_PRESERVE_PIVOTS"
+
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the importer will drop empty animation curves or
+ *    animation curves which match the bind pose transformation over their
+ *    entire defined range.
+ *
+ * The default value is true (1)
+ * Property type: bool
+ */
+#define AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES \
+    "IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES"
+
+
+
+// ---------------------------------------------------------------------------
+/** @brief  Set the vertex animation keyframe to be imported
+ *
+ * ASSIMP does not support vertex keyframes (only bone animation is supported).
+ * The library reads only one frame of models with vertex animations.
+ * By default this is the first frame.
+ * \note The default value is 0. This option applies to all importers.
+ *   However, it is also possible to override the global setting
+ *   for a specific loader. You can use the AI_CONFIG_IMPORT_XXX_KEYFRAME
+ *   options (where XXX is a placeholder for the file format for which you
+ *   want to override the global setting).
+ * Property type: integer.
+ */
+#define AI_CONFIG_IMPORT_GLOBAL_KEYFRAME    "IMPORT_GLOBAL_KEYFRAME"
+
+#define AI_CONFIG_IMPORT_MD3_KEYFRAME       "IMPORT_MD3_KEYFRAME"
+#define AI_CONFIG_IMPORT_MD2_KEYFRAME       "IMPORT_MD2_KEYFRAME"
+#define AI_CONFIG_IMPORT_MDL_KEYFRAME       "IMPORT_MDL_KEYFRAME"
+#define AI_CONFIG_IMPORT_MDC_KEYFRAME       "IMPORT_MDC_KEYFRAME"
+#define AI_CONFIG_IMPORT_SMD_KEYFRAME       "IMPORT_SMD_KEYFRAME"
+#define AI_CONFIG_IMPORT_UNREAL_KEYFRAME    "IMPORT_UNREAL_KEYFRAME"
+
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures the AC loader to collect all surfaces which have the
+ *    "Backface cull" flag set in separate meshes.
+ *
+ *  Property type: bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_AC_SEPARATE_BFCULL \
+    "IMPORT_AC_SEPARATE_BFCULL"
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures whether the AC loader evaluates subdivision surfaces (
+ *  indicated by the presence of the 'subdiv' attribute in the file). By
+ *  default, Assimp performs the subdivision using the standard
+ *  Catmull-Clark algorithm
+ *
+ * * Property type: bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_AC_EVAL_SUBDIVISION    \
+    "IMPORT_AC_EVAL_SUBDIVISION"
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures the UNREAL 3D loader to separate faces with different
+ *    surface flags (e.g. two-sided vs. single-sided).
+ *
+ * * Property type: bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_UNREAL_HANDLE_FLAGS \
+    "UNREAL_HANDLE_FLAGS"
+
+// ---------------------------------------------------------------------------
+/** @brief Configures the terragen import plugin to compute uv's for
+ *  terrains, if not given. Furthermore a default texture is assigned.
+ *
+ * UV coordinates for terrains are so simple to compute that you'll usually
+ * want to compute them on your own, if you need them. This option is intended
+ * for model viewers which want to offer an easy way to apply textures to
+ * terrains.
+ * * Property type: bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_TER_MAKE_UVS \
+    "IMPORT_TER_MAKE_UVS"
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures the ASE loader to always reconstruct normal vectors
+ *  basing on the smoothing groups loaded from the file.
+ *
+ * Some ASE files have carry invalid normals, other don't.
+ * * Property type: bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_ASE_RECONSTRUCT_NORMALS    \
+    "IMPORT_ASE_RECONSTRUCT_NORMALS"
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures the M3D loader to detect and process multi-part
+ *    Quake player models.
+ *
+ * These models usually consist of 3 files, lower.md3, upper.md3 and
+ * head.md3. If this property is set to true, Assimp will try to load and
+ * combine all three files if one of them is loaded.
+ * Property type: bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_MD3_HANDLE_MULTIPART \
+    "IMPORT_MD3_HANDLE_MULTIPART"
+
+// ---------------------------------------------------------------------------
+/** @brief  Tells the MD3 loader which skin files to load.
+ *
+ * When loading MD3 files, Assimp checks whether a file
+ * [md3_file_name]_[skin_name].skin is existing. These files are used by
+ * Quake III to be able to assign different skins (e.g. red and blue team)
+ * to models. 'default', 'red', 'blue' are typical skin names.
+ * Property type: String. Default value: "default".
+ */
+#define AI_CONFIG_IMPORT_MD3_SKIN_NAME \
+    "IMPORT_MD3_SKIN_NAME"
+
+// ---------------------------------------------------------------------------
+/** @brief  Specify the Quake 3 shader file to be used for a particular
+ *  MD3 file. This can also be a search path.
+ *
+ * By default Assimp's behaviour is as follows: If a MD3 file
+ * <tt>any_path/models/any_q3_subdir/model_name/file_name.md3</tt> is
+ * loaded, the library tries to locate the corresponding shader file in
+ * <tt>any_path/scripts/model_name.shader</tt>. This property overrides this
+ * behaviour. It can either specify a full path to the shader to be loaded
+ * or alternatively the path (relative or absolute) to the directory where
+ * the shaders for all MD3s to be loaded reside. Assimp attempts to open
+ * <tt>IMPORT_MD3_SHADER_SRC/model_name.shader</tt> first, <tt>IMPORT_MD3_SHADER_SRC/file_name.shader</tt>
+ * is the fallback file. Note that IMPORT_MD3_SHADER_SRC should have a terminal (back)slash.
+ * Property type: String. Default value: n/a.
+ */
+#define AI_CONFIG_IMPORT_MD3_SHADER_SRC \
+    "IMPORT_MD3_SHADER_SRC"
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures the LWO loader to load just one layer from the model.
+ *
+ * LWO files consist of layers and in some cases it could be useful to load
+ * only one of them. This property can be either a string - which specifies
+ * the name of the layer - or an integer - the index of the layer. If the
+ * property is not set the whole LWO model is loaded. Loading fails if the
+ * requested layer is not available. The layer index is zero-based and the
+ * layer name may not be empty.<br>
+ * Property type: Integer. Default value: all layers are loaded.
+ */
+#define AI_CONFIG_IMPORT_LWO_ONE_LAYER_ONLY         \
+    "IMPORT_LWO_ONE_LAYER_ONLY"
+
+// ---------------------------------------------------------------------------
+/** @brief  Configures the MD5 loader to not load the MD5ANIM file for
+ *  a MD5MESH file automatically.
+ *
+ * The default strategy is to look for a file with the same name but the
+ * MD5ANIM extension in the same directory. If it is found, it is loaded
+ * and combined with the MD5MESH file. This configuration option can be
+ * used to disable this behaviour.
+ *
+ * * Property type: bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_MD5_NO_ANIM_AUTOLOAD           \
+    "IMPORT_MD5_NO_ANIM_AUTOLOAD"
+
+// ---------------------------------------------------------------------------
+/** @brief Defines the begin of the time range for which the LWS loader
+ *    evaluates animations and computes aiNodeAnim's.
+ *
+ * Assimp provides full conversion of LightWave's envelope system, including
+ * pre and post conditions. The loader computes linearly subsampled animation
+ * chanels with the frame rate given in the LWS file. This property defines
+ * the start time. Note: animation channels are only generated if a node
+ * has at least one envelope with more tan one key assigned. This property.
+ * is given in frames, '0' is the first frame. By default, if this property
+ * is not set, the importer takes the animation start from the input LWS
+ * file ('FirstFrame' line)<br>
+ * Property type: Integer. Default value: taken from file.
+ *
+ * @see AI_CONFIG_IMPORT_LWS_ANIM_END - end of the imported time range
+ */
+#define AI_CONFIG_IMPORT_LWS_ANIM_START         \
+    "IMPORT_LWS_ANIM_START"
+#define AI_CONFIG_IMPORT_LWS_ANIM_END           \
+    "IMPORT_LWS_ANIM_END"
+
+// ---------------------------------------------------------------------------
+/** @brief Defines the output frame rate of the IRR loader.
+ *
+ * IRR animations are difficult to convert for Assimp and there will
+ * always be a loss of quality. This setting defines how many keys per second
+ * are returned by the converter.<br>
+ * Property type: integer. Default value: 100
+ */
+#define AI_CONFIG_IMPORT_IRR_ANIM_FPS               \
+    "IMPORT_IRR_ANIM_FPS"
+
+// ---------------------------------------------------------------------------
+/** @brief Ogre Importer will try to find referenced materials from this file.
+ *
+ * Ogre meshes reference with material names, this does not tell Assimp the file
+ * where it is located in. Assimp will try to find the source file in the following
+ * order: <material-name>.material, <mesh-filename-base>.material and
+ * lastly the material name defined by this config property.
+ * <br>
+ * Property type: String. Default value: Scene.material.
+ */
+#define AI_CONFIG_IMPORT_OGRE_MATERIAL_FILE \
+    "IMPORT_OGRE_MATERIAL_FILE"
+
+// ---------------------------------------------------------------------------
+/** @brief Ogre Importer detect the texture usage from its filename.
+ *
+ * Ogre material texture units do not define texture type, the textures usage
+ * depends on the used shader or Ogre's fixed pipeline. If this config property
+ * is true Assimp will try to detect the type from the textures filename postfix:
+ * _n, _nrm, _nrml, _normal, _normals and _normalmap for normal map, _s, _spec,
+ * _specular and _specularmap for specular map, _l, _light, _lightmap, _occ
+ * and _occlusion for light map, _disp and _displacement for displacement map.
+ * The matching is case insensitive. Post fix is taken between the last
+ * underscore and the last period.
+ * Default behavior is to detect type from lower cased texture unit name by
+ * matching against: normalmap, specularmap, lightmap and displacementmap.
+ * For both cases if no match is found aiTextureType_DIFFUSE is used.
+ * <br>
+ * Property type: Bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME \
+    "IMPORT_OGRE_TEXTURETYPE_FROM_FILENAME"
+
+/** @brief Specifies whether the IFC loader skips over IfcSpace elements.
+ *
+ * IfcSpace elements (and their geometric representations) are used to
+ * represent, well, free space in a building storey.<br>
+ * Property type: Bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS "IMPORT_IFC_SKIP_SPACE_REPRESENTATIONS"
+
+ /** @brief Specifies whether the Android JNI asset extraction is supported.
+  *
+  * Turn on this option if you want to manage assets in native
+  * Android application without having to keep the internal directory and asset
+  * manager pointer.
+  */
+ #define AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT "AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT"
+
+
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the IFC loader skips over
+ *    shape representations of type 'Curve2D'.
+ *
+ * A lot of files contain both a faceted mesh representation and a outline
+ * with a presentation type of 'Curve2D'. Currently Assimp doesn't convert those,
+ * so turning this option off just clutters the log with errors.<br>
+ * Property type: Bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS "IMPORT_IFC_SKIP_CURVE_REPRESENTATIONS"
+
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the IFC loader will use its own, custom triangulation
+ *   algorithm to triangulate wall and floor meshes.
+ *
+ * If this property is set to false, walls will be either triangulated by
+ * #aiProcess_Triangulate or will be passed through as huge polygons with
+ * faked holes (i.e. holes that are connected with the outer boundary using
+ * a dummy edge). It is highly recommended to set this property to true
+ * if you want triangulated data because #aiProcess_Triangulate is known to
+ * have problems with the kind of polygons that the IFC loader spits out for
+ * complicated meshes.
+ * Property type: Bool. Default value: true.
+ */
+#define AI_CONFIG_IMPORT_IFC_CUSTOM_TRIANGULATION "IMPORT_IFC_CUSTOM_TRIANGULATION"
+
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the Collada loader will ignore the provided up direction.
+ *
+ * If this property is set to true, the up direction provided in the file header will
+ * be ignored and the file will be loaded as is.
+ * Property type: Bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION "IMPORT_COLLADA_IGNORE_UP_DIRECTION"
+
+// ---------------------------------------------------------------------------
+/** @brief Specifies whether the Collada loader will invert the transparency value.
+ *
+ * If this property is set to true, the transparency value will be interpreted as the
+ * inverse of the usual transparency. This is useful because lots of exporters does
+ * not respect the standard and do the opposite of what is normally expected.
+ * Property type: Bool. Default value: false.
+ */
+#define AI_CONFIG_IMPORT_COLLADA_INVERT_TRANSPARENCY "IMPORT_COLLADA_INVERT_TRANSPARENCY"
+
+// ---------- All the Export defines ------------
+
+/** @brief Specifies the xfile use double for real values of float
+ *
+ * Property type: Bool. Default value: false.
+ */
+
+#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
+
+#endif // !! AI_CONFIG_H_INC

+ 287 - 0
include/assimp/defs.h

@@ -0,0 +1,287 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file defs.h
+ *  @brief Assimp build configuration setup. See the notes in the comment
+ *  blocks to find out how to customize _your_ Assimp build.
+ */
+
+#ifndef INCLUDED_AI_DEFINES_H
+#define INCLUDED_AI_DEFINES_H
+
+    //////////////////////////////////////////////////////////////////////////
+    /* Define ASSIMP_BUILD_NO_XX_IMPORTER to disable a specific
+     * file format loader. The loader is be excluded from the
+     * build in this case. 'XX' stands for the most common file
+     * extension of the file format. E.g.:
+     * ASSIMP_BUILD_NO_X_IMPORTER disables the X loader.
+     *
+     * If you're unsure about that, take a look at the implementation of the
+     * import plugin you wish to disable. You'll find the right define in the
+     * first lines of the corresponding unit.
+     *
+     * Other (mixed) configuration switches are listed here:
+     *    ASSIMP_BUILD_NO_COMPRESSED_X
+     *      - Disable support for compressed X files (zip)
+     *    ASSIMP_BUILD_NO_COMPRESSED_BLEND
+     *      - Disable support for compressed Blender files (zip)
+     *    ASSIMP_BUILD_NO_COMPRESSED_IFC
+     *      - Disable support for IFCZIP files (unzip)
+     */
+    //////////////////////////////////////////////////////////////////////////
+
+#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
+#   define ASSIMP_BUILD_NEED_Z_INFLATE
+#endif
+
+#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
+#   define ASSIMP_BUILD_NEED_Z_INFLATE
+#endif
+
+#ifndef ASSIMP_BUILD_NO_COMPRESSED_IFC
+#   define ASSIMP_BUILD_NEED_Z_INFLATE
+#   define ASSIMP_BUILD_NEED_UNZIP
+#endif
+
+#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
+#   define ASSIMP_BUILD_NEED_Z_INFLATE
+#   define ASSIMP_BUILD_NEED_UNZIP
+#endif
+
+    //////////////////////////////////////////////////////////////////////////
+    /* Define ASSIMP_BUILD_NO_XX_PROCESS to disable a specific
+     * post processing step. This is the current list of process names ('XX'):
+     * CALCTANGENTS
+     * JOINVERTICES
+     * TRIANGULATE
+     * GENFACENORMALS
+     * GENVERTEXNORMALS
+     * REMOVEVC
+     * SPLITLARGEMESHES
+     * PRETRANSFORMVERTICES
+     * LIMITBONEWEIGHTS
+     * VALIDATEDS
+     * IMPROVECACHELOCALITY
+     * FIXINFACINGNORMALS
+     * REMOVE_REDUNDANTMATERIALS
+     * OPTIMIZEGRAPH
+     * SORTBYPTYPE
+     * FINDINVALIDDATA
+     * TRANSFORMTEXCOORDS
+     * GENUVCOORDS
+     * ENTITYMESHBUILDER
+     * MAKELEFTHANDED
+     * FLIPUVS
+     * FLIPWINDINGORDER
+     * OPTIMIZEMESHES
+     * OPTIMIZEANIMS
+     * OPTIMIZEGRAPH
+     * GENENTITYMESHES
+     * FIXTEXTUREPATHS */
+    //////////////////////////////////////////////////////////////////////////
+
+#ifdef _MSC_VER
+#   undef ASSIMP_API
+
+    //////////////////////////////////////////////////////////////////////////
+    /* Define 'ASSIMP_BUILD_DLL_EXPORT' to build a DLL of the library */
+    //////////////////////////////////////////////////////////////////////////
+#   ifdef ASSIMP_BUILD_DLL_EXPORT
+#       define ASSIMP_API __declspec(dllexport)
+#       define ASSIMP_API_WINONLY __declspec(dllexport)
+#       pragma warning (disable : 4251)
+
+    //////////////////////////////////////////////////////////////////////////
+    /* Define 'ASSIMP_DLL' before including Assimp to link to ASSIMP in
+     * an external DLL under Windows. Default is static linkage. */
+    //////////////////////////////////////////////////////////////////////////
+#   elif (defined ASSIMP_DLL)
+#       define ASSIMP_API __declspec(dllimport)
+#       define ASSIMP_API_WINONLY __declspec(dllimport)
+#   else
+#       define ASSIMP_API
+#       define ASSIMP_API_WINONLY
+#   endif
+
+    /* Force the compiler to inline a function, if possible
+     */
+#   define AI_FORCE_INLINE __forceinline
+
+    /* Tells the compiler that a function never returns. Used in code analysis
+     * to skip dead paths (e.g. after an assertion evaluated to false). */
+#   define AI_WONT_RETURN __declspec(noreturn)
+
+#elif defined(SWIG)
+
+    /* Do nothing, the relevant defines are all in AssimpSwigPort.i */
+
+#else
+
+#   define AI_WONT_RETURN
+
+#   define ASSIMP_API __attribute__ ((visibility("default")))
+#   define ASSIMP_API_WINONLY
+#   define AI_FORCE_INLINE inline
+#endif // (defined _MSC_VER)
+
+#ifdef __GNUC__
+#   define AI_WONT_RETURN_SUFFIX  __attribute__((noreturn))
+#else
+#   define AI_WONT_RETURN_SUFFIX
+#endif // (defined __clang__)
+
+#ifdef __cplusplus
+    /* No explicit 'struct' and 'enum' tags for C++, this keeps showing up
+     * in doxydocs.
+     */
+#   define C_STRUCT
+#   define C_ENUM
+#else
+    //////////////////////////////////////////////////////////////////////////
+    /* To build the documentation, make sure ASSIMP_DOXYGEN_BUILD
+     * is defined by Doxygen's preprocessor. The corresponding
+     * entries in the DOXYFILE are: */
+    //////////////////////////////////////////////////////////////////////////
+#if 0
+    ENABLE_PREPROCESSING   = YES
+    MACRO_EXPANSION        = YES
+    EXPAND_ONLY_PREDEF     = YES
+    SEARCH_INCLUDES        = YES
+    INCLUDE_PATH           =
+    INCLUDE_FILE_PATTERNS  =
+    PREDEFINED             = ASSIMP_DOXYGEN_BUILD=1
+    EXPAND_AS_DEFINED      = C_STRUCT C_ENUM
+    SKIP_FUNCTION_MACROS   = YES
+#endif
+    //////////////////////////////////////////////////////////////////////////
+    /* Doxygen gets confused if we use c-struct typedefs to avoid
+     * the explicit 'struct' notation. This trick here has the same
+     * effect as the TYPEDEF_HIDES_STRUCT option, but we don't need
+     * to typedef all structs/enums. */
+     //////////////////////////////////////////////////////////////////////////
+#   if (defined ASSIMP_DOXYGEN_BUILD)
+#       define C_STRUCT
+#       define C_ENUM
+#   else
+#       define C_STRUCT struct
+#       define C_ENUM   enum
+#   endif
+#endif
+
+#if (defined(__BORLANDC__) || defined (__BCPLUSPLUS__))
+#error Currently, Borland is unsupported. Feel free to port Assimp.
+
+// "W8059 Packgr��e der Struktur ge�ndert"
+
+#endif
+    //////////////////////////////////////////////////////////////////////////
+    /* Define 'ASSIMP_BUILD_BOOST_WORKAROUND' to compile assimp
+     * without boost. This is done by using a few workaround
+     * classes and brings some limitations (e.g. some logging won't be done,
+     * the library won't utilize threads or be threadsafe at all).
+     * This implies the 'ASSIMP_BUILD_SINGLETHREADED' setting. */
+     //////////////////////////////////////////////////////////////////////////
+#ifdef ASSIMP_BUILD_BOOST_WORKAROUND
+
+    // threading support requires boost
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+#   define ASSIMP_BUILD_SINGLETHREADED
+#endif
+
+#endif // !! ASSIMP_BUILD_BOOST_WORKAROUND
+
+    //////////////////////////////////////////////////////////////////////////
+    /* Define ASSIMP_BUILD_SINGLETHREADED to compile assimp
+     * without threading support. The library doesn't utilize
+     * threads then and is itself not threadsafe.
+     * If this flag is specified boost::threads is *not* required. */
+    //////////////////////////////////////////////////////////////////////////
+#ifndef ASSIMP_BUILD_SINGLETHREADED
+#   define ASSIMP_BUILD_SINGLETHREADED
+#endif
+
+#if defined(_DEBUG) || ! defined(NDEBUG)
+#   define ASSIMP_BUILD_DEBUG
+#endif
+
+    //////////////////////////////////////////////////////////////////////////
+    /* Useful constants */
+    //////////////////////////////////////////////////////////////////////////
+
+/* This is PI. Hi PI. */
+#define AI_MATH_PI          (3.141592653589793238462643383279 )
+#define AI_MATH_TWO_PI      (AI_MATH_PI * 2.0)
+#define AI_MATH_HALF_PI     (AI_MATH_PI * 0.5)
+
+/* And this is to avoid endless casts to float */
+#define AI_MATH_PI_F        (3.1415926538f)
+#define AI_MATH_TWO_PI_F    (AI_MATH_PI_F * 2.0f)
+#define AI_MATH_HALF_PI_F   (AI_MATH_PI_F * 0.5f)
+
+/* Tiny macro to convert from radians to degrees and back */
+#define AI_DEG_TO_RAD(x) ((x)*0.0174532925f)
+#define AI_RAD_TO_DEG(x) ((x)*57.2957795f)
+
+/* Support for big-endian builds */
+#if defined(__BYTE_ORDER__)
+#   if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
+#       if !defined(__BIG_ENDIAN__)
+#           define __BIG_ENDIAN__
+#       endif
+#   else /* little endian */
+#       if defined (__BIG_ENDIAN__)
+#           undef __BIG_ENDIAN__
+#       endif
+#   endif
+#endif
+#if defined(__BIG_ENDIAN__)
+#   define AI_BUILD_BIG_ENDIAN
+#endif
+
+
+/* To avoid running out of memory
+ * This can be adjusted for specific use cases
+ * It's NOT a total limit, just a limit for individual allocations
+ */
+#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type))
+
+
+#endif // !! INCLUDED_AI_DEFINES_H

+ 143 - 0
include/assimp/importerdesc.h

@@ -0,0 +1,143 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file importerdesc.h
+ *  @brief #aiImporterFlags, aiImporterDesc implementation.
+ */
+#ifndef INCLUDED_AI_IMPORTER_DESC_H
+#define INCLUDED_AI_IMPORTER_DESC_H
+
+
+/** Mixed set of flags for #aiImporterDesc, indicating some features
+  *  common to many importers*/
+enum aiImporterFlags
+{
+    /** Indicates that there is a textual encoding of the
+     *  file format; and that it is supported.*/
+    aiImporterFlags_SupportTextFlavour = 0x1,
+
+    /** Indicates that there is a binary encoding of the
+     *  file format; and that it is supported.*/
+    aiImporterFlags_SupportBinaryFlavour = 0x2,
+
+    /** Indicates that there is a compressed encoding of the
+     *  file format; and that it is supported.*/
+    aiImporterFlags_SupportCompressedFlavour = 0x4,
+
+    /** Indicates that the importer reads only a very particular
+      * subset of the file format. This happens commonly for
+      * declarative or procedural formats which cannot easily
+      * be mapped to #aiScene */
+    aiImporterFlags_LimitedSupport = 0x8,
+
+    /** Indicates that the importer is highly experimental and
+      * should be used with care. This only happens for trunk
+      * (i.e. SVN) versions, experimental code is not included
+      * in releases. */
+    aiImporterFlags_Experimental = 0x10
+};
+
+
+/** Meta information about a particular importer. Importers need to fill
+ *  this structure, but they can freely decide how talkative they are.
+ *  A common use case for loader meta info is a user interface
+ *  in which the user can choose between various import/export file
+ *  formats. Building such an UI by hand means a lot of maintenance
+ *  as importers/exporters are added to Assimp, so it might be useful
+ *  to have a common mechanism to query some rough importer
+ *  characteristics. */
+struct aiImporterDesc
+{
+    /** Full name of the importer (i.e. Blender3D importer)*/
+    const char* mName;
+
+    /** Original author (left blank if unknown or whole assimp team) */
+    const char* mAuthor;
+
+    /** Current maintainer, left blank if the author maintains */
+    const char* mMaintainer;
+
+    /** Implementation comments, i.e. unimplemented features*/
+    const char* mComments;
+
+    /** These flags indicate some characteristics common to many
+        importers. */
+    unsigned int mFlags;
+
+    /** Minimum format version that can be loaded im major.minor format,
+        both are set to 0 if there is either no version scheme
+        or if the loader doesn't care. */
+    unsigned int mMinMajor;
+    unsigned int mMinMinor;
+
+    /** Maximum format version that can be loaded im major.minor format,
+        both are set to 0 if there is either no version scheme
+        or if the loader doesn't care. Loaders that expect to be
+        forward-compatible to potential future format versions should
+        indicate  zero, otherwise they should specify the current
+        maximum version.*/
+    unsigned int mMaxMajor;
+    unsigned int mMaxMinor;
+
+    /** List of file extensions this importer can handle.
+        List entries are separated by space characters.
+        All entries are lower case without a leading dot (i.e.
+        "xml dae" would be a valid value. Note that multiple
+        importers may respond to the same file extension -
+        assimp calls all importers in the order in which they
+        are registered and each importer gets the opportunity
+        to load the file until one importer "claims" the file. Apart
+        from file extension checks, importers typically use
+        other methods to quickly reject files (i.e. magic
+        words) so this does not mean that common or generic
+        file extensions such as XML would be tediously slow. */
+    const char* mFileExtensions;
+};
+
+/** \brief  Returns the Importer description for a given extension.
+
+Will return a NULL-pointer if no assigned importer desc. was found for the given extension
+    \param  extension   [in] The extension to look for
+    \return A pointer showing to the ImporterDesc, \see aiImporterDesc.
+*/
+ASSIMP_API const C_STRUCT aiImporterDesc* aiGetImporterDesc( const char *extension );
+
+#endif

+ 240 - 0
include/assimp/light.h

@@ -0,0 +1,240 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file light.h
+ *  @brief Defines the aiLight data structure
+ */
+
+#ifndef __AI_LIGHT_H_INC__
+#define __AI_LIGHT_H_INC__
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+/** Enumerates all supported types of light sources.
+ */
+enum aiLightSourceType
+{
+    aiLightSource_UNDEFINED     = 0x0,
+
+    //! A directional light source has a well-defined direction
+    //! but is infinitely far away. That's quite a good
+    //! approximation for sun light.
+    aiLightSource_DIRECTIONAL   = 0x1,
+
+    //! A point light source has a well-defined position
+    //! in space but no direction - it emits light in all
+    //! directions. A normal bulb is a point light.
+    aiLightSource_POINT         = 0x2,
+
+    //! A spot light source emits light in a specific
+    //! angle. It has a position and a direction it is pointing to.
+    //! A good example for a spot light is a light spot in
+    //! sport arenas.
+    aiLightSource_SPOT          = 0x3,
+
+    //! The generic light level of the world, including the bounces
+    //! of all other lightsources.
+    //! Typically, there's at most one ambient light in a scene.
+    //! This light type doesn't have a valid position, direction, or
+    //! other properties, just a color.
+    aiLightSource_AMBIENT       = 0x4,
+
+
+    /** This value is not used. It is just there to force the
+     *  compiler to map this enum to a 32 Bit integer.
+     */
+#ifndef SWIG
+    _aiLightSource_Force32Bit = INT_MAX
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** Helper structure to describe a light source.
+ *
+ *  Assimp supports multiple sorts of light sources, including
+ *  directional, point and spot lights. All of them are defined with just
+ *  a single structure and distinguished by their parameters.
+ *  Note - some file formats (such as 3DS, ASE) export a "target point" -
+ *  the point a spot light is looking at (it can even be animated). Assimp
+ *  writes the target point as a subnode of a spotlights's main node,
+ *  called "<spotName>.Target". However, this is just additional information
+ *  then, the transformation tracks of the main node make the
+ *  spot light already point in the right direction.
+*/
+struct aiLight
+{
+    /** The name of the light source.
+     *
+     *  There must be a node in the scenegraph with the same name.
+     *  This node specifies the position of the light in the scene
+     *  hierarchy and can be animated.
+     */
+    C_STRUCT aiString mName;
+
+    /** The type of the light source.
+     *
+     * aiLightSource_UNDEFINED is not a valid value for this member.
+     */
+    C_ENUM aiLightSourceType mType;
+
+    /** Position of the light source in space. Relative to the
+     *  transformation of the node corresponding to the light.
+     *
+     *  The position is undefined for directional lights.
+     */
+    C_STRUCT aiVector3D mPosition;
+
+    /** Direction of the light source in space. Relative to the
+     *  transformation of the node corresponding to the light.
+     *
+     *  The direction is undefined for point lights. The vector
+     *  may be normalized, but it needn't.
+     */
+    C_STRUCT aiVector3D mDirection;
+
+    /** Constant light attenuation factor.
+     *
+     *  The intensity of the light source at a given distance 'd' from
+     *  the light's position is
+     *  @code
+     *  Atten = 1/( att0 + att1 * d + att2 * d*d)
+     *  @endcode
+     *  This member corresponds to the att0 variable in the equation.
+     *  Naturally undefined for directional lights.
+     */
+    float mAttenuationConstant;
+
+    /** Linear light attenuation factor.
+     *
+     *  The intensity of the light source at a given distance 'd' from
+     *  the light's position is
+     *  @code
+     *  Atten = 1/( att0 + att1 * d + att2 * d*d)
+     *  @endcode
+     *  This member corresponds to the att1 variable in the equation.
+     *  Naturally undefined for directional lights.
+     */
+    float mAttenuationLinear;
+
+    /** Quadratic light attenuation factor.
+     *
+     *  The intensity of the light source at a given distance 'd' from
+     *  the light's position is
+     *  @code
+     *  Atten = 1/( att0 + att1 * d + att2 * d*d)
+     *  @endcode
+     *  This member corresponds to the att2 variable in the equation.
+     *  Naturally undefined for directional lights.
+     */
+    float mAttenuationQuadratic;
+
+    /** Diffuse color of the light source
+     *
+     *  The diffuse light color is multiplied with the diffuse
+     *  material color to obtain the final color that contributes
+     *  to the diffuse shading term.
+     */
+    C_STRUCT aiColor3D mColorDiffuse;
+
+    /** Specular color of the light source
+     *
+     *  The specular light color is multiplied with the specular
+     *  material color to obtain the final color that contributes
+     *  to the specular shading term.
+     */
+    C_STRUCT aiColor3D mColorSpecular;
+
+    /** Ambient color of the light source
+     *
+     *  The ambient light color is multiplied with the ambient
+     *  material color to obtain the final color that contributes
+     *  to the ambient shading term. Most renderers will ignore
+     *  this value it, is just a remaining of the fixed-function pipeline
+     *  that is still supported by quite many file formats.
+     */
+    C_STRUCT aiColor3D mColorAmbient;
+
+    /** Inner angle of a spot light's light cone.
+     *
+     *  The spot light has maximum influence on objects inside this
+     *  angle. The angle is given in radians. It is 2PI for point
+     *  lights and undefined for directional lights.
+     */
+    float mAngleInnerCone;
+
+    /** Outer angle of a spot light's light cone.
+     *
+     *  The spot light does not affect objects outside this angle.
+     *  The angle is given in radians. It is 2PI for point lights and
+     *  undefined for directional lights. The outer angle must be
+     *  greater than or equal to the inner angle.
+     *  It is assumed that the application uses a smooth
+     *  interpolation between the inner and the outer cone of the
+     *  spot light.
+     */
+    float mAngleOuterCone;
+
+#ifdef __cplusplus
+
+    aiLight()
+        :   mType                 (aiLightSource_UNDEFINED)
+        ,   mAttenuationConstant  (0.f)
+        ,   mAttenuationLinear    (1.f)
+        ,   mAttenuationQuadratic (0.f)
+        ,   mAngleInnerCone       ((float)AI_MATH_TWO_PI)
+        ,   mAngleOuterCone       ((float)AI_MATH_TWO_PI)
+    {
+    }
+
+#endif
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // !! __AI_LIGHT_H_INC__

+ 1542 - 0
include/assimp/material.h

@@ -0,0 +1,1542 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file material.h
+ *  @brief Defines the material system of the library
+ */
+
+#ifndef AI_MATERIAL_H_INC
+#define AI_MATERIAL_H_INC
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Name for default materials (2nd is used if meshes have UV coords)
+#define AI_DEFAULT_MATERIAL_NAME          "DefaultMaterial"
+
+// ---------------------------------------------------------------------------
+/** @brief Defines how the Nth texture of a specific type is combined with
+ *  the result of all previous layers.
+ *
+ *  Example (left: key, right: value): <br>
+ *  @code
+ *  DiffColor0     - gray
+ *  DiffTextureOp0 - aiTextureOpMultiply
+ *  DiffTexture0   - tex1.png
+ *  DiffTextureOp0 - aiTextureOpAdd
+ *  DiffTexture1   - tex2.png
+ *  @endcode
+ *  Written as equation, the final diffuse term for a specific pixel would be:
+ *  @code
+ *  diffFinal = DiffColor0 * sampleTex(DiffTexture0,UV0) +
+ *     sampleTex(DiffTexture1,UV0) * diffContrib;
+ *  @endcode
+ *  where 'diffContrib' is the intensity of the incoming light for that pixel.
+ */
+enum aiTextureOp
+{
+    /** T = T1 * T2 */
+    aiTextureOp_Multiply = 0x0,
+
+    /** T = T1 + T2 */
+    aiTextureOp_Add = 0x1,
+
+    /** T = T1 - T2 */
+    aiTextureOp_Subtract = 0x2,
+
+    /** T = T1 / T2 */
+    aiTextureOp_Divide = 0x3,
+
+    /** T = (T1 + T2) - (T1 * T2) */
+    aiTextureOp_SmoothAdd = 0x4,
+
+    /** T = T1 + (T2-0.5) */
+    aiTextureOp_SignedAdd = 0x5,
+
+
+#ifndef SWIG
+    _aiTextureOp_Force32Bit = INT_MAX
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** @brief Defines how UV coordinates outside the [0...1] range are handled.
+ *
+ *  Commonly refered to as 'wrapping mode'.
+ */
+enum aiTextureMapMode
+{
+    /** A texture coordinate u|v is translated to u%1|v%1
+     */
+    aiTextureMapMode_Wrap = 0x0,
+
+    /** Texture coordinates outside [0...1]
+     *  are clamped to the nearest valid value.
+     */
+    aiTextureMapMode_Clamp = 0x1,
+
+    /** If the texture coordinates for a pixel are outside [0...1]
+     *  the texture is not applied to that pixel
+     */
+    aiTextureMapMode_Decal = 0x3,
+
+    /** A texture coordinate u|v becomes u%1|v%1 if (u-(u%1))%2 is zero and
+     *  1-(u%1)|1-(v%1) otherwise
+     */
+    aiTextureMapMode_Mirror = 0x2,
+
+#ifndef SWIG
+    _aiTextureMapMode_Force32Bit = INT_MAX
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** @brief Defines how the mapping coords for a texture are generated.
+ *
+ *  Real-time applications typically require full UV coordinates, so the use of
+ *  the aiProcess_GenUVCoords step is highly recommended. It generates proper
+ *  UV channels for non-UV mapped objects, as long as an accurate description
+ *  how the mapping should look like (e.g spherical) is given.
+ *  See the #AI_MATKEY_MAPPING property for more details.
+ */
+enum aiTextureMapping
+{
+    /** The mapping coordinates are taken from an UV channel.
+     *
+     *  The #AI_MATKEY_UVWSRC key specifies from which UV channel
+     *  the texture coordinates are to be taken from (remember,
+     *  meshes can have more than one UV channel).
+    */
+    aiTextureMapping_UV = 0x0,
+
+     /** Spherical mapping */
+    aiTextureMapping_SPHERE = 0x1,
+
+     /** Cylindrical mapping */
+    aiTextureMapping_CYLINDER = 0x2,
+
+     /** Cubic mapping */
+    aiTextureMapping_BOX = 0x3,
+
+     /** Planar mapping */
+    aiTextureMapping_PLANE = 0x4,
+
+     /** Undefined mapping. Have fun. */
+    aiTextureMapping_OTHER = 0x5,
+
+
+#ifndef SWIG
+    _aiTextureMapping_Force32Bit = INT_MAX
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** @brief Defines the purpose of a texture
+ *
+ *  This is a very difficult topic. Different 3D packages support different
+ *  kinds of textures. For very common texture types, such as bumpmaps, the
+ *  rendering results depend on implementation details in the rendering
+ *  pipelines of these applications. Assimp loads all texture references from
+ *  the model file and tries to determine which of the predefined texture
+ *  types below is the best choice to match the original use of the texture
+ *  as closely as possible.<br>
+ *
+ *  In content pipelines you'll usually define how textures have to be handled,
+ *  and the artists working on models have to conform to this specification,
+ *  regardless which 3D tool they're using.
+ */
+enum aiTextureType
+{
+    /** Dummy value.
+     *
+     *  No texture, but the value to be used as 'texture semantic'
+     *  (#aiMaterialProperty::mSemantic) for all material properties
+     *  *not* related to textures.
+     */
+    aiTextureType_NONE = 0x0,
+
+
+
+    /** The texture is combined with the result of the diffuse
+     *  lighting equation.
+     */
+    aiTextureType_DIFFUSE = 0x1,
+
+    /** The texture is combined with the result of the specular
+     *  lighting equation.
+     */
+    aiTextureType_SPECULAR = 0x2,
+
+    /** The texture is combined with the result of the ambient
+     *  lighting equation.
+     */
+    aiTextureType_AMBIENT = 0x3,
+
+    /** The texture is added to the result of the lighting
+     *  calculation. It isn't influenced by incoming light.
+     */
+    aiTextureType_EMISSIVE = 0x4,
+
+    /** The texture is a height map.
+     *
+     *  By convention, higher gray-scale values stand for
+     *  higher elevations from the base height.
+     */
+    aiTextureType_HEIGHT = 0x5,
+
+    /** The texture is a (tangent space) normal-map.
+     *
+     *  Again, there are several conventions for tangent-space
+     *  normal maps. Assimp does (intentionally) not
+     *  distinguish here.
+     */
+    aiTextureType_NORMALS = 0x6,
+
+    /** The texture defines the glossiness of the material.
+     *
+     *  The glossiness is in fact the exponent of the specular
+     *  (phong) lighting equation. Usually there is a conversion
+     *  function defined to map the linear color values in the
+     *  texture to a suitable exponent. Have fun.
+    */
+    aiTextureType_SHININESS = 0x7,
+
+    /** The texture defines per-pixel opacity.
+     *
+     *  Usually 'white' means opaque and 'black' means
+     *  'transparency'. Or quite the opposite. Have fun.
+    */
+    aiTextureType_OPACITY = 0x8,
+
+    /** Displacement texture
+     *
+     *  The exact purpose and format is application-dependent.
+     *  Higher color values stand for higher vertex displacements.
+    */
+    aiTextureType_DISPLACEMENT = 0x9,
+
+    /** Lightmap texture (aka Ambient Occlusion)
+     *
+     *  Both 'Lightmaps' and dedicated 'ambient occlusion maps' are
+     *  covered by this material property. The texture contains a
+     *  scaling value for the final color value of a pixel. Its
+     *  intensity is not affected by incoming light.
+    */
+    aiTextureType_LIGHTMAP = 0xA,
+
+    /** Reflection texture
+     *
+     * Contains the color of a perfect mirror reflection.
+     * Rarely used, almost never for real-time applications.
+    */
+    aiTextureType_REFLECTION = 0xB,
+
+    /** Unknown texture
+     *
+     *  A texture reference that does not match any of the definitions
+     *  above is considered to be 'unknown'. It is still imported,
+     *  but is excluded from any further postprocessing.
+    */
+    aiTextureType_UNKNOWN = 0xC,
+
+
+#ifndef SWIG
+    _aiTextureType_Force32Bit = INT_MAX
+#endif
+};
+
+#define AI_TEXTURE_TYPE_MAX  aiTextureType_UNKNOWN
+
+// ---------------------------------------------------------------------------
+/** @brief Defines all shading models supported by the library
+ *
+ *  The list of shading modes has been taken from Blender.
+ *  See Blender documentation for more information. The API does
+ *  not distinguish between "specular" and "diffuse" shaders (thus the
+ *  specular term for diffuse shading models like Oren-Nayar remains
+ *  undefined). <br>
+ *  Again, this value is just a hint. Assimp tries to select the shader whose
+ *  most common implementation matches the original rendering results of the
+ *  3D modeller which wrote a particular model as closely as possible.
+ */
+enum aiShadingMode
+{
+    /** Flat shading. Shading is done on per-face base,
+     *  diffuse only. Also known as 'faceted shading'.
+     */
+    aiShadingMode_Flat = 0x1,
+
+    /** Simple Gouraud shading.
+     */
+    aiShadingMode_Gouraud = 0x2,
+
+    /** Phong-Shading -
+     */
+    aiShadingMode_Phong = 0x3,
+
+    /** Phong-Blinn-Shading
+     */
+    aiShadingMode_Blinn = 0x4,
+
+    /** Toon-Shading per pixel
+     *
+     *  Also known as 'comic' shader.
+     */
+    aiShadingMode_Toon = 0x5,
+
+    /** OrenNayar-Shading per pixel
+     *
+     *  Extension to standard Lambertian shading, taking the
+     *  roughness of the material into account
+     */
+    aiShadingMode_OrenNayar = 0x6,
+
+    /** Minnaert-Shading per pixel
+     *
+     *  Extension to standard Lambertian shading, taking the
+     *  "darkness" of the material into account
+     */
+    aiShadingMode_Minnaert = 0x7,
+
+    /** CookTorrance-Shading per pixel
+     *
+     *  Special shader for metallic surfaces.
+     */
+    aiShadingMode_CookTorrance = 0x8,
+
+    /** No shading at all. Constant light influence of 1.0.
+    */
+    aiShadingMode_NoShading = 0x9,
+
+     /** Fresnel shading
+     */
+    aiShadingMode_Fresnel = 0xa,
+
+
+#ifndef SWIG
+    _aiShadingMode_Force32Bit = INT_MAX
+#endif
+};
+
+
+// ---------------------------------------------------------------------------
+/** @brief Defines some mixed flags for a particular texture.
+ *
+ *  Usually you'll instruct your cg artists how textures have to look like ...
+ *  and how they will be processed in your application. However, if you use
+ *  Assimp for completely generic loading purposes you might also need to
+ *  process these flags in order to display as many 'unknown' 3D models as
+ *  possible correctly.
+ *
+ *  This corresponds to the #AI_MATKEY_TEXFLAGS property.
+*/
+enum aiTextureFlags
+{
+    /** The texture's color values have to be inverted (componentwise 1-n)
+     */
+    aiTextureFlags_Invert = 0x1,
+
+    /** Explicit request to the application to process the alpha channel
+     *  of the texture.
+     *
+     *  Mutually exclusive with #aiTextureFlags_IgnoreAlpha. These
+     *  flags are set if the library can say for sure that the alpha
+     *  channel is used/is not used. If the model format does not
+     *  define this, it is left to the application to decide whether
+     *  the texture alpha channel - if any - is evaluated or not.
+     */
+    aiTextureFlags_UseAlpha = 0x2,
+
+    /** Explicit request to the application to ignore the alpha channel
+     *  of the texture.
+     *
+     *  Mutually exclusive with #aiTextureFlags_UseAlpha.
+     */
+    aiTextureFlags_IgnoreAlpha = 0x4,
+
+#ifndef SWIG
+      _aiTextureFlags_Force32Bit = INT_MAX
+#endif
+};
+
+
+// ---------------------------------------------------------------------------
+/** @brief Defines alpha-blend flags.
+ *
+ *  If you're familiar with OpenGL or D3D, these flags aren't new to you.
+ *  They define *how* the final color value of a pixel is computed, basing
+ *  on the previous color at that pixel and the new color value from the
+ *  material.
+ *  The blend formula is:
+ *  @code
+ *    SourceColor * SourceBlend + DestColor * DestBlend
+ *  @endcode
+ *  where DestColor is the previous color in the framebuffer at this
+ *  position and SourceColor is the material colro before the transparency
+ *  calculation.<br>
+ *  This corresponds to the #AI_MATKEY_BLEND_FUNC property.
+*/
+enum aiBlendMode
+{
+    /**
+     *  Formula:
+     *  @code
+     *  SourceColor*SourceAlpha + DestColor*(1-SourceAlpha)
+     *  @endcode
+     */
+    aiBlendMode_Default = 0x0,
+
+    /** Additive blending
+     *
+     *  Formula:
+     *  @code
+     *  SourceColor*1 + DestColor*1
+     *  @endcode
+     */
+    aiBlendMode_Additive = 0x1,
+
+    // we don't need more for the moment, but we might need them
+    // in future versions ...
+
+#ifndef SWIG
+    _aiBlendMode_Force32Bit = INT_MAX
+#endif
+};
+
+
+#include "./Compiler/pushpack1.h"
+
+// ---------------------------------------------------------------------------
+/** @brief Defines how an UV channel is transformed.
+ *
+ *  This is just a helper structure for the #AI_MATKEY_UVTRANSFORM key.
+ *  See its documentation for more details.
+ *
+ *  Typically you'll want to build a matrix of this information. However,
+ *  we keep separate scaling/translation/rotation values to make it
+ *  easier to process and optimize UV transformations internally.
+ */
+struct aiUVTransform
+{
+    /** Translation on the u and v axes.
+     *
+     *  The default value is (0|0).
+     */
+    C_STRUCT aiVector2D mTranslation;
+
+    /** Scaling on the u and v axes.
+     *
+     *  The default value is (1|1).
+     */
+    C_STRUCT aiVector2D mScaling;
+
+    /** Rotation - in counter-clockwise direction.
+     *
+     *  The rotation angle is specified in radians. The
+     *  rotation center is 0.5f|0.5f. The default value
+     *  0.f.
+     */
+    float mRotation;
+
+
+#ifdef __cplusplus
+    aiUVTransform()
+        :   mScaling    (1.f,1.f)
+        ,   mRotation   (0.f)
+    {
+        // nothing to be done here ...
+    }
+#endif
+
+} PACK_STRUCT;
+
+#include "./Compiler/poppack1.h"
+
+//! @cond AI_DOX_INCLUDE_INTERNAL
+// ---------------------------------------------------------------------------
+/** @brief A very primitive RTTI system for the contents of material
+ *  properties.
+ */
+enum aiPropertyTypeInfo
+{
+    /** Array of single-precision (32 Bit) floats
+     *
+     *  It is possible to use aiGetMaterialInteger[Array]() (or the C++-API
+     *  aiMaterial::Get()) to query properties stored in floating-point format.
+     *  The material system performs the type conversion automatically.
+    */
+    aiPTI_Float   = 0x1,
+
+    /** The material property is an aiString.
+     *
+     *  Arrays of strings aren't possible, aiGetMaterialString() (or the
+     *  C++-API aiMaterial::Get()) *must* be used to query a string property.
+    */
+    aiPTI_String  = 0x3,
+
+    /** Array of (32 Bit) integers
+     *
+     *  It is possible to use aiGetMaterialFloat[Array]() (or the C++-API
+     *  aiMaterial::Get()) to query properties stored in integer format.
+     *  The material system performs the type conversion automatically.
+    */
+    aiPTI_Integer = 0x4,
+
+
+    /** Simple binary buffer, content undefined. Not convertible to anything.
+    */
+    aiPTI_Buffer  = 0x5,
+
+
+     /** This value is not used. It is just there to force the
+     *  compiler to map this enum to a 32 Bit integer.
+     */
+#ifndef SWIG
+     _aiPTI_Force32Bit = INT_MAX
+#endif
+};
+
+// ---------------------------------------------------------------------------
+/** @brief Data structure for a single material property
+ *
+ *  As an user, you'll probably never need to deal with this data structure.
+ *  Just use the provided aiGetMaterialXXX() or aiMaterial::Get() family
+ *  of functions to query material properties easily. Processing them
+ *  manually is faster, but it is not the recommended way. It isn't worth
+ *  the effort. <br>
+ *  Material property names follow a simple scheme:
+ *  @code
+ *    $<name>
+ *    ?<name>
+ *       A public property, there must be corresponding AI_MATKEY_XXX define
+ *       2nd: Public, but ignored by the #aiProcess_RemoveRedundantMaterials
+ *       post-processing step.
+ *    ~<name>
+ *       A temporary property for internal use.
+ *  @endcode
+ *  @see aiMaterial
+ */
+struct aiMaterialProperty
+{
+    /** Specifies the name of the property (key)
+     *  Keys are generally case insensitive.
+     */
+    C_STRUCT aiString mKey;
+
+    /** Textures: Specifies their exact usage semantic.
+     * For non-texture properties, this member is always 0
+     * (or, better-said, #aiTextureType_NONE).
+     */
+    unsigned int mSemantic;
+
+    /** Textures: Specifies the index of the texture.
+     *  For non-texture properties, this member is always 0.
+     */
+    unsigned int mIndex;
+
+    /** Size of the buffer mData is pointing to, in bytes.
+     *  This value may not be 0.
+     */
+    unsigned int mDataLength;
+
+    /** Type information for the property.
+     *
+     * Defines the data layout inside the data buffer. This is used
+     * by the library internally to perform debug checks and to
+     * utilize proper type conversions.
+     * (It's probably a hacky solution, but it works.)
+     */
+    C_ENUM aiPropertyTypeInfo mType;
+
+    /** Binary buffer to hold the property's value.
+     * The size of the buffer is always mDataLength.
+     */
+    char* mData;
+
+#ifdef __cplusplus
+
+    aiMaterialProperty()
+        : mSemantic( 0 )
+        , mIndex( 0 )
+        , mDataLength( 0 )
+        , mType( aiPTI_Float )
+        , mData( NULL )
+    {
+    }
+
+    ~aiMaterialProperty()   {
+        delete[] mData;
+    }
+
+#endif
+};
+//! @endcond
+
+#ifdef __cplusplus
+} // We need to leave the "C" block here to allow template member functions
+#endif
+
+// ---------------------------------------------------------------------------
+/** @brief Data structure for a material
+*
+*  Material data is stored using a key-value structure. A single key-value
+*  pair is called a 'material property'. C++ users should use the provided
+*  member functions of aiMaterial to process material properties, C users
+*  have to stick with the aiMaterialGetXXX family of unbound functions.
+*  The library defines a set of standard keys (AI_MATKEY_XXX).
+*/
+#ifdef __cplusplus
+struct ASSIMP_API aiMaterial
+#else
+struct aiMaterial
+#endif
+{
+
+#ifdef __cplusplus
+
+public:
+
+    aiMaterial();
+    ~aiMaterial();
+
+    // -------------------------------------------------------------------
+    /** @brief Retrieve an array of Type values with a specific key
+     *  from the material
+     *
+     * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
+     * @param type .. set by AI_MATKEY_XXX
+     * @param idx .. set by AI_MATKEY_XXX
+     * @param pOut Pointer to a buffer to receive the result.
+     * @param pMax Specifies the size of the given buffer, in Type's.
+     * Receives the number of values (not bytes!) read.
+     * NULL is a valid value for this parameter.
+     */
+    template <typename Type>
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, Type* pOut, unsigned int* pMax) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, int* pOut, unsigned int* pMax) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, float* pOut, unsigned int* pMax) const;
+
+    // -------------------------------------------------------------------
+    /** @brief Retrieve a Type value with a specific key
+     *  from the material
+     *
+     * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
+    * @param type Specifies the type of the texture to be retrieved (
+    *    e.g. diffuse, specular, height map ...)
+    * @param idx Index of the texture to be retrieved.
+     * @param pOut Reference to receive the output value
+     */
+    template <typename Type>
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx,Type& pOut) const;
+
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, int& pOut) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, float& pOut) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, aiString& pOut) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, aiColor3D& pOut) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, aiColor4D& pOut) const;
+
+    aiReturn Get(const char* pKey,unsigned int type,
+        unsigned int idx, aiUVTransform& pOut) const;
+
+    // -------------------------------------------------------------------
+    /** Get the number of textures for a particular texture type.
+     *  @param type Texture type to check for
+     *  @return Number of textures for this type.
+     *  @note A texture can be easily queried using #GetTexture() */
+    unsigned int GetTextureCount(aiTextureType type) const;
+
+    // -------------------------------------------------------------------
+    /** Helper function to get all parameters pertaining to a
+     *  particular texture slot from a material.
+    *
+    *  This function is provided just for convenience, you could also
+    *  read the single material properties manually.
+    *  @param type Specifies the type of the texture to be retrieved (
+    *    e.g. diffuse, specular, height map ...)
+    *  @param index Index of the texture to be retrieved. The function fails
+    *    if there is no texture of that type with this index.
+    *    #GetTextureCount() can be used to determine the number of textures
+    *    per texture type.
+    *  @param path Receives the path to the texture.
+    *    NULL is a valid value.
+   *  @param mapping The texture mapping.
+   *        NULL is allowed as value.
+    *  @param uvindex Receives the UV index of the texture.
+    *    NULL is a valid value.
+    *  @param blend Receives the blend factor for the texture
+    *    NULL is a valid value.
+    *  @param op Receives the texture operation to be performed between
+    *    this texture and the previous texture. NULL is allowed as value.
+    *  @param mapmode Receives the mapping modes to be used for the texture.
+    *    The parameter may be NULL but if it is a valid pointer it MUST
+    *    point to an array of 3 aiTextureMapMode's (one for each
+    *    axis: UVW order (=XYZ)).
+    */
+    // -------------------------------------------------------------------
+    aiReturn GetTexture(aiTextureType type,
+        unsigned int  index,
+        C_STRUCT aiString* path,
+        aiTextureMapping* mapping   = NULL,
+        unsigned int* uvindex       = NULL,
+        float* blend                = NULL,
+        aiTextureOp* op             = NULL,
+        aiTextureMapMode* mapmode   = NULL) const;
+
+
+    // Setters
+
+
+    // ------------------------------------------------------------------------------
+    /** @brief Add a property with a given key and type info to the material
+     *  structure
+     *
+     *  @param pInput Pointer to input data
+     *  @param pSizeInBytes Size of input data
+     *  @param pKey Key/Usage of the property (AI_MATKEY_XXX)
+     *  @param type Set by the AI_MATKEY_XXX macro
+     *  @param index Set by the AI_MATKEY_XXX macro
+     *  @param pType Type information hint */
+    aiReturn AddBinaryProperty (const void* pInput,
+        unsigned int pSizeInBytes,
+        const char* pKey,
+        unsigned int type ,
+        unsigned int index ,
+        aiPropertyTypeInfo pType);
+
+    // ------------------------------------------------------------------------------
+    /** @brief Add a string property with a given key and type info to the
+     *  material structure
+     *
+     *  @param pInput Input string
+     *  @param pKey Key/Usage of the property (AI_MATKEY_XXX)
+     *  @param type Set by the AI_MATKEY_XXX macro
+     *  @param index Set by the AI_MATKEY_XXX macro */
+    aiReturn AddProperty (const aiString* pInput,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    // ------------------------------------------------------------------------------
+    /** @brief Add a property with a given key to the material structure
+     *  @param pInput Pointer to the input data
+     *  @param pNumValues Number of values in the array
+     *  @param pKey Key/Usage of the property (AI_MATKEY_XXX)
+     *  @param type Set by the AI_MATKEY_XXX macro
+     *  @param index Set by the AI_MATKEY_XXX macro  */
+    template<class TYPE>
+    aiReturn AddProperty (const TYPE* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    aiReturn AddProperty (const aiVector3D* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    aiReturn AddProperty (const aiColor3D* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    aiReturn AddProperty (const aiColor4D* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    aiReturn AddProperty (const int* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    aiReturn AddProperty (const float* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    aiReturn AddProperty (const aiUVTransform* pInput,
+        unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    // ------------------------------------------------------------------------------
+    /** @brief Remove a given key from the list.
+     *
+     *  The function fails if the key isn't found
+     *  @param pKey Key to be deleted
+     *  @param type Set by the AI_MATKEY_XXX macro
+     *  @param index Set by the AI_MATKEY_XXX macro  */
+    aiReturn RemoveProperty (const char* pKey,
+        unsigned int type  = 0,
+        unsigned int index = 0);
+
+    // ------------------------------------------------------------------------------
+    /** @brief Removes all properties from the material.
+     *
+     *  The data array remains allocated so adding new properties is quite fast.  */
+    void Clear();
+
+    // ------------------------------------------------------------------------------
+    /** Copy the property list of a material
+     *  @param pcDest Destination material
+     *  @param pcSrc Source material
+     */
+    static void CopyPropertyList(aiMaterial* pcDest,
+        const aiMaterial* pcSrc);
+
+
+#endif
+
+    /** List of all material properties loaded. */
+    C_STRUCT aiMaterialProperty** mProperties;
+
+    /** Number of properties in the data base */
+    unsigned int mNumProperties;
+
+     /** Storage allocated */
+    unsigned int mNumAllocated;
+};
+
+// Go back to extern "C" again
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_NAME "?mat.name",0,0
+#define AI_MATKEY_TWOSIDED "$mat.twosided",0,0
+#define AI_MATKEY_SHADING_MODEL "$mat.shadingm",0,0
+#define AI_MATKEY_ENABLE_WIREFRAME "$mat.wireframe",0,0
+#define AI_MATKEY_BLEND_FUNC "$mat.blend",0,0
+#define AI_MATKEY_OPACITY "$mat.opacity",0,0
+#define AI_MATKEY_BUMPSCALING "$mat.bumpscaling",0,0
+#define AI_MATKEY_SHININESS "$mat.shininess",0,0
+#define AI_MATKEY_REFLECTIVITY "$mat.reflectivity",0,0
+#define AI_MATKEY_SHININESS_STRENGTH "$mat.shinpercent",0,0
+#define AI_MATKEY_REFRACTI "$mat.refracti",0,0
+#define AI_MATKEY_COLOR_DIFFUSE "$clr.diffuse",0,0
+#define AI_MATKEY_COLOR_AMBIENT "$clr.ambient",0,0
+#define AI_MATKEY_COLOR_SPECULAR "$clr.specular",0,0
+#define AI_MATKEY_COLOR_EMISSIVE "$clr.emissive",0,0
+#define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0
+#define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0
+#define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "?bg.global",0,0
+
+// ---------------------------------------------------------------------------
+// Pure key names for all texture-related properties
+//! @cond MATS_DOC_FULL
+#define _AI_MATKEY_TEXTURE_BASE         "$tex.file"
+#define _AI_MATKEY_UVWSRC_BASE          "$tex.uvwsrc"
+#define _AI_MATKEY_TEXOP_BASE           "$tex.op"
+#define _AI_MATKEY_MAPPING_BASE         "$tex.mapping"
+#define _AI_MATKEY_TEXBLEND_BASE        "$tex.blend"
+#define _AI_MATKEY_MAPPINGMODE_U_BASE   "$tex.mapmodeu"
+#define _AI_MATKEY_MAPPINGMODE_V_BASE   "$tex.mapmodev"
+#define _AI_MATKEY_TEXMAP_AXIS_BASE     "$tex.mapaxis"
+#define _AI_MATKEY_UVTRANSFORM_BASE     "$tex.uvtrafo"
+#define _AI_MATKEY_TEXFLAGS_BASE        "$tex.flags"
+//! @endcond
+
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_TEXTURE(type, N) _AI_MATKEY_TEXTURE_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_TEXTURE_DIFFUSE(N)    \
+    AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_TEXTURE_SPECULAR(N)   \
+    AI_MATKEY_TEXTURE(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_TEXTURE_AMBIENT(N)    \
+    AI_MATKEY_TEXTURE(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_TEXTURE_EMISSIVE(N)   \
+    AI_MATKEY_TEXTURE(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_TEXTURE_NORMALS(N)    \
+    AI_MATKEY_TEXTURE(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_TEXTURE_HEIGHT(N) \
+    AI_MATKEY_TEXTURE(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_TEXTURE_SHININESS(N)  \
+    AI_MATKEY_TEXTURE(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_TEXTURE_OPACITY(N)    \
+    AI_MATKEY_TEXTURE(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_TEXTURE_DISPLACEMENT(N)   \
+    AI_MATKEY_TEXTURE(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_TEXTURE_LIGHTMAP(N)   \
+    AI_MATKEY_TEXTURE(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_TEXTURE_REFLECTION(N) \
+    AI_MATKEY_TEXTURE(aiTextureType_REFLECTION,N)
+
+//! @endcond
+
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_UVWSRC(type, N) _AI_MATKEY_UVWSRC_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_UVWSRC_DIFFUSE(N) \
+    AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_UVWSRC_SPECULAR(N)    \
+    AI_MATKEY_UVWSRC(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_UVWSRC_AMBIENT(N) \
+    AI_MATKEY_UVWSRC(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_UVWSRC_EMISSIVE(N)    \
+    AI_MATKEY_UVWSRC(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_UVWSRC_NORMALS(N) \
+    AI_MATKEY_UVWSRC(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_UVWSRC_HEIGHT(N)  \
+    AI_MATKEY_UVWSRC(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_UVWSRC_SHININESS(N)   \
+    AI_MATKEY_UVWSRC(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_UVWSRC_OPACITY(N) \
+    AI_MATKEY_UVWSRC(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_UVWSRC_DISPLACEMENT(N)    \
+    AI_MATKEY_UVWSRC(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_UVWSRC_LIGHTMAP(N)    \
+    AI_MATKEY_UVWSRC(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_UVWSRC_REFLECTION(N)  \
+    AI_MATKEY_UVWSRC(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_TEXOP(type, N) _AI_MATKEY_TEXOP_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_TEXOP_DIFFUSE(N)  \
+    AI_MATKEY_TEXOP(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_TEXOP_SPECULAR(N) \
+    AI_MATKEY_TEXOP(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_TEXOP_AMBIENT(N)  \
+    AI_MATKEY_TEXOP(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_TEXOP_EMISSIVE(N) \
+    AI_MATKEY_TEXOP(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_TEXOP_NORMALS(N)  \
+    AI_MATKEY_TEXOP(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_TEXOP_HEIGHT(N)   \
+    AI_MATKEY_TEXOP(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_TEXOP_SHININESS(N)    \
+    AI_MATKEY_TEXOP(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_TEXOP_OPACITY(N)  \
+    AI_MATKEY_TEXOP(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_TEXOP_DISPLACEMENT(N) \
+    AI_MATKEY_TEXOP(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_TEXOP_LIGHTMAP(N) \
+    AI_MATKEY_TEXOP(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_TEXOP_REFLECTION(N)   \
+    AI_MATKEY_TEXOP(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_MAPPING(type, N) _AI_MATKEY_MAPPING_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_MAPPING_DIFFUSE(N)    \
+    AI_MATKEY_MAPPING(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_MAPPING_SPECULAR(N)   \
+    AI_MATKEY_MAPPING(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_MAPPING_AMBIENT(N)    \
+    AI_MATKEY_MAPPING(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_MAPPING_EMISSIVE(N)   \
+    AI_MATKEY_MAPPING(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_MAPPING_NORMALS(N)    \
+    AI_MATKEY_MAPPING(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_MAPPING_HEIGHT(N) \
+    AI_MATKEY_MAPPING(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_MAPPING_SHININESS(N)  \
+    AI_MATKEY_MAPPING(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_MAPPING_OPACITY(N)    \
+    AI_MATKEY_MAPPING(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_MAPPING_DISPLACEMENT(N)   \
+    AI_MATKEY_MAPPING(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_MAPPING_LIGHTMAP(N)   \
+    AI_MATKEY_MAPPING(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_MAPPING_REFLECTION(N) \
+    AI_MATKEY_MAPPING(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_TEXBLEND(type, N) _AI_MATKEY_TEXBLEND_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_TEXBLEND_DIFFUSE(N)   \
+    AI_MATKEY_TEXBLEND(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_TEXBLEND_SPECULAR(N)  \
+    AI_MATKEY_TEXBLEND(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_TEXBLEND_AMBIENT(N)   \
+    AI_MATKEY_TEXBLEND(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_TEXBLEND_EMISSIVE(N)  \
+    AI_MATKEY_TEXBLEND(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_TEXBLEND_NORMALS(N)   \
+    AI_MATKEY_TEXBLEND(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_TEXBLEND_HEIGHT(N)    \
+    AI_MATKEY_TEXBLEND(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_TEXBLEND_SHININESS(N) \
+    AI_MATKEY_TEXBLEND(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_TEXBLEND_OPACITY(N)   \
+    AI_MATKEY_TEXBLEND(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_TEXBLEND_DISPLACEMENT(N)  \
+    AI_MATKEY_TEXBLEND(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_TEXBLEND_LIGHTMAP(N)  \
+    AI_MATKEY_TEXBLEND(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_TEXBLEND_REFLECTION(N)    \
+    AI_MATKEY_TEXBLEND(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_MAPPINGMODE_U(type, N) _AI_MATKEY_MAPPINGMODE_U_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_MAPPINGMODE_U_DIFFUSE(N)  \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_SPECULAR(N) \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_AMBIENT(N)  \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_EMISSIVE(N) \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_NORMALS(N)  \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_HEIGHT(N)   \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_SHININESS(N)    \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_OPACITY(N)  \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_DISPLACEMENT(N) \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_LIGHTMAP(N) \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_MAPPINGMODE_U_REFLECTION(N)   \
+    AI_MATKEY_MAPPINGMODE_U(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_MAPPINGMODE_V(type, N) _AI_MATKEY_MAPPINGMODE_V_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_MAPPINGMODE_V_DIFFUSE(N)  \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_SPECULAR(N) \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_AMBIENT(N)  \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_EMISSIVE(N) \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_NORMALS(N)  \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_HEIGHT(N)   \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_SHININESS(N)    \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_OPACITY(N)  \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_DISPLACEMENT(N) \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_LIGHTMAP(N) \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_MAPPINGMODE_V_REFLECTION(N)   \
+    AI_MATKEY_MAPPINGMODE_V(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_TEXMAP_AXIS(type, N) _AI_MATKEY_TEXMAP_AXIS_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_TEXMAP_AXIS_DIFFUSE(N)    \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_SPECULAR(N)   \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_AMBIENT(N)    \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_EMISSIVE(N)   \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_NORMALS(N)    \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_HEIGHT(N) \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_SHININESS(N)  \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_OPACITY(N)    \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_DISPLACEMENT(N)   \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_LIGHTMAP(N)   \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_TEXMAP_AXIS_REFLECTION(N) \
+    AI_MATKEY_TEXMAP_AXIS(aiTextureType_REFLECTION,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_UVTRANSFORM(type, N) _AI_MATKEY_UVTRANSFORM_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_UVTRANSFORM_DIFFUSE(N)    \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_UVTRANSFORM_SPECULAR(N)   \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_UVTRANSFORM_AMBIENT(N)    \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_UVTRANSFORM_EMISSIVE(N)   \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_UVTRANSFORM_NORMALS(N)    \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_UVTRANSFORM_HEIGHT(N) \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_UVTRANSFORM_SHININESS(N)  \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_UVTRANSFORM_OPACITY(N)    \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_UVTRANSFORM_DISPLACEMENT(N)   \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_UVTRANSFORM_LIGHTMAP(N)   \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_UVTRANSFORM_REFLECTION(N) \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_REFLECTION,N)
+
+#define AI_MATKEY_UVTRANSFORM_UNKNOWN(N)    \
+    AI_MATKEY_UVTRANSFORM(aiTextureType_UNKNOWN,N)
+
+//! @endcond
+// ---------------------------------------------------------------------------
+#define AI_MATKEY_TEXFLAGS(type, N) _AI_MATKEY_TEXFLAGS_BASE,type,N
+
+// For backward compatibility and simplicity
+//! @cond MATS_DOC_FULL
+#define AI_MATKEY_TEXFLAGS_DIFFUSE(N)   \
+    AI_MATKEY_TEXFLAGS(aiTextureType_DIFFUSE,N)
+
+#define AI_MATKEY_TEXFLAGS_SPECULAR(N)  \
+    AI_MATKEY_TEXFLAGS(aiTextureType_SPECULAR,N)
+
+#define AI_MATKEY_TEXFLAGS_AMBIENT(N)   \
+    AI_MATKEY_TEXFLAGS(aiTextureType_AMBIENT,N)
+
+#define AI_MATKEY_TEXFLAGS_EMISSIVE(N)  \
+    AI_MATKEY_TEXFLAGS(aiTextureType_EMISSIVE,N)
+
+#define AI_MATKEY_TEXFLAGS_NORMALS(N)   \
+    AI_MATKEY_TEXFLAGS(aiTextureType_NORMALS,N)
+
+#define AI_MATKEY_TEXFLAGS_HEIGHT(N)    \
+    AI_MATKEY_TEXFLAGS(aiTextureType_HEIGHT,N)
+
+#define AI_MATKEY_TEXFLAGS_SHININESS(N) \
+    AI_MATKEY_TEXFLAGS(aiTextureType_SHININESS,N)
+
+#define AI_MATKEY_TEXFLAGS_OPACITY(N)   \
+    AI_MATKEY_TEXFLAGS(aiTextureType_OPACITY,N)
+
+#define AI_MATKEY_TEXFLAGS_DISPLACEMENT(N)  \
+    AI_MATKEY_TEXFLAGS(aiTextureType_DISPLACEMENT,N)
+
+#define AI_MATKEY_TEXFLAGS_LIGHTMAP(N)  \
+    AI_MATKEY_TEXFLAGS(aiTextureType_LIGHTMAP,N)
+
+#define AI_MATKEY_TEXFLAGS_REFLECTION(N)    \
+    AI_MATKEY_TEXFLAGS(aiTextureType_REFLECTION,N)
+
+#define AI_MATKEY_TEXFLAGS_UNKNOWN(N)   \
+    AI_MATKEY_TEXFLAGS(aiTextureType_UNKNOWN,N)
+
+//! @endcond
+//!
+// ---------------------------------------------------------------------------
+/** @brief Retrieve a material property with a specific key from the material
+ *
+ * @param pMat Pointer to the input material. May not be NULL
+ * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
+ * @param type Specifies the type of the texture to be retrieved (
+ *    e.g. diffuse, specular, height map ...)
+ * @param index Index of the texture to be retrieved.
+ * @param pPropOut Pointer to receive a pointer to a valid aiMaterialProperty
+ *        structure or NULL if the key has not been found. */
+// ---------------------------------------------------------------------------
+ASSIMP_API C_ENUM aiReturn aiGetMaterialProperty(
+     const C_STRUCT aiMaterial* pMat,
+    const char* pKey,
+     unsigned int type,
+    unsigned int  index,
+    const C_STRUCT aiMaterialProperty** pPropOut);
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve an array of float values with a specific key
+ *  from the material
+ *
+ * Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
+ * example reads the #AI_MATKEY_UVTRANSFORM property of the first diffuse texture)
+ * @code
+ * aiUVTransform trafo;
+ * unsigned int max = sizeof(aiUVTransform);
+ * if (AI_SUCCESS != aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE,0),
+ *    (float*)&trafo, &max) || sizeof(aiUVTransform) != max)
+ * {
+ *   // error handling
+ * }
+ * @endcode
+ *
+ * @param pMat Pointer to the input material. May not be NULL
+ * @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
+ * @param pOut Pointer to a buffer to receive the result.
+ * @param pMax Specifies the size of the given buffer, in float's.
+ *        Receives the number of values (not bytes!) read.
+ * @param type (see the code sample above)
+ * @param index (see the code sample above)
+ * @return Specifies whether the key has been found. If not, the output
+ *   arrays remains unmodified and pMax is set to 0.*/
+// ---------------------------------------------------------------------------
+ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
+    const C_STRUCT aiMaterial* pMat,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index,
+    float* pOut,
+    unsigned int* pMax);
+
+
+#ifdef __cplusplus
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve a single float property with a specific key from the material.
+*
+* Pass one of the AI_MATKEY_XXX constants for the last three parameters (the
+* example reads the #AI_MATKEY_SHININESS_STRENGTH property of the first diffuse texture)
+* @code
+* float specStrength = 1.f; // default value, remains unmodified if we fail.
+* aiGetMaterialFloat(mat, AI_MATKEY_SHININESS_STRENGTH,
+*    (float*)&specStrength);
+* @endcode
+*
+* @param pMat Pointer to the input material. May not be NULL
+* @param pKey Key to search for. One of the AI_MATKEY_XXX constants.
+* @param pOut Receives the output float.
+* @param type (see the code sample above)
+* @param index (see the code sample above)
+* @return Specifies whether the key has been found. If not, the output
+*   float remains unmodified.*/
+// ---------------------------------------------------------------------------
+inline aiReturn aiGetMaterialFloat(const aiMaterial* pMat,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index,
+    float* pOut)
+{
+    return aiGetMaterialFloatArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0);
+}
+
+#else
+
+// Use our friend, the C preprocessor
+#define aiGetMaterialFloat (pMat, type, index, pKey, pOut) \
+    aiGetMaterialFloatArray(pMat, type, index, pKey, pOut, NULL)
+
+#endif //!__cplusplus
+
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve an array of integer values with a specific key
+ *  from a material
+ *
+ * See the sample for aiGetMaterialFloatArray for more information.*/
+ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial* pMat,
+     const char* pKey,
+     unsigned int  type,
+     unsigned int  index,
+     int* pOut,
+     unsigned int* pMax);
+
+
+#ifdef __cplusplus
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve an integer property with a specific key from a material
+ *
+ * See the sample for aiGetMaterialFloat for more information.*/
+// ---------------------------------------------------------------------------
+inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat,
+    const char* pKey,
+    unsigned int type,
+   unsigned int index,
+    int* pOut)
+{
+    return aiGetMaterialIntegerArray(pMat,pKey,type,index,pOut,(unsigned int*)0x0);
+}
+
+#else
+
+// use our friend, the C preprocessor
+#define aiGetMaterialInteger (pMat, type, index, pKey, pOut) \
+    aiGetMaterialIntegerArray(pMat, type, index, pKey, pOut, NULL)
+
+#endif //!__cplusplus
+
+
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve a color value from the material property table
+*
+* See the sample for aiGetMaterialFloat for more information*/
+// ---------------------------------------------------------------------------
+ASSIMP_API C_ENUM aiReturn aiGetMaterialColor(const C_STRUCT aiMaterial* pMat,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index,
+    C_STRUCT aiColor4D* pOut);
+
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve a aiUVTransform value from the material property table
+*
+* See the sample for aiGetMaterialFloat for more information*/
+// ---------------------------------------------------------------------------
+ASSIMP_API C_ENUM aiReturn aiGetMaterialUVTransform(const C_STRUCT aiMaterial* pMat,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index,
+    C_STRUCT aiUVTransform* pOut);
+
+
+// ---------------------------------------------------------------------------
+/** @brief Retrieve a string from the material property table
+*
+* See the sample for aiGetMaterialFloat for more information.*/
+// ---------------------------------------------------------------------------
+ASSIMP_API C_ENUM aiReturn aiGetMaterialString(const C_STRUCT aiMaterial* pMat,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index,
+    C_STRUCT aiString* pOut);
+
+// ---------------------------------------------------------------------------
+/** Get the number of textures for a particular texture type.
+ *  @param[in] pMat Pointer to the input material. May not be NULL
+ *  @param type Texture type to check for
+ *  @return Number of textures for this type.
+ *  @note A texture can be easily queried using #aiGetMaterialTexture() */
+// ---------------------------------------------------------------------------
+ASSIMP_API unsigned int aiGetMaterialTextureCount(const C_STRUCT aiMaterial* pMat,
+    C_ENUM aiTextureType type);
+
+// ---------------------------------------------------------------------------
+/** @brief Helper function to get all values pertaining to a particular
+ *  texture slot from a material structure.
+ *
+ *  This function is provided just for convenience. You could also read the
+ *  texture by parsing all of its properties manually. This function bundles
+ *  all of them in a huge function monster.
+ *
+ *  @param[in] mat Pointer to the input material. May not be NULL
+ *  @param[in] type Specifies the texture stack to read from (e.g. diffuse,
+ *     specular, height map ...).
+ *  @param[in] index Index of the texture. The function fails if the
+ *     requested index is not available for this texture type.
+ *     #aiGetMaterialTextureCount() can be used to determine the number of
+ *     textures in a particular texture stack.
+ *  @param[out] path Receives the output path
+ *      This parameter must be non-null.
+ *  @param mapping The texture mapping mode to be used.
+ *      Pass NULL if you're not interested in this information.
+ *  @param[out] uvindex For UV-mapped textures: receives the index of the UV
+ *      source channel. Unmodified otherwise.
+ *      Pass NULL if you're not interested in this information.
+ *  @param[out] blend Receives the blend factor for the texture
+ *      Pass NULL if you're not interested in this information.
+ *  @param[out] op Receives the texture blend operation to be perform between
+ *      this texture and the previous texture.
+ *      Pass NULL if you're not interested in this information.
+ *  @param[out] mapmode Receives the mapping modes to be used for the texture.
+ *      Pass NULL if you're not interested in this information. Otherwise,
+ *      pass a pointer to an array of two aiTextureMapMode's (one for each
+ *      axis, UV order).
+ *  @param[out] flags Receives the the texture flags.
+ *  @return AI_SUCCESS on success, otherwise something else. Have fun.*/
+// ---------------------------------------------------------------------------
+#ifdef __cplusplus
+ASSIMP_API aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
+    aiTextureType type,
+    unsigned int  index,
+    aiString* path,
+    aiTextureMapping* mapping   = NULL,
+    unsigned int* uvindex       = NULL,
+    float* blend                = NULL,
+    aiTextureOp* op             = NULL,
+    aiTextureMapMode* mapmode   = NULL,
+    unsigned int* flags         = NULL);
+#else
+C_ENUM aiReturn aiGetMaterialTexture(const C_STRUCT aiMaterial* mat,
+    C_ENUM aiTextureType type,
+    unsigned int  index,
+    C_STRUCT aiString* path,
+    C_ENUM aiTextureMapping* mapping    /*= NULL*/,
+    unsigned int* uvindex               /*= NULL*/,
+    float* blend                        /*= NULL*/,
+    C_ENUM aiTextureOp* op              /*= NULL*/,
+    C_ENUM aiTextureMapMode* mapmode    /*= NULL*/,
+    unsigned int* flags                 /*= NULL*/);
+#endif // !#ifdef __cplusplus
+
+#ifdef __cplusplus
+}
+
+#include "material.inl"
+
+#endif //!__cplusplus
+#endif //!!AI_MATERIAL_H_INC

+ 350 - 0
include/assimp/material.inl

@@ -0,0 +1,350 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file material.inl
+ *  @brief Defines the C++ getters for the material system
+ */
+
+#ifndef AI_MATERIAL_INL_INC
+#define AI_MATERIAL_INL_INC
+
+//! @cond never
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::GetTexture( aiTextureType type,
+   unsigned int  index,
+   C_STRUCT aiString* path,
+   aiTextureMapping* mapping    /*= NULL*/,
+   unsigned int* uvindex        /*= NULL*/,
+   float* blend                /*= NULL*/,
+   aiTextureOp* op              /*= NULL*/,
+   aiTextureMapMode* mapmode    /*= NULL*/) const
+{
+    return ::aiGetMaterialTexture(this,type,index,path,mapping,uvindex,blend,op,mapmode);
+}
+
+// ---------------------------------------------------------------------------
+inline unsigned int aiMaterial::GetTextureCount(aiTextureType type) const
+{
+    return ::aiGetMaterialTextureCount(this,type);
+}
+
+// ---------------------------------------------------------------------------
+template <typename Type>
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx, Type* pOut,
+    unsigned int* pMax) const
+{
+    unsigned int iNum = pMax ? *pMax : 1;
+
+    const aiMaterialProperty* prop;
+    const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
+        (const aiMaterialProperty**)&prop);
+    if ( AI_SUCCESS == ret )    {
+
+        if (prop->mDataLength < sizeof(Type)*iNum) {
+            return AI_FAILURE;
+        }
+
+        if (prop->mType != aiPTI_Buffer) {
+            return AI_FAILURE;
+        }
+
+        iNum = std::min((size_t)iNum,prop->mDataLength / sizeof(Type));
+        ::memcpy(pOut,prop->mData,iNum * sizeof(Type));
+        if (pMax) {
+            *pMax = iNum;
+        }
+    }
+    return ret;
+}
+
+// ---------------------------------------------------------------------------
+template <typename Type>
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,Type& pOut) const
+{
+    const aiMaterialProperty* prop;
+    const aiReturn ret = ::aiGetMaterialProperty(this,pKey,type,idx,
+        (const aiMaterialProperty**)&prop);
+    if ( AI_SUCCESS == ret )    {
+
+        if (prop->mDataLength < sizeof(Type)) {
+            return AI_FAILURE;
+        }
+
+        if (prop->mType != aiPTI_Buffer) {
+            return AI_FAILURE;
+        }
+
+        ::memcpy(&pOut,prop->mData,sizeof(Type));
+    }
+    return ret;
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,float* pOut,
+    unsigned int* pMax) const
+{
+    return ::aiGetMaterialFloatArray(this,pKey,type,idx,pOut,pMax);
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,int* pOut,
+    unsigned int* pMax) const
+{
+    return ::aiGetMaterialIntegerArray(this,pKey,type,idx,pOut,pMax);
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,float& pOut) const
+{
+    return aiGetMaterialFloat(this,pKey,type,idx,&pOut);
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,int& pOut) const
+{
+    return aiGetMaterialInteger(this,pKey,type,idx,&pOut);
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,aiColor4D& pOut) const
+{
+    return aiGetMaterialColor(this,pKey,type,idx,&pOut);
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,aiColor3D& pOut) const
+{
+    aiColor4D c;
+    const aiReturn ret = aiGetMaterialColor(this,pKey,type,idx,&c);
+    pOut = aiColor3D(c.r,c.g,c.b);
+    return ret;
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,aiString& pOut) const
+{
+    return aiGetMaterialString(this,pKey,type,idx,&pOut);
+}
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+    unsigned int idx,aiUVTransform& pOut) const
+{
+    return aiGetMaterialUVTransform(this,pKey,type,idx,&pOut);
+}
+
+
+// ---------------------------------------------------------------------------
+template<class TYPE>
+aiReturn aiMaterial::AddProperty (const TYPE* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(TYPE),
+        pKey,type,index,aiPTI_Buffer);
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::AddProperty(const float* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(float),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiUVTransform),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiColor4D),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiColor3D),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiVector3D),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+inline aiReturn aiMaterial::AddProperty(const int* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(int),
+        pKey,type,index,aiPTI_Integer);
+}
+
+
+// ---------------------------------------------------------------------------
+// The template specializations below are for backwards compatibility.
+// The recommended way to add material properties is using the non-template
+// overloads.
+// ---------------------------------------------------------------------------
+
+// ---------------------------------------------------------------------------
+template<>
+inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(float),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+template<>
+inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiUVTransform),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+template<>
+inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiColor4D),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+template<>
+inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiColor3D),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+template<>
+inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(aiVector3D),
+        pKey,type,index,aiPTI_Float);
+}
+
+// ---------------------------------------------------------------------------
+template<>
+inline aiReturn aiMaterial::AddProperty<int>(const int* pInput,
+    const unsigned int pNumValues,
+    const char* pKey,
+    unsigned int type,
+    unsigned int index)
+{
+    return AddBinaryProperty((const void*)pInput,
+        pNumValues * sizeof(int),
+        pKey,type,index,aiPTI_Integer);
+}
+
+//! @endcond
+
+#endif //! AI_MATERIAL_INL_INC

+ 185 - 0
include/assimp/matrix3x3.h

@@ -0,0 +1,185 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file matrix3x3.h
+ *  @brief Definition of a 3x3 matrix, including operators when compiling in C++
+ */
+#ifndef AI_MATRIX3x3_H_INC
+#define AI_MATRIX3x3_H_INC
+
+#include "./Compiler/pushpack1.h"
+
+#ifdef __cplusplus
+
+template <typename T> class aiMatrix4x4t;
+template <typename T> class aiVector2t;
+
+// ---------------------------------------------------------------------------
+/** @brief Represents a row-major 3x3 matrix
+ *
+ *  There's much confusion about matrix layouts (column vs. row order).
+ *  This is *always* a row-major matrix. Not even with the
+ *  #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
+ *  matrix order - it just affects the handedness of the coordinate system
+ *  defined thereby.
+ */
+template <typename TReal>
+class aiMatrix3x3t
+{
+public:
+
+    aiMatrix3x3t () :
+        a1(static_cast<TReal>(1.0f)), a2(), a3(),
+        b1(), b2(static_cast<TReal>(1.0f)), b3(),
+        c1(), c2(), c3(static_cast<TReal>(1.0f)) {}
+
+    aiMatrix3x3t (  TReal _a1, TReal _a2, TReal _a3,
+                    TReal _b1, TReal _b2, TReal _b3,
+                    TReal _c1, TReal _c2, TReal _c3) :
+        a1(_a1), a2(_a2), a3(_a3),
+        b1(_b1), b2(_b2), b3(_b3),
+        c1(_c1), c2(_c2), c3(_c3)
+    {}
+
+public:
+
+    // matrix multiplication.
+    aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
+    aiMatrix3x3t  operator  * (const aiMatrix3x3t& m) const;
+
+    // array access operators
+    TReal* operator[]       (unsigned int p_iIndex);
+    const TReal* operator[] (unsigned int p_iIndex) const;
+
+    // comparison operators
+    bool operator== (const aiMatrix4x4t<TReal>& m) const;
+    bool operator!= (const aiMatrix4x4t<TReal>& m) const;
+
+    bool Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon = 1e-6) const;
+
+    template <typename TOther>
+    operator aiMatrix3x3t<TOther> () const;
+
+public:
+
+    // -------------------------------------------------------------------
+    /** @brief Construction from a 4x4 matrix. The remaining parts
+     *  of the matrix are ignored.
+     */
+    explicit aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix);
+
+    // -------------------------------------------------------------------
+    /** @brief Transpose the matrix
+     */
+    aiMatrix3x3t& Transpose();
+
+    // -------------------------------------------------------------------
+    /** @brief Invert the matrix.
+     *  If the matrix is not invertible all elements are set to qnan.
+     *  Beware, use (f != f) to check whether a TReal f is qnan.
+     */
+    aiMatrix3x3t& Inverse();
+    TReal Determinant() const;
+
+public:
+    // -------------------------------------------------------------------
+    /** @brief Returns a rotation matrix for a rotation around z
+     *  @param a Rotation angle, in radians
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix3x3t& RotationZ(TReal a, aiMatrix3x3t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief Returns a rotation matrix for a rotation around
+     *    an arbitrary axis.
+     *
+     *  @param a Rotation angle, in radians
+     *  @param axis Axis to rotate around
+     *  @param out To be filled
+     */
+    static aiMatrix3x3t& Rotation( TReal a,
+        const aiVector3t<TReal>& axis, aiMatrix3x3t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief Returns a translation matrix
+     *  @param v Translation vector
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix3x3t& Translation( const aiVector2t<TReal>& v, aiMatrix3x3t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief A function for creating a rotation matrix that rotates a
+     *  vector called "from" into another vector called "to".
+     * Input : from[3], to[3] which both must be *normalized* non-zero vectors
+     * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
+     * Authors: Tomas Möller, John Hughes
+     *          "Efficiently Building a Matrix to Rotate One Vector to Another"
+     *          Journal of Graphics Tools, 4(4):1-4, 1999
+     */
+    static aiMatrix3x3t& FromToMatrix(const aiVector3t<TReal>& from,
+        const aiVector3t<TReal>& to, aiMatrix3x3t& out);
+
+public:
+
+
+    TReal a1, a2, a3;
+    TReal b1, b2, b3;
+    TReal c1, c2, c3;
+} PACK_STRUCT;
+
+typedef aiMatrix3x3t<float> aiMatrix3x3;
+
+#else
+
+struct aiMatrix3x3 {
+
+    float a1, a2, a3;
+    float b1, b2, b3;
+    float c1, c2, c3;
+} PACK_STRUCT;
+
+#endif
+
+#include "./Compiler/poppack1.h"
+
+#endif // AI_MATRIX3x3_H_INC

+ 332 - 0
include/assimp/matrix3x3.inl

@@ -0,0 +1,332 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file matrix3x3.inl
+ *  @brief Inline implementation of the 3x3 matrix operators
+ */
+#ifndef AI_MATRIX3x3_INL_INC
+#define AI_MATRIX3x3_INL_INC
+
+#ifdef __cplusplus
+#include "matrix3x3.h"
+
+#include "matrix4x4.h"
+#include <algorithm>
+#include <cmath>
+#include <limits>
+
+// ------------------------------------------------------------------------------------------------
+// Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
+template <typename TReal>
+inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
+{
+    a1 = pMatrix.a1; a2 = pMatrix.a2; a3 = pMatrix.a3;
+    b1 = pMatrix.b1; b2 = pMatrix.b2; b3 = pMatrix.b3;
+    c1 = pMatrix.c1; c2 = pMatrix.c2; c3 = pMatrix.c3;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
+{
+    *this = aiMatrix3x3t<TReal>(m.a1 * a1 + m.b1 * a2 + m.c1 * a3,
+        m.a2 * a1 + m.b2 * a2 + m.c2 * a3,
+        m.a3 * a1 + m.b3 * a2 + m.c3 * a3,
+        m.a1 * b1 + m.b1 * b2 + m.c1 * b3,
+        m.a2 * b1 + m.b2 * b2 + m.c2 * b3,
+        m.a3 * b1 + m.b3 * b2 + m.c3 * b3,
+        m.a1 * c1 + m.b1 * c2 + m.c1 * c3,
+        m.a2 * c1 + m.b2 * c2 + m.c2 * c3,
+        m.a3 * c1 + m.b3 * c2 + m.c3 * c3);
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+template <typename TOther>
+aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
+{
+    return aiMatrix3x3t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),
+        static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),
+        static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3));
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
+{
+    aiMatrix3x3t<TReal> temp( *this);
+    temp *= m;
+    return temp;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex)
+{
+    return &this->a1 + p_iIndex * 3;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const
+{
+    return &this->a1 + p_iIndex * 3;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
+{
+    return a1 == m.a1 && a2 == m.a2 && a3 == m.a3 &&
+           b1 == m.b1 && b2 == m.b2 && b3 == m.b3 &&
+           c1 == m.c1 && c2 == m.c2 && c3 == m.c3;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
+{
+    return !(*this == m);
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
+    return
+        std::abs(a1 - m.a1) <= epsilon &&
+        std::abs(a2 - m.a2) <= epsilon &&
+        std::abs(a3 - m.a3) <= epsilon &&
+        std::abs(b1 - m.b1) <= epsilon &&
+        std::abs(b2 - m.b2) <= epsilon &&
+        std::abs(b3 - m.b3) <= epsilon &&
+        std::abs(c1 - m.c1) <= epsilon &&
+        std::abs(c2 - m.c2) <= epsilon &&
+        std::abs(c3 - m.c3) <= epsilon;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
+{
+    // (TReal&) don't remove, GCC complains cause of packed fields
+    std::swap( (TReal&)a2, (TReal&)b1);
+    std::swap( (TReal&)a3, (TReal&)c1);
+    std::swap( (TReal&)b3, (TReal&)c2);
+    return *this;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline TReal aiMatrix3x3t<TReal>::Determinant() const
+{
+    return a1*b2*c3 - a1*b3*c2 + a2*b3*c1 - a2*b1*c3 + a3*b1*c2 - a3*b2*c1;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
+{
+    // Compute the reciprocal determinant
+    TReal det = Determinant();
+    if(det == static_cast<TReal>(0.0))
+    {
+        // Matrix not invertible. Setting all elements to nan is not really
+        // correct in a mathematical sense; but at least qnans are easy to
+        // spot. XXX we might throw an exception instead, which would
+        // be even much better to spot :/.
+        const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
+        *this = aiMatrix3x3t<TReal>( nan,nan,nan,nan,nan,nan,nan,nan,nan);
+
+        return *this;
+    }
+
+    TReal invdet = static_cast<TReal>(1.0) / det;
+
+    aiMatrix3x3t<TReal> res;
+    res.a1 = invdet  * (b2 * c3 - b3 * c2);
+    res.a2 = -invdet * (a2 * c3 - a3 * c2);
+    res.a3 = invdet  * (a2 * b3 - a3 * b2);
+    res.b1 = -invdet * (b1 * c3 - b3 * c1);
+    res.b2 = invdet  * (a1 * c3 - a3 * c1);
+    res.b3 = -invdet * (a1 * b3 - a3 * b1);
+    res.c1 = invdet  * (b1 * c2 - b2 * c1);
+    res.c2 = -invdet * (a1 * c2 - a2 * c1);
+    res.c3 = invdet  * (a1 * b2 - a2 * b1);
+    *this = res;
+
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
+{
+    out.a1 = out.b2 = std::cos(a);
+    out.b1 = std::sin(a);
+    out.a2 = - out.b1;
+
+    out.a3 = out.b3 = out.c1 = out.c2 = 0.f;
+    out.c3 = 1.f;
+
+    return out;
+}
+
+// ------------------------------------------------------------------------------------------------
+// Returns a rotation matrix for a rotation around an arbitrary axis.
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix3x3t<TReal>& out)
+{
+  TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
+  TReal x = axis.x, y = axis.y, z = axis.z;
+
+  // Many thanks to MathWorld and Wikipedia
+  out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
+  out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
+  out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
+
+  return out;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
+{
+    out = aiMatrix3x3t<TReal>();
+    out.a3 = v.x;
+    out.b3 = v.y;
+    return out;
+}
+
+// ----------------------------------------------------------------------------------------
+/** A function for creating a rotation matrix that rotates a vector called
+ * "from" into another vector called "to".
+ * Input : from[3], to[3] which both must be *normalized* non-zero vectors
+ * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
+ * Authors: Tomas Möller, John Hughes
+ *          "Efficiently Building a Matrix to Rotate One Vector to Another"
+ *          Journal of Graphics Tools, 4(4):1-4, 1999
+ */
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
+    const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
+{
+    const TReal e = from * to;
+    const TReal f = (e < 0)? -e:e;
+
+    if (f > static_cast<TReal>(1.0) - static_cast<TReal>(0.00001))     /* "from" and "to"-vector almost parallel */
+    {
+        aiVector3D u,v;     /* temporary storage vectors */
+        aiVector3D x;       /* vector most nearly orthogonal to "from" */
+
+        x.x = (from.x > 0.0)? from.x : -from.x;
+        x.y = (from.y > 0.0)? from.y : -from.y;
+        x.z = (from.z > 0.0)? from.z : -from.z;
+
+        if (x.x < x.y)
+        {
+            if (x.x < x.z)
+            {
+                x.x = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
+            }
+            else
+            {
+                x.z = static_cast<TReal>(1.0); x.y = x.z = static_cast<TReal>(0.0);
+            }
+        }
+        else
+        {
+            if (x.y < x.z)
+            {
+                x.y = static_cast<TReal>(1.0); x.x = x.z = static_cast<TReal>(0.0);
+            }
+            else
+            {
+                x.z = static_cast<TReal>(1.0); x.x = x.y = static_cast<TReal>(0.0);
+            }
+        }
+
+        u.x = x.x - from.x; u.y = x.y - from.y; u.z = x.z - from.z;
+        v.x = x.x - to.x;   v.y = x.y - to.y;   v.z = x.z - to.z;
+
+        const TReal c1 = static_cast<TReal>(2.0) / (u * u);
+        const TReal c2 = static_cast<TReal>(2.0) / (v * v);
+        const TReal c3 = c1 * c2  * (u * v);
+
+        for (unsigned int i = 0; i < 3; i++)
+        {
+            for (unsigned int j = 0; j < 3; j++)
+            {
+                mtx[i][j] =  - c1 * u[i] * u[j] - c2 * v[i] * v[j]
+                    + c3 * v[i] * u[j];
+            }
+            mtx[i][i] += static_cast<TReal>(1.0);
+        }
+    }
+    else  /* the most common case, unless "from"="to", or "from"=-"to" */
+    {
+        const aiVector3D v = from ^ to;
+        /* ... use this hand optimized version (9 mults less) */
+        const TReal h = static_cast<TReal>(1.0)/(static_cast<TReal>(1.0) + e);      /* optimization by Gottfried Chen */
+        const TReal hvx = h * v.x;
+        const TReal hvz = h * v.z;
+        const TReal hvxy = hvx * v.y;
+        const TReal hvxz = hvx * v.z;
+        const TReal hvyz = hvz * v.y;
+        mtx[0][0] = e + hvx * v.x;
+        mtx[0][1] = hvxy - v.z;
+        mtx[0][2] = hvxz + v.y;
+
+        mtx[1][0] = hvxy + v.z;
+        mtx[1][1] = e + h * v.y * v.y;
+        mtx[1][2] = hvyz - v.x;
+
+        mtx[2][0] = hvxz - v.y;
+        mtx[2][1] = hvyz + v.x;
+        mtx[2][2] = e + hvz * v.z;
+    }
+    return mtx;
+}
+
+
+#endif // __cplusplus
+#endif // AI_MATRIX3x3_INL_INC

+ 249 - 0
include/assimp/matrix4x4.h

@@ -0,0 +1,249 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+/** @file matrix4x4.h
+ *  @brief 4x4 matrix structure, including operators when compiling in C++
+ */
+#ifndef AI_MATRIX4X4_H_INC
+#define AI_MATRIX4X4_H_INC
+
+#include "vector3.h"
+#include "./Compiler/pushpack1.h"
+
+#ifdef __cplusplus
+
+template<typename TReal> class aiMatrix3x3t;
+template<typename TReal> class aiQuaterniont;
+
+// ---------------------------------------------------------------------------
+/** @brief Represents a row-major 4x4 matrix, use this for homogeneous
+ *   coordinates.
+ *
+ *  There's much confusion about matrix layouts (column vs. row order).
+ *  This is *always* a row-major matrix. Not even with the
+ *  #aiProcess_ConvertToLeftHanded flag, which absolutely does not affect
+ *  matrix order - it just affects the handedness of the coordinate system
+ *  defined thereby.
+ */
+template<typename TReal>
+class aiMatrix4x4t
+{
+public:
+
+    /** set to identity */
+    aiMatrix4x4t ();
+
+    /** construction from single values */
+    aiMatrix4x4t (  TReal _a1, TReal _a2, TReal _a3, TReal _a4,
+                    TReal _b1, TReal _b2, TReal _b3, TReal _b4,
+                    TReal _c1, TReal _c2, TReal _c3, TReal _c4,
+                    TReal _d1, TReal _d2, TReal _d3, TReal _d4);
+
+
+    /** construction from 3x3 matrix, remaining elements are set to identity */
+    explicit aiMatrix4x4t( const aiMatrix3x3t<TReal>& m);
+
+    /** construction from position, rotation and scaling components
+     * @param scaling The scaling for the x,y,z axes
+     * @param rotation The rotation as a hamilton quaternion
+     * @param position The position for the x,y,z axes
+     */
+    aiMatrix4x4t(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation,
+        const aiVector3t<TReal>& position);
+
+public:
+
+    // array access operators
+    TReal* operator[]       (unsigned int p_iIndex);
+    const TReal* operator[] (unsigned int p_iIndex) const;
+
+    // comparison operators
+    bool operator== (const aiMatrix4x4t& m) const;
+    bool operator!= (const aiMatrix4x4t& m) const;
+
+    bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const;
+
+    // matrix multiplication.
+    aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);
+    aiMatrix4x4t  operator *  (const aiMatrix4x4t& m) const;
+
+    template <typename TOther>
+    operator aiMatrix4x4t<TOther> () const;
+
+public:
+
+    // -------------------------------------------------------------------
+    /** @brief Transpose the matrix */
+    aiMatrix4x4t& Transpose();
+
+    // -------------------------------------------------------------------
+    /** @brief Invert the matrix.
+     *  If the matrix is not invertible all elements are set to qnan.
+     *  Beware, use (f != f) to check whether a TReal f is qnan.
+     */
+    aiMatrix4x4t& Inverse();
+    TReal Determinant() const;
+
+
+    // -------------------------------------------------------------------
+    /** @brief Returns true of the matrix is the identity matrix.
+     *  The check is performed against a not so small epsilon.
+     */
+    inline bool IsIdentity() const;
+
+    // -------------------------------------------------------------------
+    /** @brief Decompose a trafo matrix into its original components
+     *  @param scaling Receives the output scaling for the x,y,z axes
+     *  @param rotation Receives the output rotation as a hamilton
+     *   quaternion
+     *  @param position Receives the output position for the x,y,z axes
+     */
+    void Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
+        aiVector3t<TReal>& position) const;
+
+    // -------------------------------------------------------------------
+    /** @brief Decompose a trafo matrix with no scaling into its
+     *    original components
+     *  @param rotation Receives the output rotation as a hamilton
+     *    quaternion
+     *  @param position Receives the output position for the x,y,z axes
+     */
+    void DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
+        aiVector3t<TReal>& position) const;
+
+
+    // -------------------------------------------------------------------
+    /** @brief Creates a trafo matrix from a set of euler angles
+     *  @param x Rotation angle for the x-axis, in radians
+     *  @param y Rotation angle for the y-axis, in radians
+     *  @param z Rotation angle for the z-axis, in radians
+     */
+    aiMatrix4x4t& FromEulerAnglesXYZ(TReal x, TReal y, TReal z);
+    aiMatrix4x4t& FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb);
+
+public:
+    // -------------------------------------------------------------------
+    /** @brief Returns a rotation matrix for a rotation around the x axis
+     *  @param a Rotation angle, in radians
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix4x4t& RotationX(TReal a, aiMatrix4x4t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief Returns a rotation matrix for a rotation around the y axis
+     *  @param a Rotation angle, in radians
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix4x4t& RotationY(TReal a, aiMatrix4x4t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief Returns a rotation matrix for a rotation around the z axis
+     *  @param a Rotation angle, in radians
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix4x4t& RotationZ(TReal a, aiMatrix4x4t& out);
+
+    // -------------------------------------------------------------------
+    /** Returns a rotation matrix for a rotation around an arbitrary axis.
+     *  @param a Rotation angle, in radians
+     *  @param axis Rotation axis, should be a normalized vector.
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix4x4t& Rotation(TReal a, const aiVector3t<TReal>& axis,
+        aiMatrix4x4t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief Returns a translation matrix
+     *  @param v Translation vector
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix4x4t& Translation( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief Returns a scaling matrix
+     *  @param v Scaling vector
+     *  @param out Receives the output matrix
+     *  @return Reference to the output matrix
+     */
+    static aiMatrix4x4t& Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t& out);
+
+    // -------------------------------------------------------------------
+    /** @brief A function for creating a rotation matrix that rotates a
+     *  vector called "from" into another vector called "to".
+     * Input : from[3], to[3] which both must be *normalized* non-zero vectors
+     * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
+     * Authors: Tomas Möller, John Hughes
+     *          "Efficiently Building a Matrix to Rotate One Vector to Another"
+     *          Journal of Graphics Tools, 4(4):1-4, 1999
+     */
+    static aiMatrix4x4t& FromToMatrix(const aiVector3t<TReal>& from,
+        const aiVector3t<TReal>& to, aiMatrix4x4t& out);
+
+public:
+
+    TReal a1, a2, a3, a4;
+    TReal b1, b2, b3, b4;
+    TReal c1, c2, c3, c4;
+    TReal d1, d2, d3, d4;
+
+} PACK_STRUCT;
+
+typedef aiMatrix4x4t<float> aiMatrix4x4;
+
+#else
+
+struct aiMatrix4x4 {
+    float a1, a2, a3, a4;
+    float b1, b2, b3, b4;
+    float c1, c2, c3, c4;
+    float d1, d2, d3, d4;
+};
+
+
+#endif // __cplusplus
+
+#include "./Compiler/poppack1.h"
+
+#endif // AI_MATRIX4X4_H_INC

+ 535 - 0
include/assimp/matrix4x4.inl

@@ -0,0 +1,535 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file matrix4x4.inl
+ *  @brief Inline implementation of the 4x4 matrix operators
+ */
+#ifndef AI_MATRIX4x4_INL_INC
+#define AI_MATRIX4x4_INL_INC
+
+#ifdef __cplusplus
+
+#include "matrix4x4.h"
+#include "matrix3x3.h"
+#include "quaternion.h"
+
+#include <algorithm>
+#include <limits>
+#include <cmath>
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+aiMatrix4x4t<TReal> ::aiMatrix4x4t () :
+    a1(1.0f), a2(), a3(), a4(),
+    b1(), b2(1.0f), b3(), b4(),
+    c1(), c2(), c3(1.0f), c4(),
+    d1(), d2(), d3(), d4(1.0f)
+{
+
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+aiMatrix4x4t<TReal> ::aiMatrix4x4t (TReal _a1, TReal _a2, TReal _a3, TReal _a4,
+              TReal _b1, TReal _b2, TReal _b3, TReal _b4,
+              TReal _c1, TReal _c2, TReal _c3, TReal _c4,
+              TReal _d1, TReal _d2, TReal _d3, TReal _d4) :
+    a1(_a1), a2(_a2), a3(_a3), a4(_a4),
+    b1(_b1), b2(_b2), b3(_b3), b4(_b4),
+    c1(_c1), c2(_c2), c3(_c3), c4(_c4),
+    d1(_d1), d2(_d2), d3(_d3), d4(_d4)
+{
+
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+template <typename TOther>
+aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
+{
+    return aiMatrix4x4t<TOther>(static_cast<TOther>(a1),static_cast<TOther>(a2),static_cast<TOther>(a3),static_cast<TOther>(a4),
+        static_cast<TOther>(b1),static_cast<TOther>(b2),static_cast<TOther>(b3),static_cast<TOther>(b4),
+        static_cast<TOther>(c1),static_cast<TOther>(c2),static_cast<TOther>(c3),static_cast<TOther>(c4),
+        static_cast<TOther>(d1),static_cast<TOther>(d2),static_cast<TOther>(d3),static_cast<TOther>(d4));
+}
+
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
+{
+    a1 = m.a1; a2 = m.a2; a3 = m.a3; a4 = static_cast<TReal>(0.0);
+    b1 = m.b1; b2 = m.b2; b3 = m.b3; b4 = static_cast<TReal>(0.0);
+    c1 = m.c1; c2 = m.c2; c3 = m.c3; c4 = static_cast<TReal>(0.0);
+    d1 = static_cast<TReal>(0.0); d2 = static_cast<TReal>(0.0); d3 = static_cast<TReal>(0.0); d4 = static_cast<TReal>(1.0);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position)
+{
+    // build a 3x3 rotation matrix
+    aiMatrix3x3t<TReal> m = rotation.GetMatrix();
+
+    a1 = m.a1 * scaling.x;
+    a2 = m.a2 * scaling.x;
+    a3 = m.a3 * scaling.x;
+    a4 = position.x;
+
+    b1 = m.b1 * scaling.y;
+    b2 = m.b2 * scaling.y;
+    b3 = m.b3 * scaling.y;
+    b4 = position.y;
+
+    c1 = m.c1 * scaling.z;
+    c2 = m.c2 * scaling.z;
+    c3 = m.c3 * scaling.z;
+    c4= position.z;
+
+    d1 = static_cast<TReal>(0.0);
+    d2 = static_cast<TReal>(0.0);
+    d3 = static_cast<TReal>(0.0);
+    d4 = static_cast<TReal>(1.0);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
+{
+    *this = aiMatrix4x4t<TReal>(
+        m.a1 * a1 + m.b1 * a2 + m.c1 * a3 + m.d1 * a4,
+        m.a2 * a1 + m.b2 * a2 + m.c2 * a3 + m.d2 * a4,
+        m.a3 * a1 + m.b3 * a2 + m.c3 * a3 + m.d3 * a4,
+        m.a4 * a1 + m.b4 * a2 + m.c4 * a3 + m.d4 * a4,
+        m.a1 * b1 + m.b1 * b2 + m.c1 * b3 + m.d1 * b4,
+        m.a2 * b1 + m.b2 * b2 + m.c2 * b3 + m.d2 * b4,
+        m.a3 * b1 + m.b3 * b2 + m.c3 * b3 + m.d3 * b4,
+        m.a4 * b1 + m.b4 * b2 + m.c4 * b3 + m.d4 * b4,
+        m.a1 * c1 + m.b1 * c2 + m.c1 * c3 + m.d1 * c4,
+        m.a2 * c1 + m.b2 * c2 + m.c2 * c3 + m.d2 * c4,
+        m.a3 * c1 + m.b3 * c2 + m.c3 * c3 + m.d3 * c4,
+        m.a4 * c1 + m.b4 * c2 + m.c4 * c3 + m.d4 * c4,
+        m.a1 * d1 + m.b1 * d2 + m.c1 * d3 + m.d1 * d4,
+        m.a2 * d1 + m.b2 * d2 + m.c2 * d3 + m.d2 * d4,
+        m.a3 * d1 + m.b3 * d2 + m.c3 * d3 + m.d3 * d4,
+        m.a4 * d1 + m.b4 * d2 + m.c4 * d3 + m.d4 * d4);
+    return *this;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
+{
+    aiMatrix4x4t<TReal> temp( *this);
+    temp *= m;
+    return temp;
+}
+
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
+{
+    // (TReal&) don't remove, GCC complains cause of packed fields
+    std::swap( (TReal&)b1, (TReal&)a2);
+    std::swap( (TReal&)c1, (TReal&)a3);
+    std::swap( (TReal&)c2, (TReal&)b3);
+    std::swap( (TReal&)d1, (TReal&)a4);
+    std::swap( (TReal&)d2, (TReal&)b4);
+    std::swap( (TReal&)d3, (TReal&)c4);
+    return *this;
+}
+
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline TReal aiMatrix4x4t<TReal>::Determinant() const
+{
+    return a1*b2*c3*d4 - a1*b2*c4*d3 + a1*b3*c4*d2 - a1*b3*c2*d4
+        + a1*b4*c2*d3 - a1*b4*c3*d2 - a2*b3*c4*d1 + a2*b3*c1*d4
+        - a2*b4*c1*d3 + a2*b4*c3*d1 - a2*b1*c3*d4 + a2*b1*c4*d3
+        + a3*b4*c1*d2 - a3*b4*c2*d1 + a3*b1*c2*d4 - a3*b1*c4*d2
+        + a3*b2*c4*d1 - a3*b2*c1*d4 - a4*b1*c2*d3 + a4*b1*c3*d2
+        - a4*b2*c3*d1 + a4*b2*c1*d3 - a4*b3*c1*d2 + a4*b3*c2*d1;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
+{
+    // Compute the reciprocal determinant
+    const TReal det = Determinant();
+    if(det == static_cast<TReal>(0.0))
+    {
+        // Matrix not invertible. Setting all elements to nan is not really
+        // correct in a mathematical sense but it is easy to debug for the
+        // programmer.
+        const TReal nan = std::numeric_limits<TReal>::quiet_NaN();
+        *this = aiMatrix4x4t<TReal>(
+            nan,nan,nan,nan,
+            nan,nan,nan,nan,
+            nan,nan,nan,nan,
+            nan,nan,nan,nan);
+
+        return *this;
+    }
+
+    const TReal invdet = static_cast<TReal>(1.0) / det;
+
+    aiMatrix4x4t<TReal> res;
+    res.a1 = invdet  * (b2 * (c3 * d4 - c4 * d3) + b3 * (c4 * d2 - c2 * d4) + b4 * (c2 * d3 - c3 * d2));
+    res.a2 = -invdet * (a2 * (c3 * d4 - c4 * d3) + a3 * (c4 * d2 - c2 * d4) + a4 * (c2 * d3 - c3 * d2));
+    res.a3 = invdet  * (a2 * (b3 * d4 - b4 * d3) + a3 * (b4 * d2 - b2 * d4) + a4 * (b2 * d3 - b3 * d2));
+    res.a4 = -invdet * (a2 * (b3 * c4 - b4 * c3) + a3 * (b4 * c2 - b2 * c4) + a4 * (b2 * c3 - b3 * c2));
+    res.b1 = -invdet * (b1 * (c3 * d4 - c4 * d3) + b3 * (c4 * d1 - c1 * d4) + b4 * (c1 * d3 - c3 * d1));
+    res.b2 = invdet  * (a1 * (c3 * d4 - c4 * d3) + a3 * (c4 * d1 - c1 * d4) + a4 * (c1 * d3 - c3 * d1));
+    res.b3 = -invdet * (a1 * (b3 * d4 - b4 * d3) + a3 * (b4 * d1 - b1 * d4) + a4 * (b1 * d3 - b3 * d1));
+    res.b4 = invdet  * (a1 * (b3 * c4 - b4 * c3) + a3 * (b4 * c1 - b1 * c4) + a4 * (b1 * c3 - b3 * c1));
+    res.c1 = invdet  * (b1 * (c2 * d4 - c4 * d2) + b2 * (c4 * d1 - c1 * d4) + b4 * (c1 * d2 - c2 * d1));
+    res.c2 = -invdet * (a1 * (c2 * d4 - c4 * d2) + a2 * (c4 * d1 - c1 * d4) + a4 * (c1 * d2 - c2 * d1));
+    res.c3 = invdet  * (a1 * (b2 * d4 - b4 * d2) + a2 * (b4 * d1 - b1 * d4) + a4 * (b1 * d2 - b2 * d1));
+    res.c4 = -invdet * (a1 * (b2 * c4 - b4 * c2) + a2 * (b4 * c1 - b1 * c4) + a4 * (b1 * c2 - b2 * c1));
+    res.d1 = -invdet * (b1 * (c2 * d3 - c3 * d2) + b2 * (c3 * d1 - c1 * d3) + b3 * (c1 * d2 - c2 * d1));
+    res.d2 = invdet  * (a1 * (c2 * d3 - c3 * d2) + a2 * (c3 * d1 - c1 * d3) + a3 * (c1 * d2 - c2 * d1));
+    res.d3 = -invdet * (a1 * (b2 * d3 - b3 * d2) + a2 * (b3 * d1 - b1 * d3) + a3 * (b1 * d2 - b2 * d1));
+    res.d4 = invdet  * (a1 * (b2 * c3 - b3 * c2) + a2 * (b3 * c1 - b1 * c3) + a3 * (b1 * c2 - b2 * c1));
+    *this = res;
+
+    return *this;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex)
+{
+    // XXX this is UB. Has been for years. The fact that it works now does not make it better.
+    return &this->a1 + p_iIndex * 4;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
+{
+    // XXX same
+    return &this->a1 + p_iIndex * 4;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
+{
+    return (a1 == m.a1 && a2 == m.a2 && a3 == m.a3 && a4 == m.a4 &&
+            b1 == m.b1 && b2 == m.b2 && b3 == m.b3 && b4 == m.b4 &&
+            c1 == m.c1 && c2 == m.c2 && c3 == m.c3 && c4 == m.c4 &&
+            d1 == m.d1 && d2 == m.d2 && d3 == m.d3 && d4 == m.d4);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
+{
+    return !(*this == m);
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsilon) const {
+    return
+        std::abs(a1 - m.a1) <= epsilon &&
+        std::abs(a2 - m.a2) <= epsilon &&
+        std::abs(a3 - m.a3) <= epsilon &&
+        std::abs(a4 - m.a4) <= epsilon &&
+        std::abs(b1 - m.b1) <= epsilon &&
+        std::abs(b2 - m.b2) <= epsilon &&
+        std::abs(b3 - m.b3) <= epsilon &&
+        std::abs(b4 - m.b4) <= epsilon &&
+        std::abs(c1 - m.c1) <= epsilon &&
+        std::abs(c2 - m.c2) <= epsilon &&
+        std::abs(c3 - m.c3) <= epsilon &&
+        std::abs(c4 - m.c4) <= epsilon &&
+        std::abs(d1 - m.d1) <= epsilon &&
+        std::abs(d2 - m.d2) <= epsilon &&
+        std::abs(d3 - m.d3) <= epsilon &&
+        std::abs(d4 - m.d4) <= epsilon;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& scaling, aiQuaterniont<TReal>& rotation,
+    aiVector3t<TReal>& position) const
+{
+    const aiMatrix4x4t<TReal>& _this = *this;
+
+    // extract translation
+    position.x = _this[0][3];
+    position.y = _this[1][3];
+    position.z = _this[2][3];
+
+    // extract the rows of the matrix
+    aiVector3t<TReal> vRows[3] = {
+        aiVector3t<TReal>(_this[0][0],_this[1][0],_this[2][0]),
+        aiVector3t<TReal>(_this[0][1],_this[1][1],_this[2][1]),
+        aiVector3t<TReal>(_this[0][2],_this[1][2],_this[2][2])
+    };
+
+    // extract the scaling factors
+    scaling.x = vRows[0].Length();
+    scaling.y = vRows[1].Length();
+    scaling.z = vRows[2].Length();
+
+    // and the sign of the scaling
+    if (Determinant() < 0) {
+        scaling.x = -scaling.x;
+        scaling.y = -scaling.y;
+        scaling.z = -scaling.z;
+    }
+
+    // and remove all scaling from the matrix
+    if(scaling.x)
+    {
+        vRows[0] /= scaling.x;
+    }
+    if(scaling.y)
+    {
+        vRows[1] /= scaling.y;
+    }
+    if(scaling.z)
+    {
+        vRows[2] /= scaling.z;
+    }
+
+    // build a 3x3 rotation matrix
+    aiMatrix3x3t<TReal> m(vRows[0].x,vRows[1].x,vRows[2].x,
+        vRows[0].y,vRows[1].y,vRows[2].y,
+        vRows[0].z,vRows[1].z,vRows[2].z);
+
+    // and generate the rotation quaternion from it
+    rotation = aiQuaterniont<TReal>(m);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
+    aiVector3t<TReal>& position) const
+{
+    const aiMatrix4x4t<TReal>& _this = *this;
+
+    // extract translation
+    position.x = _this[0][3];
+    position.y = _this[1][3];
+    position.z = _this[2][3];
+
+    // extract rotation
+    rotation = aiQuaterniont<TReal>((aiMatrix3x3t<TReal>)_this);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
+{
+    return FromEulerAnglesXYZ(blubb.x,blubb.y,blubb.z);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z)
+{
+    aiMatrix4x4t<TReal>& _this = *this;
+
+    TReal cr = std::cos( x );
+    TReal sr = std::sin( x );
+    TReal cp = std::cos( y );
+    TReal sp = std::sin( y );
+    TReal cy = std::cos( z );
+    TReal sy = std::sin( z );
+
+    _this.a1 = cp*cy ;
+    _this.a2 = cp*sy;
+    _this.a3 = -sp ;
+
+    TReal srsp = sr*sp;
+    TReal crsp = cr*sp;
+
+    _this.b1 = srsp*cy-cr*sy ;
+    _this.b2 = srsp*sy+cr*cy ;
+    _this.b3 = sr*cp ;
+
+    _this.c1 =  crsp*cy+sr*sy ;
+    _this.c2 =  crsp*sy-sr*cy ;
+    _this.c3 = cr*cp ;
+
+    return *this;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline bool aiMatrix4x4t<TReal>::IsIdentity() const
+{
+    // Use a small epsilon to solve floating-point inaccuracies
+    const static TReal epsilon = 10e-3f;
+
+    return (a2 <= epsilon && a2 >= -epsilon &&
+            a3 <= epsilon && a3 >= -epsilon &&
+            a4 <= epsilon && a4 >= -epsilon &&
+            b1 <= epsilon && b1 >= -epsilon &&
+            b3 <= epsilon && b3 >= -epsilon &&
+            b4 <= epsilon && b4 >= -epsilon &&
+            c1 <= epsilon && c1 >= -epsilon &&
+            c2 <= epsilon && c2 >= -epsilon &&
+            c4 <= epsilon && c4 >= -epsilon &&
+            d1 <= epsilon && d1 >= -epsilon &&
+            d2 <= epsilon && d2 >= -epsilon &&
+            d3 <= epsilon && d3 >= -epsilon &&
+            a1 <= 1.f+epsilon && a1 >= 1.f-epsilon &&
+            b2 <= 1.f+epsilon && b2 >= 1.f-epsilon &&
+            c3 <= 1.f+epsilon && c3 >= 1.f-epsilon &&
+            d4 <= 1.f+epsilon && d4 >= 1.f-epsilon);
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
+{
+    /*
+         |  1  0       0       0 |
+     M = |  0  cos(A) -sin(A)  0 |
+         |  0  sin(A)  cos(A)  0 |
+         |  0  0       0       1 |  */
+    out = aiMatrix4x4t<TReal>();
+    out.b2 = out.c3 = std::cos(a);
+    out.b3 = -(out.c2 = std::sin(a));
+    return out;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
+{
+    /*
+         |  cos(A)  0   sin(A)  0 |
+     M = |  0       1   0       0 |
+         | -sin(A)  0   cos(A)  0 |
+         |  0       0   0       1 |
+        */
+    out = aiMatrix4x4t<TReal>();
+    out.a1 = out.c3 = std::cos(a);
+    out.c1 = -(out.a3 = std::sin(a));
+    return out;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
+{
+    /*
+         |  cos(A)  -sin(A)   0   0 |
+     M = |  sin(A)   cos(A)   0   0 |
+         |  0        0        1   0 |
+         |  0        0        0   1 |   */
+    out = aiMatrix4x4t<TReal>();
+    out.a1 = out.b2 = std::cos(a);
+    out.a2 = -(out.b1 = std::sin(a));
+    return out;
+}
+
+// ----------------------------------------------------------------------------------------
+// Returns a rotation matrix for a rotation around an arbitrary axis.
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Rotation( TReal a, const aiVector3t<TReal>& axis, aiMatrix4x4t<TReal>& out)
+{
+  TReal c = std::cos( a), s = std::sin( a), t = 1 - c;
+  TReal x = axis.x, y = axis.y, z = axis.z;
+
+  // Many thanks to MathWorld and Wikipedia
+  out.a1 = t*x*x + c;   out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
+  out.b1 = t*x*y + s*z; out.b2 = t*y*y + c;   out.b3 = t*y*z - s*x;
+  out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
+  out.a4 = out.b4 = out.c4 = static_cast<TReal>(0.0);
+  out.d1 = out.d2 = out.d3 = static_cast<TReal>(0.0);
+  out.d4 = static_cast<TReal>(1.0);
+
+  return out;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
+{
+    out = aiMatrix4x4t<TReal>();
+    out.a4 = v.x;
+    out.b4 = v.y;
+    out.c4 = v.z;
+    return out;
+}
+
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
+{
+    out = aiMatrix4x4t<TReal>();
+    out.a1 = v.x;
+    out.b2 = v.y;
+    out.c3 = v.z;
+    return out;
+}
+
+// ----------------------------------------------------------------------------------------
+/** A function for creating a rotation matrix that rotates a vector called
+ * "from" into another vector called "to".
+ * Input : from[3], to[3] which both must be *normalized* non-zero vectors
+ * Output: mtx[3][3] -- a 3x3 matrix in colum-major form
+ * Authors: Tomas Möller, John Hughes
+ *          "Efficiently Building a Matrix to Rotate One Vector to Another"
+ *          Journal of Graphics Tools, 4(4):1-4, 1999
+ */
+// ----------------------------------------------------------------------------------------
+template <typename TReal>
+inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
+    const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
+{
+    aiMatrix3x3t<TReal> m3;
+    aiMatrix3x3t<TReal>::FromToMatrix(from,to,m3);
+    mtx = aiMatrix4x4t<TReal>(m3);
+    return mtx;
+}
+
+#endif // __cplusplus
+#endif // AI_MATRIX4x4_INL_INC

+ 739 - 0
include/assimp/mesh.h

@@ -0,0 +1,739 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file mesh.h
+ *  @brief Declares the data structures in which the imported geometry is
+    returned by ASSIMP: aiMesh, aiFace and aiBone data structures.
+ */
+#ifndef INCLUDED_AI_MESH_H
+#define INCLUDED_AI_MESH_H
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+// Limits. These values are required to match the settings Assimp was
+// compiled against. Therfore, do not redefine them unless you build the
+// library from source using the same definitions.
+// ---------------------------------------------------------------------------
+
+/** @def AI_MAX_FACE_INDICES
+ *  Maximum number of indices per face (polygon). */
+
+#ifndef AI_MAX_FACE_INDICES
+#   define AI_MAX_FACE_INDICES 0x7fff
+#endif
+
+/** @def AI_MAX_BONE_WEIGHTS
+ *  Maximum number of indices per face (polygon). */
+
+#ifndef AI_MAX_BONE_WEIGHTS
+#   define AI_MAX_BONE_WEIGHTS 0x7fffffff
+#endif
+
+/** @def AI_MAX_VERTICES
+ *  Maximum number of vertices per mesh.  */
+
+#ifndef AI_MAX_VERTICES
+#   define AI_MAX_VERTICES 0x7fffffff
+#endif
+
+/** @def AI_MAX_FACES
+ *  Maximum number of faces per mesh. */
+
+#ifndef AI_MAX_FACES
+#   define AI_MAX_FACES 0x7fffffff
+#endif
+
+/** @def AI_MAX_NUMBER_OF_COLOR_SETS
+ *  Supported number of vertex color sets per mesh. */
+
+#ifndef AI_MAX_NUMBER_OF_COLOR_SETS
+#   define AI_MAX_NUMBER_OF_COLOR_SETS 0x8
+#endif // !! AI_MAX_NUMBER_OF_COLOR_SETS
+
+/** @def AI_MAX_NUMBER_OF_TEXTURECOORDS
+ *  Supported number of texture coord sets (UV(W) channels) per mesh */
+
+#ifndef AI_MAX_NUMBER_OF_TEXTURECOORDS
+#   define AI_MAX_NUMBER_OF_TEXTURECOORDS 0x8
+#endif // !! AI_MAX_NUMBER_OF_TEXTURECOORDS
+
+// ---------------------------------------------------------------------------
+/** @brief A single face in a mesh, referring to multiple vertices.
+ *
+ * If mNumIndices is 3, we call the face 'triangle', for mNumIndices > 3
+ * it's called 'polygon' (hey, that's just a definition!).
+ * <br>
+ * aiMesh::mPrimitiveTypes can be queried to quickly examine which types of
+ * primitive are actually present in a mesh. The #aiProcess_SortByPType flag
+ * executes a special post-processing algorithm which splits meshes with
+ * *different* primitive types mixed up (e.g. lines and triangles) in several
+ * 'clean' submeshes. Furthermore there is a configuration option (
+ * #AI_CONFIG_PP_SBP_REMOVE) to force #aiProcess_SortByPType to remove
+ * specific kinds of primitives from the imported scene, completely and forever.
+ * In many cases you'll probably want to set this setting to
+ * @code
+ * aiPrimitiveType_LINE|aiPrimitiveType_POINT
+ * @endcode
+ * Together with the #aiProcess_Triangulate flag you can then be sure that
+ * #aiFace::mNumIndices is always 3.
+ * @note Take a look at the @link data Data Structures page @endlink for
+ * more information on the layout and winding order of a face.
+ */
+struct aiFace
+{
+    //! Number of indices defining this face.
+    //! The maximum value for this member is #AI_MAX_FACE_INDICES.
+    unsigned int mNumIndices;
+
+    //! Pointer to the indices array. Size of the array is given in numIndices.
+    unsigned int* mIndices;
+
+#ifdef __cplusplus
+
+    //! Default constructor
+    aiFace()
+      : mNumIndices( 0 )
+      , mIndices( NULL )
+    {
+    }
+
+    //! Default destructor. Delete the index array
+    ~aiFace()
+    {
+        delete [] mIndices;
+    }
+
+    //! Copy constructor. Copy the index array
+    aiFace( const aiFace& o)
+      : mIndices( NULL )
+    {
+        *this = o;
+    }
+
+    //! Assignment operator. Copy the index array
+    aiFace& operator = ( const aiFace& o)
+    {
+        if (&o == this)
+            return *this;
+
+        delete[] mIndices;
+        mNumIndices = o.mNumIndices;
+        if (mNumIndices) {
+            mIndices = new unsigned int[mNumIndices];
+            ::memcpy( mIndices, o.mIndices, mNumIndices * sizeof( unsigned int));
+        }
+        else {
+            mIndices = NULL;
+        }
+        return *this;
+    }
+
+    //! Comparison operator. Checks whether the index array
+    //! of two faces is identical
+    bool operator== (const aiFace& o) const
+    {
+        if (mIndices == o.mIndices)return true;
+        else if (mIndices && mNumIndices == o.mNumIndices)
+        {
+            for (unsigned int i = 0;i < this->mNumIndices;++i)
+                if (mIndices[i] != o.mIndices[i])return false;
+            return true;
+        }
+        return false;
+    }
+
+    //! Inverse comparison operator. Checks whether the index
+    //! array of two faces is NOT identical
+    bool operator != (const aiFace& o) const
+    {
+        return !(*this == o);
+    }
+#endif // __cplusplus
+}; // struct aiFace
+
+
+// ---------------------------------------------------------------------------
+/** @brief A single influence of a bone on a vertex.
+ */
+struct aiVertexWeight
+{
+    //! Index of the vertex which is influenced by the bone.
+    unsigned int mVertexId;
+
+    //! The strength of the influence in the range (0...1).
+    //! The influence from all bones at one vertex amounts to 1.
+    float mWeight;
+
+#ifdef __cplusplus
+
+    //! Default constructor
+    aiVertexWeight() { }
+
+    //! Initialisation from a given index and vertex weight factor
+    //! \param pID ID
+    //! \param pWeight Vertex weight factor
+    aiVertexWeight( unsigned int pID, float pWeight)
+        : mVertexId( pID), mWeight( pWeight)
+    { /* nothing to do here */ }
+
+#endif // __cplusplus
+};
+
+
+// ---------------------------------------------------------------------------
+/** @brief A single bone of a mesh.
+ *
+ *  A bone has a name by which it can be found in the frame hierarchy and by
+ *  which it can be addressed by animations. In addition it has a number of
+ *  influences on vertices.
+ */
+struct aiBone
+{
+    //! The name of the bone.
+    C_STRUCT aiString mName;
+
+    //! The number of vertices affected by this bone
+    //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
+    unsigned int mNumWeights;
+
+    //! The vertices affected by this bone
+    C_STRUCT aiVertexWeight* mWeights;
+
+    //! Matrix that transforms from mesh space to bone space in bind pose
+    C_STRUCT aiMatrix4x4 mOffsetMatrix;
+
+#ifdef __cplusplus
+
+    //! Default constructor
+    aiBone()
+      : mNumWeights( 0 )
+      , mWeights( NULL )
+    {
+    }
+
+    //! Copy constructor
+    aiBone(const aiBone& other)
+      : mName( other.mName )
+      , mNumWeights( other.mNumWeights )
+      , mOffsetMatrix( other.mOffsetMatrix )
+    {
+        if (other.mWeights && other.mNumWeights)
+        {
+            mWeights = new aiVertexWeight[mNumWeights];
+            ::memcpy(mWeights,other.mWeights,mNumWeights * sizeof(aiVertexWeight));
+        }
+    }
+
+    //! Destructor - deletes the array of vertex weights
+    ~aiBone()
+    {
+        delete [] mWeights;
+    }
+#endif // __cplusplus
+};
+
+
+// ---------------------------------------------------------------------------
+/** @brief Enumerates the types of geometric primitives supported by Assimp.
+ *
+ *  @see aiFace Face data structure
+ *  @see aiProcess_SortByPType Per-primitive sorting of meshes
+ *  @see aiProcess_Triangulate Automatic triangulation
+ *  @see AI_CONFIG_PP_SBP_REMOVE Removal of specific primitive types.
+ */
+enum aiPrimitiveType
+{
+    /** A point primitive.
+     *
+     * This is just a single vertex in the virtual world,
+     * #aiFace contains just one index for such a primitive.
+     */
+    aiPrimitiveType_POINT       = 0x1,
+
+    /** A line primitive.
+     *
+     * This is a line defined through a start and an end position.
+     * #aiFace contains exactly two indices for such a primitive.
+     */
+    aiPrimitiveType_LINE        = 0x2,
+
+    /** A triangular primitive.
+     *
+     * A triangle consists of three indices.
+     */
+    aiPrimitiveType_TRIANGLE    = 0x4,
+
+    /** A higher-level polygon with more than 3 edges.
+     *
+     * A triangle is a polygon, but polygon in this context means
+     * "all polygons that are not triangles". The "Triangulate"-Step
+     * is provided for your convenience, it splits all polygons in
+     * triangles (which are much easier to handle).
+     */
+    aiPrimitiveType_POLYGON     = 0x8,
+
+
+    /** This value is not used. It is just here to force the
+     *  compiler to map this enum to a 32 Bit integer.
+     */
+#ifndef SWIG
+    _aiPrimitiveType_Force32Bit = INT_MAX
+#endif
+}; //! enum aiPrimitiveType
+
+// Get the #aiPrimitiveType flag for a specific number of face indices
+#define AI_PRIMITIVE_TYPE_FOR_N_INDICES(n) \
+    ((n) > 3 ? aiPrimitiveType_POLYGON : (aiPrimitiveType)(1u << ((n)-1)))
+
+
+
+// ---------------------------------------------------------------------------
+/** @brief NOT CURRENTLY IN USE. An AnimMesh is an attachment to an #aiMesh stores per-vertex
+ *  animations for a particular frame.
+ *
+ *  You may think of an #aiAnimMesh as a `patch` for the host mesh, which
+ *  replaces only certain vertex data streams at a particular time.
+ *  Each mesh stores n attached attached meshes (#aiMesh::mAnimMeshes).
+ *  The actual relationship between the time line and anim meshes is
+ *  established by #aiMeshAnim, which references singular mesh attachments
+ *  by their ID and binds them to a time offset.
+*/
+struct aiAnimMesh
+{
+    /** Replacement for aiMesh::mVertices. If this array is non-NULL,
+     *  it *must* contain mNumVertices entries. The corresponding
+     *  array in the host mesh must be non-NULL as well - animation
+     *  meshes may neither add or nor remove vertex components (if
+     *  a replacement array is NULL and the corresponding source
+     *  array is not, the source data is taken instead)*/
+    C_STRUCT aiVector3D* mVertices;
+
+    /** Replacement for aiMesh::mNormals.  */
+    C_STRUCT aiVector3D* mNormals;
+
+    /** Replacement for aiMesh::mTangents. */
+    C_STRUCT aiVector3D* mTangents;
+
+    /** Replacement for aiMesh::mBitangents. */
+    C_STRUCT aiVector3D* mBitangents;
+
+    /** Replacement for aiMesh::mColors */
+    C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
+
+    /** Replacement for aiMesh::mTextureCoords */
+    C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
+    /** The number of vertices in the aiAnimMesh, and thus the length of all
+     * the member arrays.
+     *
+     * This has always the same value as the mNumVertices property in the
+     * corresponding aiMesh. It is duplicated here merely to make the length
+     * of the member arrays accessible even if the aiMesh is not known, e.g.
+     * from language bindings.
+     */
+    unsigned int mNumVertices;
+
+#ifdef __cplusplus
+
+    aiAnimMesh()
+        : mVertices( NULL )
+        , mNormals( NULL )
+        , mTangents( NULL )
+        , mBitangents( NULL )
+        , mNumVertices( 0 )
+    {
+        // fixme consider moving this to the ctor initializer list as well
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++){
+            mTextureCoords[a] = NULL;
+        }
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
+            mColors[a] = NULL;
+        }
+    }
+
+    ~aiAnimMesh()
+    {
+        delete [] mVertices;
+        delete [] mNormals;
+        delete [] mTangents;
+        delete [] mBitangents;
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+            delete [] mTextureCoords[a];
+        }
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
+            delete [] mColors[a];
+        }
+    }
+
+    /** Check whether the anim mesh overrides the vertex positions
+     *  of its host mesh*/
+    bool HasPositions() const {
+        return mVertices != NULL;
+    }
+
+    /** Check whether the anim mesh overrides the vertex normals
+     *  of its host mesh*/
+    bool HasNormals() const {
+        return mNormals != NULL;
+    }
+
+    /** Check whether the anim mesh overrides the vertex tangents
+     *  and bitangents of its host mesh. As for aiMesh,
+     *  tangents and bitangents always go together. */
+    bool HasTangentsAndBitangents() const {
+        return mTangents != NULL;
+    }
+
+    /** Check whether the anim mesh overrides a particular
+     * set of vertex colors on his host mesh.
+     *  @param pIndex 0<index<AI_MAX_NUMBER_OF_COLOR_SETS */
+    bool HasVertexColors( unsigned int pIndex) const    {
+        return pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS ? false : mColors[pIndex] != NULL;
+    }
+
+    /** Check whether the anim mesh overrides a particular
+     * set of texture coordinates on his host mesh.
+     *  @param pIndex 0<index<AI_MAX_NUMBER_OF_TEXTURECOORDS */
+    bool HasTextureCoords( unsigned int pIndex) const   {
+        return pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? false : mTextureCoords[pIndex] != NULL;
+    }
+
+#endif
+};
+
+
+// ---------------------------------------------------------------------------
+/** @brief A mesh represents a geometry or model with a single material.
+*
+* It usually consists of a number of vertices and a series of primitives/faces
+* referencing the vertices. In addition there might be a series of bones, each
+* of them addressing a number of vertices with a certain weight. Vertex data
+* is presented in channels with each channel containing a single per-vertex
+* information such as a set of texture coords or a normal vector.
+* If a data pointer is non-null, the corresponding data stream is present.
+* From C++-programs you can also use the comfort functions Has*() to
+* test for the presence of various data streams.
+*
+* A Mesh uses only a single material which is referenced by a material ID.
+* @note The mPositions member is usually not optional. However, vertex positions
+* *could* be missing if the #AI_SCENE_FLAGS_INCOMPLETE flag is set in
+* @code
+* aiScene::mFlags
+* @endcode
+*/
+struct aiMesh
+{
+    /** Bitwise combination of the members of the #aiPrimitiveType enum.
+     * This specifies which types of primitives are present in the mesh.
+     * The "SortByPrimitiveType"-Step can be used to make sure the
+     * output meshes consist of one primitive type each.
+     */
+    unsigned int mPrimitiveTypes;
+
+    /** The number of vertices in this mesh.
+    * This is also the size of all of the per-vertex data arrays.
+    * The maximum value for this member is #AI_MAX_VERTICES.
+    */
+    unsigned int mNumVertices;
+
+    /** The number of primitives (triangles, polygons, lines) in this  mesh.
+    * This is also the size of the mFaces array.
+    * The maximum value for this member is #AI_MAX_FACES.
+    */
+    unsigned int mNumFaces;
+
+    /** Vertex positions.
+    * This array is always present in a mesh. The array is
+    * mNumVertices in size.
+    */
+    C_STRUCT aiVector3D* mVertices;
+
+    /** Vertex normals.
+    * The array contains normalized vectors, NULL if not present.
+    * The array is mNumVertices in size. Normals are undefined for
+    * point and line primitives. A mesh consisting of points and
+    * lines only may not have normal vectors. Meshes with mixed
+    * primitive types (i.e. lines and triangles) may have normals,
+    * but the normals for vertices that are only referenced by
+    * point or line primitives are undefined and set to QNaN (WARN:
+    * qNaN compares to inequal to *everything*, even to qNaN itself.
+    * Using code like this to check whether a field is qnan is:
+    * @code
+    * #define IS_QNAN(f) (f != f)
+    * @endcode
+    * still dangerous because even 1.f == 1.f could evaluate to false! (
+    * remember the subtleties of IEEE754 artithmetics). Use stuff like
+    * @c fpclassify instead.
+    * @note Normal vectors computed by Assimp are always unit-length.
+    * However, this needn't apply for normals that have been taken
+    *   directly from the model file.
+    */
+    C_STRUCT aiVector3D* mNormals;
+
+    /** Vertex tangents.
+    * The tangent of a vertex points in the direction of the positive
+    * X texture axis. The array contains normalized vectors, NULL if
+    * not present. The array is mNumVertices in size. A mesh consisting
+    * of points and lines only may not have normal vectors. Meshes with
+    * mixed primitive types (i.e. lines and triangles) may have
+    * normals, but the normals for vertices that are only referenced by
+    * point or line primitives are undefined and set to qNaN.  See
+    * the #mNormals member for a detailled discussion of qNaNs.
+    * @note If the mesh contains tangents, it automatically also
+    * contains bitangents.
+    */
+    C_STRUCT aiVector3D* mTangents;
+
+    /** Vertex bitangents.
+    * The bitangent of a vertex points in the direction of the positive
+    * Y texture axis. The array contains normalized vectors, NULL if not
+    * present. The array is mNumVertices in size.
+    * @note If the mesh contains tangents, it automatically also contains
+    * bitangents.
+    */
+    C_STRUCT aiVector3D* mBitangents;
+
+    /** Vertex color sets.
+    * A mesh may contain 0 to #AI_MAX_NUMBER_OF_COLOR_SETS vertex
+    * colors per vertex. NULL if not present. Each array is
+    * mNumVertices in size if present.
+    */
+    C_STRUCT aiColor4D* mColors[AI_MAX_NUMBER_OF_COLOR_SETS];
+
+    /** Vertex texture coords, also known as UV channels.
+    * A mesh may contain 0 to AI_MAX_NUMBER_OF_TEXTURECOORDS per
+    * vertex. NULL if not present. The array is mNumVertices in size.
+    */
+    C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
+    /** Specifies the number of components for a given UV channel.
+    * Up to three channels are supported (UVW, for accessing volume
+    * or cube maps). If the value is 2 for a given channel n, the
+    * component p.z of mTextureCoords[n][p] is set to 0.0f.
+    * If the value is 1 for a given channel, p.y is set to 0.0f, too.
+    * @note 4D coords are not supported
+    */
+    unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];
+
+    /** The faces the mesh is constructed from.
+    * Each face refers to a number of vertices by their indices.
+    * This array is always present in a mesh, its size is given
+    * in mNumFaces. If the #AI_SCENE_FLAGS_NON_VERBOSE_FORMAT
+    * is NOT set each face references an unique set of vertices.
+    */
+    C_STRUCT aiFace* mFaces;
+
+    /** The number of bones this mesh contains.
+    * Can be 0, in which case the mBones array is NULL.
+    */
+    unsigned int mNumBones;
+
+    /** The bones of this mesh.
+    * A bone consists of a name by which it can be found in the
+    * frame hierarchy and a set of vertex weights.
+    */
+    C_STRUCT aiBone** mBones;
+
+    /** The material used by this mesh.
+     * A mesh does use only a single material. If an imported model uses
+     * multiple materials, the import splits up the mesh. Use this value
+     * as index into the scene's material list.
+     */
+    unsigned int mMaterialIndex;
+
+    /** Name of the mesh. Meshes can be named, but this is not a
+     *  requirement and leaving this field empty is totally fine.
+     *  There are mainly three uses for mesh names:
+     *   - some formats name nodes and meshes independently.
+     *   - importers tend to split meshes up to meet the
+     *      one-material-per-mesh requirement. Assigning
+     *      the same (dummy) name to each of the result meshes
+     *      aids the caller at recovering the original mesh
+     *      partitioning.
+     *   - Vertex animations refer to meshes by their names.
+     **/
+    C_STRUCT aiString mName;
+
+
+    /** NOT CURRENTLY IN USE. The number of attachment meshes */
+    unsigned int mNumAnimMeshes;
+
+    /** NOT CURRENTLY IN USE. Attachment meshes for this mesh, for vertex-based animation.
+     *  Attachment meshes carry replacement data for some of the
+     *  mesh'es vertex components (usually positions, normals). */
+    C_STRUCT aiAnimMesh** mAnimMeshes;
+
+
+#ifdef __cplusplus
+
+    //! Default constructor. Initializes all members to 0
+    aiMesh()
+        : mPrimitiveTypes( 0 )
+        , mNumVertices( 0 )
+        , mNumFaces( 0 )
+        , mVertices( NULL )
+        , mNormals( NULL )
+        , mTangents( NULL )
+        , mBitangents( NULL )
+        , mFaces( NULL )
+        , mNumBones( 0 )
+        , mBones( NULL )
+        , mMaterialIndex( 0 )
+        , mNumAnimMeshes( 0 )
+        , mAnimMeshes( NULL )
+    {
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
+        {
+            mNumUVComponents[a] = 0;
+            mTextureCoords[a] = NULL;
+        }
+
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++)
+            mColors[a] = NULL;
+    }
+
+    //! Deletes all storage allocated for the mesh
+    ~aiMesh()
+    {
+        delete [] mVertices;
+        delete [] mNormals;
+        delete [] mTangents;
+        delete [] mBitangents;
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++) {
+            delete [] mTextureCoords[a];
+        }
+        for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; a++) {
+            delete [] mColors[a];
+        }
+
+        // DO NOT REMOVE THIS ADDITIONAL CHECK
+        if (mNumBones && mBones)    {
+            for( unsigned int a = 0; a < mNumBones; a++) {
+                delete mBones[a];
+            }
+            delete [] mBones;
+        }
+
+        if (mNumAnimMeshes && mAnimMeshes)  {
+            for( unsigned int a = 0; a < mNumAnimMeshes; a++) {
+                delete mAnimMeshes[a];
+            }
+            delete [] mAnimMeshes;
+        }
+
+        delete [] mFaces;
+    }
+
+    //! Check whether the mesh contains positions. Provided no special
+    //! scene flags are set, this will always be true
+    bool HasPositions() const
+        { return mVertices != NULL && mNumVertices > 0; }
+
+    //! Check whether the mesh contains faces. If no special scene flags
+    //! are set this should always return true
+    bool HasFaces() const
+        { return mFaces != NULL && mNumFaces > 0; }
+
+    //! Check whether the mesh contains normal vectors
+    bool HasNormals() const
+        { return mNormals != NULL && mNumVertices > 0; }
+
+    //! Check whether the mesh contains tangent and bitangent vectors
+    //! It is not possible that it contains tangents and no bitangents
+    //! (or the other way round). The existence of one of them
+    //! implies that the second is there, too.
+    bool HasTangentsAndBitangents() const
+        { return mTangents != NULL && mBitangents != NULL && mNumVertices > 0; }
+
+    //! Check whether the mesh contains a vertex color set
+    //! \param pIndex Index of the vertex color set
+    bool HasVertexColors( unsigned int pIndex) const
+    {
+        if( pIndex >= AI_MAX_NUMBER_OF_COLOR_SETS)
+            return false;
+        else
+            return mColors[pIndex] != NULL && mNumVertices > 0;
+    }
+
+    //! Check whether the mesh contains a texture coordinate set
+    //! \param pIndex Index of the texture coordinates set
+    bool HasTextureCoords( unsigned int pIndex) const
+    {
+        if( pIndex >= AI_MAX_NUMBER_OF_TEXTURECOORDS)
+            return false;
+        else
+            return mTextureCoords[pIndex] != NULL && mNumVertices > 0;
+    }
+
+    //! Get the number of UV channels the mesh contains
+    unsigned int GetNumUVChannels() const
+    {
+        unsigned int n = 0;
+        while (n < AI_MAX_NUMBER_OF_TEXTURECOORDS && mTextureCoords[n])++n;
+        return n;
+    }
+
+    //! Get the number of vertex color channels the mesh contains
+    unsigned int GetNumColorChannels() const
+    {
+        unsigned int n = 0;
+        while (n < AI_MAX_NUMBER_OF_COLOR_SETS && mColors[n])++n;
+        return n;
+    }
+
+    //! Check whether the mesh contains bones
+    inline bool HasBones() const
+        { return mBones != NULL && mNumBones > 0; }
+
+#endif // __cplusplus
+};
+
+
+#ifdef __cplusplus
+}
+#endif //! extern "C"
+#endif // __AI_MESH_H_INC
+

+ 248 - 0
include/assimp/metadata.h

@@ -0,0 +1,248 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file metadata.h
+ *  @brief Defines the data structures for holding node meta information.
+ */
+#ifndef __AI_METADATA_H_INC__
+#define __AI_METADATA_H_INC__
+
+#include <assert.h>
+
+#if defined(_MSC_VER) && (_MSC_VER <= 1500)
+#include "Compiler/pstdint.h"
+#else
+#include <limits.h>
+#include <stdint.h>
+#endif
+
+
+
+// -------------------------------------------------------------------------------
+/**
+  * Enum used to distinguish data types
+  */
+ // -------------------------------------------------------------------------------
+typedef enum aiMetadataType
+{
+    AI_BOOL = 0,
+    AI_INT = 1,
+    AI_UINT64 = 2,
+    AI_FLOAT = 3,
+    AI_AISTRING = 4,
+    AI_AIVECTOR3D = 5,
+
+#ifndef SWIG
+    FORCE_32BIT = INT_MAX
+#endif
+} aiMetadataType;
+
+
+
+// -------------------------------------------------------------------------------
+/**
+  * Metadata entry
+  *
+  * The type field uniquely identifies the underlying type of the data field
+  */
+ // -------------------------------------------------------------------------------
+struct aiMetadataEntry
+{
+    aiMetadataType mType;
+    void* mData;
+};
+
+
+
+#ifdef __cplusplus
+
+#include <string>
+
+
+
+// -------------------------------------------------------------------------------
+/**
+  * Helper functions to get the aiType enum entry for a type
+  */
+ // -------------------------------------------------------------------------------
+inline aiMetadataType GetAiType( bool ) { return AI_BOOL; }
+inline aiMetadataType GetAiType( int ) { return AI_INT; }
+inline aiMetadataType GetAiType( uint64_t ) { return AI_UINT64; }
+inline aiMetadataType GetAiType( float ) { return AI_FLOAT; }
+inline aiMetadataType GetAiType( aiString ) { return AI_AISTRING; }
+inline aiMetadataType GetAiType( aiVector3D ) { return AI_AIVECTOR3D; }
+
+
+
+#endif
+
+
+
+// -------------------------------------------------------------------------------
+/**
+  * Container for holding metadata.
+  *
+  * Metadata is a key-value store using string keys and values.
+  */
+ // -------------------------------------------------------------------------------
+struct aiMetadata
+{
+    /** Length of the mKeys and mValues arrays, respectively */
+    unsigned int mNumProperties;
+
+    /** Arrays of keys, may not be NULL. Entries in this array may not be NULL as well. */
+    C_STRUCT aiString* mKeys;
+
+    /** Arrays of values, may not be NULL. Entries in this array may be NULL if the
+      * corresponding property key has no assigned value. */
+    C_STRUCT aiMetadataEntry* mValues;
+
+#ifdef __cplusplus
+
+    /** Constructor */
+    aiMetadata()
+        // set all members to zero by default
+        : mNumProperties(0)
+        , mKeys(NULL)
+        , mValues(NULL)
+    {}
+
+
+    /** Destructor */
+    ~aiMetadata()
+    {
+        delete[] mKeys;
+        mKeys = NULL;
+        if (mValues)
+        {
+            // Delete each metadata entry
+            for (unsigned i=0; i<mNumProperties; ++i)
+            {
+                void* data = mValues[i].mData;
+                switch (mValues[i].mType)
+                {
+                case AI_BOOL:
+                    delete static_cast<bool*>(data);
+                    break;
+                case AI_INT:
+                    delete static_cast<int*>(data);
+                    break;
+                case AI_UINT64:
+                    delete static_cast<uint64_t*>(data);
+                    break;
+                case AI_FLOAT:
+                    delete static_cast<float*>(data);
+                    break;
+                case AI_AISTRING:
+                    delete static_cast<aiString*>(data);
+                    break;
+                case AI_AIVECTOR3D:
+                    delete static_cast<aiVector3D*>(data);
+                    break;
+                default:
+                    assert(false);
+                    break;
+                }
+            }
+
+            // Delete the metadata array
+            delete [] mValues;
+            mValues = NULL;
+        }
+    }
+
+
+
+    template<typename T>
+    inline void Set( unsigned index, const std::string& key, const T& value )
+    {
+        // In range assertion
+        assert(index < mNumProperties);
+
+        // Set metadata key
+        mKeys[index] = key;
+
+        // Set metadata type
+        mValues[index].mType = GetAiType(value);
+        // Copy the given value to the dynamic storage
+        mValues[index].mData = new T(value);
+    }
+
+    template<typename T>
+    inline bool Get( unsigned index, T& value )
+    {
+        // In range assertion
+        assert(index < mNumProperties);
+
+        // Return false if the output data type does
+        // not match the found value's data type
+        if ( GetAiType( value ) != mValues[ index ].mType ) {
+            return false;
+        }
+
+        // Otherwise, output the found value and
+        // return true
+        value = *static_cast<T*>(mValues[index].mData);
+        return true;
+    }
+
+    template<typename T>
+    inline bool Get( const aiString& key, T& value )
+    {
+        // Search for the given key
+        for (unsigned i=0; i<mNumProperties; ++i)
+            if (mKeys[i]==key)
+                return Get(i, value);
+        return false;
+    }
+
+    template<typename T>
+    inline bool Get( const std::string& key, T& value ) {
+        return Get(aiString(key), value);
+    }
+
+#endif // __cplusplus
+
+};
+
+#endif // __AI_METADATA_H_INC__
+
+

+ 92 - 0
include/assimp/port/AndroidJNI/AndroidJNIIOSystem.h

@@ -0,0 +1,92 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2012, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, 
+with or without modification, are permitted provided that the 
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file Android implementation of IOSystem using the standard C file functions.
+ * Aimed to ease the acces to android assets */
+
+#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
+#ifndef AI_ANDROIDJNIIOSYSTEM_H_INC
+#define AI_ANDROIDJNIIOSYSTEM_H_INC
+
+#include "../code/DefaultIOSystem.h"
+#include <android/asset_manager.h>
+#include <android/asset_manager_jni.h>
+#include <android/native_activity.h>
+
+namespace Assimp	{
+
+// ---------------------------------------------------------------------------
+/** Android extension to DefaultIOSystem using the standard C file functions */
+class AndroidJNIIOSystem : public DefaultIOSystem
+{
+public:
+
+	/** Initialize android activity data */
+	std::string mApkWorkspacePath;
+	AAssetManager* mApkAssetManager;
+
+	/** Constructor. */
+	AndroidJNIIOSystem(ANativeActivity* activity);
+
+	/** Destructor. */
+	~AndroidJNIIOSystem();
+
+	// -------------------------------------------------------------------
+	/** Tests for the existence of a file at the given path. */
+	bool Exists( const char* pFile) const;
+
+	// -------------------------------------------------------------------
+	/** Opens a file at the given path, with given mode */
+	IOStream* Open( const char* strFile, const char* strMode);
+
+	// ------------------------------------------------------------------------------------------------
+	// Inits Android extractor
+	void AndroidActivityInit(ANativeActivity* activity);
+
+	// ------------------------------------------------------------------------------------------------
+	// Extracts android asset
+	bool AndroidExtractAsset(std::string name);
+
+};
+
+} //!ns Assimp
+
+#endif //AI_ANDROIDJNIIOSYSTEM_H_INC
+#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)

+ 633 - 0
include/assimp/postprocess.h

@@ -0,0 +1,633 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file postprocess.h
+ *  @brief Definitions for import post processing steps
+ */
+#ifndef AI_POSTPROCESS_H_INC
+#define AI_POSTPROCESS_H_INC
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// -----------------------------------------------------------------------------------
+/** @enum  aiPostProcessSteps
+ *  @brief Defines the flags for all possible post processing steps.
+ *
+ *  @note Some steps are influenced by properties set on the Assimp::Importer itself
+ *
+ *  @see Assimp::Importer::ReadFile()
+ *  @see Assimp::Importer::SetPropertyInteger()
+ *  @see aiImportFile
+ *  @see aiImportFileEx
+ */
+// -----------------------------------------------------------------------------------
+enum aiPostProcessSteps
+{
+
+    // -------------------------------------------------------------------------
+    /** <hr>Calculates the tangents and bitangents for the imported meshes.
+     *
+     * Does nothing if a mesh does not have normals. You might want this post
+     * processing step to be executed if you plan to use tangent space calculations
+     * such as normal mapping  applied to the meshes. There's an importer property,
+     * <tt>#AI_CONFIG_PP_CT_MAX_SMOOTHING_ANGLE</tt>, which allows you to specify
+     * a maximum smoothing angle for the algorithm. However, usually you'll
+     * want to leave it at the default value.
+     */
+    aiProcess_CalcTangentSpace = 0x1,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Identifies and joins identical vertex data sets within all
+     *  imported meshes.
+     *
+     * After this step is run, each mesh contains unique vertices,
+     * so a vertex may be used by multiple faces. You usually want
+     * to use this post processing step. If your application deals with
+     * indexed geometry, this step is compulsory or you'll just waste rendering
+     * time. <b>If this flag is not specified</b>, no vertices are referenced by
+     * more than one face and <b>no index buffer is required</b> for rendering.
+     */
+    aiProcess_JoinIdenticalVertices = 0x2,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Converts all the imported data to a left-handed coordinate space.
+     *
+     * By default the data is returned in a right-handed coordinate space (which
+     * OpenGL prefers). In this space, +X points to the right,
+     * +Z points towards the viewer, and +Y points upwards. In the DirectX
+     * coordinate space +X points to the right, +Y points upwards, and +Z points
+     * away from the viewer.
+     *
+     * You'll probably want to consider this flag if you use Direct3D for
+     * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this
+     * setting and bundles all conversions typically required for D3D-based
+     * applications.
+     */
+    aiProcess_MakeLeftHanded = 0x4,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Triangulates all faces of all meshes.
+     *
+     * By default the imported mesh data might contain faces with more than 3
+     * indices. For rendering you'll usually want all faces to be triangles.
+     * This post processing step splits up faces with more than 3 indices into
+     * triangles. Line and point primitives are *not* modified! If you want
+     * 'triangles only' with no other kinds of primitives, try the following
+     * solution:
+     * <ul>
+     * <li>Specify both #aiProcess_Triangulate and #aiProcess_SortByPType </li>
+     * <li>Ignore all point and line meshes when you process assimp's output</li>
+     * </ul>
+     */
+    aiProcess_Triangulate = 0x8,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Removes some parts of the data structure (animations, materials,
+     *  light sources, cameras, textures, vertex components).
+     *
+     * The  components to be removed are specified in a separate
+     * importer property, <tt>#AI_CONFIG_PP_RVC_FLAGS</tt>. This is quite useful
+     * if you don't need all parts of the output structure. Vertex colors
+     * are rarely used today for example... Calling this step to remove unneeded
+     * data from the pipeline as early as possible results in increased
+     * performance and a more optimized output data structure.
+     * This step is also useful if you want to force Assimp to recompute
+     * normals or tangents. The corresponding steps don't recompute them if
+     * they're already there (loaded from the source asset). By using this
+     * step you can make sure they are NOT there.
+     *
+     * This flag is a poor one, mainly because its purpose is usually
+     * misunderstood. Consider the following case: a 3D model has been exported
+     * from a CAD app, and it has per-face vertex colors. Vertex positions can't be
+     * shared, thus the #aiProcess_JoinIdenticalVertices step fails to
+     * optimize the data because of these nasty little vertex colors.
+     * Most apps don't even process them, so it's all for nothing. By using
+     * this step, unneeded components are excluded as early as possible
+     * thus opening more room for internal optimizations.
+     */
+    aiProcess_RemoveComponent = 0x10,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Generates normals for all faces of all meshes.
+     *
+     * This is ignored if normals are already there at the time this flag
+     * is evaluated. Model importers try to load them from the source file, so
+     * they're usually already there. Face normals are shared between all points
+     * of a single face, so a single point can have multiple normals, which
+     * forces the library to duplicate vertices in some cases.
+     * #aiProcess_JoinIdenticalVertices is *senseless* then.
+     *
+     * This flag may not be specified together with #aiProcess_GenSmoothNormals.
+     */
+    aiProcess_GenNormals = 0x20,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Generates smooth normals for all vertices in the mesh.
+    *
+    * This is ignored if normals are already there at the time this flag
+    * is evaluated. Model importers try to load them from the source file, so
+    * they're usually already there.
+    *
+    * This flag may not be specified together with
+    * #aiProcess_GenNormals. There's a importer property,
+    * <tt>#AI_CONFIG_PP_GSN_MAX_SMOOTHING_ANGLE</tt> which allows you to specify
+    * an angle maximum for the normal smoothing algorithm. Normals exceeding
+    * this limit are not smoothed, resulting in a 'hard' seam between two faces.
+    * Using a decent angle here (e.g. 80 degrees) results in very good visual
+    * appearance.
+    */
+    aiProcess_GenSmoothNormals = 0x40,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Splits large meshes into smaller sub-meshes.
+    *
+    * This is quite useful for real-time rendering, where the number of triangles
+    * which can be maximally processed in a single draw-call is limited
+    * by the video driver/hardware. The maximum vertex buffer is usually limited
+    * too. Both requirements can be met with this step: you may specify both a
+    * triangle and vertex limit for a single mesh.
+    *
+    * The split limits can (and should!) be set through the
+    * <tt>#AI_CONFIG_PP_SLM_VERTEX_LIMIT</tt> and <tt>#AI_CONFIG_PP_SLM_TRIANGLE_LIMIT</tt>
+    * importer properties. The default values are <tt>#AI_SLM_DEFAULT_MAX_VERTICES</tt> and
+    * <tt>#AI_SLM_DEFAULT_MAX_TRIANGLES</tt>.
+    *
+    * Note that splitting is generally a time-consuming task, but only if there's
+    * something to split. The use of this step is recommended for most users.
+    */
+    aiProcess_SplitLargeMeshes = 0x80,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Removes the node graph and pre-transforms all vertices with
+    * the local transformation matrices of their nodes.
+    *
+    * The output scene still contains nodes, however there is only a
+    * root node with children, each one referencing only one mesh,
+    * and each mesh referencing one material. For rendering, you can
+    * simply render all meshes in order - you don't need to pay
+    * attention to local transformations and the node hierarchy.
+    * Animations are removed during this step.
+    * This step is intended for applications without a scenegraph.
+    * The step CAN cause some problems: if e.g. a mesh of the asset
+    * contains normals and another, using the same material index, does not,
+    * they will be brought together, but the first meshes's part of
+    * the normal list is zeroed. However, these artifacts are rare.
+    * @note The <tt>#AI_CONFIG_PP_PTV_NORMALIZE</tt> configuration property
+    * can be set to normalize the scene's spatial dimension to the -1...1
+    * range.
+    */
+    aiProcess_PreTransformVertices = 0x100,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Limits the number of bones simultaneously affecting a single vertex
+    *  to a maximum value.
+    *
+    * If any vertex is affected by more than the maximum number of bones, the least
+    * important vertex weights are removed and the remaining vertex weights are
+    * renormalized so that the weights still sum up to 1.
+    * The default bone weight limit is 4 (defined as <tt>#AI_LMW_MAX_WEIGHTS</tt> in
+    * config.h), but you can use the <tt>#AI_CONFIG_PP_LBW_MAX_WEIGHTS</tt> importer
+    * property to supply your own limit to the post processing step.
+    *
+    * If you intend to perform the skinning in hardware, this post processing
+    * step might be of interest to you.
+    */
+    aiProcess_LimitBoneWeights = 0x200,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Validates the imported scene data structure.
+     * This makes sure that all indices are valid, all animations and
+     * bones are linked correctly, all material references are correct .. etc.
+     *
+     * It is recommended that you capture Assimp's log output if you use this flag,
+     * so you can easily find out what's wrong if a file fails the
+     * validation. The validator is quite strict and will find *all*
+     * inconsistencies in the data structure... It is recommended that plugin
+     * developers use it to debug their loaders. There are two types of
+     * validation failures:
+     * <ul>
+     * <li>Error: There's something wrong with the imported data. Further
+     *   postprocessing is not possible and the data is not usable at all.
+     *   The import fails. #Importer::GetErrorString() or #aiGetErrorString()
+     *   carry the error message around.</li>
+     * <li>Warning: There are some minor issues (e.g. 1000000 animation
+     *   keyframes with the same time), but further postprocessing and use
+     *   of the data structure is still safe. Warning details are written
+     *   to the log file, <tt>#AI_SCENE_FLAGS_VALIDATION_WARNING</tt> is set
+     *   in #aiScene::mFlags</li>
+     * </ul>
+     *
+     * This post-processing step is not time-consuming. Its use is not
+     * compulsory, but recommended.
+    */
+    aiProcess_ValidateDataStructure = 0x400,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Reorders triangles for better vertex cache locality.
+     *
+     * The step tries to improve the ACMR (average post-transform vertex cache
+     * miss ratio) for all meshes. The implementation runs in O(n) and is
+     * roughly based on the 'tipsify' algorithm (see <a href="
+     * http://www.cs.princeton.edu/gfx/pubs/Sander_2007_%3ETR/tipsy.pdf">this
+     * paper</a>).
+     *
+     * If you intend to render huge models in hardware, this step might
+     * be of interest to you. The <tt>#AI_CONFIG_PP_ICL_PTCACHE_SIZE</tt>
+     * importer property can be used to fine-tune the cache optimization.
+     */
+    aiProcess_ImproveCacheLocality = 0x800,
+
+    // -------------------------------------------------------------------------
+    /** <hr>Searches for redundant/unreferenced materials and removes them.
+     *
+     * This is especially useful in combination with the
+     * #aiProcess_PreTransformVertices and #aiProcess_OptimizeMeshes flags.
+     * Both join small meshes with equal characteristics, but they can't do
+     * their work if two meshes have different materials. Because several
+     * material settings are lost during Assimp's import filters,
+     * (and because many exporters don't check for redundant materials), huge
+     * models often have materials which are are defined several times with
+     * exactly the same settings.
+     *
+     * Several material settings not contributing to the final appearance of
+     * a surface are ignored in all comparisons (e.g. the material name).
+     * So, if you're passing additional information through the
+     * content pipeline (probably using *magic* material names), don't
+     * specify this flag. Alternatively take a look at the
+     * <tt>#AI_CONFIG_PP_RRM_EXCLUDE_LIST</tt> importer property.
+     */
+    aiProcess_RemoveRedundantMaterials = 0x1000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step tries to determine which meshes have normal vectors
+     * that are facing inwards and inverts them.
+     *
+     * The algorithm is simple but effective:
+     * the bounding box of all vertices + their normals is compared against
+     * the volume of the bounding box of all vertices without their normals.
+     * This works well for most objects, problems might occur with planar
+     * surfaces. However, the step tries to filter such cases.
+     * The step inverts all in-facing normals. Generally it is recommended
+     * to enable this step, although the result is not always correct.
+    */
+    aiProcess_FixInfacingNormals = 0x2000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step splits meshes with more than one primitive type in
+     *  homogeneous sub-meshes.
+     *
+     *  The step is executed after the triangulation step. After the step
+     *  returns, just one bit is set in aiMesh::mPrimitiveTypes. This is
+     *  especially useful for real-time rendering where point and line
+     *  primitives are often ignored or rendered separately.
+     *  You can use the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to
+     *  specify which primitive types you need. This can be used to easily
+     *  exclude lines and points, which are rarely used, from the import.
+    */
+    aiProcess_SortByPType = 0x8000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step searches all meshes for degenerate primitives and
+     *  converts them to proper lines or points.
+     *
+     * A face is 'degenerate' if one or more of its points are identical.
+     * To have the degenerate stuff not only detected and collapsed but
+     * removed, try one of the following procedures:
+     * <br><b>1.</b> (if you support lines and points for rendering but don't
+     *    want the degenerates)<br>
+     * <ul>
+     *   <li>Specify the #aiProcess_FindDegenerates flag.
+     *   </li>
+     *   <li>Set the <tt>#AI_CONFIG_PP_FD_REMOVE</tt> importer property to
+     *       1. This will cause the step to remove degenerate triangles from the
+     *       import as soon as they're detected. They won't pass any further
+     *       pipeline steps.
+     *   </li>
+     * </ul>
+     * <br><b>2.</b>(if you don't support lines and points at all)<br>
+     * <ul>
+     *   <li>Specify the #aiProcess_FindDegenerates flag.
+     *   </li>
+     *   <li>Specify the #aiProcess_SortByPType flag. This moves line and
+     *     point primitives to separate meshes.
+     *   </li>
+     *   <li>Set the <tt>#AI_CONFIG_PP_SBP_REMOVE</tt> importer property to
+     *       @code aiPrimitiveType_POINTS | aiPrimitiveType_LINES
+     *       @endcode to cause SortByPType to reject point
+     *       and line meshes from the scene.
+     *   </li>
+     * </ul>
+     * @note Degenerate polygons are not necessarily evil and that's why
+     * they're not removed by default. There are several file formats which
+     * don't support lines or points, and some exporters bypass the
+     * format specification and write them as degenerate triangles instead.
+    */
+    aiProcess_FindDegenerates = 0x10000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step searches all meshes for invalid data, such as zeroed
+     *  normal vectors or invalid UV coords and removes/fixes them. This is
+     *  intended to get rid of some common exporter errors.
+     *
+     * This is especially useful for normals. If they are invalid, and
+     * the step recognizes this, they will be removed and can later
+     * be recomputed, i.e. by the #aiProcess_GenSmoothNormals flag.<br>
+     * The step will also remove meshes that are infinitely small and reduce
+     * animation tracks consisting of hundreds if redundant keys to a single
+     * key. The <tt>AI_CONFIG_PP_FID_ANIM_ACCURACY</tt> config property decides
+     * the accuracy of the check for duplicate animation tracks.
+    */
+    aiProcess_FindInvalidData = 0x20000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step converts non-UV mappings (such as spherical or
+     *  cylindrical mapping) to proper texture coordinate channels.
+     *
+     * Most applications will support UV mapping only, so you will
+     * probably want to specify this step in every case. Note that Assimp is not
+     * always able to match the original mapping implementation of the
+     * 3D app which produced a model perfectly. It's always better to let the
+     * modelling app compute the UV channels - 3ds max, Maya, Blender,
+     * LightWave, and Modo do this for example.
+     *
+     * @note If this step is not requested, you'll need to process the
+     * <tt>#AI_MATKEY_MAPPING</tt> material property in order to display all assets
+     * properly.
+     */
+    aiProcess_GenUVCoords = 0x40000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step applies per-texture UV transformations and bakes
+     *  them into stand-alone vtexture coordinate channels.
+     *
+     * UV transformations are specified per-texture - see the
+     * <tt>#AI_MATKEY_UVTRANSFORM</tt> material key for more information.
+     * This step processes all textures with
+     * transformed input UV coordinates and generates a new (pre-transformed) UV channel
+     * which replaces the old channel. Most applications won't support UV
+     * transformations, so you will probably want to specify this step.
+     *
+     * @note UV transformations are usually implemented in real-time apps by
+     * transforming texture coordinates at vertex shader stage with a 3x3
+     * (homogenous) transformation matrix.
+    */
+    aiProcess_TransformUVCoords = 0x80000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step searches for duplicate meshes and replaces them
+     *  with references to the first mesh.
+     *
+     *  This step takes a while, so don't use it if speed is a concern.
+     *  Its main purpose is to workaround the fact that many export
+     *  file formats don't support instanced meshes, so exporters need to
+     *  duplicate meshes. This step removes the duplicates again. Please
+     *  note that Assimp does not currently support per-node material
+     *  assignment to meshes, which means that identical meshes with
+     *  different materials are currently *not* joined, although this is
+     *  planned for future versions.
+     */
+    aiProcess_FindInstances = 0x100000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>A postprocessing step to reduce the number of meshes.
+     *
+     *  This will, in fact, reduce the number of draw calls.
+     *
+     *  This is a very effective optimization and is recommended to be used
+     *  together with #aiProcess_OptimizeGraph, if possible. The flag is fully
+     *  compatible with both #aiProcess_SplitLargeMeshes and #aiProcess_SortByPType.
+    */
+    aiProcess_OptimizeMeshes  = 0x200000,
+
+
+    // -------------------------------------------------------------------------
+    /** <hr>A postprocessing step to optimize the scene hierarchy.
+     *
+     *  Nodes without animations, bones, lights or cameras assigned are
+     *  collapsed and joined.
+     *
+     *  Node names can be lost during this step. If you use special 'tag nodes'
+     *  to pass additional information through your content pipeline, use the
+     *  <tt>#AI_CONFIG_PP_OG_EXCLUDE_LIST</tt> importer property to specify a
+     *  list of node names you want to be kept. Nodes matching one of the names
+     *  in this list won't be touched or modified.
+     *
+     *  Use this flag with caution. Most simple files will be collapsed to a
+     *  single node, so complex hierarchies are usually completely lost. This is not
+     *  useful for editor environments, but probably a very effective
+     *  optimization if you just want to get the model data, convert it to your
+     *  own format, and render it as fast as possible.
+     *
+     *  This flag is designed to be used with #aiProcess_OptimizeMeshes for best
+     *  results.
+     *
+     *  @note 'Crappy' scenes with thousands of extremely small meshes packed
+     *  in deeply nested nodes exist for almost all file formats.
+     *  #aiProcess_OptimizeMeshes in combination with #aiProcess_OptimizeGraph
+     *  usually fixes them all and makes them renderable.
+    */
+    aiProcess_OptimizeGraph  = 0x400000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step flips all UV coordinates along the y-axis and adjusts
+     * material settings and bitangents accordingly.
+     *
+     * <b>Output UV coordinate system:</b>
+     * @code
+     * 0y|0y ---------- 1x|0y
+     * |                 |
+     * |                 |
+     * |                 |
+     * 0x|1y ---------- 1x|1y
+     * @endcode
+     *
+     * You'll probably want to consider this flag if you use Direct3D for
+     * rendering. The #aiProcess_ConvertToLeftHanded flag supersedes this
+     * setting and bundles all conversions typically required for D3D-based
+     * applications.
+    */
+    aiProcess_FlipUVs = 0x800000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step adjusts the output face winding order to be CW.
+     *
+     * The default face winding order is counter clockwise (CCW).
+     *
+     * <b>Output face order:</b>
+     * @code
+     *       x2
+     *
+     *                         x0
+     *  x1
+     * @endcode
+    */
+    aiProcess_FlipWindingOrder  = 0x1000000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step splits meshes with many bones into sub-meshes so that each
+     * su-bmesh has fewer or as many bones as a given limit.
+    */
+    aiProcess_SplitByBoneCount  = 0x2000000,
+
+    // -------------------------------------------------------------------------
+    /** <hr>This step removes bones losslessly or according to some threshold.
+     *
+     *  In some cases (i.e. formats that require it) exporters are forced to
+     *  assign dummy bone weights to otherwise static meshes assigned to
+     *  animated meshes. Full, weight-based skinning is expensive while
+     *  animating nodes is extremely cheap, so this step is offered to clean up
+     *  the data in that regard.
+     *
+     *  Use <tt>#AI_CONFIG_PP_DB_THRESHOLD</tt> to control this.
+     *  Use <tt>#AI_CONFIG_PP_DB_ALL_OR_NONE</tt> if you want bones removed if and
+     *  only if all bones within the scene qualify for removal.
+    */
+    aiProcess_Debone  = 0x4000000
+
+    // aiProcess_GenEntityMeshes = 0x100000,
+    // aiProcess_OptimizeAnimations = 0x200000
+    // aiProcess_FixTexturePaths = 0x200000
+};
+
+
+// ---------------------------------------------------------------------------------------
+/** @def aiProcess_ConvertToLeftHanded
+ *  @brief Shortcut flag for Direct3D-based applications.
+ *
+ *  Supersedes the #aiProcess_MakeLeftHanded and #aiProcess_FlipUVs and
+ *  #aiProcess_FlipWindingOrder flags.
+ *  The output data matches Direct3D's conventions: left-handed geometry, upper-left
+ *  origin for UV coordinates and finally clockwise face order, suitable for CCW culling.
+ *
+ *  @deprecated
+ */
+#define aiProcess_ConvertToLeftHanded ( \
+    aiProcess_MakeLeftHanded     | \
+    aiProcess_FlipUVs            | \
+    aiProcess_FlipWindingOrder   | \
+    0 )
+
+
+// ---------------------------------------------------------------------------------------
+/** @def aiProcessPreset_TargetRealtime_Fast
+ *  @brief Default postprocess configuration optimizing the data for real-time rendering.
+ *
+ *  Applications would want to use this preset to load models on end-user PCs,
+ *  maybe for direct use in game.
+ *
+ * If you're using DirectX, don't forget to combine this value with
+ * the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
+ * in your application apply the #aiProcess_TransformUVCoords step, too.
+ *  @note Please take the time to read the docs for the steps enabled by this preset.
+ *  Some of them offer further configurable properties, while some of them might not be of
+ *  use for you so it might be better to not specify them.
+ */
+#define aiProcessPreset_TargetRealtime_Fast ( \
+    aiProcess_CalcTangentSpace      |  \
+    aiProcess_GenNormals            |  \
+    aiProcess_JoinIdenticalVertices |  \
+    aiProcess_Triangulate           |  \
+    aiProcess_GenUVCoords           |  \
+    aiProcess_SortByPType           |  \
+    0 )
+
+ // ---------------------------------------------------------------------------------------
+ /** @def aiProcessPreset_TargetRealtime_Quality
+  *  @brief Default postprocess configuration optimizing the data for real-time rendering.
+  *
+  *  Unlike #aiProcessPreset_TargetRealtime_Fast, this configuration
+  *  performs some extra optimizations to improve rendering speed and
+  *  to minimize memory usage. It could be a good choice for a level editor
+  *  environment where import speed is not so important.
+  *
+  *  If you're using DirectX, don't forget to combine this value with
+  *  the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
+  *  in your application apply the #aiProcess_TransformUVCoords step, too.
+  *  @note Please take the time to read the docs for the steps enabled by this preset.
+  *  Some of them offer further configurable properties, while some of them might not be
+  *  of use for you so it might be better to not specify them.
+  */
+#define aiProcessPreset_TargetRealtime_Quality ( \
+    aiProcess_CalcTangentSpace              |  \
+    aiProcess_GenSmoothNormals              |  \
+    aiProcess_JoinIdenticalVertices         |  \
+    aiProcess_ImproveCacheLocality          |  \
+    aiProcess_LimitBoneWeights              |  \
+    aiProcess_RemoveRedundantMaterials      |  \
+    aiProcess_SplitLargeMeshes              |  \
+    aiProcess_Triangulate                   |  \
+    aiProcess_GenUVCoords                   |  \
+    aiProcess_SortByPType                   |  \
+    aiProcess_FindDegenerates               |  \
+    aiProcess_FindInvalidData               |  \
+    0 )
+
+ // ---------------------------------------------------------------------------------------
+ /** @def aiProcessPreset_TargetRealtime_MaxQuality
+  *  @brief Default postprocess configuration optimizing the data for real-time rendering.
+  *
+  *  This preset enables almost every optimization step to achieve perfectly
+  *  optimized data. It's your choice for level editor environments where import speed
+  *  is not important.
+  *
+  *  If you're using DirectX, don't forget to combine this value with
+  *  the #aiProcess_ConvertToLeftHanded step. If you don't support UV transformations
+  *  in your application, apply the #aiProcess_TransformUVCoords step, too.
+  *  @note Please take the time to read the docs for the steps enabled by this preset.
+  *  Some of them offer further configurable properties, while some of them might not be
+  *  of use for you so it might be better to not specify them.
+  */
+#define aiProcessPreset_TargetRealtime_MaxQuality ( \
+    aiProcessPreset_TargetRealtime_Quality   |  \
+    aiProcess_FindInstances                  |  \
+    aiProcess_ValidateDataStructure          |  \
+    aiProcess_OptimizeMeshes                 |  \
+    0 )
+
+
+#ifdef __cplusplus
+} // end of extern "C"
+#endif
+
+#endif // AI_POSTPROCESS_H_INC

+ 126 - 0
include/assimp/quaternion.h

@@ -0,0 +1,126 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+
+/** @file quaternion.h
+ *  @brief Quaternion structure, including operators when compiling in C++
+ */
+#ifndef AI_QUATERNION_H_INC
+#define AI_QUATERNION_H_INC
+
+#ifdef __cplusplus
+
+template <typename TReal> class aiVector3t;
+template <typename TReal> class aiMatrix3x3t;
+
+// ---------------------------------------------------------------------------
+/** Represents a quaternion in a 4D vector. */
+template <typename TReal>
+class aiQuaterniont
+{
+public:
+    aiQuaterniont() : w(1.0), x(), y(), z() {}
+    aiQuaterniont(TReal pw, TReal px, TReal py, TReal pz)
+        : w(pw), x(px), y(py), z(pz) {}
+
+    /** Construct from rotation matrix. Result is undefined if the matrix is not orthonormal. */
+    explicit aiQuaterniont( const aiMatrix3x3t<TReal>& pRotMatrix);
+
+    /** Construct from euler angles */
+    aiQuaterniont( TReal rotx, TReal roty, TReal rotz);
+
+    /** Construct from an axis-angle pair */
+    aiQuaterniont( aiVector3t<TReal> axis, TReal angle);
+
+    /** Construct from a normalized quaternion stored in a vec3 */
+    explicit aiQuaterniont( aiVector3t<TReal> normalized);
+
+    /** Returns a matrix representation of the quaternion */
+    aiMatrix3x3t<TReal> GetMatrix() const;
+
+public:
+
+    bool operator== (const aiQuaterniont& o) const;
+    bool operator!= (const aiQuaterniont& o) const;
+
+    bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const;
+
+public:
+
+    /** Normalize the quaternion */
+    aiQuaterniont& Normalize();
+
+    /** Compute quaternion conjugate */
+    aiQuaterniont& Conjugate ();
+
+    /** Rotate a point by this quaternion */
+    aiVector3t<TReal> Rotate (const aiVector3t<TReal>& in);
+
+    /** Multiply two quaternions */
+    aiQuaterniont operator* (const aiQuaterniont& two) const;
+
+public:
+
+    /** Performs a spherical interpolation between two quaternions and writes the result into the third.
+     * @param pOut Target object to received the interpolated rotation.
+     * @param pStart Start rotation of the interpolation at factor == 0.
+     * @param pEnd End rotation, factor == 1.
+     * @param pFactor Interpolation factor between 0 and 1. Values outside of this range yield undefined results.
+     */
+    static void Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart,
+        const aiQuaterniont& pEnd, TReal pFactor);
+
+public:
+
+    //! w,x,y,z components of the quaternion
+    TReal w, x, y, z;
+} ;
+
+typedef aiQuaterniont<float> aiQuaternion;
+
+#else
+
+struct aiQuaternion {
+    float w, x, y, z;
+};
+
+#endif
+
+
+#endif // AI_QUATERNION_H_INC

+ 283 - 0
include/assimp/quaternion.inl

@@ -0,0 +1,283 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  quaternion.inl
+ *  @brief Inline implementation of aiQuaterniont<TReal> operators
+ */
+#ifndef AI_QUATERNION_INL_INC
+#define AI_QUATERNION_INL_INC
+
+#ifdef __cplusplus
+#include "quaternion.h"
+
+#include <cmath>
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+bool aiQuaterniont<TReal>::operator== (const aiQuaterniont& o) const
+{
+    return x == o.x && y == o.y && z == o.z && w == o.w;
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+bool aiQuaterniont<TReal>::operator!= (const aiQuaterniont& o) const
+{
+    return !(*this == o);
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline bool aiQuaterniont<TReal>::Equal(const aiQuaterniont& o, TReal epsilon) const {
+    return
+        std::abs(x - o.x) <= epsilon &&
+        std::abs(y - o.y) <= epsilon &&
+        std::abs(z - o.z) <= epsilon &&
+        std::abs(w - o.w) <= epsilon;
+}
+
+// ---------------------------------------------------------------------------
+// Constructs a quaternion from a rotation matrix
+template<typename TReal>
+inline aiQuaterniont<TReal>::aiQuaterniont( const aiMatrix3x3t<TReal> &pRotMatrix)
+{
+    TReal t = pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3;
+
+    // large enough
+    if( t > static_cast<TReal>(0))
+    {
+        TReal s = std::sqrt(1 + t) * static_cast<TReal>(2.0);
+        x = (pRotMatrix.c2 - pRotMatrix.b3) / s;
+        y = (pRotMatrix.a3 - pRotMatrix.c1) / s;
+        z = (pRotMatrix.b1 - pRotMatrix.a2) / s;
+        w = static_cast<TReal>(0.25) * s;
+    } // else we have to check several cases
+    else if( pRotMatrix.a1 > pRotMatrix.b2 && pRotMatrix.a1 > pRotMatrix.c3 )
+    {
+        // Column 0:
+        TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.a1 - pRotMatrix.b2 - pRotMatrix.c3) * static_cast<TReal>(2.0);
+        x = static_cast<TReal>(0.25) * s;
+        y = (pRotMatrix.b1 + pRotMatrix.a2) / s;
+        z = (pRotMatrix.a3 + pRotMatrix.c1) / s;
+        w = (pRotMatrix.c2 - pRotMatrix.b3) / s;
+    }
+    else if( pRotMatrix.b2 > pRotMatrix.c3)
+    {
+        // Column 1:
+        TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.b2 - pRotMatrix.a1 - pRotMatrix.c3) * static_cast<TReal>(2.0);
+        x = (pRotMatrix.b1 + pRotMatrix.a2) / s;
+        y = static_cast<TReal>(0.25) * s;
+        z = (pRotMatrix.c2 + pRotMatrix.b3) / s;
+        w = (pRotMatrix.a3 - pRotMatrix.c1) / s;
+    } else
+    {
+        // Column 2:
+        TReal s = std::sqrt( static_cast<TReal>(1.0) + pRotMatrix.c3 - pRotMatrix.a1 - pRotMatrix.b2) * static_cast<TReal>(2.0);
+        x = (pRotMatrix.a3 + pRotMatrix.c1) / s;
+        y = (pRotMatrix.c2 + pRotMatrix.b3) / s;
+        z = static_cast<TReal>(0.25) * s;
+        w = (pRotMatrix.b1 - pRotMatrix.a2) / s;
+    }
+}
+
+// ---------------------------------------------------------------------------
+// Construction from euler angles
+template<typename TReal>
+inline aiQuaterniont<TReal>::aiQuaterniont( TReal fPitch, TReal fYaw, TReal fRoll )
+{
+    const TReal fSinPitch(std::sin(fPitch*static_cast<TReal>(0.5)));
+    const TReal fCosPitch(std::cos(fPitch*static_cast<TReal>(0.5)));
+    const TReal fSinYaw(std::sin(fYaw*static_cast<TReal>(0.5)));
+    const TReal fCosYaw(std::cos(fYaw*static_cast<TReal>(0.5)));
+    const TReal fSinRoll(std::sin(fRoll*static_cast<TReal>(0.5)));
+    const TReal fCosRoll(std::cos(fRoll*static_cast<TReal>(0.5)));
+    const TReal fCosPitchCosYaw(fCosPitch*fCosYaw);
+    const TReal fSinPitchSinYaw(fSinPitch*fSinYaw);
+    x = fSinRoll * fCosPitchCosYaw     - fCosRoll * fSinPitchSinYaw;
+    y = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw;
+    z = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw;
+    w = fCosRoll * fCosPitchCosYaw     + fSinRoll * fSinPitchSinYaw;
+}
+
+// ---------------------------------------------------------------------------
+// Returns a matrix representation of the quaternion
+template<typename TReal>
+inline aiMatrix3x3t<TReal> aiQuaterniont<TReal>::GetMatrix() const
+{
+    aiMatrix3x3t<TReal> resMatrix;
+    resMatrix.a1 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (y * y + z * z);
+    resMatrix.a2 = static_cast<TReal>(2.0) * (x * y - z * w);
+    resMatrix.a3 = static_cast<TReal>(2.0) * (x * z + y * w);
+    resMatrix.b1 = static_cast<TReal>(2.0) * (x * y + z * w);
+    resMatrix.b2 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + z * z);
+    resMatrix.b3 = static_cast<TReal>(2.0) * (y * z - x * w);
+    resMatrix.c1 = static_cast<TReal>(2.0) * (x * z - y * w);
+    resMatrix.c2 = static_cast<TReal>(2.0) * (y * z + x * w);
+    resMatrix.c3 = static_cast<TReal>(1.0) - static_cast<TReal>(2.0) * (x * x + y * y);
+
+    return resMatrix;
+}
+
+// ---------------------------------------------------------------------------
+// Construction from an axis-angle pair
+template<typename TReal>
+inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> axis, TReal angle)
+{
+    axis.Normalize();
+
+    const TReal sin_a = std::sin( angle / 2 );
+    const TReal cos_a = std::cos( angle / 2 );
+    x    = axis.x * sin_a;
+    y    = axis.y * sin_a;
+    z    = axis.z * sin_a;
+    w    = cos_a;
+}
+// ---------------------------------------------------------------------------
+// Construction from am existing, normalized quaternion
+template<typename TReal>
+inline aiQuaterniont<TReal>::aiQuaterniont( aiVector3t<TReal> normalized)
+{
+    x = normalized.x;
+    y = normalized.y;
+    z = normalized.z;
+
+    const TReal t = static_cast<TReal>(1.0) - (x*x) - (y*y) - (z*z);
+
+    if (t < static_cast<TReal>(0.0)) {
+        w = static_cast<TReal>(0.0);
+    }
+    else w = std::sqrt (t);
+}
+
+// ---------------------------------------------------------------------------
+// Performs a spherical interpolation between two quaternions
+// Implementation adopted from the gmtl project. All others I found on the net fail in some cases.
+// Congrats, gmtl!
+template<typename TReal>
+inline void aiQuaterniont<TReal>::Interpolate( aiQuaterniont& pOut, const aiQuaterniont& pStart, const aiQuaterniont& pEnd, TReal pFactor)
+{
+    // calc cosine theta
+    TReal cosom = pStart.x * pEnd.x + pStart.y * pEnd.y + pStart.z * pEnd.z + pStart.w * pEnd.w;
+
+    // adjust signs (if necessary)
+    aiQuaterniont end = pEnd;
+    if( cosom < static_cast<TReal>(0.0))
+    {
+        cosom = -cosom;
+        end.x = -end.x;   // Reverse all signs
+        end.y = -end.y;
+        end.z = -end.z;
+        end.w = -end.w;
+    }
+
+    // Calculate coefficients
+    TReal sclp, sclq;
+    if( (static_cast<TReal>(1.0) - cosom) > static_cast<TReal>(0.0001)) // 0.0001 -> some epsillon
+    {
+        // Standard case (slerp)
+        TReal omega, sinom;
+        omega = std::acos( cosom); // extract theta from dot product's cos theta
+        sinom = std::sin( omega);
+        sclp  = std::sin( (static_cast<TReal>(1.0) - pFactor) * omega) / sinom;
+        sclq  = std::sin( pFactor * omega) / sinom;
+    } else
+    {
+        // Very close, do linear interp (because it's faster)
+        sclp = static_cast<TReal>(1.0) - pFactor;
+        sclq = pFactor;
+    }
+
+    pOut.x = sclp * pStart.x + sclq * end.x;
+    pOut.y = sclp * pStart.y + sclq * end.y;
+    pOut.z = sclp * pStart.z + sclq * end.z;
+    pOut.w = sclp * pStart.w + sclq * end.w;
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Normalize()
+{
+    // compute the magnitude and divide through it
+    const TReal mag = std::sqrt(x*x + y*y + z*z + w*w);
+    if (mag)
+    {
+        const TReal invMag = static_cast<TReal>(1.0)/mag;
+        x *= invMag;
+        y *= invMag;
+        z *= invMag;
+        w *= invMag;
+    }
+    return *this;
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline aiQuaterniont<TReal> aiQuaterniont<TReal>::operator* (const aiQuaterniont& t) const
+{
+    return aiQuaterniont(w*t.w - x*t.x - y*t.y - z*t.z,
+        w*t.x + x*t.w + y*t.z - z*t.y,
+        w*t.y + y*t.w + z*t.x - x*t.z,
+        w*t.z + z*t.w + x*t.y - y*t.x);
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline aiQuaterniont<TReal>& aiQuaterniont<TReal>::Conjugate ()
+{
+    x = -x;
+    y = -y;
+    z = -z;
+    return *this;
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+inline aiVector3t<TReal> aiQuaterniont<TReal>::Rotate (const aiVector3t<TReal>& v)
+{
+    aiQuaterniont q2(0.f,v.x,v.y,v.z), q = *this, qinv = q;
+    qinv.Conjugate();
+
+    q = q*q2*qinv;
+    return aiVector3t<TReal>(q.x,q.y,q.z);
+}
+
+#endif
+#endif

+ 426 - 0
include/assimp/scene.h

@@ -0,0 +1,426 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file scene.h
+ *  @brief Defines the data structures in which the imported scene is returned.
+ */
+#ifndef __AI_SCENE_H_INC__
+#define __AI_SCENE_H_INC__
+
+#include "types.h"
+#include "texture.h"
+#include "mesh.h"
+#include "light.h"
+#include "camera.h"
+#include "material.h"
+#include "anim.h"
+#include "metadata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// -------------------------------------------------------------------------------
+/** A node in the imported hierarchy.
+ *
+ * Each node has name, a parent node (except for the root node),
+ * a transformation relative to its parent and possibly several child nodes.
+ * Simple file formats don't support hierarchical structures - for these formats
+ * the imported scene does consist of only a single root node without children.
+ */
+// -------------------------------------------------------------------------------
+struct aiNode
+{
+    /** The name of the node.
+     *
+     * The name might be empty (length of zero) but all nodes which
+     * need to be referenced by either bones or animations are named.
+     * Multiple nodes may have the same name, except for nodes which are referenced
+     * by bones (see #aiBone and #aiMesh::mBones). Their names *must* be unique.
+     *
+     * Cameras and lights reference a specific node by name - if there
+     * are multiple nodes with this name, they are assigned to each of them.
+     * <br>
+     * There are no limitations with regard to the characters contained in
+     * the name string as it is usually taken directly from the source file.
+     *
+     * Implementations should be able to handle tokens such as whitespace, tabs,
+     * line feeds, quotation marks, ampersands etc.
+     *
+     * Sometimes assimp introduces new nodes not present in the source file
+     * into the hierarchy (usually out of necessity because sometimes the
+     * source hierarchy format is simply not compatible). Their names are
+     * surrounded by @verbatim <> @endverbatim e.g.
+     *  @verbatim<DummyRootNode> @endverbatim.
+     */
+    C_STRUCT aiString mName;
+
+    /** The transformation relative to the node's parent. */
+    C_STRUCT aiMatrix4x4 mTransformation;
+
+    /** Parent node. NULL if this node is the root node. */
+    C_STRUCT aiNode* mParent;
+
+    /** The number of child nodes of this node. */
+    unsigned int mNumChildren;
+
+    /** The child nodes of this node. NULL if mNumChildren is 0. */
+    C_STRUCT aiNode** mChildren;
+
+    /** The number of meshes of this node. */
+    unsigned int mNumMeshes;
+
+    /** The meshes of this node. Each entry is an index into the mesh */
+    unsigned int* mMeshes;
+
+    /** Metadata associated with this node or NULL if there is no metadata.
+      *  Whether any metadata is generated depends on the source file format. See the
+      * @link importer_notes @endlink page for more information on every source file
+      * format. Importers that don't document any metadata don't write any.
+      */
+    C_STRUCT aiMetadata* mMetaData;
+
+#ifdef __cplusplus
+    /** Constructor */
+    aiNode()
+        // set all members to zero by default
+        : mName("")
+        , mParent(NULL)
+        , mNumChildren(0)
+        , mChildren(NULL)
+        , mNumMeshes(0)
+        , mMeshes(NULL)
+        , mMetaData(NULL)
+    {
+    }
+
+
+    /** Construction from a specific name */
+    explicit aiNode(const std::string& name)
+        // set all members to zero by default
+        : mName(name)
+        , mParent(NULL)
+        , mNumChildren(0)
+        , mChildren(NULL)
+        , mNumMeshes(0)
+        , mMeshes(NULL)
+        , mMetaData(NULL)
+    {
+    }
+
+    /** Destructor */
+    ~aiNode()
+    {
+        // delete all children recursively
+        // to make sure we won't crash if the data is invalid ...
+        if (mChildren && mNumChildren)
+        {
+            for( unsigned int a = 0; a < mNumChildren; a++)
+                delete mChildren[a];
+        }
+        delete [] mChildren;
+        delete [] mMeshes;
+        delete mMetaData;
+    }
+
+
+    /** Searches for a node with a specific name, beginning at this
+     *  nodes. Normally you will call this method on the root node
+     *  of the scene.
+     *
+     *  @param name Name to search for
+     *  @return NULL or a valid Node if the search was successful.
+     */
+    inline const aiNode* FindNode(const aiString& name) const
+    {
+        return FindNode(name.data);
+    }
+
+
+    inline aiNode* FindNode(const aiString& name)
+    {
+        return FindNode(name.data);
+    }
+
+
+    inline const aiNode* FindNode(const char* name) const
+    {
+        if (!::strcmp( mName.data,name))return this;
+        for (unsigned int i = 0; i < mNumChildren;++i)
+        {
+            const aiNode* const p = mChildren[i]->FindNode(name);
+            if (p) {
+                return p;
+            }
+        }
+        // there is definitely no sub-node with this name
+        return NULL;
+    }
+
+    inline aiNode* FindNode(const char* name)
+    {
+        if (!::strcmp( mName.data,name))return this;
+        for (unsigned int i = 0; i < mNumChildren;++i)
+        {
+            aiNode* const p = mChildren[i]->FindNode(name);
+            if (p) {
+                return p;
+            }
+        }
+        // there is definitely no sub-node with this name
+        return NULL;
+    }
+
+#endif // __cplusplus
+};
+
+
+// -------------------------------------------------------------------------------
+/**
+ * Specifies that the scene data structure that was imported is not complete.
+ * This flag bypasses some internal validations and allows the import
+ * of animation skeletons, material libraries or camera animation paths
+ * using Assimp. Most applications won't support such data.
+ */
+#define AI_SCENE_FLAGS_INCOMPLETE   0x1
+
+/**
+ * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
+ * if the validation is successful. In a validated scene you can be sure that
+ * any cross references in the data structure (e.g. vertex indices) are valid.
+ */
+#define AI_SCENE_FLAGS_VALIDATED    0x2
+
+/**
+ * This flag is set by the validation postprocess-step (aiPostProcess_ValidateDS)
+ * if the validation is successful but some issues have been found.
+ * This can for example mean that a texture that does not exist is referenced
+ * by a material or that the bone weights for a vertex don't sum to 1.0 ... .
+ * In most cases you should still be able to use the import. This flag could
+ * be useful for applications which don't capture Assimp's log output.
+ */
+#define AI_SCENE_FLAGS_VALIDATION_WARNING   0x4
+
+/**
+ * This flag is currently only set by the aiProcess_JoinIdenticalVertices step.
+ * It indicates that the vertices of the output meshes aren't in the internal
+ * verbose format anymore. In the verbose format all vertices are unique,
+ * no vertex is ever referenced by more than one face.
+ */
+#define AI_SCENE_FLAGS_NON_VERBOSE_FORMAT   0x8
+
+ /**
+ * Denotes pure height-map terrain data. Pure terrains usually consist of quads,
+ * sometimes triangles, in a regular grid. The x,y coordinates of all vertex
+ * positions refer to the x,y coordinates on the terrain height map, the z-axis
+ * stores the elevation at a specific point.
+ *
+ * TER (Terragen) and HMP (3D Game Studio) are height map formats.
+ * @note Assimp is probably not the best choice for loading *huge* terrains -
+ * fully triangulated data takes extremely much free store and should be avoided
+ * as long as possible (typically you'll do the triangulation when you actually
+ * need to render it).
+ */
+#define AI_SCENE_FLAGS_TERRAIN 0x10
+
+
+// -------------------------------------------------------------------------------
+/** The root structure of the imported data.
+ *
+ *  Everything that was imported from the given file can be accessed from here.
+ *  Objects of this class are generally maintained and owned by Assimp, not
+ *  by the caller. You shouldn't want to instance it, nor should you ever try to
+ *  delete a given scene on your own.
+ */
+// -------------------------------------------------------------------------------
+struct aiScene
+{
+
+    /** Any combination of the AI_SCENE_FLAGS_XXX flags. By default
+    * this value is 0, no flags are set. Most applications will
+    * want to reject all scenes with the AI_SCENE_FLAGS_INCOMPLETE
+    * bit set.
+    */
+    unsigned int mFlags;
+
+
+    /** The root node of the hierarchy.
+    *
+    * There will always be at least the root node if the import
+    * was successful (and no special flags have been set).
+    * Presence of further nodes depends on the format and content
+    * of the imported file.
+    */
+    C_STRUCT aiNode* mRootNode;
+
+
+
+    /** The number of meshes in the scene. */
+    unsigned int mNumMeshes;
+
+    /** The array of meshes.
+    *
+    * Use the indices given in the aiNode structure to access
+    * this array. The array is mNumMeshes in size. If the
+    * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always
+    * be at least ONE material.
+    */
+    C_STRUCT aiMesh** mMeshes;
+
+
+
+    /** The number of materials in the scene. */
+    unsigned int mNumMaterials;
+
+    /** The array of materials.
+    *
+    * Use the index given in each aiMesh structure to access this
+    * array. The array is mNumMaterials in size. If the
+    * AI_SCENE_FLAGS_INCOMPLETE flag is not set there will always
+    * be at least ONE material.
+    */
+    C_STRUCT aiMaterial** mMaterials;
+
+
+
+    /** The number of animations in the scene. */
+    unsigned int mNumAnimations;
+
+    /** The array of animations.
+    *
+    * All animations imported from the given file are listed here.
+    * The array is mNumAnimations in size.
+    */
+    C_STRUCT aiAnimation** mAnimations;
+
+
+
+    /** The number of textures embedded into the file */
+    unsigned int mNumTextures;
+
+    /** The array of embedded textures.
+    *
+    * Not many file formats embed their textures into the file.
+    * An example is Quake's MDL format (which is also used by
+    * some GameStudio versions)
+    */
+    C_STRUCT aiTexture** mTextures;
+
+
+    /** The number of light sources in the scene. Light sources
+    * are fully optional, in most cases this attribute will be 0
+        */
+    unsigned int mNumLights;
+
+    /** The array of light sources.
+    *
+    * All light sources imported from the given file are
+    * listed here. The array is mNumLights in size.
+    */
+    C_STRUCT aiLight** mLights;
+
+
+    /** The number of cameras in the scene. Cameras
+    * are fully optional, in most cases this attribute will be 0
+        */
+    unsigned int mNumCameras;
+
+    /** The array of cameras.
+    *
+    * All cameras imported from the given file are listed here.
+    * The array is mNumCameras in size. The first camera in the
+    * array (if existing) is the default camera view into
+    * the scene.
+    */
+    C_STRUCT aiCamera** mCameras;
+
+#ifdef __cplusplus
+
+    //! Default constructor - set everything to 0/NULL
+    ASSIMP_API aiScene();
+
+    //! Destructor
+    ASSIMP_API ~aiScene();
+
+    //! Check whether the scene contains meshes
+    //! Unless no special scene flags are set this will always be true.
+    inline bool HasMeshes() const
+        { return mMeshes != NULL && mNumMeshes > 0; }
+
+    //! Check whether the scene contains materials
+    //! Unless no special scene flags are set this will always be true.
+    inline bool HasMaterials() const
+        { return mMaterials != NULL && mNumMaterials > 0; }
+
+    //! Check whether the scene contains lights
+    inline bool HasLights() const
+        { return mLights != NULL && mNumLights > 0; }
+
+    //! Check whether the scene contains textures
+    inline bool HasTextures() const
+        { return mTextures != NULL && mNumTextures > 0; }
+
+    //! Check whether the scene contains cameras
+    inline bool HasCameras() const
+        { return mCameras != NULL && mNumCameras > 0; }
+
+    //! Check whether the scene contains animations
+    inline bool HasAnimations() const
+        { return mAnimations != NULL && mNumAnimations > 0; }
+
+#endif // __cplusplus
+
+
+    /**  Internal data, do not touch */
+#ifdef __cplusplus
+    void* mPrivate;
+#else
+    char* mPrivate;
+#endif
+
+};
+
+#ifdef __cplusplus
+} //! namespace Assimp
+#endif
+
+#endif // __AI_SCENE_H_INC__

+ 197 - 0
include/assimp/texture.h

@@ -0,0 +1,197 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file texture.h
+ *  @brief Defines texture helper structures for the library
+ *
+ * Used for file formats which embed their textures into the model file.
+ * Supported are both normal textures, which are stored as uncompressed
+ * pixels, and "compressed" textures, which are stored in a file format
+ * such as PNG or TGA.
+ */
+
+#ifndef AI_TEXTURE_H_INC
+#define AI_TEXTURE_H_INC
+
+#include "types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// --------------------------------------------------------------------------------
+/** @def AI_MAKE_EMBEDDED_TEXNAME
+ *  Used to build the reserved path name used by the material system to
+ *  reference textures that are embedded into their corresponding
+ *  model files. The parameter specifies the index of the texture
+ *  (zero-based, in the aiScene::mTextures array)
+ */
+#if (!defined AI_MAKE_EMBEDDED_TEXNAME)
+#   define AI_MAKE_EMBEDDED_TEXNAME(_n_) "*" # _n_
+#endif
+
+
+#include "./Compiler/pushpack1.h"
+
+// --------------------------------------------------------------------------------
+/** @brief Helper structure to represent a texel in a ARGB8888 format
+*
+*  Used by aiTexture.
+*/
+struct aiTexel
+{
+    unsigned char b,g,r,a;
+
+#ifdef __cplusplus
+    //! Comparison operator
+    bool operator== (const aiTexel& other) const
+    {
+        return b == other.b && r == other.r &&
+               g == other.g && a == other.a;
+    }
+
+    //! Inverse comparison operator
+    bool operator!= (const aiTexel& other) const
+    {
+        return b != other.b || r != other.r ||
+               g != other.g || a != other.a;
+    }
+
+    //! Conversion to a floating-point 4d color
+    operator aiColor4D() const
+    {
+        return aiColor4D(r/255.f,g/255.f,b/255.f,a/255.f);
+    }
+#endif // __cplusplus
+
+} PACK_STRUCT;
+
+#include "./Compiler/poppack1.h"
+
+// --------------------------------------------------------------------------------
+/** Helper structure to describe an embedded texture
+ *
+ * Normally textures are contained in external files but some file formats embed
+ * them directly in the model file. There are two types of embedded textures:
+ * 1. Uncompressed textures. The color data is given in an uncompressed format.
+ * 2. Compressed textures stored in a file format like png or jpg. The raw file
+ * bytes are given so the application must utilize an image decoder (e.g. DevIL) to
+ * get access to the actual color data.
+ */
+struct aiTexture
+{
+    /** Width of the texture, in pixels
+     *
+     * If mHeight is zero the texture is compressed in a format
+     * like JPEG. In this case mWidth specifies the size of the
+     * memory area pcData is pointing to, in bytes.
+     */
+    unsigned int mWidth;
+
+    /** Height of the texture, in pixels
+     *
+     * If this value is zero, pcData points to an compressed texture
+     * in any format (e.g. JPEG).
+     */
+    unsigned int mHeight;
+
+    /** A hint from the loader to make it easier for applications
+     *  to determine the type of embedded compressed textures.
+     *
+     * If mHeight != 0 this member is undefined. Otherwise it
+     * is set set to '\\0\\0\\0\\0' if the loader has no additional
+     * information about the texture file format used OR the
+     * file extension of the format without a trailing dot. If there
+     * are multiple file extensions for a format, the shortest
+     * extension is chosen (JPEG maps to 'jpg', not to 'jpeg').
+     * E.g. 'dds\\0', 'pcx\\0', 'jpg\\0'.  All characters are lower-case.
+     * The fourth character will always be '\\0'.
+     */
+    char achFormatHint[4];
+
+    /** Data of the texture.
+     *
+     * Points to an array of mWidth * mHeight aiTexel's.
+     * The format of the texture data is always ARGB8888 to
+     * make the implementation for user of the library as easy
+     * as possible. If mHeight = 0 this is a pointer to a memory
+     * buffer of size mWidth containing the compressed texture
+     * data. Good luck, have fun!
+     */
+    C_STRUCT aiTexel* pcData;
+
+#ifdef __cplusplus
+
+    //! For compressed textures (mHeight == 0): compare the
+    //! format hint against a given string.
+    //! @param s Input string. 3 characters are maximally processed.
+    //!        Example values: "jpg", "png"
+    //! @return true if the given string matches the format hint
+    bool CheckFormat(const char* s) const
+    {
+        return (0 == ::strncmp(achFormatHint,s,3));
+    }
+
+    // Construction
+    aiTexture ()
+        : mWidth  (0)
+        , mHeight (0)
+        , pcData  (NULL)
+    {
+        achFormatHint[0] = achFormatHint[1] = 0;
+        achFormatHint[2] = achFormatHint[3] = 0;
+    }
+
+    // Destruction
+    ~aiTexture ()
+    {
+        delete[] pcData;
+    }
+#endif
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // AI_TEXTURE_H_INC

+ 515 - 0
include/assimp/types.h

@@ -0,0 +1,515 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file types.h
+ *  Basic data types and primitives, such as vectors or colors.
+ */
+#ifndef AI_TYPES_H_INC
+#define AI_TYPES_H_INC
+
+// Some runtime headers
+#include <sys/types.h>
+#include <math.h>
+#include <stddef.h>
+#include <string.h>
+#include <limits.h>
+
+// Our compile configuration
+#include "defs.h"
+
+// Some types moved to separate header due to size of operators
+#include "vector3.h"
+#include "vector2.h"
+#include "color4.h"
+#include "matrix3x3.h"
+#include "matrix4x4.h"
+#include "quaternion.h"
+
+#ifdef __cplusplus
+#include <cstring>
+#include <new>      // for std::nothrow_t
+#include <string>   // for aiString::Set(const std::string&)
+
+namespace Assimp    {
+    //! @cond never
+namespace Intern        {
+    // --------------------------------------------------------------------
+    /** @brief Internal helper class to utilize our internal new/delete
+     *    routines for allocating object of this and derived classes.
+     *
+     * By doing this you can safely share class objects between Assimp
+     * and the application - it works even over DLL boundaries. A good
+     * example is the #IOSystem where the application allocates its custom
+     * #IOSystem, then calls #Importer::SetIOSystem(). When the Importer
+     * destructs, Assimp calls operator delete on the stored #IOSystem.
+     * If it lies on a different heap than Assimp is working with,
+     * the application is determined to crash.
+     */
+    // --------------------------------------------------------------------
+#ifndef SWIG
+    struct ASSIMP_API AllocateFromAssimpHeap    {
+        // http://www.gotw.ca/publications/mill15.htm
+
+        // new/delete overload
+        void *operator new    ( size_t num_bytes) /* throw( std::bad_alloc ) */;
+        void *operator new    ( size_t num_bytes, const std::nothrow_t& ) throw();
+        void  operator delete ( void* data);
+
+        // array new/delete overload
+        void *operator new[]    ( size_t num_bytes) /* throw( std::bad_alloc ) */;
+        void *operator new[]    ( size_t num_bytes, const std::nothrow_t& )  throw();
+        void  operator delete[] ( void* data);
+
+    }; // struct AllocateFromAssimpHeap
+#endif
+} // namespace Intern
+    //! @endcond
+} // namespace Assimp
+
+extern "C" {
+#endif
+
+/** Maximum dimension for strings, ASSIMP strings are zero terminated. */
+#ifdef __cplusplus
+const size_t MAXLEN = 1024;
+#else
+#   define MAXLEN 1024
+#endif
+
+#include "./Compiler/pushpack1.h"
+
+// ----------------------------------------------------------------------------------
+/** Represents a plane in a three-dimensional, euclidean space
+*/
+struct aiPlane
+{
+#ifdef __cplusplus
+    aiPlane () : a(0.f), b(0.f), c(0.f), d(0.f) {}
+    aiPlane (float _a, float _b, float _c, float _d)
+        : a(_a), b(_b), c(_c), d(_d) {}
+
+    aiPlane (const aiPlane& o) : a(o.a), b(o.b), c(o.c), d(o.d) {}
+
+#endif // !__cplusplus
+
+    //! Plane equation
+    float a,b,c,d;
+} PACK_STRUCT; // !struct aiPlane
+
+// ----------------------------------------------------------------------------------
+/** Represents a ray
+*/
+struct aiRay
+{
+#ifdef __cplusplus
+    aiRay () {}
+    aiRay (const aiVector3D& _pos, const aiVector3D& _dir)
+        : pos(_pos), dir(_dir) {}
+
+    aiRay (const aiRay& o) : pos (o.pos), dir (o.dir) {}
+
+#endif // !__cplusplus
+
+    //! Position and direction of the ray
+    C_STRUCT aiVector3D pos, dir;
+} PACK_STRUCT; // !struct aiRay
+
+// ----------------------------------------------------------------------------------
+/** Represents a color in Red-Green-Blue space.
+*/
+struct aiColor3D
+{
+#ifdef __cplusplus
+    aiColor3D () : r(0.0f), g(0.0f), b(0.0f) {}
+    aiColor3D (float _r, float _g, float _b) : r(_r), g(_g), b(_b) {}
+    explicit aiColor3D (float _r) : r(_r), g(_r), b(_r) {}
+    aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {}
+
+    /** Component-wise comparison */
+    // TODO: add epsilon?
+    bool operator == (const aiColor3D& other) const
+        {return r == other.r && g == other.g && b == other.b;}
+
+    /** Component-wise inverse comparison */
+    // TODO: add epsilon?
+    bool operator != (const aiColor3D& other) const
+        {return r != other.r || g != other.g || b != other.b;}
+
+    /** Component-wise comparison */
+    // TODO: add epsilon?
+    bool operator < (const aiColor3D& other) const {
+        return r < other.r || (
+            r == other.r && (g < other.g ||
+                (g == other.g && b < other.b)
+            )
+        );
+    }
+
+    /** Component-wise addition */
+    aiColor3D operator+(const aiColor3D& c) const {
+        return aiColor3D(r+c.r,g+c.g,b+c.b);
+    }
+
+    /** Component-wise subtraction */
+    aiColor3D operator-(const aiColor3D& c) const {
+        return aiColor3D(r-c.r,g-c.g,b-c.b);
+    }
+
+    /** Component-wise multiplication */
+    aiColor3D operator*(const aiColor3D& c) const {
+        return aiColor3D(r*c.r,g*c.g,b*c.b);
+    }
+
+    /** Multiply with a scalar */
+    aiColor3D operator*(float f) const {
+        return aiColor3D(r*f,g*f,b*f);
+    }
+
+    /** Access a specific color component */
+    float operator[](unsigned int i) const {
+        return *(&r + i);
+    }
+
+    /** Access a specific color component */
+    float& operator[](unsigned int i) {
+        return *(&r + i);
+    }
+
+    /** Check whether a color is black */
+    bool IsBlack() const {
+        static const float epsilon = 10e-3f;
+        return std::fabs( r ) < epsilon && std::fabs( g ) < epsilon && std::fabs( b ) < epsilon;
+    }
+
+#endif // !__cplusplus
+
+    //! Red, green and blue color values
+    float r, g, b;
+} PACK_STRUCT;  // !struct aiColor3D
+#include "./Compiler/poppack1.h"
+
+// ----------------------------------------------------------------------------------
+/** Represents an UTF-8 string, zero byte terminated.
+ *
+ *  The character set of an aiString is explicitly defined to be UTF-8. This Unicode
+ *  transformation was chosen in the belief that most strings in 3d files are limited
+ *  to ASCII, thus the character set needed to be strictly ASCII compatible.
+ *
+ *  Most text file loaders provide proper Unicode input file handling, special unicode
+ *  characters are correctly transcoded to UTF8 and are kept throughout the libraries'
+ *  import pipeline.
+ *
+ *  For most applications, it will be absolutely sufficient to interpret the
+ *  aiString as ASCII data and work with it as one would work with a plain char*.
+ *  Windows users in need of proper support for i.e asian characters can use the
+ *  MultiByteToWideChar(), WideCharToMultiByte() WinAPI functionality to convert the
+ *  UTF-8 strings to their working character set (i.e. MBCS, WideChar).
+ *
+ *  We use this representation instead of std::string to be C-compatible. The
+ *  (binary) length of such a string is limited to MAXLEN characters (including the
+ *  the terminating zero).
+*/
+struct aiString
+{
+#ifdef __cplusplus
+    /** Default constructor, the string is set to have zero length */
+    aiString() :
+        length(0)
+    {
+        data[0] = '\0';
+
+#ifdef ASSIMP_BUILD_DEBUG
+        // Debug build: overwrite the string on its full length with ESC (27)
+        memset(data+1,27,MAXLEN-1);
+#endif
+    }
+
+    /** Copy constructor */
+    aiString(const aiString& rOther) :
+        length(rOther.length)
+    {
+        // Crop the string to the maximum length
+        length = length>=MAXLEN?MAXLEN-1:length;
+        memcpy( data, rOther.data, length);
+        data[length] = '\0';
+    }
+
+    /** Constructor from std::string */
+    explicit aiString(const std::string& pString) :
+        length(pString.length())
+    {
+        length = length>=MAXLEN?MAXLEN-1:length;
+        memcpy( data, pString.c_str(), length);
+        data[length] = '\0';
+    }
+
+    /** Copy a std::string to the aiString */
+    void Set( const std::string& pString) {
+        if( pString.length() > MAXLEN - 1) {
+            return;
+        }
+        length = pString.length();
+        memcpy( data, pString.c_str(), length);
+        data[length] = 0;
+    }
+
+    /** Copy a const char* to the aiString */
+    void Set( const char* sz) {
+        const size_t len = ::strlen(sz);
+        if( len > MAXLEN - 1) {
+            return;
+        }
+        length = len;
+        memcpy( data, sz, len);
+        data[len] = 0;
+    }
+
+    /** Assign a const char* to the string */
+    aiString& operator = (const char* sz) {
+        Set(sz);
+        return *this;
+    }
+
+    /** Assign a cstd::string to the string */
+    aiString& operator = ( const std::string& pString) {
+        Set(pString);
+        return *this;
+    }
+
+    /** Comparison operator */
+    bool operator==(const aiString& other) const {
+        return  (length == other.length && 0 == memcmp(data,other.data,length));
+    }
+
+    /** Inverse comparison operator */
+    bool operator!=(const aiString& other) const {
+        return  (length != other.length || 0 != memcmp(data,other.data,length));
+    }
+
+    /** Append a string to the string */
+    void Append (const char* app)   {
+        const size_t len = ::strlen(app);
+        if (!len) {
+            return;
+        }
+        if (length + len >= MAXLEN) {
+            return;
+        }
+
+        memcpy(&data[length],app,len+1);
+        length += len;
+    }
+
+    /** Clear the string - reset its length to zero */
+    void Clear ()   {
+        length  = 0;
+        data[0] = '\0';
+
+#ifdef ASSIMP_BUILD_DEBUG
+        // Debug build: overwrite the string on its full length with ESC (27)
+        memset(data+1,27,MAXLEN-1);
+#endif
+    }
+
+    /** Returns a pointer to the underlying zero-terminated array of characters */
+    const char* C_Str() const {
+        return data;
+    }
+
+#endif // !__cplusplus
+
+    /** Binary length of the string excluding the terminal 0. This is NOT the
+     *  logical length of strings containing UTF-8 multibyte sequences! It's
+     *  the number of bytes from the beginning of the string to its end.*/
+    size_t length;
+
+    /** String buffer. Size limit is MAXLEN */
+    char data[MAXLEN];
+} ;  // !struct aiString
+
+
+// ----------------------------------------------------------------------------------
+/** Standard return type for some library functions.
+ * Rarely used, and if, mostly in the C API.
+ */
+typedef enum aiReturn
+{
+    /** Indicates that a function was successful */
+    aiReturn_SUCCESS = 0x0,
+
+    /** Indicates that a function failed */
+    aiReturn_FAILURE = -0x1,
+
+    /** Indicates that not enough memory was available
+     * to perform the requested operation
+     */
+    aiReturn_OUTOFMEMORY = -0x3,
+
+    /** @cond never
+     *  Force 32-bit size enum
+     */
+    _AI_ENFORCE_ENUM_SIZE = 0x7fffffff
+
+    /// @endcond
+} aiReturn;  // !enum aiReturn
+
+// just for backwards compatibility, don't use these constants anymore
+#define AI_SUCCESS     aiReturn_SUCCESS
+#define AI_FAILURE     aiReturn_FAILURE
+#define AI_OUTOFMEMORY aiReturn_OUTOFMEMORY
+
+// ----------------------------------------------------------------------------------
+/** Seek origins (for the virtual file system API).
+ *  Much cooler than using SEEK_SET, SEEK_CUR or SEEK_END.
+ */
+enum aiOrigin
+{
+    /** Beginning of the file */
+    aiOrigin_SET = 0x0,
+
+    /** Current position of the file pointer */
+    aiOrigin_CUR = 0x1,
+
+    /** End of the file, offsets must be negative */
+    aiOrigin_END = 0x2,
+
+    /**  @cond never
+     *   Force 32-bit size enum
+     */
+    _AI_ORIGIN_ENFORCE_ENUM_SIZE = 0x7fffffff
+
+    /// @endcond
+}; // !enum aiOrigin
+
+// ----------------------------------------------------------------------------------
+/** @brief Enumerates predefined log streaming destinations.
+ *  Logging to these streams can be enabled with a single call to
+ *   #LogStream::createDefaultStream.
+ */
+enum aiDefaultLogStream
+{
+    /** Stream the log to a file */
+    aiDefaultLogStream_FILE = 0x1,
+
+    /** Stream the log to std::cout */
+    aiDefaultLogStream_STDOUT = 0x2,
+
+    /** Stream the log to std::cerr */
+    aiDefaultLogStream_STDERR = 0x4,
+
+    /** MSVC only: Stream the log the the debugger
+     * (this relies on OutputDebugString from the Win32 SDK)
+     */
+    aiDefaultLogStream_DEBUGGER = 0x8,
+
+    /** @cond never
+     *  Force 32-bit size enum
+     */
+    _AI_DLS_ENFORCE_ENUM_SIZE = 0x7fffffff
+    /// @endcond
+}; // !enum aiDefaultLogStream
+
+// just for backwards compatibility, don't use these constants anymore
+#define DLS_FILE     aiDefaultLogStream_FILE
+#define DLS_STDOUT   aiDefaultLogStream_STDOUT
+#define DLS_STDERR   aiDefaultLogStream_STDERR
+#define DLS_DEBUGGER aiDefaultLogStream_DEBUGGER
+
+// ----------------------------------------------------------------------------------
+/** Stores the memory requirements for different components (e.g. meshes, materials,
+ *  animations) of an import. All sizes are in bytes.
+ *  @see Importer::GetMemoryRequirements()
+*/
+struct aiMemoryInfo
+{
+#ifdef __cplusplus
+
+    /** Default constructor */
+    aiMemoryInfo()
+        : textures   (0)
+        , materials  (0)
+        , meshes     (0)
+        , nodes      (0)
+        , animations (0)
+        , cameras    (0)
+        , lights     (0)
+        , total      (0)
+    {}
+
+#endif
+
+    /** Storage allocated for texture data */
+    unsigned int textures;
+
+    /** Storage allocated for material data  */
+    unsigned int materials;
+
+    /** Storage allocated for mesh data */
+    unsigned int meshes;
+
+    /** Storage allocated for node data */
+    unsigned int nodes;
+
+    /** Storage allocated for animation data */
+    unsigned int animations;
+
+    /** Storage allocated for camera data */
+    unsigned int cameras;
+
+    /** Storage allocated for light data */
+    unsigned int lights;
+
+    /** Total storage allocated for the full import. */
+    unsigned int total;
+}; // !struct aiMemoryInfo
+
+#ifdef __cplusplus
+}
+#endif //!  __cplusplus
+
+// Include implementation files
+#include "vector2.inl"
+#include "vector3.inl"
+#include "color4.inl"
+#include "quaternion.inl"
+#include "matrix3x3.inl"
+#include "matrix4x4.inl"
+#endif

+ 113 - 0
include/assimp/vector2.h

@@ -0,0 +1,113 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+/** @file vector2.h
+ *  @brief 2D vector structure, including operators when compiling in C++
+ */
+#ifndef AI_VECTOR2D_H_INC
+#define AI_VECTOR2D_H_INC
+
+#ifdef __cplusplus
+#   include <cmath>
+#else
+#   include <math.h>
+#endif
+
+#include "./Compiler/pushpack1.h"
+
+// ----------------------------------------------------------------------------------
+/** Represents a two-dimensional vector.
+ */
+
+#ifdef __cplusplus
+template <typename TReal>
+class aiVector2t
+{
+public:
+
+    aiVector2t () : x(), y() {}
+    aiVector2t (TReal _x, TReal _y) : x(_x), y(_y) {}
+    explicit aiVector2t (TReal _xyz) : x(_xyz), y(_xyz) {}
+    aiVector2t (const aiVector2t& o) : x(o.x), y(o.y) {}
+
+public:
+
+    void Set( TReal pX, TReal pY);
+    TReal SquareLength() const ;
+    TReal Length() const ;
+    aiVector2t& Normalize();
+
+public:
+
+    const aiVector2t& operator += (const aiVector2t& o);
+    const aiVector2t& operator -= (const aiVector2t& o);
+    const aiVector2t& operator *= (TReal f);
+    const aiVector2t& operator /= (TReal f);
+
+    TReal operator[](unsigned int i) const;
+    TReal& operator[](unsigned int i);
+
+    bool operator== (const aiVector2t& other) const;
+    bool operator!= (const aiVector2t& other) const;
+
+    bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const;
+
+    aiVector2t& operator= (TReal f);
+    const aiVector2t SymMul(const aiVector2t& o);
+
+    template <typename TOther>
+    operator aiVector2t<TOther> () const;
+
+    TReal x, y;
+} PACK_STRUCT;
+
+typedef aiVector2t<float> aiVector2D;
+
+#else
+
+struct aiVector2D {
+    float x,y;
+};
+
+#endif // __cplusplus
+
+#include "./Compiler/poppack1.h"
+
+#endif // AI_VECTOR2D_H_INC

+ 224 - 0
include/assimp/vector2.inl

@@ -0,0 +1,224 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  vector2.inl
+ *  @brief Inline implementation of aiVector2t<TReal> operators
+ */
+#ifndef AI_VECTOR2D_INL_INC
+#define AI_VECTOR2D_INL_INC
+
+#ifdef __cplusplus
+#include "vector2.h"
+
+#include <cmath>
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+template <typename TOther>
+aiVector2t<TReal>::operator aiVector2t<TOther> () const {
+    return aiVector2t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y));
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+void aiVector2t<TReal>::Set( TReal pX, TReal pY) {
+    x = pX; y = pY;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+TReal aiVector2t<TReal>::SquareLength() const {
+    return x*x + y*y;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+TReal aiVector2t<TReal>::Length() const {
+    return std::sqrt( SquareLength());
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+aiVector2t<TReal>& aiVector2t<TReal>::Normalize() {
+    *this /= Length();
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+const aiVector2t<TReal>& aiVector2t<TReal>::operator += (const aiVector2t& o) {
+    x += o.x; y += o.y;
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+const aiVector2t<TReal>& aiVector2t<TReal>::operator -= (const aiVector2t& o) {
+    x -= o.x; y -= o.y;
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+const aiVector2t<TReal>& aiVector2t<TReal>::operator *= (TReal f) {
+    x *= f; y *= f;
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+const aiVector2t<TReal>& aiVector2t<TReal>::operator /= (TReal f) {
+    x /= f; y /= f;
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+TReal aiVector2t<TReal>::operator[](unsigned int i) const {
+    return *(&x + i);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+TReal& aiVector2t<TReal>::operator[](unsigned int i) {
+    return *(&x + i);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+bool aiVector2t<TReal>::operator== (const aiVector2t& other) const {
+    return x == other.x && y == other.y;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+bool aiVector2t<TReal>::operator!= (const aiVector2t& other) const {
+    return x != other.x || y != other.y;
+}
+
+// ---------------------------------------------------------------------------
+template<typename TReal>
+bool aiVector2t<TReal>::Equal(const aiVector2t& other, TReal epsilon) const {
+    return
+        std::abs(x - other.x) <= epsilon &&
+        std::abs(y - other.y) <= epsilon;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+aiVector2t<TReal>& aiVector2t<TReal>::operator= (TReal f)   {
+    x = y = f;
+    return *this;
+}
+
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+const aiVector2t<TReal> aiVector2t<TReal>::SymMul(const aiVector2t& o) {
+    return aiVector2t(x*o.x,y*o.y);
+}
+
+
+// ------------------------------------------------------------------------------------------------
+// symmetric addition
+template <typename TReal>
+inline aiVector2t<TReal> operator + (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
+{
+    return aiVector2t<TReal>( v1.x + v2.x, v1.y + v2.y);
+}
+
+// ------------------------------------------------------------------------------------------------
+// symmetric subtraction
+template <typename TReal>
+inline aiVector2t<TReal> operator - (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
+{
+    return aiVector2t<TReal>( v1.x - v2.x, v1.y - v2.y);
+}
+
+// ------------------------------------------------------------------------------------------------
+// scalar product
+template <typename TReal>
+inline TReal operator * (const aiVector2t<TReal>& v1, const aiVector2t<TReal>& v2)
+{
+    return v1.x*v2.x + v1.y*v2.y;
+}
+
+// ------------------------------------------------------------------------------------------------
+// scalar multiplication
+template <typename TReal>
+inline aiVector2t<TReal> operator * ( TReal f, const aiVector2t<TReal>& v)
+{
+    return aiVector2t<TReal>( f*v.x, f*v.y);
+}
+
+// ------------------------------------------------------------------------------------------------
+// and the other way around
+template <typename TReal>
+inline aiVector2t<TReal> operator * ( const aiVector2t<TReal>& v, TReal f)
+{
+    return aiVector2t<TReal>( f*v.x, f*v.y);
+}
+
+// ------------------------------------------------------------------------------------------------
+// scalar division
+template <typename TReal>
+inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, TReal f)
+{
+
+    return v * (1/f);
+}
+
+// ------------------------------------------------------------------------------------------------
+// vector division
+template <typename TReal>
+inline aiVector2t<TReal> operator / ( const aiVector2t<TReal>& v, const aiVector2t<TReal>& v2)
+{
+    return aiVector2t<TReal>(v.x / v2.x,v.y / v2.y);
+}
+
+// ------------------------------------------------------------------------------------------------
+// vector negation
+template <typename TReal>
+inline aiVector2t<TReal> operator - ( const aiVector2t<TReal>& v)
+{
+    return aiVector2t<TReal>( -v.x, -v.y);
+}
+
+#endif
+#endif

+ 149 - 0
include/assimp/vector3.h

@@ -0,0 +1,149 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+/** @file vector3.h
+ *  @brief 3D vector structure, including operators when compiling in C++
+ */
+#ifndef AI_VECTOR3D_H_INC
+#define AI_VECTOR3D_H_INC
+
+#ifdef __cplusplus
+#   include <cmath>
+#else
+#   include <math.h>
+#endif
+
+#include "./Compiler/pushpack1.h"
+
+#ifdef __cplusplus
+
+template<typename TReal> class aiMatrix3x3t;
+template<typename TReal> class aiMatrix4x4t;
+
+// ---------------------------------------------------------------------------
+/** Represents a three-dimensional vector. */
+template <typename TReal>
+class aiVector3t
+{
+public:
+
+    aiVector3t () : x(), y(), z() {}
+    aiVector3t (TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
+    explicit aiVector3t (TReal _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
+    aiVector3t (const aiVector3t& o) : x(o.x), y(o.y), z(o.z) {}
+
+public:
+
+    // combined operators
+    const aiVector3t& operator += (const aiVector3t& o);
+    const aiVector3t& operator -= (const aiVector3t& o);
+    const aiVector3t& operator *= (TReal f);
+    const aiVector3t& operator /= (TReal f);
+
+    // transform vector by matrix
+    aiVector3t& operator *= (const aiMatrix3x3t<TReal>& mat);
+    aiVector3t& operator *= (const aiMatrix4x4t<TReal>& mat);
+
+    // access a single element
+    TReal operator[](unsigned int i) const;
+    TReal& operator[](unsigned int i);
+
+    // comparison
+    bool operator== (const aiVector3t& other) const;
+    bool operator!= (const aiVector3t& other) const;
+    bool operator < (const aiVector3t& other) const;
+
+    bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const;
+
+    template <typename TOther>
+    operator aiVector3t<TOther> () const;
+
+public:
+
+    /** @brief Set the components of a vector
+     *  @param pX X component
+     *  @param pY Y component
+     *  @param pZ Z component  */
+    void Set( TReal pX, TReal pY, TReal pZ);
+
+    /** @brief Get the squared length of the vector
+     *  @return Square length */
+    TReal SquareLength() const;
+
+
+    /** @brief Get the length of the vector
+     *  @return length */
+    TReal Length() const;
+
+
+    /** @brief Normalize the vector */
+    aiVector3t& Normalize();
+
+
+    /** @brief Componentwise multiplication of two vectors
+     *
+     *  Note that vec*vec yields the dot product.
+     *  @param o Second factor */
+    const aiVector3t SymMul(const aiVector3t& o);
+
+    TReal x, y, z;
+} PACK_STRUCT;
+
+
+typedef aiVector3t<float> aiVector3D;
+
+#else
+
+struct aiVector3D {
+
+    float x,y,z;
+} PACK_STRUCT;
+
+#endif // __cplusplus
+
+#include "./Compiler/poppack1.h"
+
+#ifdef __cplusplus
+
+
+
+#endif // __cplusplus
+
+#endif // AI_VECTOR3D_H_INC

+ 228 - 0
include/assimp/vector3.inl

@@ -0,0 +1,228 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  vector3.inl
+ *  @brief Inline implementation of aiVector3t<TReal> operators
+ */
+#ifndef AI_VECTOR3D_INL_INC
+#define AI_VECTOR3D_INL_INC
+
+#ifdef __cplusplus
+#include "vector3.h"
+
+#include <cmath>
+
+// ------------------------------------------------------------------------------------------------
+/** Transformation of a vector by a 3x3 matrix */
+template <typename TReal>
+inline aiVector3t<TReal> operator * (const aiMatrix3x3t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
+{
+    aiVector3t<TReal> res;
+    res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z;
+    res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z;
+    res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z;
+    return res;
+}
+
+// ------------------------------------------------------------------------------------------------
+/** Transformation of a vector by a 4x4 matrix */
+template <typename TReal>
+inline aiVector3t<TReal> operator * (const aiMatrix4x4t<TReal>& pMatrix, const aiVector3t<TReal>& pVector)
+{
+    aiVector3t<TReal> res;
+    res.x = pMatrix.a1 * pVector.x + pMatrix.a2 * pVector.y + pMatrix.a3 * pVector.z + pMatrix.a4;
+    res.y = pMatrix.b1 * pVector.x + pMatrix.b2 * pVector.y + pMatrix.b3 * pVector.z + pMatrix.b4;
+    res.z = pMatrix.c1 * pVector.x + pMatrix.c2 * pVector.y + pMatrix.c3 * pVector.z + pMatrix.c4;
+    return res;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+template <typename TOther>
+aiVector3t<TReal>::operator aiVector3t<TOther> () const {
+    return aiVector3t<TOther>(static_cast<TOther>(x),static_cast<TOther>(y),static_cast<TOther>(z));
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE void aiVector3t<TReal>::Set( TReal pX, TReal pY, TReal pZ) {
+    x = pX; y = pY; z = pZ;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE TReal aiVector3t<TReal>::SquareLength() const {
+    return x*x + y*y + z*z;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE TReal aiVector3t<TReal>::Length() const {
+    return std::sqrt( SquareLength());
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::Normalize() {
+    *this /= Length(); return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator += (const aiVector3t<TReal>& o) {
+    x += o.x; y += o.y; z += o.z; return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator -= (const aiVector3t<TReal>& o) {
+    x -= o.x; y -= o.y; z -= o.z; return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator *= (TReal f) {
+    x *= f; y *= f; z *= f; return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiVector3t<TReal>& aiVector3t<TReal>::operator /= (TReal f) {
+    x /= f; y /= f; z /= f; return *this;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& mat){
+    return(*this =  mat * (*this));
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE aiVector3t<TReal>& aiVector3t<TReal>::operator *= (const aiMatrix4x4t<TReal>& mat){
+    return(*this = mat * (*this));
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE TReal aiVector3t<TReal>::operator[](unsigned int i) const {
+    return *(&x + i);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE TReal& aiVector3t<TReal>::operator[](unsigned int i) {
+    return *(&x + i);
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE bool aiVector3t<TReal>::operator== (const aiVector3t<TReal>& other) const {
+    return x == other.x && y == other.y && z == other.z;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE bool aiVector3t<TReal>::operator!= (const aiVector3t<TReal>& other) const {
+    return x != other.x || y != other.y || z != other.z;
+}
+// ---------------------------------------------------------------------------
+template<typename TReal>
+AI_FORCE_INLINE bool aiVector3t<TReal>::Equal(const aiVector3t<TReal>& other, TReal epsilon) const {
+    return
+        std::abs(x - other.x) <= epsilon &&
+        std::abs(y - other.y) <= epsilon &&
+        std::abs(z - other.z) <= epsilon;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE bool aiVector3t<TReal>::operator < (const aiVector3t<TReal>& other) const {
+    return x != other.x ? x < other.x : y != other.y ? y < other.y : z < other.z;
+}
+// ------------------------------------------------------------------------------------------------
+template <typename TReal>
+AI_FORCE_INLINE const aiVector3t<TReal> aiVector3t<TReal>::SymMul(const aiVector3t<TReal>& o) {
+    return aiVector3t<TReal>(x*o.x,y*o.y,z*o.z);
+}
+// ------------------------------------------------------------------------------------------------
+// symmetric addition
+template <typename TReal>
+AI_FORCE_INLINE aiVector3t<TReal> operator + (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
+    return aiVector3t<TReal>( v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
+}
+// ------------------------------------------------------------------------------------------------
+// symmetric subtraction
+template <typename TReal>
+AI_FORCE_INLINE aiVector3t<TReal> operator - (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
+    return aiVector3t<TReal>( v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
+}
+// ------------------------------------------------------------------------------------------------
+// scalar product
+template <typename TReal>
+AI_FORCE_INLINE TReal operator * (const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2) {
+    return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
+}
+// ------------------------------------------------------------------------------------------------
+// scalar multiplication
+template <typename TReal>
+AI_FORCE_INLINE aiVector3t<TReal> operator * ( TReal f, const aiVector3t<TReal>& v) {
+    return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
+}
+// ------------------------------------------------------------------------------------------------
+// and the other way around
+template <typename TReal>
+AI_FORCE_INLINE  aiVector3t<TReal> operator * ( const aiVector3t<TReal>& v, TReal f)    {
+    return aiVector3t<TReal>( f*v.x, f*v.y, f*v.z);
+}
+// ------------------------------------------------------------------------------------------------
+// scalar division
+template <typename TReal>
+AI_FORCE_INLINE  aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, TReal f)    {
+    return v * (1/f);
+}
+// ------------------------------------------------------------------------------------------------
+// vector division
+template <typename TReal>
+AI_FORCE_INLINE  aiVector3t<TReal> operator / ( const aiVector3t<TReal>& v, const aiVector3t<TReal>& v2)    {
+    return aiVector3t<TReal>(v.x / v2.x,v.y / v2.y,v.z / v2.z);
+}
+// ------------------------------------------------------------------------------------------------
+// cross product
+template <typename TReal>
+AI_FORCE_INLINE  aiVector3t<TReal> operator ^ ( const aiVector3t<TReal>& v1, const aiVector3t<TReal>& v2)   {
+    return aiVector3t<TReal>( v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
+}
+// ------------------------------------------------------------------------------------------------
+// vector negation
+template <typename TReal>
+AI_FORCE_INLINE  aiVector3t<TReal> operator - ( const aiVector3t<TReal>& v) {
+    return aiVector3t<TReal>( -v.x, -v.y, -v.z);
+}
+
+// ------------------------------------------------------------------------------------------------
+
+#endif // __cplusplus
+#endif // AI_VECTOR3D_INL_INC

+ 105 - 0
include/assimp/version.h

@@ -0,0 +1,105 @@
+/*
+---------------------------------------------------------------------------
+Open Asset Import Library (assimp)
+---------------------------------------------------------------------------
+
+Copyright (c) 2006-2015, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the following
+conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+---------------------------------------------------------------------------
+*/
+
+/** @file  version.h
+ *  @brief Functions to query the version of the Assimp runtime, check
+ *    compile flags, ...
+ */
+#ifndef INCLUDED_AI_VERSION_H
+#define INCLUDED_AI_VERSION_H
+
+#include "defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------------------------------------------------------------------
+/** @brief Returns a string with legal copyright and licensing information
+ *  about Assimp. The string may include multiple lines.
+ *  @return Pointer to static string.
+ */
+ASSIMP_API const char*  aiGetLegalString  (void);
+
+// ---------------------------------------------------------------------------
+/** @brief Returns the current minor version number of Assimp.
+ *  @return Minor version of the Assimp runtime the application was
+ *    linked/built against
+ */
+ASSIMP_API unsigned int aiGetVersionMinor (void);
+
+// ---------------------------------------------------------------------------
+/** @brief Returns the current major version number of Assimp.
+ *  @return Major version of the Assimp runtime the application was
+ *    linked/built against
+ */
+ASSIMP_API unsigned int aiGetVersionMajor (void);
+
+// ---------------------------------------------------------------------------
+/** @brief Returns the repository revision of the Assimp runtime.
+ *  @return SVN Repository revision number of the Assimp runtime the
+ *          application was linked/built against.
+ */
+ASSIMP_API unsigned int aiGetVersionRevision (void);
+
+//! Assimp was compiled as a shared object (Windows: DLL)
+#define ASSIMP_CFLAGS_SHARED  0x1
+//! Assimp was compiled against STLport
+#define ASSIMP_CFLAGS_STLPORT 0x2
+//! Assimp was compiled as a debug build
+#define ASSIMP_CFLAGS_DEBUG   0x4
+
+//! Assimp was compiled with ASSIMP_BUILD_BOOST_WORKAROUND defined
+#define ASSIMP_CFLAGS_NOBOOST           0x8
+//! Assimp was compiled with ASSIMP_BUILD_SINGLETHREADED defined
+#define ASSIMP_CFLAGS_SINGLETHREADED    0x10
+
+// ---------------------------------------------------------------------------
+/** @brief Returns assimp's compile flags
+ *  @return Any bitwise combination of the ASSIMP_CFLAGS_xxx constants.
+ */
+ASSIMP_API unsigned int aiGetCompileFlags (void);
+
+#ifdef __cplusplus
+} // end extern "C"
+#endif
+
+#endif // !! #ifndef INCLUDED_AI_VERSION_H

+ 33 - 0
include/polycode/core/PolyCore.h

@@ -484,5 +484,38 @@ namespace Polycode {
 		Renderer *renderer;
 		CoreServices *services;
 	};
+    
+    class _PolyExport DummyCore : public Core {
+    public:
+        
+        DummyCore();
+        ~DummyCore();
+        
+        void Render();
+        bool systemUpdate();
+        void setCursor(int cursorType);
+        void createThread(Threaded *target);
+        CoreMutex *createMutex();
+        void copyStringToClipboard(const String& str);
+        String getClipboardString();
+        void createFolder(const String& folderPath);
+        void copyDiskItem(const String& itemPath, const String& destItemPath);
+        void moveDiskItem(const String& itemPath, const String& destItemPath);
+        void removeDiskItem(const String& itemPath);
+        String openFolderPicker();
+        std::vector<String> openFilePicker(std::vector<CoreFileExtension> extensions, bool allowMultiple);
+        String saveFilePicker(std::vector<CoreFileExtension> extensions);
+        void handleVideoModeChange(VideoModeChangeInfo *modeInfo);
+        void flushRenderContext();
+        void openURL(String url);
+        unsigned int getTicks();
+        String executeExternalCommand(String command, String args, String inDirectory);
+        bool systemParseFolder(const Polycode::String& pathString, bool showHidden, std::vector<OSFileEntry> &targetVector);
+        
+        
+        
+    };
+    
+    
 	
 }

+ 5 - 6
include/polycode/tools/polyimport.h

@@ -1,11 +1,10 @@
-#include "assimp.h"
 
-#include "assimp.h"
-#include "aiPostProcess.h"
-#include "aiScene.h"
+#include "postprocess.h"
+#include "scene.h"
+
 #include <stdio.h>
-#include "PolyMesh.h"
-#include "PolyString.h"
+#include "polycode/core/PolyMesh.h"
+#include "polycode/core/PolyString.h"
 #include <vector>
 
 using std::vector;

+ 42 - 2
src/core/PolyCore.cpp

@@ -26,6 +26,7 @@
 #include "polycode/core/PolyRenderer.h"
 #include "polycode/core/PolyLogger.h"
 #include "polycode/core/PolyCoreServices.h"
+#include "polycode/core/PolyBasicFileProvider.h"
 
 #if PLATFORM == PLATFORM_WINDOWS
 #include <windows.h>
@@ -151,7 +152,6 @@ namespace Polycode {
 	}	
 	
 	Core::~Core() {
-		printf("Shutting down core");
 		delete services;
         delete input;
 	}
@@ -401,5 +401,45 @@ namespace Polycode {
 	void Core::unlockMutex(CoreMutex *mutex) {
 		mutex->unlock();
 	}
-	
+    
+    DummyCore::DummyCore(): Core(0, 0, false, false, 0, 0, 0, 0) {
+        fileProviders.push_back(new BasicFileProvider());
+    }
+    
+    DummyCore::~DummyCore() {}
+    void DummyCore::Render() {}
+    bool DummyCore::systemUpdate()  {
+        if(!running)
+            return false;
+        doSleep();
+        updateCore();
+        return running;
+    }
+    void DummyCore::setCursor(int cursorType) {}
+    void DummyCore::createThread(Threaded *target) {}
+    CoreMutex *DummyCore::createMutex() { return NULL; }
+    void DummyCore::copyStringToClipboard(const String& str) {}
+    String DummyCore::getClipboardString() { return ""; }
+    void DummyCore::createFolder(const String& folderPath) {}
+    void DummyCore::copyDiskItem(const String& itemPath, const String& destItemPath) {}
+    void DummyCore::moveDiskItem(const String& itemPath, const String& destItemPath) {}
+    void DummyCore::removeDiskItem(const String& itemPath) {}
+    String DummyCore::openFolderPicker() { return "";}
+    std::vector<String> DummyCore::openFilePicker(std::vector<CoreFileExtension> extensions, bool allowMultiple) {
+        std::vector<String> ret;
+        return ret;
+    }
+    String DummyCore::saveFilePicker(std::vector<CoreFileExtension> extensions) {
+        return "";
+    }
+    void DummyCore::handleVideoModeChange(VideoModeChangeInfo *modeInfo) {}
+    void DummyCore::flushRenderContext() {}
+    void DummyCore::openURL(String url) {}
+    unsigned int DummyCore::getTicks() { return 0;}
+    String DummyCore::executeExternalCommand(String command, String args, String inDirectory) {
+        return "";
+    }
+    bool DummyCore::systemParseFolder(const Polycode::String& pathString, bool showHidden, std::vector<OSFileEntry> &targetVector) {
+        return false;
+    }
 }

+ 0 - 2
src/core/PolyResourceManager.cpp

@@ -244,8 +244,6 @@ ResourceManager::ResourceManager() : EventDispatcher() {
 }
 
 ResourceManager::~ResourceManager() {
-    printf("Shutting down resource manager...\n");
-
     for(int i=0; i < resourceLoaders.size(); i++)	{
         delete resourceLoaders[i];
     }

+ 4 - 4
src/ide/PolycodeToolLauncher.cpp

@@ -100,11 +100,11 @@ void PolycodeToolLauncher::buildProject(PolycodeProject *project, String destina
 	
 #ifdef _WINDOWS
 	String targetFolder = projectBasePath;
-	String command = "\""+polycodeBasePath+"/Standalone/Bin/polybuild.exe\"";
+	String command = "\""+polycodeBasePath+"/bin/polybuild.exe\"";
 	String args =  "--config=\""+projectPath+"\" --out=\""+destinationPath+"\" --compileScripts=\""+((compileScripts)?"true":"false")+"\"";
 	String ret = CoreServices::getInstance()->getCore()->executeExternalCommand(command, args, targetFolder);
 #else
-	String command = polycodeBasePath+"/Standalone/Bin/polybuild";
+	String command = polycodeBasePath+"/bin/polybuild";
 	String inFolder = projectBasePath; 
 	String args = "--config=\""+projectPath+"\" --out=\""+destinationPath+"\" --compileScripts=\""+((compileScripts)?"true":"false")+"\"";
 	String ret = CoreServices::getInstance()->getCore()->executeExternalCommand(command, args, inFolder);
@@ -171,10 +171,10 @@ String PolycodeToolLauncher::importAssets(String sourceFile, String inFolder, bo
 
 	
 #ifdef _WINDOWS
-	String command = "\""+polycodeBasePath+"/Standalone/Bin/polyimport.exe\"";
+	String command = "\""+polycodeBasePath+"/bin/polyimport.exe\"";
 	ret = CoreServices::getInstance()->getCore()->executeExternalCommand(command, args, inFolder);
 #else
-	String command = polycodeBasePath+"/Standalone/Bin/polyimport";
+	String command = polycodeBasePath+"/bin/polyimport";
 	ret = CoreServices::getInstance()->getCore()->executeExternalCommand(command, args, inFolder);
 #endif
 	return ret;

+ 17 - 15
src/tools/polyimport.cpp

@@ -1,9 +1,11 @@
 
-#include "polyimport.h"
-#include "OSBasics.h"
-#include "PolyObject.h"
+#include "polycode/tools/polyimport.h"
+
+#include "polycode/core/PolyGlobals.h"
+#include "polycode/core/PolyObject.h"
+
+#include <assimp/cimport.h>
 
-#include "physfs.h"
 #ifdef WIN32
 #include "getopt.h"
 #define getopt getopt_a
@@ -105,6 +107,9 @@ void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, c
 		}
 		//apply_material(sc->mMaterials[mesh->mMaterialIndex]);
         
+        
+        int baseVertexCount = tmesh->getVertexCount();
+        
 		for (t = 0; t < mesh->mNumVertices; ++t) {
 
             Vector3 vPosition;
@@ -193,15 +198,13 @@ void addToMesh(String prefix, Polycode::Mesh *tmesh, const struct aiScene *sc, c
 
              for(i = 0; i < face->mNumIndices; i++) {
                  int index = face->mIndices[i];
-                 tmesh->addIndex(index);
+                 tmesh->addIndex(baseVertexCount+index);
              }
          }
 		
 		if(!addSubmeshes && !listOnly) {
-			String fileNameMesh = prefix+meshFileName+".mesh";			
-			OSFILE *outFile = OSBasics::open(fileNameMesh.c_str(), "wb");	
-			tmesh->saveToFile(outFile, writeNormals, writeTangents, writeColors, writeBoneWeights, writeUVs, writeSecondaryUVs);
-			OSBasics::close(outFile);
+			String fileNameMesh = prefix+meshFileName+".mesh";
+			tmesh->saveToFile(fileNameMesh, writeNormals, writeTangents, writeColors, writeBoneWeights, writeUVs, writeSecondaryUVs);
 			delete tmesh;
             
             ObjectEntry *meshEntry = parentSceneObject->addChild("child");
@@ -399,9 +402,7 @@ int exportToFile(String prefix, bool swapZY, bool addSubmeshes, bool listOnly, b
 		if(listOnly) {
 			printf("%s\n", fileNameMesh.c_str());
 		} else {
-			OSFILE *outFile = OSBasics::open(fileNameMesh.c_str(), "wb");	
-			mesh->saveToFile(outFile, writeNormals, writeTangents, writeColors, writeBoneWeights, writeUVs, writeSecondaryUVs);
-			OSBasics::close(outFile);
+			mesh->saveToFile(fileNameMesh, writeNormals, writeTangents, writeColors, writeBoneWeights, writeUVs, writeSecondaryUVs);
 		}
 	}
 		
@@ -497,6 +498,8 @@ int exportToFile(String prefix, bool swapZY, bool addSubmeshes, bool listOnly, b
 int main(int argc, char **argv) {
 
 
+    Core *core = new DummyCore();
+    
 	bool argsValid = true;
 	bool showHelp = false;
 
@@ -581,7 +584,7 @@ int main(int argc, char **argv) {
 	}
 		
 	if(!listOnly) {
-		printf("Polycode import tool v"POLYCODE_VERSION_STRING"\n");	
+		printf("Polycode import tool v%s\n", POLYCODE_VERSION_STRING);
 	}
 	
 	if(!argsValid) {
@@ -617,8 +620,6 @@ int main(int argc, char **argv) {
 		return 0;
 	}
 	
-	PHYSFS_init(argv[0]);
-	
 	if(showAssimpDebug) {
 		struct aiLogStream stream;
 		stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
@@ -659,5 +660,6 @@ int main(int argc, char **argv) {
 	}
 
 	aiReleaseImport(scene);
+    delete core;
 	return 1;
 }