Pārlūkot izejas kodu

Merge pull request #33347 from RevoluPowered/demo/assimp-importer-fbx

FBX Skinning and batch of fixes
Rémi Verschelde 5 gadi atpakaļ
vecāks
revīzija
b30e6496bd
100 mainītis faili ar 2574 papildinājumiem un 4442 dzēšanām
  1. 3 0
      modules/assimp/SCsub
  2. 548 367
      modules/assimp/editor_scene_importer_assimp.cpp
  3. 23 27
      modules/assimp/editor_scene_importer_assimp.h
  4. 34 19
      modules/assimp/import_state.h
  5. 1 1
      thirdparty/README.md
  6. 15 2
      thirdparty/assimp/code/Common/BaseImporter.cpp
  7. 60 101
      thirdparty/assimp/code/Common/DefaultIOSystem.cpp
  8. 12 30
      thirdparty/assimp/code/Common/Exporter.cpp
  9. 6 0
      thirdparty/assimp/code/Common/ImporterRegistry.cpp
  10. 7 0
      thirdparty/assimp/code/Common/PostStepRegistry.cpp
  11. 50 0
      thirdparty/assimp/code/Common/SceneCombiner.cpp
  12. 5 9
      thirdparty/assimp/code/Common/Version.cpp
  13. 9 9
      thirdparty/assimp/code/Common/scene.cpp
  14. 8 0
      thirdparty/assimp/code/FBX/FBXCompileConfig.h
  15. 229 116
      thirdparty/assimp/code/FBX/FBXConverter.cpp
  16. 55 39
      thirdparty/assimp/code/FBX/FBXConverter.h
  17. 37 2
      thirdparty/assimp/code/FBX/FBXDocument.h
  18. 1 5
      thirdparty/assimp/code/FBX/FBXExportProperty.cpp
  19. 85 37
      thirdparty/assimp/code/FBX/FBXExporter.cpp
  20. 1 1
      thirdparty/assimp/code/FBX/FBXExporter.h
  21. 102 115
      thirdparty/assimp/code/FBX/FBXImporter.cpp
  22. 8 12
      thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp
  23. 0 83
      thirdparty/assimp/code/MMD/MMDCpp14.h
  24. 0 372
      thirdparty/assimp/code/MMD/MMDImporter.cpp
  25. 0 96
      thirdparty/assimp/code/MMD/MMDImporter.h
  26. 0 597
      thirdparty/assimp/code/MMD/MMDPmdParser.h
  27. 0 608
      thirdparty/assimp/code/MMD/MMDPmxParser.cpp
  28. 0 782
      thirdparty/assimp/code/MMD/MMDPmxParser.h
  29. 0 376
      thirdparty/assimp/code/MMD/MMDVmdParser.h
  30. 1 18
      thirdparty/assimp/code/Material/MaterialSystem.cpp
  31. 268 0
      thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp
  32. 112 0
      thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h
  33. 3 3
      thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp
  34. 0 1
      thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp
  35. 0 25
      thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp
  36. 29 0
      thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp
  37. 7 0
      thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h
  38. 59 4
      thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp
  39. 8 0
      thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h
  40. 22 1
      thirdparty/assimp/code/revision.h
  41. 8 0
      thirdparty/assimp/include/assimp/.editorconfig
  42. 11 9
      thirdparty/assimp/include/assimp/BaseImporter.h
  43. 5 1
      thirdparty/assimp/include/assimp/Bitmap.h
  44. 5 0
      thirdparty/assimp/include/assimp/ByteSwapper.h
  45. 12 2
      thirdparty/assimp/include/assimp/CreateAnimMesh.h
  46. 9 10
      thirdparty/assimp/include/assimp/DefaultIOStream.h
  47. 5 0
      thirdparty/assimp/include/assimp/DefaultIOSystem.h
  48. 9 0
      thirdparty/assimp/include/assimp/Defines.h
  49. 13 10
      thirdparty/assimp/include/assimp/Exceptional.h
  50. 4 0
      thirdparty/assimp/include/assimp/Exporter.hpp
  51. 6 1
      thirdparty/assimp/include/assimp/GenericProperty.h
  52. 5 1
      thirdparty/assimp/include/assimp/Hash.h
  53. 8 4
      thirdparty/assimp/include/assimp/IOStream.hpp
  54. 25 18
      thirdparty/assimp/include/assimp/IOStreamBuffer.h
  55. 4 0
      thirdparty/assimp/include/assimp/IOSystem.hpp
  56. 4 0
      thirdparty/assimp/include/assimp/Importer.hpp
  57. 20 16
      thirdparty/assimp/include/assimp/LineSplitter.h
  58. 5 0
      thirdparty/assimp/include/assimp/LogAux.h
  59. 0 49
      thirdparty/assimp/include/assimp/Macros.h
  60. 23 10
      thirdparty/assimp/include/assimp/MathFunctions.h
  61. 6 0
      thirdparty/assimp/include/assimp/MemoryIOWrapper.h
  62. 7 2
      thirdparty/assimp/include/assimp/ParsingUtils.h
  63. 9 5
      thirdparty/assimp/include/assimp/Profiler.h
  64. 6 2
      thirdparty/assimp/include/assimp/ProgressHandler.hpp
  65. 5 3
      thirdparty/assimp/include/assimp/RemoveComments.h
  66. 5 0
      thirdparty/assimp/include/assimp/SGSpatialSort.h
  67. 10 1
      thirdparty/assimp/include/assimp/SceneCombiner.h
  68. 5 0
      thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h
  69. 6 0
      thirdparty/assimp/include/assimp/SmoothingGroups.h
  70. 5 2
      thirdparty/assimp/include/assimp/SmoothingGroups.inl
  71. 5 0
      thirdparty/assimp/include/assimp/SpatialSort.h
  72. 6 1
      thirdparty/assimp/include/assimp/StandardShapes.h
  73. 7 3
      thirdparty/assimp/include/assimp/StreamReader.h
  74. 6 2
      thirdparty/assimp/include/assimp/StreamWriter.h
  75. 6 1
      thirdparty/assimp/include/assimp/StringComparison.h
  76. 5 0
      thirdparty/assimp/include/assimp/StringUtils.h
  77. 4 1
      thirdparty/assimp/include/assimp/Subdivision.h
  78. 12 20
      thirdparty/assimp/include/assimp/TinyFormatter.h
  79. 8 59
      thirdparty/assimp/include/assimp/Vertex.h
  80. 5 0
      thirdparty/assimp/include/assimp/XMLTools.h
  81. 7 4
      thirdparty/assimp/include/assimp/aabb.h
  82. 4 0
      thirdparty/assimp/include/assimp/ai_assert.h
  83. 4 0
      thirdparty/assimp/include/assimp/anim.h
  84. 4 2
      thirdparty/assimp/include/assimp/camera.h
  85. 5 1
      thirdparty/assimp/include/assimp/cexport.h
  86. 6 0
      thirdparty/assimp/include/assimp/cfileio.h
  87. 5 1
      thirdparty/assimp/include/assimp/cimport.h
  88. 6 7
      thirdparty/assimp/include/assimp/color4.h
  89. 68 26
      thirdparty/assimp/include/assimp/color4.inl
  90. 30 13
      thirdparty/assimp/include/assimp/defs.h
  91. 5 1
      thirdparty/assimp/include/assimp/fast_atof.h
  92. 6 4
      thirdparty/assimp/include/assimp/importerdesc.h
  93. 5 1
      thirdparty/assimp/include/assimp/light.h
  94. 5 1
      thirdparty/assimp/include/assimp/material.h
  95. 132 133
      thirdparty/assimp/include/assimp/material.inl
  96. 6 9
      thirdparty/assimp/include/assimp/matrix3x3.h
  97. 37 33
      thirdparty/assimp/include/assimp/matrix3x3.inl
  98. 7 11
      thirdparty/assimp/include/assimp/matrix4x4.h
  99. 85 94
      thirdparty/assimp/include/assimp/matrix4x4.inl
  100. 30 10
      thirdparty/assimp/include/assimp/mesh.h

+ 3 - 0
modules/assimp/SCsub

@@ -72,6 +72,9 @@ env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X3D_IMPORTER'])
 env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER'])
 env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF2_IMPORTER'])
 env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED'])
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_M3D_IMPORTER'])
+env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MMD_IMPORTER'])
+
 
 if(env['platform'] == 'windows'):
     env_assimp.Append(CPPDEFINES=['PLATFORM_WINDOWS'])

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 548 - 367
modules/assimp/editor_scene_importer_assimp.cpp


+ 23 - 27
modules/assimp/editor_scene_importer_assimp.h

@@ -50,6 +50,7 @@
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/LogStream.hpp>
 #include <assimp/Logger.hpp>
+#include <map>
 
 #include "import_state.h"
 #include "import_utils.h"
@@ -72,7 +73,6 @@ public:
 class EditorSceneImporterAssimp : public EditorSceneImporter {
 private:
 	GDCLASS(EditorSceneImporterAssimp, EditorSceneImporter);
-	const String ASSIMP_FBX_KEY = "_$AssimpFbx$";
 
 	struct AssetImportAnimation {
 		enum Interpolation {
@@ -88,40 +88,32 @@ private:
 		float weight;
 	};
 
-	struct SkeletonHole { //nodes may be part of the skeleton by used by vertex
-		String name;
-		String parent;
-		Transform pose;
-		const aiNode *node;
-	};
-
-	void _calc_tangent_from_mesh(const aiMesh *ai_mesh, int i, int tri_index, int index, PoolColorArray::Write &w);
-	void _set_texture_mapping_mode(aiTextureMapMode *map_mode, Ref<Texture> texture);
+	Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices,
+			const aiNode *assimp_node, Ref<Skin> &skin,
+			Skeleton *&skeleton_assigned);
 
-	Ref<Mesh> _generate_mesh_from_surface_indices(ImportState &state, const Vector<int> &p_surface_indices, const aiNode *assimp_node, Skeleton *p_skeleton = NULL);
-
-	// utility for node creation
-	void attach_new_node(ImportState &state, Spatial *new_node, const aiNode *node, Node *parent_node, String Name, Transform &transform);
 	// simple object creation functions
-	void create_light(ImportState &state, RecursiveState &recursive_state);
-	void create_camera(ImportState &state, RecursiveState &recursive_state);
-	void create_bone(ImportState &state, RecursiveState &recursive_state);
+	Spatial *create_light(ImportState &state,
+			const String &node_name,
+			Transform &look_at_transform);
+	Spatial *create_camera(
+			ImportState &state,
+			const String &node_name,
+			Transform &look_at_transform);
 	// non recursive - linear so must not use recursive arguments
-	void create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *current_node, Node *parent_node, Transform node_transform);
-
+	MeshInstance *create_mesh(ImportState &state, const aiNode *assimp_node, const String &node_name, Node *active_node, Transform node_transform);
 	// recursive node generator
-	void _generate_node(ImportState &state, Skeleton *skeleton, const aiNode *assimp_node, Node *parent_node);
-	// runs after _generate_node as it must then use pre-created godot skeleton.
-	void generate_mesh_phase_from_skeletal_mesh(ImportState &state);
-	void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int p_track, int p_bake_fps, Ref<Animation> animation, float ticks_per_second, Skeleton *p_skeleton, const NodePath &p_path, const String &p_name);
+	void _generate_node(ImportState &state, const aiNode *assimp_node);
+	void _insert_animation_track(ImportState &scene, const aiAnimation *assimp_anim, int track_id,
+			int anim_fps, Ref<Animation> animation, float ticks_per_second,
+			Skeleton *skeleton, const NodePath &node_path,
+			const String &node_name, aiBone *track_bone);
 
 	void _import_animation(ImportState &state, int p_animation_index, int p_bake_fps);
-
+	Node *get_node_by_name(ImportState &state, String name);
+	aiBone *get_bone_from_stack(ImportState &state, aiString name);
 	Spatial *_generate_scene(const String &p_path, aiScene *scene, const uint32_t p_flags, int p_bake_fps, const int32_t p_max_bone_weights);
 
-	String _assimp_anim_string_to_string(const aiString &p_string) const;
-	String _assimp_raw_string_to_string(const aiString &p_string) const;
-	float _get_fbx_fps(int32_t time_mode, const aiScene *p_scene);
 	template <class T>
 	T _interpolate_track(const Vector<float> &p_times, const Vector<T> &p_values, float p_time, AssetImportAnimation::Interpolation p_interp);
 	void _register_project_setting_import(const String generic, const String import_setting_string, const Vector<String> &exts, List<String> *r_extensions, const bool p_enabled) const;
@@ -148,6 +140,10 @@ public:
 	virtual uint32_t get_import_flags() const;
 	virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
 	Ref<Image> load_image(ImportState &state, const aiScene *p_scene, String p_path);
+
+	static void RegenerateBoneStack(ImportState &state);
+
+	void RegenerateBoneStack(ImportState &state, aiMesh *mesh);
 };
 #endif
 #endif

+ 34 - 19
modules/assimp/import_state.h

@@ -52,28 +52,42 @@
 
 namespace AssimpImporter {
 /** Import state is for global scene import data
-	 * This makes the code simpler and contains useful lookups.
-	 */
+ * This makes the code simpler and contains useful lookups.
+ */
 struct ImportState {
 
 	String path;
+	Spatial *root;
 	const aiScene *assimp_scene;
 	uint32_t max_bone_weights;
 
-	Spatial *root;
 	Map<String, Ref<Mesh> > mesh_cache;
 	Map<int, Ref<Material> > material_cache;
 	Map<String, int> light_cache;
 	Map<String, int> camera_cache;
-	//Vector<Skeleton *> skeletons;
-	Map<Skeleton *, const Spatial *> armature_skeletons; // maps skeletons based on their armature nodes.
-	Map<const aiBone *, Skeleton *> bone_to_skeleton_lookup; // maps bones back into their skeleton
+
 	// very useful for when you need to ask assimp for the bone mesh
-	Map<String, Node *> node_map;
-	Map<const aiNode *, const Node *> assimp_node_map;
+
+	Map<const aiNode *, Node *> assimp_node_map;
 	Map<String, Ref<Image> > path_to_image_cache;
-	bool fbx; //for some reason assimp does some things different for FBX
+
+	// Generation 3 - determinisitic iteration
+	// to lower potential recursion errors
+	List<const aiNode *> nodes;
+	Map<const aiNode *, Spatial *> flat_node_map;
 	AnimationPlayer *animation_player;
+
+	// Generation 3 - deterministic armatures
+	// list of armature nodes - flat and simple to parse
+	// assimp node, node in godot
+	List<aiNode *> armature_nodes;
+	Map<const aiNode *, Skeleton *> armature_skeletons;
+	Map<aiBone *, Skeleton *> skeleton_bone_map;
+	// Generation 3 - deterministic bone handling
+	// bones from the stack are popped when found
+	// this means we can detect
+	// what bones are for other armatures
+	List<aiBone *> bone_stack;
 };
 
 struct AssimpImageData {
@@ -86,14 +100,15 @@ struct AssimpImageData {
 	* This makes the code easier to handle too and add extra arguments without breaking things
 	*/
 struct RecursiveState {
+	RecursiveState() {} // do not construct :)
 	RecursiveState(
 			Transform &_node_transform,
 			Skeleton *_skeleton,
 			Spatial *_new_node,
-			const String &_node_name,
-			const aiNode *_assimp_node,
+			String &_node_name,
+			aiNode *_assimp_node,
 			Node *_parent_node,
-			const aiBone *_bone) :
+			aiBone *_bone) :
 			node_transform(_node_transform),
 			skeleton(_skeleton),
 			new_node(_new_node),
@@ -102,13 +117,13 @@ struct RecursiveState {
 			parent_node(_parent_node),
 			bone(_bone) {}
 
-	Transform &node_transform;
-	Skeleton *skeleton;
-	Spatial *new_node;
-	const String &node_name;
-	const aiNode *assimp_node;
-	Node *parent_node;
-	const aiBone *bone;
+	Transform node_transform;
+	Skeleton *skeleton = NULL;
+	Spatial *new_node = NULL;
+	String node_name;
+	aiNode *assimp_node = NULL;
+	Node *parent_node = NULL;
+	aiBone *bone = NULL;
 };
 } // namespace AssimpImporter
 

+ 1 - 1
thirdparty/README.md

@@ -4,7 +4,7 @@
 ## assimp
 
 - Upstream: http://github.com/assimp/assimp
-- Version: git (1d565b0aab5a2ee00462f18c5b8a81f6a5454a48)
+- Version: git (308db73d0b3c2d1870cd3e465eaa283692a4cf23)
 - License: BSD-3-Clause
 
 

+ 15 - 2
thirdparty/assimp/code/Common/BaseImporter.cpp

@@ -67,7 +67,20 @@ using namespace Assimp;
 // Constructor to be privately used by Importer
 BaseImporter::BaseImporter() AI_NO_EXCEPT
 : m_progress() {
-    // nothing to do here
+    /**
+    * Assimp Importer
+    * unit conversions available
+    * if you need another measurment unit add it below.
+    * it's currently defined in assimp that we prefer meters.
+    *
+    * NOTE: Initialised here rather than in the header file
+    * to workaround a VS2013 bug with brace initialisers
+    * */
+    importerUnits[ImporterUnits::M] = 1.0;
+    importerUnits[ImporterUnits::CM] = 0.01;
+    importerUnits[ImporterUnits::MM] = 0.001;
+    importerUnits[ImporterUnits::INCHES] = 0.0254;
+    importerUnits[ImporterUnits::FEET] = 0.3048;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -85,7 +98,7 @@ void BaseImporter::UpdateImporterScale( Importer* pImp )
     double activeScale = importerScale * fileScale;
 
     // Set active scaling
-    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale);
+    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
 
     ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
 }

+ 60 - 101
thirdparty/assimp/code/Common/DefaultIOSystem.cpp

@@ -61,83 +61,66 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 
-// maximum path length
-// XXX http://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
-#ifdef PATH_MAX
-#   define PATHLIMIT PATH_MAX
-#else
-#   define PATHLIMIT 4096
+#ifdef _WIN32
+static std::wstring Utf8ToWide(const char* in)
+{
+    int size = MultiByteToWideChar(CP_UTF8, 0, in, -1, nullptr, 0);
+    // size includes terminating null; std::wstring adds null automatically
+    std::wstring out(static_cast<size_t>(size) - 1, L'\0');
+    MultiByteToWideChar(CP_UTF8, 0, in, -1, &out[0], size);
+    return out;
+}
+
+static std::string WideToUtf8(const wchar_t* in)
+{
+    int size = WideCharToMultiByte(CP_UTF8, 0, in, -1, nullptr, 0, nullptr, nullptr);
+    // size includes terminating null; std::string adds null automatically
+    std::string out(static_cast<size_t>(size) - 1, '\0');
+    WideCharToMultiByte(CP_UTF8, 0, in, -1, &out[0], size, nullptr, nullptr);
+    return out;
+}
 #endif
 
 // ------------------------------------------------------------------------------------------------
 // Tests for the existence of a file at the given path.
-bool DefaultIOSystem::Exists( const char* pFile) const
+bool DefaultIOSystem::Exists(const char* pFile) const
 {
 #ifdef _WIN32
-    wchar_t fileName16[PATHLIMIT];
-
-#ifndef WindowsStore
-    bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL) != 0;
-    if (isUnicode) {
-
-        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
-        struct __stat64 filestat;
-        if (0 != _wstat64(fileName16, &filestat)) {
-            return false;
-        }
-    } else {
-#endif
-        FILE* file = ::fopen(pFile, "rb");
-        if (!file)
-            return false;
-
-        ::fclose(file);
-#ifndef WindowsStore
+    struct __stat64 filestat;
+    if (_wstat64(Utf8ToWide(pFile).c_str(), &filestat) != 0) {
+        return false;
     }
-#endif
 #else
-    FILE* file = ::fopen( pFile, "rb");
-    if( !file)
+    FILE* file = ::fopen(pFile, "rb");
+    if (!file)
         return false;
 
-    ::fclose( file);
+    ::fclose(file);
 #endif
     return true;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Open a new file with a given path.
-IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
+IOStream* DefaultIOSystem::Open(const char* strFile, const char* strMode)
 {
-    ai_assert(NULL != strFile);
-    ai_assert(NULL != strMode);
+    ai_assert(strFile != nullptr);
+    ai_assert(strMode != nullptr);
     FILE* file;
 #ifdef _WIN32
-    wchar_t fileName16[PATHLIMIT];
-#ifndef WindowsStore
-    bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL) != 0;
-    if (isUnicode) {
-        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
-        std::string mode8(strMode);
-        file = ::_wfopen(fileName16, std::wstring(mode8.begin(), mode8.end()).c_str());
-    } else {
-#endif
-        file = ::fopen(strFile, strMode);
-#ifndef WindowsStore
-    }
-#endif
+    file = ::_wfopen(Utf8ToWide(strFile).c_str(), Utf8ToWide(strMode).c_str());
 #else
     file = ::fopen(strFile, strMode);
 #endif
-    if (nullptr == file)
+    if (!file)
         return nullptr;
 
-    return new DefaultIOStream(file, (std::string) strFile);
+    return new DefaultIOStream(file, strFile);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Closes the given file and releases all resources associated with it.
-void DefaultIOSystem::Close( IOStream* pFile)
+void DefaultIOSystem::Close(IOStream* pFile)
 {
     delete pFile;
 }
@@ -155,78 +138,56 @@ char DefaultIOSystem::getOsSeparator() const
 
 // ------------------------------------------------------------------------------------------------
 // IOSystem default implementation (ComparePaths isn't a pure virtual function)
-bool IOSystem::ComparePaths (const char* one, const char* second) const
+bool IOSystem::ComparePaths(const char* one, const char* second) const
 {
-    return !ASSIMP_stricmp(one,second);
+    return !ASSIMP_stricmp(one, second);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Convert a relative path into an absolute path
-inline static void MakeAbsolutePath (const char* in, char* _out)
+inline static std::string MakeAbsolutePath(const char* in)
 {
-    ai_assert(in && _out);
-#if defined( _MSC_VER ) || defined( __MINGW32__ )
-#ifndef WindowsStore
-    bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL) != 0;
-    if (isUnicode) {
-        wchar_t out16[PATHLIMIT];
-        wchar_t in16[PATHLIMIT];
-        MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, in, -1, out16, PATHLIMIT);
-        wchar_t* ret = ::_wfullpath(out16, in16, PATHLIMIT);
-        if (ret) {
-            WideCharToMultiByte(CP_UTF8, MB_PRECOMPOSED, out16, -1, _out, PATHLIMIT, nullptr, nullptr);
-        }
-        if (!ret) {
-            // preserve the input path, maybe someone else is able to fix
-            // the path before it is accessed (e.g. our file system filter)
-            ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
-            strcpy(_out, in);
-        }
-
-    } else {
-#endif
-        char* ret = :: _fullpath(_out, in, PATHLIMIT);
-        if (!ret) {
-            // preserve the input path, maybe someone else is able to fix
-            // the path before it is accessed (e.g. our file system filter)
-            ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
-            strcpy(_out, in);
-        }
-#ifndef WindowsStore
+    ai_assert(in);
+    std::string out;
+#ifdef _WIN32
+    wchar_t* ret = ::_wfullpath(nullptr, Utf8ToWide(in).c_str(), 0);
+    if (ret) {
+        out = WideToUtf8(ret);
+        free(ret);
     }
-#endif
 #else
-    // use realpath
-    char* ret = realpath(in, _out);
-    if(!ret) {
+    char* ret = realpath(in, nullptr);
+    if (ret) {
+        out = ret;
+        free(ret);
+    }
+#endif
+    if (!ret) {
         // preserve the input path, maybe someone else is able to fix
         // the path before it is accessed (e.g. our file system filter)
         ASSIMP_LOG_WARN_F("Invalid path: ", std::string(in));
-        strcpy(_out,in);
+        out = in;
     }
-#endif
+    return out;
 }
 
 // ------------------------------------------------------------------------------------------------
 // DefaultIOSystem's more specialized implementation
-bool DefaultIOSystem::ComparePaths (const char* one, const char* second) const
+bool DefaultIOSystem::ComparePaths(const char* one, const char* second) const
 {
     // chances are quite good both paths are formatted identically,
     // so we can hopefully return here already
-    if( !ASSIMP_stricmp(one,second) )
+    if (!ASSIMP_stricmp(one, second))
         return true;
 
-    char temp1[PATHLIMIT];
-    char temp2[PATHLIMIT];
-
-    MakeAbsolutePath (one, temp1);
-    MakeAbsolutePath (second, temp2);
+    std::string temp1 = MakeAbsolutePath(one);
+    std::string temp2 = MakeAbsolutePath(second);
 
-    return !ASSIMP_stricmp(temp1,temp2);
+    return !ASSIMP_stricmp(temp1, temp2);
 }
 
 // ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::fileName( const std::string &path )
+std::string DefaultIOSystem::fileName(const std::string& path)
 {
     std::string ret = path;
     std::size_t last = ret.find_last_of("\\/");
@@ -235,16 +196,16 @@ std::string DefaultIOSystem::fileName( const std::string &path )
 }
 
 // ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::completeBaseName( const std::string &path )
+std::string DefaultIOSystem::completeBaseName(const std::string& path)
 {
     std::string ret = fileName(path);
     std::size_t pos = ret.find_last_of('.');
-    if(pos != ret.npos) ret = ret.substr(0, pos);
+    if (pos != std::string::npos) ret = ret.substr(0, pos);
     return ret;
 }
 
 // ------------------------------------------------------------------------------------------------
-std::string DefaultIOSystem::absolutePath( const std::string &path )
+std::string DefaultIOSystem::absolutePath(const std::string& path)
 {
     std::string ret = path;
     std::size_t last = ret.find_last_of("\\/");
@@ -253,5 +214,3 @@ std::string DefaultIOSystem::absolutePath( const std::string &path )
 }
 
 // ------------------------------------------------------------------------------------------------
-
-#undef PATHLIMIT

+ 12 - 30
thirdparty/assimp/code/Common/Exporter.cpp

@@ -102,6 +102,8 @@ void ExportSceneX3D(const char*, IOSystem*, const aiScene*, const ExportProperti
 void ExportSceneFBX(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportSceneFBXA(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportScene3MF( const char*, IOSystem*, const aiScene*, const ExportProperties* );
+void ExportSceneM3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
+void ExportSceneA3D(const char*, IOSystem*, const aiScene*, const ExportProperties*);
 void ExportAssimp2Json(const char* , IOSystem*, const aiScene* , const Assimp::ExportProperties*);
 
 // ------------------------------------------------------------------------------------------------
@@ -179,6 +181,11 @@ Exporter::ExportFormatEntry gExporters[] =
     Exporter::ExportFormatEntry( "fbxa", "Autodesk FBX (ascii)", "fbx", &ExportSceneFBXA, 0 ),
 #endif
 
+#ifndef ASSIMP_BUILD_NO_M3D_EXPORTER
+    Exporter::ExportFormatEntry( "m3d", "Model 3D (binary)", "m3d", &ExportSceneM3D, 0 ),
+    Exporter::ExportFormatEntry( "a3d", "Model 3D (ascii)",  "m3d", &ExportSceneA3D, 0 ),
+#endif
+
 #ifndef ASSIMP_BUILD_NO_3MF_EXPORTER
     Exporter::ExportFormatEntry( "3mf", "The 3MF-File-Format", "3mf", &ExportScene3MF, 0 ),
 #endif
@@ -315,34 +322,6 @@ const aiExportDataBlob* Exporter::ExportToBlob( const aiScene* pScene, const cha
     return pimpl->blob;
 }
 
-// ------------------------------------------------------------------------------------------------
-bool IsVerboseFormat(const aiMesh* mesh) {
-    // avoid slow vector<bool> specialization
-    std::vector<unsigned int> seen(mesh->mNumVertices,0);
-    for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
-        const aiFace& f = mesh->mFaces[i];
-        for(unsigned int j = 0; j < f.mNumIndices; ++j) {
-            if(++seen[f.mIndices[j]] == 2) {
-                // found a duplicate index
-                return false;
-            }
-        }
-    }
-
-    return true;
-}
-
-// ------------------------------------------------------------------------------------------------
-bool IsVerboseFormat(const aiScene* pScene) {
-    for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
-        if(!IsVerboseFormat(pScene->mMeshes[i])) {
-            return false;
-        }
-    }
-
-    return true;
-}
-
 // ------------------------------------------------------------------------------------------------
 aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
         unsigned int pPreprocessing, const ExportProperties* pProperties) {
@@ -352,7 +331,7 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
     // format. They will likely not be aware that there is a flag in the scene to indicate
     // this, however. To avoid surprises and bug reports, we check for duplicates in
     // meshes upfront.
-    const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || IsVerboseFormat(pScene);
+    const bool is_verbose_format = !(pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) || MakeVerboseFormatProcess::IsVerboseFormat(pScene);
 
     pimpl->mProgressHandler->UpdateFileWrite(0, 4);
 
@@ -472,7 +451,10 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
                 }
 
                 ExportProperties emptyProperties;  // Never pass NULL ExportProperties so Exporters don't have to worry.
-                exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProperties ? pProperties : &emptyProperties);
+                ExportProperties* pProp = pProperties ? (ExportProperties*)pProperties : &emptyProperties;
+                                pProp->SetPropertyBool("bJoinIdenticalVertices", must_join_again);
+                                exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
+                exp.mExportFunction(pPath,pimpl->mIOSystem.get(),scenecopy.get(), pProp);
 
                 pimpl->mProgressHandler->UpdateFileWrite(4, 4);
             } catch (DeadlyExportError& err) {

+ 6 - 0
thirdparty/assimp/code/Common/ImporterRegistry.cpp

@@ -197,6 +197,9 @@ corresponding preprocessor flag to selectively disable formats.
 #ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
 #   include "MMD/MMDImporter.h"
 #endif
+#ifndef ASSIMP_BUILD_NO_M3D_IMPORTER
+#   include "M3D/M3DImporter.h"
+#endif
 #ifndef ASSIMP_BUILD_NO_STEP_IMPORTER
 #   include "Importer/StepFile/StepFileImporter.h"
 #endif
@@ -223,6 +226,9 @@ void GetImporterInstanceList(std::vector< BaseImporter* >& out)
 #if (!defined ASSIMP_BUILD_NO_3DS_IMPORTER)
     out.push_back( new Discreet3DSImporter());
 #endif
+#if (!defined ASSIMP_BUILD_NO_M3D_IMPORTER)
+    out.push_back( new M3DImporter());
+#endif
 #if (!defined ASSIMP_BUILD_NO_MD3_IMPORTER)
     out.push_back( new MD3Importer());
 #endif

+ 7 - 0
thirdparty/assimp/code/Common/PostStepRegistry.cpp

@@ -131,11 +131,15 @@ corresponding preprocessor flag to selectively disable steps.
 #if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
 #   include "PostProcessing/ScaleProcess.h"
 #endif
+#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
+#   include "PostProcessing/ArmaturePopulate.h"
+#endif
 #if (!defined ASSIMP_BUILD_NO_GENBOUNDINGBOXES_PROCESS)
 #   include "PostProcessing/GenBoundingBoxesProcess.h"
 #endif
 
 
+
 namespace Assimp {
 
 // ------------------------------------------------------------------------------------------------
@@ -180,6 +184,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
 #if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
     out.push_back( new ScaleProcess());
 #endif
+#if (!defined ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS)
+    out.push_back( new ArmaturePopulate());
+#endif
 #if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
     out.push_back( new PretransformVertices());
 #endif

+ 50 - 0
thirdparty/assimp/code/Common/SceneCombiner.cpp

@@ -1091,6 +1091,35 @@ void SceneCombiner::Copy( aiMesh** _dest, const aiMesh* src ) {
         aiFace& f = dest->mFaces[i];
         GetArrayCopy(f.mIndices,f.mNumIndices);
     }
+
+    // make a deep copy of all blend shapes
+    CopyPtrArray(dest->mAnimMeshes, dest->mAnimMeshes, dest->mNumAnimMeshes);
+}
+
+// ------------------------------------------------------------------------------------------------
+void SceneCombiner::Copy(aiAnimMesh** _dest, const aiAnimMesh* src) {
+    if (nullptr == _dest || nullptr == src) {
+        return;
+    }
+
+    aiAnimMesh* dest = *_dest = new aiAnimMesh();
+
+    // get a flat copy
+    ::memcpy(dest, src, sizeof(aiAnimMesh));
+
+    // and reallocate all arrays
+    GetArrayCopy(dest->mVertices, dest->mNumVertices);
+    GetArrayCopy(dest->mNormals, dest->mNumVertices);
+    GetArrayCopy(dest->mTangents, dest->mNumVertices);
+    GetArrayCopy(dest->mBitangents, dest->mNumVertices);
+
+    unsigned int n = 0;
+    while (dest->HasTextureCoords(n))
+        GetArrayCopy(dest->mTextureCoords[n++], dest->mNumVertices);
+
+    n = 0;
+    while (dest->HasVertexColors(n))
+        GetArrayCopy(dest->mColors[n++], dest->mNumVertices);
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1167,6 +1196,7 @@ void SceneCombiner::Copy( aiAnimation** _dest, const aiAnimation* src ) {
 
     // and reallocate all arrays
     CopyPtrArray( dest->mChannels, src->mChannels, dest->mNumChannels );
+    CopyPtrArray( dest->mMorphMeshChannels, src->mMorphMeshChannels, dest->mNumMorphMeshChannels );
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -1186,6 +1216,26 @@ void SceneCombiner::Copy(aiNodeAnim** _dest, const aiNodeAnim* src) {
     GetArrayCopy( dest->mRotationKeys, dest->mNumRotationKeys );
 }
 
+void SceneCombiner::Copy(aiMeshMorphAnim** _dest, const aiMeshMorphAnim* src) {
+    if ( nullptr == _dest || nullptr == src ) {
+        return;
+    }
+
+    aiMeshMorphAnim* dest = *_dest = new aiMeshMorphAnim();
+
+    // get a flat copy
+    ::memcpy(dest,src,sizeof(aiMeshMorphAnim));
+
+    // and reallocate all arrays
+    GetArrayCopy( dest->mKeys, dest->mNumKeys );
+    for (ai_uint i = 0; i < dest->mNumKeys;++i) {
+        dest->mKeys[i].mValues = new unsigned int[dest->mKeys[i].mNumValuesAndWeights];
+        dest->mKeys[i].mWeights = new double[dest->mKeys[i].mNumValuesAndWeights];
+        ::memcpy(dest->mKeys[i].mValues, src->mKeys[i].mValues, dest->mKeys[i].mNumValuesAndWeights * sizeof(unsigned int));
+        ::memcpy(dest->mKeys[i].mWeights, src->mKeys[i].mWeights, dest->mKeys[i].mNumValuesAndWeights * sizeof(double));
+    }
+}
+
 // ------------------------------------------------------------------------------------------------
 void SceneCombiner::Copy( aiCamera** _dest,const  aiCamera* src) {
     if ( nullptr == _dest || nullptr == src ) {

+ 5 - 9
thirdparty/assimp/code/Common/Version.cpp

@@ -46,8 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/scene.h>
 #include "ScenePrivate.h"
 
-static const unsigned int MajorVersion = 4;
-static const unsigned int MinorVersion = 1;
+#include "revision.h"
 
 // --------------------------------------------------------------------------------
 // Legal information string - don't remove this.
@@ -56,9 +55,9 @@ static const char* LEGAL_INFORMATION =
 "Open Asset Import Library (Assimp).\n"
 "A free C/C++ library to import various 3D file formats into applications\n\n"
 
-"(c) 2008-2017, assimp team\n"
+"(c) 2006-2019, assimp team\n"
 "License under the terms and conditions of the 3-clause BSD license\n"
-"http://assimp.sourceforge.net\n"
+"http://assimp.org\n"
 ;
 
 // ------------------------------------------------------------------------------------------------
@@ -70,13 +69,13 @@ ASSIMP_API const char*  aiGetLegalString  ()    {
 // ------------------------------------------------------------------------------------------------
 // Get Assimp minor version
 ASSIMP_API unsigned int aiGetVersionMinor ()    {
-    return MinorVersion;
+    return VER_MINOR;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Get Assimp major version
 ASSIMP_API unsigned int aiGetVersionMajor ()    {
-    return MajorVersion;
+    return VER_MAJOR;
 }
 
 // ------------------------------------------------------------------------------------------------
@@ -104,9 +103,6 @@ ASSIMP_API unsigned int aiGetCompileFlags ()    {
     return flags;
 }
 
-// include current build revision, which is even updated from time to time -- :-)
-#include "revision.h"
-
 // ------------------------------------------------------------------------------------------------
 ASSIMP_API unsigned int aiGetVersionRevision() {
     return GitVersion;

+ 9 - 9
thirdparty/assimp/code/Common/scene.cpp

@@ -44,23 +44,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 aiNode::aiNode()
 : mName("")
-, mParent(NULL)
+, mParent(nullptr)
 , mNumChildren(0)
-, mChildren(NULL)
+, mChildren(nullptr)
 , mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
+, mMeshes(nullptr)
+, mMetaData(nullptr) {
     // empty
 }
 
 aiNode::aiNode(const std::string& name)
 : mName(name)
-, mParent(NULL)
+, mParent(nullptr)
 , mNumChildren(0)
-, mChildren(NULL)
+, mChildren(nullptr)
 , mNumMeshes(0)
-, mMeshes(NULL)
-, mMetaData(NULL) {
+, mMeshes(nullptr)
+, mMetaData(nullptr) {
     // empty
 }
 
@@ -68,7 +68,7 @@ aiNode::aiNode(const std::string& name)
 aiNode::~aiNode() {
     // delete all children recursively
     // to make sure we won't crash if the data is invalid ...
-    if (mChildren && mNumChildren)
+    if (mNumChildren && mChildren)
     {
         for (unsigned int a = 0; a < mNumChildren; a++)
             delete mChildren[a];

+ 8 - 0
thirdparty/assimp/code/FBX/FBXCompileConfig.h

@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_FBX_COMPILECONFIG_H
 
 #include <map>
+#include <set>
 
 //
 #if _MSC_VER > 1500 || (defined __GNUC___)
@@ -54,16 +55,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   else
 #   define fbx_unordered_map map
 #   define fbx_unordered_multimap multimap
+#   define fbx_unordered_set set
+#   define fbx_unordered_multiset multiset
 #endif
 
 #ifdef ASSIMP_FBX_USE_UNORDERED_MULTIMAP
 #   include <unordered_map>
+#   include <unordered_set>
 #   if _MSC_VER > 1600
 #       define fbx_unordered_map unordered_map
 #       define fbx_unordered_multimap unordered_multimap
+#       define fbx_unordered_set unordered_set
+#       define fbx_unordered_multiset unordered_multiset
 #   else
 #       define fbx_unordered_map tr1::unordered_map
 #       define fbx_unordered_multimap tr1::unordered_multimap
+#       define fbx_unordered_set tr1::unordered_set
+#       define fbx_unordered_multiset tr1::unordered_multiset
 #   endif
 #endif
 

+ 229 - 116
thirdparty/assimp/code/FBX/FBXConverter.cpp

@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXImporter.h"
 
 #include <assimp/StringComparison.h>
+#include <assimp/MathFunctions.h>
 
 #include <assimp/scene.h>
 
@@ -67,7 +68,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <sstream>
 #include <iomanip>
 #include <cstdint>
-
+#include <iostream>
+#include <stdlib.h>
 
 namespace Assimp {
     namespace FBX {
@@ -76,7 +78,7 @@ namespace Assimp {
 
 #define MAGIC_NODE_TAG "_$AssimpFbx$"
 
-#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
+#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
 
         FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
         : defaultMaterialIndex()
@@ -95,6 +97,14 @@ namespace Assimp {
             // populate the node_anim_chain_bits map, which is needed
             // to determine which nodes need to be generated.
             ConvertAnimations();
+            // Embedded textures in FBX could be connected to nothing but to itself,
+            // for instance Texture -> Video connection only but not to the main graph,
+            // The idea here is to traverse all objects to find these Textures and convert them,
+            // so later during material conversion it will find converted texture in the textures_converted array.
+            if (doc.Settings().readTextures)
+            {
+                ConvertOrphantEmbeddedTextures();
+            }
             ConvertRootNode();
 
             if (doc.Settings().readAllMaterials) {
@@ -144,7 +154,7 @@ namespace Assimp {
             out->mRootNode->mName.Set(unique_name);
 
             // root has ID 0
-            ConvertNodes(0L, *out->mRootNode);
+            ConvertNodes(0L, out->mRootNode, out->mRootNode);
         }
 
         static std::string getAncestorBaseName(const aiNode* node)
@@ -178,8 +188,11 @@ namespace Assimp {
             GetUniqueName(original_name, unique_name);
             return unique_name;
         }
-
-        void FBXConverter::ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform) {
+        /// todo: pre-build node hierarchy
+        /// todo: get bone from stack
+        /// todo: make map of aiBone* to aiNode*
+        /// then update convert clusters to the new format
+        void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
             const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
 
             std::vector<aiNode*> nodes;
@@ -190,62 +203,69 @@ namespace Assimp {
 
             try {
                 for (const Connection* con : conns) {
-
                     // ignore object-property links
                     if (con->PropertyName().length()) {
-                        continue;
+                        // really important we document why this is ignored.
+                        FBXImporter::LogInfo("ignoring property link - no docs on why this is ignored");
+                        continue; //?
                     }
 
+                    // convert connection source object into Object base class
                     const Object* const object = con->SourceObject();
                     if (nullptr == object) {
-                        FBXImporter::LogWarn("failed to convert source object for Model link");
+                        FBXImporter::LogError("failed to convert source object for Model link");
                         continue;
                     }
 
+                    // FBX Model::Cube, Model::Bone001, etc elements
+                    // This detects if we can cast the object into this model structure.
                     const Model* const model = dynamic_cast<const Model*>(object);
 
                     if (nullptr != model) {
                         nodes_chain.clear();
                         post_nodes_chain.clear();
 
-                        aiMatrix4x4 new_abs_transform = parent_transform;
-
-                        std::string unique_name = MakeUniqueNodeName(model, parent);
-
+                        aiMatrix4x4 new_abs_transform = parent->mTransformation;
+                        std::string node_name = FixNodeName(model->Name());
                         // even though there is only a single input node, the design of
                         // assimp (or rather: the complicated transformation chain that
                         // is employed by fbx) means that we may need multiple aiNode's
                         // to represent a fbx node's transformation.
-                        const bool need_additional_node = GenerateTransformationNodeChain(*model, unique_name, nodes_chain, post_nodes_chain);
 
+
+                        // generate node transforms - this includes pivot data
+                        // if need_additional_node is true then you t
+                        const bool need_additional_node = GenerateTransformationNodeChain(*model, node_name, nodes_chain, post_nodes_chain);
+
+                        // assert that for the current node we must have at least a single transform
                         ai_assert(nodes_chain.size());
 
                         if (need_additional_node) {
-                            nodes_chain.push_back(new aiNode(unique_name));
+                            nodes_chain.push_back(new aiNode(node_name));
                         }
 
                         //setup metadata on newest node
                         SetupNodeMetadata(*model, *nodes_chain.back());
 
                         // link all nodes in a row
-                        aiNode* last_parent = &parent;
-                        for (aiNode* prenode : nodes_chain) {
-                            ai_assert(prenode);
+                        aiNode* last_parent = parent;
+                        for (aiNode* child : nodes_chain) {
+                            ai_assert(child);
 
-                            if (last_parent != &parent) {
+                            if (last_parent != parent) {
                                 last_parent->mNumChildren = 1;
                                 last_parent->mChildren = new aiNode*[1];
-                                last_parent->mChildren[0] = prenode;
+                                last_parent->mChildren[0] = child;
                             }
 
-                            prenode->mParent = last_parent;
-                            last_parent = prenode;
+                            child->mParent = last_parent;
+                            last_parent = child;
 
-                            new_abs_transform *= prenode->mTransformation;
+                            new_abs_transform *= child->mTransformation;
                         }
 
                         // attach geometry
-                        ConvertModel(*model, *nodes_chain.back(), new_abs_transform);
+                        ConvertModel(*model, nodes_chain.back(), root_node, new_abs_transform);
 
                         // check if there will be any child nodes
                         const std::vector<const Connection*>& child_conns
@@ -257,7 +277,7 @@ namespace Assimp {
                             for (aiNode* postnode : post_nodes_chain) {
                                 ai_assert(postnode);
 
-                                if (last_parent != &parent) {
+                                if (last_parent != parent) {
                                     last_parent->mNumChildren = 1;
                                     last_parent->mChildren = new aiNode*[1];
                                     last_parent->mChildren[0] = postnode;
@@ -279,15 +299,15 @@ namespace Assimp {
                             );
                         }
 
-                        // attach sub-nodes (if any)
-                        ConvertNodes(model->ID(), *last_parent, new_abs_transform);
+                        // recursion call - child nodes
+                        ConvertNodes(model->ID(), last_parent, root_node);
 
                         if (doc.Settings().readLights) {
-                            ConvertLights(*model, unique_name);
+                            ConvertLights(*model, node_name);
                         }
 
                         if (doc.Settings().readCameras) {
-                            ConvertCameras(*model, unique_name);
+                            ConvertCameras(*model, node_name);
                         }
 
                         nodes.push_back(nodes_chain.front());
@@ -296,11 +316,17 @@ namespace Assimp {
                 }
 
                 if (nodes.size()) {
-                    parent.mChildren = new aiNode*[nodes.size()]();
-                    parent.mNumChildren = static_cast<unsigned int>(nodes.size());
+                    parent->mChildren = new aiNode*[nodes.size()]();
+                    parent->mNumChildren = static_cast<unsigned int>(nodes.size());
 
-                    std::swap_ranges(nodes.begin(), nodes.end(), parent.mChildren);
+                    std::swap_ranges(nodes.begin(), nodes.end(), parent->mChildren);
                 }
+                else
+                {
+                    parent->mNumChildren = 0;
+                    parent->mChildren = nullptr;
+                }
+                
             }
             catch (std::exception&) {
                 Util::delete_fun<aiNode> deleter;
@@ -553,7 +579,7 @@ namespace Assimp {
                 return;
             }
 
-            const float angle_epsilon = 1e-6f;
+            const float angle_epsilon = Math::getEpsilon<float>();
 
             out = aiMatrix4x4();
 
@@ -694,7 +720,7 @@ namespace Assimp {
             std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
 
             // generate transformation matrices for all the different transformation components
-            const float zero_epsilon = 1e-6f;
+            const float zero_epsilon = Math::getEpsilon<float>();
             const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
 
             const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
@@ -802,7 +828,7 @@ namespace Assimp {
             // is_complex needs to be consistent with NeedsComplexTransformationChain()
             // or the interplay between this code and the animation converter would
             // not be guaranteed.
-            ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
+            //ai_assert(NeedsComplexTransformationChain(model) == ((chainBits & chainMaskComplex) != 0));
 
             // now, if we have more than just Translation, Scaling and Rotation,
             // we need to generate a full node chain to accommodate for assimp's
@@ -904,7 +930,8 @@ namespace Assimp {
             }
         }
 
-        void FBXConverter::ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform)
+        void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
+                                        const aiMatrix4x4 &absolute_transform)
         {
             const std::vector<const Geometry*>& geos = model.GetGeometry();
 
@@ -916,11 +943,12 @@ namespace Assimp {
                 const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(geo);
                 const LineGeometry* const line = dynamic_cast<const LineGeometry*>(geo);
                 if (mesh) {
-                    const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, node_global_transform, nd);
+                    const std::vector<unsigned int>& indices = ConvertMesh(*mesh, model, parent, root_node,
+                                                                           absolute_transform);
                     std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
                 }
                 else if (line) {
-                    const std::vector<unsigned int>& indices = ConvertLine(*line, model, node_global_transform, nd);
+                    const std::vector<unsigned int>& indices = ConvertLine(*line, model, parent, root_node);
                     std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
                 }
                 else {
@@ -929,15 +957,16 @@ namespace Assimp {
             }
 
             if (meshes.size()) {
-                nd.mMeshes = new unsigned int[meshes.size()]();
-                nd.mNumMeshes = static_cast<unsigned int>(meshes.size());
+                parent->mMeshes = new unsigned int[meshes.size()]();
+                parent->mNumMeshes = static_cast<unsigned int>(meshes.size());
 
-                std::swap_ranges(meshes.begin(), meshes.end(), nd.mMeshes);
+                std::swap_ranges(meshes.begin(), meshes.end(), parent->mMeshes);
             }
         }
 
-        std::vector<unsigned int> FBXConverter::ConvertMesh(const MeshGeometry& mesh, const Model& model,
-            const aiMatrix4x4& node_global_transform, aiNode& nd)
+        std::vector<unsigned int>
+        FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+                                  const aiMatrix4x4 &absolute_transform)
         {
             std::vector<unsigned int> temp;
 
@@ -961,18 +990,18 @@ namespace Assimp {
                 const MatIndexArray::value_type base = mindices[0];
                 for (MatIndexArray::value_type index : mindices) {
                     if (index != base) {
-                        return ConvertMeshMultiMaterial(mesh, model, node_global_transform, nd);
+                        return ConvertMeshMultiMaterial(mesh, model, parent, root_node, absolute_transform);
                     }
                 }
             }
 
             // faster code-path, just copy the data
-            temp.push_back(ConvertMeshSingleMaterial(mesh, model, node_global_transform, nd));
+            temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node));
             return temp;
         }
 
         std::vector<unsigned int> FBXConverter::ConvertLine(const LineGeometry& line, const Model& model,
-            const aiMatrix4x4& node_global_transform, aiNode& nd)
+                                                            aiNode *parent, aiNode *root_node)
         {
             std::vector<unsigned int> temp;
 
@@ -983,7 +1012,7 @@ namespace Assimp {
                 return temp;
             }
 
-            aiMesh* const out_mesh = SetupEmptyMesh(line, nd);
+            aiMesh* const out_mesh = SetupEmptyMesh(line, root_node);
             out_mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
 
             // copy vertices
@@ -1018,7 +1047,7 @@ namespace Assimp {
             return temp;
         }
 
-        aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode& nd)
+        aiMesh* FBXConverter::SetupEmptyMesh(const Geometry& mesh, aiNode *parent)
         {
             aiMesh* const out_mesh = new aiMesh();
             meshes.push_back(out_mesh);
@@ -1035,17 +1064,18 @@ namespace Assimp {
             }
             else
             {
-                out_mesh->mName = nd.mName;
+                out_mesh->mName = parent->mName;
             }
 
             return out_mesh;
         }
 
-        unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
-            const aiMatrix4x4& node_global_transform, aiNode& nd)
+        unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
+                                                             const aiMatrix4x4 &absolute_transform, aiNode *parent,
+                                                             aiNode *root_node)
         {
             const MatIndexArray& mindices = mesh.GetMaterialIndices();
-            aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
+            aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
 
             const std::vector<aiVector3D>& vertices = mesh.GetVertices();
             const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
@@ -1112,7 +1142,7 @@ namespace Assimp {
                         binormals = &tempBinormals;
                     }
                     else {
-                        binormals = NULL;
+                        binormals = nullptr;
                     }
                 }
 
@@ -1162,8 +1192,9 @@ namespace Assimp {
                 ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
             }
 
-            if (doc.Settings().readWeights && mesh.DeformerSkin() != NULL) {
-                ConvertWeights(out_mesh, model, mesh, node_global_transform, NO_MATERIAL_SEPARATION);
+            if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
+                ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, NO_MATERIAL_SEPARATION,
+                               nullptr);
             }
 
             std::vector<aiAnimMesh*> animMeshes;
@@ -1208,8 +1239,10 @@ namespace Assimp {
             return static_cast<unsigned int>(meshes.size() - 1);
         }
 
-        std::vector<unsigned int> FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
-            const aiMatrix4x4& node_global_transform, aiNode& nd)
+        std::vector<unsigned int>
+        FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
+                                               aiNode *root_node,
+                                               const aiMatrix4x4 &absolute_transform)
         {
             const MatIndexArray& mindices = mesh.GetMaterialIndices();
             ai_assert(mindices.size());
@@ -1220,7 +1253,7 @@ namespace Assimp {
             for (MatIndexArray::value_type index : mindices) {
                 if (had.find(index) == had.end()) {
 
-                    indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, node_global_transform, nd));
+                    indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node, absolute_transform));
                     had.insert(index);
                 }
             }
@@ -1228,18 +1261,18 @@ namespace Assimp {
             return indices;
         }
 
-        unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
-            MatIndexArray::value_type index,
-            const aiMatrix4x4& node_global_transform,
-            aiNode& nd)
+        unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
+                                                            MatIndexArray::value_type index,
+                                                            aiNode *parent, aiNode *root_node,
+                                                            const aiMatrix4x4 &absolute_transform)
         {
-            aiMesh* const out_mesh = SetupEmptyMesh(mesh, nd);
+            aiMesh* const out_mesh = SetupEmptyMesh(mesh, parent);
 
             const MatIndexArray& mindices = mesh.GetMaterialIndices();
             const std::vector<aiVector3D>& vertices = mesh.GetVertices();
             const std::vector<unsigned int>& faces = mesh.GetFaceIndexCounts();
 
-            const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != NULL;
+            const bool process_weights = doc.Settings().readWeights && mesh.DeformerSkin() != nullptr;
 
             unsigned int count_faces = 0;
             unsigned int count_vertices = 0;
@@ -1299,7 +1332,7 @@ namespace Assimp {
                         binormals = &tempBinormals;
                     }
                     else {
-                        binormals = NULL;
+                        binormals = nullptr;
                     }
                 }
 
@@ -1398,7 +1431,7 @@ namespace Assimp {
             ConvertMaterialForMesh(out_mesh, model, mesh, index);
 
             if (process_weights) {
-                ConvertWeights(out_mesh, model, mesh, node_global_transform, index, &reverseMapping);
+                ConvertWeights(out_mesh, model, mesh, absolute_transform, parent, root_node, index, &reverseMapping);
             }
 
             std::vector<aiAnimMesh*> animMeshes;
@@ -1448,10 +1481,10 @@ namespace Assimp {
             return static_cast<unsigned int>(meshes.size() - 1);
         }
 
-        void FBXConverter::ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
-            const aiMatrix4x4& node_global_transform,
-            unsigned int materialIndex,
-            std::vector<unsigned int>* outputVertStartIndices)
+        void FBXConverter::ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo,
+                                          const aiMatrix4x4 &absolute_transform,
+                                          aiNode *parent, aiNode *root_node, unsigned int materialIndex,
+                                          std::vector<unsigned int> *outputVertStartIndices)
         {
             ai_assert(geo.DeformerSkin());
 
@@ -1462,13 +1495,12 @@ namespace Assimp {
             const Skin& sk = *geo.DeformerSkin();
 
             std::vector<aiBone*> bones;
-            bones.reserve(sk.Clusters().size());
 
             const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
             ai_assert(no_mat_check || outputVertStartIndices);
 
             try {
-
+                // iterate over the sub deformers
                 for (const Cluster* cluster : sk.Clusters()) {
                     ai_assert(cluster);
 
@@ -1482,15 +1514,16 @@ namespace Assimp {
                     index_out_indices.clear();
                     out_indices.clear();
 
+
                     // now check if *any* of these weights is contained in the output mesh,
                     // taking notes so we don't need to do it twice.
                     for (WeightIndexArray::value_type index : indices) {
 
                         unsigned int count = 0;
                         const unsigned int* const out_idx = geo.ToOutputVertexIndex(index, count);
-                        // ToOutputVertexIndex only returns NULL if index is out of bounds
+                        // ToOutputVertexIndex only returns nullptr if index is out of bounds
                         // which should never happen
-                        ai_assert(out_idx != NULL);
+                        ai_assert(out_idx != nullptr);
 
                         index_out_indices.push_back(no_index_sentinel);
                         count_out_indices.push_back(0);
@@ -1519,68 +1552,107 @@ namespace Assimp {
                             }
                         }
                     }
-                    
+
                     // if we found at least one, generate the output bones
                     // XXX this could be heavily simplified by collecting the bone
                     // data in a single step.
-                    ConvertCluster(bones, model, *cluster, out_indices, index_out_indices,
-                            count_out_indices, node_global_transform);
+                    ConvertCluster(bones, cluster, out_indices, index_out_indices,
+                                   count_out_indices, absolute_transform, parent, root_node);
                 }
+
+                bone_map.clear();
             }
-            catch (std::exception&) {
+            catch (std::exception&e) {
                 std::for_each(bones.begin(), bones.end(), Util::delete_fun<aiBone>());
                 throw;
             }
 
             if (bones.empty()) {
+                out->mBones = nullptr;
+                out->mNumBones = 0;
                 return;
-            }
-
-            out->mBones = new aiBone*[bones.size()]();
-            out->mNumBones = static_cast<unsigned int>(bones.size());
+            } else {
+                out->mBones = new aiBone *[bones.size()]();
+                out->mNumBones = static_cast<unsigned int>(bones.size());
 
-            std::swap_ranges(bones.begin(), bones.end(), out->mBones);
+                std::swap_ranges(bones.begin(), bones.end(), out->mBones);
+            }
         }
 
-        void FBXConverter::ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
-            std::vector<size_t>& out_indices,
-            std::vector<size_t>& index_out_indices,
-            std::vector<size_t>& count_out_indices,
-            const aiMatrix4x4& node_global_transform)
+        const aiNode* FBXConverter::GetNodeByName( const aiString& name, aiNode *current_node )
         {
+            aiNode * iter = current_node;
+            //printf("Child count: %d", iter->mNumChildren);
+            return iter;
+        }
 
-            aiBone* const bone = new aiBone();
-            bones.push_back(bone);
+        void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+                                          std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
+                                          std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+                                          aiNode *parent, aiNode *root_node) {
+            ai_assert(cl); // make sure cluster valid
+            std::string deformer_name = cl->TargetNode()->Name();
+            aiString bone_name = aiString(FixNodeName(deformer_name));
 
-            bone->mName = FixNodeName(cl.TargetNode()->Name());
+            aiBone *bone = nullptr;
 
-            bone->mOffsetMatrix = cl.TransformLink();
-            bone->mOffsetMatrix.Inverse();
+            if (bone_map.count(deformer_name)) {
+                std::cout << "retrieved bone from lookup " << bone_name.C_Str() << ". Deformer: " << deformer_name
+                          << std::endl;
+                bone = bone_map[deformer_name];
+            } else {
+                std::cout << "created new bone " << bone_name.C_Str() << ". Deformer: " << deformer_name << std::endl;
+                bone = new aiBone();
+                bone->mName = bone_name;
 
-            bone->mOffsetMatrix = bone->mOffsetMatrix * node_global_transform;
+                // store local transform link for post processing
+                bone->mOffsetMatrix = cl->TransformLink();
+                bone->mOffsetMatrix.Inverse();
 
-            bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
-            aiVertexWeight* cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
+                aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
 
-            const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
-            const WeightArray& weights = cl.GetWeights();
+                bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
 
-            const size_t c = index_out_indices.size();
-            for (size_t i = 0; i < c; ++i) {
-                const size_t index_index = index_out_indices[i];
 
-                if (index_index == no_index_sentinel) {
-                    continue;
-                }
+                //
+                // Now calculate the aiVertexWeights
+                //
+
+                aiVertexWeight *cursor = nullptr;
+
+                bone->mNumWeights = static_cast<unsigned int>(out_indices.size());
+                cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
 
-                const size_t cc = count_out_indices[i];
-                for (size_t j = 0; j < cc; ++j) {
-                    aiVertexWeight& out_weight = *cursor++;
+                const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
+                const WeightArray& weights = cl->GetWeights();
 
-                    out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
-                    out_weight.mWeight = weights[i];
+                const size_t c = index_out_indices.size();
+                for (size_t i = 0; i < c; ++i) {
+                    const size_t index_index = index_out_indices[i];
+
+                    if (index_index == no_index_sentinel) {
+                        continue;
+                    }
+
+                    const size_t cc = count_out_indices[i];
+                    for (size_t j = 0; j < cc; ++j) {
+                        // cursor runs from first element relative to the start
+                        // or relative to the start of the next indexes.
+                        aiVertexWeight& out_weight = *cursor++;
+
+                        out_weight.mVertexId = static_cast<unsigned int>(out_indices[index_index + j]);
+                        out_weight.mWeight = weights[i];
+                    }
                 }
+
+                bone_map.insert(std::pair<const std::string, aiBone *>(deformer_name, bone));
             }
+
+            std::cout << "bone research: Indicies size: " << out_indices.size() << std::endl;
+
+            // lookup must be populated in case something goes wrong
+            // this also allocates bones to mesh instance outside
+            local_mesh_bones.push_back(bone);
         }
 
         void FBXConverter::ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -1710,7 +1782,7 @@ namespace Assimp {
                 bool textureReady = false; //tells if our texture is ready (if it was loaded or if it was found)
                 unsigned int index;
 
-                VideoMap::const_iterator it = textures_converted.find(media);
+                VideoMap::const_iterator it = textures_converted.find(*media);
                 if (it != textures_converted.end()) {
                     index = (*it).second;
                     textureReady = true;
@@ -1718,7 +1790,7 @@ namespace Assimp {
                 else {
                     if (media->ContentLength() > 0) {
                         index = ConvertVideo(*media);
-                        textures_converted[media] = index;
+                        textures_converted[*media] = index;
                         textureReady = true;
                     }
                 }
@@ -2242,13 +2314,13 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
             if (media != nullptr && media->ContentLength() > 0) {
                 unsigned int index;
 
-                VideoMap::const_iterator it = textures_converted.find(media);
+                VideoMap::const_iterator it = textures_converted.find(*media);
                 if (it != textures_converted.end()) {
                     index = (*it).second;
                 }
                 else {
                     index = ConvertVideo(*media);
-                    textures_converted[media] = index;
+                    textures_converted[*media] = index;
                 }
 
                 // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
@@ -2676,7 +2748,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
         // sanity check whether the input is ok
         static void validateAnimCurveNodes(const std::vector<const AnimationCurveNode*>& curves,
             bool strictMode) {
-            const Object* target(NULL);
+            const Object* target(nullptr);
             for (const AnimationCurveNode* node : curves) {
                 if (!target) {
                     target = node->Target();
@@ -2707,7 +2779,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
 #ifdef ASSIMP_BUILD_DEBUG
             validateAnimCurveNodes(curves, doc.Settings().strictMode);
 #endif
-            const AnimationCurveNode* curve_node = NULL;
+            const AnimationCurveNode* curve_node = nullptr;
             for (const AnimationCurveNode* node : curves) {
                 ai_assert(node);
 
@@ -2967,7 +3039,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
                 TransformationCompDefaultValue(comp)
                 );
 
-            const float epsilon = 1e-6f;
+            const float epsilon = Math::getEpsilon<float>();
             return (dyn_val - static_val).SquareLength() < epsilon;
         }
 
@@ -3555,7 +3627,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
             ai_assert(!out->mMeshes);
             ai_assert(!out->mNumMeshes);
 
-            // note: the trailing () ensures initialization with NULL - not
+            // note: the trailing () ensures initialization with nullptr - not
             // many C++ users seem to know this, so pointing it out to avoid
             // confusion why this code works.
 
@@ -3602,6 +3674,47 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
             }
         }
 
+        void FBXConverter::ConvertOrphantEmbeddedTextures()
+        {
+            // in C++14 it could be:
+            // for (auto&& [id, object] : objects)
+            for (auto&& id_and_object : doc.Objects())
+            {
+                auto&& id = std::get<0>(id_and_object);
+                auto&& object = std::get<1>(id_and_object);
+                // If an object doesn't have parent
+                if (doc.ConnectionsBySource().count(id) == 0)
+                {
+                    const Texture* realTexture = nullptr;
+                    try
+                    {
+                        const auto& element = object->GetElement();
+                        const Token& key = element.KeyToken();
+                        const char* obtype = key.begin();
+                        const size_t length = static_cast<size_t>(key.end() - key.begin());
+                        if (strncmp(obtype, "Texture", length) == 0)
+                        {
+                            const Texture* texture = static_cast<const Texture*>(object->Get());
+                            if (texture->Media() && texture->Media()->ContentLength() > 0)
+                            {
+                                realTexture = texture;
+                            }
+                        }
+                    }
+                    catch (...)
+                    {
+                        // do nothing
+                    }
+                    if (realTexture)
+                    {
+                        const Video* media = realTexture->Media();
+                        unsigned int index = ConvertVideo(*media);
+                        textures_converted[*media] = index;
+                    }
+                }
+            }
+        }
+
         // ------------------------------------------------------------------------------------------------
         void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
         {

+ 55 - 39
thirdparty/assimp/code/FBX/FBXConverter.h

@@ -76,16 +76,6 @@ namespace Assimp {
 namespace FBX {
 
 class Document;
-
-enum class FbxUnit {
-    cm = 0,
-    m,
-    km,
-    NumUnits,
-
-    Undefined
-};
-
 /** 
  *  Convert a FBX #Document to #aiScene
  *  @param out Empty scene to be populated
@@ -133,7 +123,7 @@ private:
 
     // ------------------------------------------------------------------------------------------------
     // collect and assign child nodes
-    void ConvertNodes(uint64_t id, aiNode& parent, const aiMatrix4x4& parent_transform = aiMatrix4x4());
+    void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
 
     // ------------------------------------------------------------------------------------------------
     void ConvertLights(const Model& model, const std::string &orig_name );
@@ -189,32 +179,35 @@ private:
     void SetupNodeMetadata(const Model& model, aiNode& nd);
 
     // ------------------------------------------------------------------------------------------------
-    void ConvertModel(const Model& model, aiNode& nd, const aiMatrix4x4& node_global_transform);
+    void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node,
+                      const aiMatrix4x4 &absolute_transform);
     
     // ------------------------------------------------------------------------------------------------
     // MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
-    std::vector<unsigned int> ConvertMesh(const MeshGeometry& mesh, const Model& model,
-        const aiMatrix4x4& node_global_transform, aiNode& nd);
+    std::vector<unsigned int>
+    ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+                const aiMatrix4x4 &absolute_transform);
 
     // ------------------------------------------------------------------------------------------------
     std::vector<unsigned int> ConvertLine(const LineGeometry& line, const Model& model,
-        const aiMatrix4x4& node_global_transform, aiNode& nd);
+                                          aiNode *parent, aiNode *root_node);
 
     // ------------------------------------------------------------------------------------------------
-    aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode& nd);
+    aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
 
     // ------------------------------------------------------------------------------------------------
-    unsigned int ConvertMeshSingleMaterial(const MeshGeometry& mesh, const Model& model,
-        const aiMatrix4x4& node_global_transform, aiNode& nd);
+    unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
+                                           const aiMatrix4x4 &absolute_transform, aiNode *parent,
+                                           aiNode *root_node);
 
     // ------------------------------------------------------------------------------------------------
-    std::vector<unsigned int> ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
-        const aiMatrix4x4& node_global_transform, aiNode& nd);
+    std::vector<unsigned int>
+    ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node,
+                             const aiMatrix4x4 &absolute_transform);
 
     // ------------------------------------------------------------------------------------------------
-    unsigned int ConvertMeshMultiMaterial(const MeshGeometry& mesh, const Model& model,
-        MatIndexArray::value_type index,
-        const aiMatrix4x4& node_global_transform, aiNode& nd);
+    unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index,
+                                          aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
 
     // ------------------------------------------------------------------------------------------------
     static const unsigned int NO_MATERIAL_SEPARATION = /* std::numeric_limits<unsigned int>::max() */
@@ -227,17 +220,17 @@ private:
     *  - outputVertStartIndices is only used when a material index is specified, it gives for
     *    each output vertex the DOM index it maps to.
     */
-    void ConvertWeights(aiMesh* out, const Model& model, const MeshGeometry& geo,
-        const aiMatrix4x4& node_global_transform = aiMatrix4x4(),
-        unsigned int materialIndex = NO_MATERIAL_SEPARATION,
-        std::vector<unsigned int>* outputVertStartIndices = NULL);
-
+    void ConvertWeights(aiMesh *out, const Model &model, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
+                        aiNode *parent = NULL, aiNode *root_node = NULL,
+                        unsigned int materialIndex = NO_MATERIAL_SEPARATION,
+                        std::vector<unsigned int> *outputVertStartIndices = NULL);
+    // lookup
+    static const aiNode* GetNodeByName( const aiString& name, aiNode *current_node );
     // ------------------------------------------------------------------------------------------------
-    void ConvertCluster(std::vector<aiBone*>& bones, const Model& /*model*/, const Cluster& cl,
-        std::vector<size_t>& out_indices,
-        std::vector<size_t>& index_out_indices,
-        std::vector<size_t>& count_out_indices,
-        const aiMatrix4x4& node_global_transform);
+    void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
+                        std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
+                        std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
+                        aiNode *parent, aiNode *root_node);
 
     // ------------------------------------------------------------------------------------------------
     void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
@@ -434,6 +427,10 @@ private:
     // copy generated meshes, animations, lights, cameras and textures to the output scene
     void TransferDataToScene();
 
+    // ------------------------------------------------------------------------------------------------
+    // FBX file could have embedded textures not connected to anything
+    void ConvertOrphantEmbeddedTextures();
+
 private:
     // 0: not assigned yet, others: index is value - 1
     unsigned int defaultMaterialIndex;
@@ -445,28 +442,47 @@ private:
     std::vector<aiCamera*> cameras;
     std::vector<aiTexture*> textures;
 
-    using MaterialMap = std::map<const Material*, unsigned int>;
+    using MaterialMap = std::fbx_unordered_map<const Material*, unsigned int>;
     MaterialMap materials_converted;
 
-    using VideoMap = std::map<const Video*, unsigned int>;
+    using VideoMap = std::fbx_unordered_map<const Video, unsigned int>;
     VideoMap textures_converted;
 
-    using MeshMap = std::map<const Geometry*, std::vector<unsigned int> >;
+    using MeshMap = std::fbx_unordered_map<const Geometry*, std::vector<unsigned int> >;
     MeshMap meshes_converted;
 
     // fixed node name -> which trafo chain components have animations?
-    using NodeAnimBitMap = std::map<std::string, unsigned int> ;
+    using NodeAnimBitMap = std::fbx_unordered_map<std::string, unsigned int> ;
     NodeAnimBitMap node_anim_chain_bits;
 
     // number of nodes with the same name
-    using NodeNameCache = std::unordered_map<std::string, unsigned int>;
+    using NodeNameCache = std::fbx_unordered_map<std::string, unsigned int>;
     NodeNameCache mNodeNames;
 
+    // Deformer name is not the same as a bone name - it does contain the bone name though :)
+    // Deformer names in FBX are always unique in an FBX file.
+    std::map<const std::string, aiBone *> bone_map;
+
     double anim_fps;
 
     aiScene* const out;
     const FBX::Document& doc;
-    FbxUnit mCurrentUnit;
+
+    static void BuildBoneList(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
+                             std::vector<aiBone*>& bones);
+
+    void BuildBoneStack(aiNode *current_node, const aiNode *root_node, const aiScene *scene,
+                   const std::vector<aiBone *> &bones,
+                   std::map<aiBone *, aiNode *> &bone_stack,
+                   std::vector<aiNode*> &node_stack );
+
+    static void BuildNodeList(aiNode *current_node, std::vector<aiNode *> &nodes);
+
+    static aiNode *GetNodeFromStack(const aiString &node_name, std::vector<aiNode *> &nodes);
+
+    static aiNode *GetArmatureRoot(aiNode *bone_node, std::vector<aiBone*> &bone_list);
+
+    static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones);
 };
 
 }

+ 37 - 2
thirdparty/assimp/code/FBX/FBXDocument.h

@@ -637,6 +637,20 @@ public:
         return ptr;
     }
 
+    bool operator==(const Video& other) const
+    {
+        return (
+               type == other.type
+            && relativeFileName == other.relativeFileName
+            && fileName == other.fileName
+        );
+    }
+
+    bool operator<(const Video& other) const
+    {
+        return std::tie(type, relativeFileName, fileName) < std::tie(other.type, other.relativeFileName, other.fileName);
+    }
+
 private:
     std::string type;
     std::string relativeFileName;
@@ -1005,10 +1019,10 @@ public:
 // during their entire lifetime (Document). FBX files have
 // up to many thousands of objects (most of which we never use),
 // so the memory overhead for them should be kept at a minimum.
-typedef std::map<uint64_t, LazyObject*> ObjectMap;
+typedef std::fbx_unordered_map<uint64_t, LazyObject*> ObjectMap;
 typedef std::fbx_unordered_map<std::string, std::shared_ptr<const PropertyTable> > PropertyTemplateMap;
 
-typedef std::multimap<uint64_t, const Connection*> ConnectionMap;
+typedef std::fbx_unordered_multimap<uint64_t, const Connection*> ConnectionMap;
 
 /** DOM class for global document settings, a single instance per document can
  *  be accessed via Document.Globals(). */
@@ -1177,4 +1191,25 @@ private:
 } // Namespace FBX
 } // Namespace Assimp
 
+namespace std
+{
+    template <>
+    struct hash<const Assimp::FBX::Video>
+    {
+        std::size_t operator()(const Assimp::FBX::Video& video) const
+        {
+            using std::size_t;
+            using std::hash;
+            using std::string;
+
+            size_t res = 17;
+            res = res * 31 + hash<string>()(video.Name());
+            res = res * 31 + hash<string>()(video.RelativeFilename());
+            res = res * 31 + hash<string>()(video.Type());
+
+            return res;
+        }
+    };
+}
+
 #endif // INCLUDED_AI_FBX_DOCUMENT_H

+ 1 - 5
thirdparty/assimp/code/FBX/FBXExportProperty.cpp

@@ -59,11 +59,7 @@ namespace FBX {
 
 FBXExportProperty::FBXExportProperty(bool v)
 : type('C')
-, data(1) {
-    data = {
-        uint8_t(v)
-    };
-}
+, data(1, uint8_t(v)) {}
 
 FBXExportProperty::FBXExportProperty(int16_t v)
 : type('Y')

+ 85 - 37
thirdparty/assimp/code/FBX/FBXExporter.cpp

@@ -67,6 +67,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <vector>
 #include <array>
 #include <unordered_set>
+#include <numeric>
 
 // RESOURCES:
 // https://code.blender.org/2013/08/fbx-binary-file-format-specification/
@@ -1005,6 +1006,9 @@ void FBXExporter::WriteObjects ()
     object_node.EndProperties(outstream, binary, indent);
     object_node.BeginChildren(outstream, binary, indent);
 
+    bool bJoinIdenticalVertices = mProperties->GetPropertyBool("bJoinIdenticalVertices", true);
+    std::vector<std::vector<int32_t>> vVertexIndice;//save vertex_indices as it is needed later
+
     // geometry (aiMesh)
     mesh_uids.clear();
     indent = 1;
@@ -1031,21 +1035,35 @@ void FBXExporter::WriteObjects ()
         std::vector<int32_t> vertex_indices;
         // map of vertex value to its index in the data vector
         std::map<aiVector3D,size_t> index_by_vertex_value;
-        int32_t index = 0;
-        for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
-            aiVector3D vtx = m->mVertices[vi];
-            auto elem = index_by_vertex_value.find(vtx);
-            if (elem == index_by_vertex_value.end()) {
-                vertex_indices.push_back(index);
-                index_by_vertex_value[vtx] = index;
-                flattened_vertices.push_back(vtx[0]);
-                flattened_vertices.push_back(vtx[1]);
-                flattened_vertices.push_back(vtx[2]);
-                ++index;
-            } else {
-                vertex_indices.push_back(int32_t(elem->second));
+        if(bJoinIdenticalVertices){
+            int32_t index = 0;
+            for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
+                aiVector3D vtx = m->mVertices[vi];
+                auto elem = index_by_vertex_value.find(vtx);
+                if (elem == index_by_vertex_value.end()) {
+                    vertex_indices.push_back(index);
+                    index_by_vertex_value[vtx] = index;
+                    flattened_vertices.push_back(vtx[0]);
+                    flattened_vertices.push_back(vtx[1]);
+                    flattened_vertices.push_back(vtx[2]);
+                    ++index;
+                } else {
+                    vertex_indices.push_back(int32_t(elem->second));
+                }
+            }
+        }
+        else { // do not join vertex, respect the export flag
+            vertex_indices.resize(m->mNumVertices);
+            std::iota(vertex_indices.begin(), vertex_indices.end(), 0);
+            for(unsigned int v = 0; v < m->mNumVertices; ++ v) {
+                aiVector3D vtx = m->mVertices[v];
+                flattened_vertices.push_back(vtx.x);
+                flattened_vertices.push_back(vtx.y);
+                flattened_vertices.push_back(vtx.z);
             }
         }
+        vVertexIndice.push_back(vertex_indices);
+
         FBX::Node::WritePropertyNode(
             "Vertices", flattened_vertices, outstream, binary, indent
         );
@@ -1116,6 +1134,51 @@ void FBXExporter::WriteObjects ()
             normals.End(outstream, binary, indent, true);
         }
 
+        // colors, if any
+        // TODO only one color channel currently
+        const int32_t colorChannelIndex = 0;
+        if (m->HasVertexColors(colorChannelIndex)) {
+            FBX::Node vertexcolors("LayerElementColor", int32_t(colorChannelIndex));
+            vertexcolors.Begin(outstream, binary, indent);
+            vertexcolors.DumpProperties(outstream, binary, indent);
+            vertexcolors.EndProperties(outstream, binary, indent);
+            vertexcolors.BeginChildren(outstream, binary, indent);
+            indent = 3;
+            FBX::Node::WritePropertyNode(
+                "Version", int32_t(101), outstream, binary, indent
+            );
+            char layerName[8];
+            sprintf(layerName, "COLOR_%d", colorChannelIndex);
+            FBX::Node::WritePropertyNode(
+                "Name", (const char*)layerName, outstream, binary, indent
+            );
+            FBX::Node::WritePropertyNode(
+                "MappingInformationType", "ByPolygonVertex",
+                outstream, binary, indent
+            );
+            FBX::Node::WritePropertyNode(
+                "ReferenceInformationType", "Direct",
+                outstream, binary, indent
+            );
+            std::vector<double> color_data;
+            color_data.reserve(4 * polygon_data.size());
+            for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
+                const aiFace &f = m->mFaces[fi];
+                for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
+                    const aiColor4D &c = m->mColors[colorChannelIndex][f.mIndices[pvi]];
+                    color_data.push_back(c.r);
+                    color_data.push_back(c.g);
+                    color_data.push_back(c.b);
+                    color_data.push_back(c.a);
+                }
+            }
+            FBX::Node::WritePropertyNode(
+                "Colors", color_data, outstream, binary, indent
+            );
+            indent = 2;
+            vertexcolors.End(outstream, binary, indent, true);
+        }
+        
         // uvs, if any
         for (size_t uvi = 0; uvi < m->GetNumUVChannels(); ++uvi) {
             if (m->mNumUVComponents[uvi] > 2) {
@@ -1209,6 +1272,11 @@ void FBXExporter::WriteObjects ()
         le.AddChild("Type", "LayerElementNormal");
         le.AddChild("TypedIndex", int32_t(0));
         layer.AddChild(le);
+        // TODO only 1 color channel currently
+        le = FBX::Node("LayerElement");
+        le.AddChild("Type", "LayerElementColor");
+        le.AddChild("TypedIndex", int32_t(0));
+        layer.AddChild(le);
         le = FBX::Node("LayerElement");
         le.AddChild("Type", "LayerElementMaterial");
         le.AddChild("TypedIndex", int32_t(0));
@@ -1221,7 +1289,7 @@ void FBXExporter::WriteObjects ()
 
         for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
         {
-            FBX::Node layerExtra("Layer", int32_t(1));
+            FBX::Node layerExtra("Layer", int32_t(lr));
             layerExtra.AddChild("Version", int32_t(100));
             FBX::Node leExtra("LayerElement");
             leExtra.AddChild("Type", "LayerElementUV");
@@ -1748,28 +1816,8 @@ void FBXExporter::WriteObjects ()
         // connect it
         connections.emplace_back("C", "OO", deformer_uid, mesh_uids[mi]);
 
-        // we will be indexing by vertex...
-        // but there might be a different number of "vertices"
-        // between assimp and our output FBX.
-        // this code is cut-and-pasted from the geometry section above...
-        // ideally this should not be so.
-        // ---
-        // index of original vertex in vertex data vector
-        std::vector<int32_t> vertex_indices;
-        // map of vertex value to its index in the data vector
-        std::map<aiVector3D,size_t> index_by_vertex_value;
-        int32_t index = 0;
-        for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
-            aiVector3D vtx = m->mVertices[vi];
-            auto elem = index_by_vertex_value.find(vtx);
-            if (elem == index_by_vertex_value.end()) {
-                vertex_indices.push_back(index);
-                index_by_vertex_value[vtx] = index;
-                ++index;
-            } else {
-                vertex_indices.push_back(int32_t(elem->second));
-            }
-        }
+        //computed before
+        std::vector<int32_t>& vertex_indices = vVertexIndice[mi];
 
         // TODO, FIXME: this won't work if anything is not in the bind pose.
         // for now if such a situation is detected, we throw an exception.
@@ -2435,7 +2483,7 @@ void FBXExporter::WriteModelNodes(
 void FBXExporter::WriteAnimationCurveNode(
     StreamWriterLE& outstream,
     int64_t uid,
-    std::string name, // "T", "R", or "S"
+    const std::string& name, // "T", "R", or "S"
     aiVector3D default_value,
     std::string property_name, // "Lcl Translation" etc
     int64_t layer_uid,

+ 1 - 1
thirdparty/assimp/code/FBX/FBXExporter.h

@@ -156,7 +156,7 @@ namespace Assimp
         void WriteAnimationCurveNode(
             StreamWriterLE& outstream,
             int64_t uid,
-            std::string name, // "T", "R", or "S"
+            const std::string& name, // "T", "R", or "S"
             aiVector3D default_value,
             std::string property_name, // "Lcl Translation" etc
             int64_t animation_layer_uid,

+ 102 - 115
thirdparty/assimp/code/FBX/FBXImporter.cpp

@@ -48,26 +48,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "FBXImporter.h"
 
-#include "FBXTokenizer.h"
+#include "FBXConverter.h"
+#include "FBXDocument.h"
 #include "FBXParser.h"
+#include "FBXTokenizer.h"
 #include "FBXUtil.h"
-#include "FBXDocument.h"
-#include "FBXConverter.h"
 
-#include <assimp/StreamReader.h>
 #include <assimp/MemoryIOWrapper.h>
-#include <assimp/Importer.hpp>
+#include <assimp/StreamReader.h>
 #include <assimp/importerdesc.h>
+#include <assimp/Importer.hpp>
 
 namespace Assimp {
 
-template<>
-const char* LogFunctions<FBXImporter>::Prefix() {
-    static auto prefix = "FBX: ";
-    return prefix;
+template <>
+const char *LogFunctions<FBXImporter>::Prefix() {
+	static auto prefix = "FBX: ";
+	return prefix;
 }
 
-}
+} // namespace Assimp
 
 using namespace Assimp;
 using namespace Assimp::Formatter;
@@ -76,136 +76,123 @@ using namespace Assimp::FBX;
 namespace {
 
 static const aiImporterDesc desc = {
-    "Autodesk FBX Importer",
-    "",
-    "",
-    "",
-    aiImporterFlags_SupportTextFlavour,
-    0,
-    0,
-    0,
-    0,
-    "fbx"
+	"Autodesk FBX Importer",
+	"",
+	"",
+	"",
+	aiImporterFlags_SupportTextFlavour,
+	0,
+	0,
+	0,
+	0,
+	"fbx"
 };
 }
 
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by #Importer
-FBXImporter::FBXImporter()
-{
+FBXImporter::FBXImporter() {
 }
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-FBXImporter::~FBXImporter()
-{
+FBXImporter::~FBXImporter() {
 }
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
-bool FBXImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
-    const std::string& extension = GetExtension(pFile);
-    if (extension == std::string( desc.mFileExtensions ) ) {
-        return true;
-    }
-
-    else if ((!extension.length() || checkSig) && pIOHandler)   {
-        // at least ASCII-FBX files usually have a 'FBX' somewhere in their head
-        const char* tokens[] = {"fbx"};
-        return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
-    }
-    return false;
+bool FBXImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
+	const std::string &extension = GetExtension(pFile);
+	if (extension == std::string(desc.mFileExtensions)) {
+		return true;
+	}
+
+	else if ((!extension.length() || checkSig) && pIOHandler) {
+		// at least ASCII-FBX files usually have a 'FBX' somewhere in their head
+		const char *tokens[] = { "fbx" };
+		return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
+	}
+	return false;
 }
 
 // ------------------------------------------------------------------------------------------------
 // List all extensions handled by this loader
-const aiImporterDesc* FBXImporter::GetInfo () const
-{
-    return &desc;
+const aiImporterDesc *FBXImporter::GetInfo() const {
+	return &desc;
 }
 
 // ------------------------------------------------------------------------------------------------
 // Setup configuration properties for the loader
-void FBXImporter::SetupProperties(const Importer* pImp)
-{
-    settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
-    settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
-    settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
-    settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
-    settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
-    settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
-    settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
-    settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
-    settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
-    settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
-    settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
-    settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
-    settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
+void FBXImporter::SetupProperties(const Importer *pImp) {
+	settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
+	settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
+	settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
+	settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
+	settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
+	settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
+	settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
+	settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
+	settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
+	settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
+	settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
+	settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
+	settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
 }
 
 // ------------------------------------------------------------------------------------------------
 // Imports the given file into the given scene structure.
-void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
-{
-    std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile,"rb"));
-    if (!stream) {
-        ThrowException("Could not open file for reading");
-    }
-
-    // read entire file into memory - no streaming for this, fbx
-    // files can grow large, but the assimp output data structure
-    // then becomes very large, too. Assimp doesn't support
-    // streaming for its output data structures so the net win with
-    // streaming input data would be very low.
-    std::vector<char> contents;
-    contents.resize(stream->FileSize()+1);
-    stream->Read( &*contents.begin(), 1, contents.size()-1 );
-    contents[ contents.size() - 1 ] = 0;
-    const char* const begin = &*contents.begin();
-
-    // broadphase tokenizing pass in which we identify the core
-    // syntax elements of FBX (brackets, commas, key:value mappings)
-    TokenList tokens;
-    try {
-
-        bool is_binary = false;
-        if (!strncmp(begin,"Kaydara FBX Binary",18)) {
-            is_binary = true;
-            TokenizeBinary(tokens,begin,contents.size());
-        }
-        else {
-            Tokenize(tokens,begin);
-        }
-
-        // use this information to construct a very rudimentary
-        // parse-tree representing the FBX scope structure
-        Parser parser(tokens, is_binary);
-
-        // take the raw parse-tree and convert it to a FBX DOM
-        Document doc(parser,settings);
-
-        FbxUnit unit(FbxUnit::cm);
-        if (settings.convertToMeters) {
-            unit = FbxUnit::m;
-        }
-
-        // convert the FBX DOM to aiScene
-        ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
-
-        // size relative to cm
-        float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
-
-        // Set FBX file scale is relative to CM must be converted to M for
-        // assimp universal format (M)
-        SetFileScale( size_relative_to_cm * 0.01f);
-
-        std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
-    }
-    catch(std::exception&) {
-        std::for_each(tokens.begin(),tokens.end(),Util::delete_fun<Token>());
-        throw;
-    }
+void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
+	std::unique_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
+	if (!stream) {
+		ThrowException("Could not open file for reading");
+	}
+
+	// read entire file into memory - no streaming for this, fbx
+	// files can grow large, but the assimp output data structure
+	// then becomes very large, too. Assimp doesn't support
+	// streaming for its output data structures so the net win with
+	// streaming input data would be very low.
+	std::vector<char> contents;
+	contents.resize(stream->FileSize() + 1);
+	stream->Read(&*contents.begin(), 1, contents.size() - 1);
+	contents[contents.size() - 1] = 0;
+	const char *const begin = &*contents.begin();
+
+	// broadphase tokenizing pass in which we identify the core
+	// syntax elements of FBX (brackets, commas, key:value mappings)
+	TokenList tokens;
+	try {
+
+		bool is_binary = false;
+		if (!strncmp(begin, "Kaydara FBX Binary", 18)) {
+			is_binary = true;
+			TokenizeBinary(tokens, begin, contents.size());
+		} else {
+			Tokenize(tokens, begin);
+		}
+
+		// use this information to construct a very rudimentary
+		// parse-tree representing the FBX scope structure
+		Parser parser(tokens, is_binary);
+
+		// take the raw parse-tree and convert it to a FBX DOM
+		Document doc(parser, settings);
+
+		// convert the FBX DOM to aiScene
+		ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
+
+		// size relative to cm
+		float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
+
+		// Set FBX file scale is relative to CM must be converted to M for
+		// assimp universal format (M)
+		SetFileScale(size_relative_to_cm * 0.01f);
+
+		std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
+	} catch (std::exception &) {
+		std::for_each(tokens.begin(), tokens.end(), Util::delete_fun<Token>());
+		throw;
+	}
 }
 
 #endif // !ASSIMP_BUILD_NO_FBX_IMPORTER

+ 8 - 12
thirdparty/assimp/code/FBX/FBXMeshGeometry.cpp

@@ -610,11 +610,11 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
     const std::string& ReferenceInformationType)
 {
     const size_t face_count = m_faces.size();
-    if(face_count <= 0)
+    if( 0 == face_count )
     {
         return;
     }
-
+    
     // materials are handled separately. First of all, they are assigned per-face
     // and not per polyvert. Secondly, ReferenceInformationType=IndexToDirect
     // has a slightly different meaning for materials.
@@ -625,16 +625,14 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
         if (materials_out.empty()) {
             FBXImporter::LogError(Formatter::format("expected material index, ignoring"));
             return;
-        }
-        else if (materials_out.size() > 1) {
+        } else if (materials_out.size() > 1) {
             FBXImporter::LogWarn(Formatter::format("expected only a single material index, ignoring all except the first one"));
             materials_out.clear();
         }
 
         materials_out.resize(m_vertices.size());
         std::fill(materials_out.begin(), materials_out.end(), materials_out.at(0));
-    }
-    else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
+    } else if (MappingInformationType == "ByPolygon" && ReferenceInformationType == "IndexToDirect") {
         materials_out.resize(face_count);
 
         if(materials_out.size() != face_count) {
@@ -643,18 +641,16 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
             );
             return;
         }
-    }
-    else {
+    } else {
         FBXImporter::LogError(Formatter::format("ignoring material assignments, access type not implemented: ")
             << MappingInformationType << "," << ReferenceInformationType);
     }
 }
 // ------------------------------------------------------------------------------------------------
 ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
-    : Geometry(id, element, name, doc)
-{
-    const Scope* sc = element.Compound();
-    if (!sc) {
+: Geometry(id, element, name, doc) {
+    const Scope *sc = element.Compound();
+    if (nullptr == sc) {
         DOMError("failed to read Geometry object (class: Shape), no data scope found");
     }
     const Element& Indexes = GetRequiredElement(*sc, "Indexes", &element);

+ 0 - 83
thirdparty/assimp/code/MMD/MMDCpp14.h

@@ -1,83 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#ifndef MMD_CPP14_H
-#define MMD_CPP14_H
-
-#include <cstddef>
-#include <memory>
-#include <type_traits>
-#include <utility>
-
-namespace mmd {
-    template<class T> struct _Unique_if {
-        typedef std::unique_ptr<T> _Single_object;
-    };
-
-    template<class T> struct _Unique_if<T[]> {
-        typedef std::unique_ptr<T[]> _Unknown_bound;
-    };
-
-    template<class T, size_t N> struct _Unique_if<T[N]> {
-        typedef void _Known_bound;
-    };
-
-    template<class T, class... Args>
-        typename _Unique_if<T>::_Single_object
-        make_unique(Args&&... args) {
-            return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-        }
-
-    template<class T>
-        typename _Unique_if<T>::_Unknown_bound
-        make_unique(size_t n) {
-            typedef typename std::remove_extent<T>::type U;
-            return std::unique_ptr<T>(new U[n]());
-        }
-
-    template<class T, class... Args>
-        typename _Unique_if<T>::_Known_bound
-        make_unique(Args&&...) = delete;
-}
-
-#endif

+ 0 - 372
thirdparty/assimp/code/MMD/MMDImporter.cpp

@@ -1,372 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2016, assimp team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-  copyright notice, this list of conditions and the
-  following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the
-  following disclaimer in the documentation and/or other
-  materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-  contributors may be used to endorse or promote products
-  derived from this software without specific prior
-  written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
-
-#include "MMD/MMDImporter.h"
-#include "MMD/MMDPmdParser.h"
-#include "MMD/MMDPmxParser.h"
-#include "MMD/MMDVmdParser.h"
-#include "PostProcessing/ConvertToLHProcess.h"
-
-#include <assimp/DefaultIOSystem.h>
-#include <assimp/Importer.hpp>
-#include <assimp/ai_assert.h>
-#include <assimp/scene.h>
-
-#include <fstream>
-#include <iomanip>
-#include <memory>
-
-static const aiImporterDesc desc = {"MMD Importer",
-                                    "",
-                                    "",
-                                    "surfaces supported?",
-                                    aiImporterFlags_SupportTextFlavour,
-                                    0,
-                                    0,
-                                    0,
-                                    0,
-                                    "pmx"};
-
-namespace Assimp {
-
-using namespace std;
-
-// ------------------------------------------------------------------------------------------------
-//  Default constructor
-MMDImporter::MMDImporter()
-: m_Buffer()
-, m_strAbsPath("") {
-    DefaultIOSystem io;
-    m_strAbsPath = io.getOsSeparator();
-}
-
-// ------------------------------------------------------------------------------------------------
-//  Destructor.
-MMDImporter::~MMDImporter() {
-    // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-//  Returns true, if file is an pmx file.
-bool MMDImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler,
-                          bool checkSig) const {
-  if (!checkSig) // Check File Extension
-  {
-    return SimpleExtensionCheck(pFile, "pmx");
-  } else // Check file Header
-  {
-    static const char *pTokens[] = {"PMX "};
-    return BaseImporter::SearchFileHeaderForToken(pIOHandler, pFile, pTokens, 1);
-  }
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc *MMDImporter::GetInfo() const { return &desc; }
-
-// ------------------------------------------------------------------------------------------------
-//  MMD import implementation
-void MMDImporter::InternReadFile(const std::string &file, aiScene *pScene,
-                                 IOSystem * /*pIOHandler*/) {
-  // Read file by istream
-  std::filebuf fb;
-  if (!fb.open(file, std::ios::in | std::ios::binary)) {
-    throw DeadlyImportError("Failed to open file " + file + ".");
-  }
-
-  std::istream fileStream(&fb);
-
-  // Get the file-size and validate it, throwing an exception when fails
-  fileStream.seekg(0, fileStream.end);
-  size_t fileSize = static_cast<size_t>(fileStream.tellg());
-  fileStream.seekg(0, fileStream.beg);
-
-  if (fileSize < sizeof(pmx::PmxModel)) {
-    throw DeadlyImportError(file + " is too small.");
-  }
-
-  pmx::PmxModel model;
-  model.Read(&fileStream);
-
-  CreateDataFromImport(&model, pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-void MMDImporter::CreateDataFromImport(const pmx::PmxModel *pModel,
-                                       aiScene *pScene) {
-  if (pModel == NULL) {
-    return;
-  }
-
-  aiNode *pNode = new aiNode;
-  if (!pModel->model_name.empty()) {
-    pNode->mName.Set(pModel->model_name);
-  }
-
-  pScene->mRootNode = pNode;
-
-  pNode = new aiNode;
-  pScene->mRootNode->addChildren(1, &pNode);
-  pNode->mName.Set(string(pModel->model_name) + string("_mesh"));
-
-  // split mesh by materials
-  pNode->mNumMeshes = pModel->material_count;
-  pNode->mMeshes = new unsigned int[pNode->mNumMeshes];
-  for (unsigned int index = 0; index < pNode->mNumMeshes; index++) {
-    pNode->mMeshes[index] = index;
-  }
-
-  pScene->mNumMeshes = pModel->material_count;
-  pScene->mMeshes = new aiMesh *[pScene->mNumMeshes];
-  for (unsigned int i = 0, indexStart = 0; i < pScene->mNumMeshes; i++) {
-    const int indexCount = pModel->materials[i].index_count;
-
-    pScene->mMeshes[i] = CreateMesh(pModel, indexStart, indexCount);
-    pScene->mMeshes[i]->mName = pModel->materials[i].material_name;
-    pScene->mMeshes[i]->mMaterialIndex = i;
-    indexStart += indexCount;
-  }
-
-  // create node hierarchy for bone position
-  std::unique_ptr<aiNode *[]> ppNode(new aiNode *[pModel->bone_count]);
-  for (auto i = 0; i < pModel->bone_count; i++) {
-    ppNode[i] = new aiNode(pModel->bones[i].bone_name);
-  }
-
-  for (auto i = 0; i < pModel->bone_count; i++) {
-    const pmx::PmxBone &bone = pModel->bones[i];
-
-    if (bone.parent_index < 0) {
-      pScene->mRootNode->addChildren(1, ppNode.get() + i);
-    } else {
-      ppNode[bone.parent_index]->addChildren(1, ppNode.get() + i);
-
-      aiVector3D v3 = aiVector3D(
-          bone.position[0] - pModel->bones[bone.parent_index].position[0],
-          bone.position[1] - pModel->bones[bone.parent_index].position[1],
-          bone.position[2] - pModel->bones[bone.parent_index].position[2]);
-      aiMatrix4x4::Translation(v3, ppNode[i]->mTransformation);
-    }
-  }
-
-  // create materials
-  pScene->mNumMaterials = pModel->material_count;
-  pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
-  for (unsigned int i = 0; i < pScene->mNumMaterials; i++) {
-    pScene->mMaterials[i] = CreateMaterial(&pModel->materials[i], pModel);
-  }
-
-  // Convert everything to OpenGL space
-  MakeLeftHandedProcess convertProcess;
-  convertProcess.Execute(pScene);
-
-  FlipUVsProcess uvFlipper;
-  uvFlipper.Execute(pScene);
-
-  FlipWindingOrderProcess windingFlipper;
-  windingFlipper.Execute(pScene);
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh *MMDImporter::CreateMesh(const pmx::PmxModel *pModel,
-                                const int indexStart, const int indexCount) {
-  aiMesh *pMesh = new aiMesh;
-
-  pMesh->mNumVertices = indexCount;
-
-  pMesh->mNumFaces = indexCount / 3;
-  pMesh->mFaces = new aiFace[pMesh->mNumFaces];
-
-  const int numIndices = 3; // triangular face
-  for (unsigned int index = 0; index < pMesh->mNumFaces; index++) {
-    pMesh->mFaces[index].mNumIndices = numIndices;
-    unsigned int *indices = new unsigned int[numIndices];
-    indices[0] = numIndices * index;
-    indices[1] = numIndices * index + 1;
-    indices[2] = numIndices * index + 2;
-    pMesh->mFaces[index].mIndices = indices;
-  }
-
-  pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
-  pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
-  pMesh->mTextureCoords[0] = new aiVector3D[pMesh->mNumVertices];
-  pMesh->mNumUVComponents[0] = 2;
-
-  // additional UVs
-  for (int i = 1; i <= pModel->setting.uv; i++) {
-    pMesh->mTextureCoords[i] = new aiVector3D[pMesh->mNumVertices];
-    pMesh->mNumUVComponents[i] = 4;
-  }
-
-  map<int, vector<aiVertexWeight>> bone_vertex_map;
-
-  // fill in contents and create bones
-  for (int index = 0; index < indexCount; index++) {
-    const pmx::PmxVertex *v =
-        &pModel->vertices[pModel->indices[indexStart + index]];
-    const float *position = v->position;
-    pMesh->mVertices[index].Set(position[0], position[1], position[2]);
-    const float *normal = v->normal;
-
-    pMesh->mNormals[index].Set(normal[0], normal[1], normal[2]);
-    pMesh->mTextureCoords[0][index].x = v->uv[0];
-    pMesh->mTextureCoords[0][index].y = v->uv[1];
-
-    for (int i = 1; i <= pModel->setting.uv; i++) {
-      // TODO: wrong here? use quaternion transform?
-      pMesh->mTextureCoords[i][index].x = v->uva[i][0];
-      pMesh->mTextureCoords[i][index].y = v->uva[i][1];
-    }
-
-    // handle bone map
-    const auto vsBDEF1_ptr =
-        dynamic_cast<pmx::PmxVertexSkinningBDEF1 *>(v->skinning.get());
-    const auto vsBDEF2_ptr =
-        dynamic_cast<pmx::PmxVertexSkinningBDEF2 *>(v->skinning.get());
-    const auto vsBDEF4_ptr =
-        dynamic_cast<pmx::PmxVertexSkinningBDEF4 *>(v->skinning.get());
-    const auto vsSDEF_ptr =
-        dynamic_cast<pmx::PmxVertexSkinningSDEF *>(v->skinning.get());
-    switch (v->skinning_type) {
-    case pmx::PmxVertexSkinningType::BDEF1:
-      bone_vertex_map[vsBDEF1_ptr->bone_index].push_back(
-          aiVertexWeight(index, 1.0));
-      break;
-    case pmx::PmxVertexSkinningType::BDEF2:
-      bone_vertex_map[vsBDEF2_ptr->bone_index1].push_back(
-          aiVertexWeight(index, vsBDEF2_ptr->bone_weight));
-      bone_vertex_map[vsBDEF2_ptr->bone_index2].push_back(
-          aiVertexWeight(index, 1.0f - vsBDEF2_ptr->bone_weight));
-      break;
-    case pmx::PmxVertexSkinningType::BDEF4:
-      bone_vertex_map[vsBDEF4_ptr->bone_index1].push_back(
-          aiVertexWeight(index, vsBDEF4_ptr->bone_weight1));
-      bone_vertex_map[vsBDEF4_ptr->bone_index2].push_back(
-          aiVertexWeight(index, vsBDEF4_ptr->bone_weight2));
-      bone_vertex_map[vsBDEF4_ptr->bone_index3].push_back(
-          aiVertexWeight(index, vsBDEF4_ptr->bone_weight3));
-      bone_vertex_map[vsBDEF4_ptr->bone_index4].push_back(
-          aiVertexWeight(index, vsBDEF4_ptr->bone_weight4));
-      break;
-    case pmx::PmxVertexSkinningType::SDEF: // TODO: how to use sdef_c, sdef_r0,
-                                           // sdef_r1?
-      bone_vertex_map[vsSDEF_ptr->bone_index1].push_back(
-          aiVertexWeight(index, vsSDEF_ptr->bone_weight));
-      bone_vertex_map[vsSDEF_ptr->bone_index2].push_back(
-          aiVertexWeight(index, 1.0f - vsSDEF_ptr->bone_weight));
-      break;
-    case pmx::PmxVertexSkinningType::QDEF:
-      const auto vsQDEF_ptr =
-          dynamic_cast<pmx::PmxVertexSkinningQDEF *>(v->skinning.get());
-      bone_vertex_map[vsQDEF_ptr->bone_index1].push_back(
-          aiVertexWeight(index, vsQDEF_ptr->bone_weight1));
-      bone_vertex_map[vsQDEF_ptr->bone_index2].push_back(
-          aiVertexWeight(index, vsQDEF_ptr->bone_weight2));
-      bone_vertex_map[vsQDEF_ptr->bone_index3].push_back(
-          aiVertexWeight(index, vsQDEF_ptr->bone_weight3));
-      bone_vertex_map[vsQDEF_ptr->bone_index4].push_back(
-          aiVertexWeight(index, vsQDEF_ptr->bone_weight4));
-      break;
-    }
-  }
-
-  // make all bones for each mesh
-  // assign bone weights to skinned bones (otherwise just initialize)
-  auto bone_ptr_ptr = new aiBone *[pModel->bone_count];
-  pMesh->mNumBones = pModel->bone_count;
-  pMesh->mBones = bone_ptr_ptr;
-  for (auto ii = 0; ii < pModel->bone_count; ++ii) {
-    auto pBone = new aiBone;
-    const auto &pmxBone = pModel->bones[ii];
-    pBone->mName = pmxBone.bone_name;
-    aiVector3D pos(pmxBone.position[0], pmxBone.position[1], pmxBone.position[2]);
-    aiMatrix4x4::Translation(-pos, pBone->mOffsetMatrix);
-    auto it = bone_vertex_map.find(ii);
-    if (it != bone_vertex_map.end()) {
-      pBone->mNumWeights = static_cast<unsigned int>(it->second.size());
-      pBone->mWeights = new aiVertexWeight[pBone->mNumWeights];
-      for (unsigned int j = 0; j < pBone->mNumWeights; j++) {
-          pBone->mWeights[j] = it->second[j];
-      }
-    }
-    bone_ptr_ptr[ii] = pBone;
-  }
-
-  return pMesh;
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMaterial *MMDImporter::CreateMaterial(const pmx::PmxMaterial *pMat,
-                                        const pmx::PmxModel *pModel) {
-  aiMaterial *mat = new aiMaterial();
-  aiString name(pMat->material_english_name);
-  mat->AddProperty(&name, AI_MATKEY_NAME);
-
-  aiColor3D diffuse(pMat->diffuse[0], pMat->diffuse[1], pMat->diffuse[2]);
-  mat->AddProperty(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
-  aiColor3D specular(pMat->specular[0], pMat->specular[1], pMat->specular[2]);
-  mat->AddProperty(&specular, 1, AI_MATKEY_COLOR_SPECULAR);
-  aiColor3D ambient(pMat->ambient[0], pMat->ambient[1], pMat->ambient[2]);
-  mat->AddProperty(&ambient, 1, AI_MATKEY_COLOR_AMBIENT);
-
-  float opacity = pMat->diffuse[3];
-  mat->AddProperty(&opacity, 1, AI_MATKEY_OPACITY);
-  float shininess = pMat->specularlity;
-  mat->AddProperty(&shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
-
-  if(pMat->diffuse_texture_index >= 0) {
-      aiString texture_path(pModel->textures[pMat->diffuse_texture_index]);
-      mat->AddProperty(&texture_path, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
-  }
-
-  int mapping_uvwsrc = 0;
-  mat->AddProperty(&mapping_uvwsrc, 1,
-                   AI_MATKEY_UVWSRC(aiTextureType_DIFFUSE, 0));
-
-  return mat;
-}
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif // !! ASSIMP_BUILD_NO_MMD_IMPORTER

+ 0 - 96
thirdparty/assimp/code/MMD/MMDImporter.h

@@ -1,96 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2016, assimp team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-  copyright notice, this list of conditions and the
-  following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the
-  following disclaimer in the documentation and/or other
-  materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-  contributors may be used to endorse or promote products
-  derived from this software without specific prior
-  written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#ifndef MMD_FILE_IMPORTER_H_INC
-#define MMD_FILE_IMPORTER_H_INC
-
-#include <assimp/BaseImporter.h>
-#include "MMDPmxParser.h"
-#include <assimp/material.h>
-#include <vector>
-
-struct aiMesh;
-
-namespace Assimp {
-
-// ------------------------------------------------------------------------------------------------
-/// \class  MMDImporter
-/// \brief  Imports MMD a pmx/pmd/vmd file
-// ------------------------------------------------------------------------------------------------
-class MMDImporter : public BaseImporter {
-public:
-    /// \brief  Default constructor
-    MMDImporter();
-
-    /// \brief  Destructor
-    ~MMDImporter();
-
-public:
-    /// \brief  Returns whether the class can handle the format of the given file.
-    /// \remark See BaseImporter::CanRead() for details.
-    bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
-
-private:
-    //! \brief  Appends the supported extension.
-    const aiImporterDesc* GetInfo () const;
-
-    //! \brief  File import implementation.
-    void InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
-
-    //! \brief  Create the data from imported content.
-    void CreateDataFromImport(const pmx::PmxModel* pModel, aiScene* pScene);
-
-    //! \brief Create the mesh
-    aiMesh* CreateMesh(const pmx::PmxModel* pModel, const int indexStart, const int indexCount);
-
-    //! \brief Create the material
-    aiMaterial* CreateMaterial(const pmx::PmxMaterial* pMat, const pmx::PmxModel* pModel);
-
-private:
-    //! Data buffer
-    std::vector<char> m_Buffer;
-    //! Absolute pathname of model in file system
-    std::string m_strAbsPath;
-};
-
-// ------------------------------------------------------------------------------------------------
-
-} // Namespace Assimp
-
-#endif

+ 0 - 597
thirdparty/assimp/code/MMD/MMDPmdParser.h

@@ -1,597 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include "MMDCpp14.h"
-
-namespace pmd
-{
-	class PmdHeader
-	{
-	public:
-		std::string name;
-		std::string name_english;
-		std::string comment;
-		std::string comment_english;
-
-		bool Read(std::ifstream* stream)
-		{
-			char buffer[256];
-			stream->read(buffer, 20);
-			name = std::string(buffer);
-			stream->read(buffer, 256);
-			comment = std::string(buffer);
-			return true;
-		}
-
-		bool ReadExtension(std::ifstream* stream)
-		{
-			char buffer[256];
-			stream->read(buffer, 20);
-			name_english = std::string(buffer);
-			stream->read(buffer, 256);
-			comment_english = std::string(buffer);
-			return true;
-		}
-	};
-
-	class PmdVertex
-	{
-	public:
-		float position[3];
-
-		float normal[3];
-
-		float uv[2];
-
-		uint16_t bone_index[2];
-
-		uint8_t bone_weight;
-
-		bool edge_invisible;
-
-		bool Read(std::ifstream* stream)
-		{
-			stream->read((char*) position, sizeof(float) * 3);
-			stream->read((char*) normal, sizeof(float) * 3);
-			stream->read((char*) uv, sizeof(float) * 2);
-			stream->read((char*) bone_index, sizeof(uint16_t) * 2);
-			stream->read((char*) &bone_weight, sizeof(uint8_t));
-			stream->read((char*) &edge_invisible, sizeof(uint8_t));
-			return true;
-		}
-	};
-
-	class PmdMaterial
-	{
-	public:
-		float diffuse[4];
-		float power;
-		float specular[3];
-		float ambient[3];
-		uint8_t toon_index;
-		uint8_t edge_flag;
-		uint32_t index_count;
-		std::string texture_filename;
-		std::string sphere_filename;
-
-		bool Read(std::ifstream* stream)
-		{
-			char buffer[20];
-			stream->read((char*) &diffuse, sizeof(float) * 4);
-			stream->read((char*) &power, sizeof(float));
-			stream->read((char*) &specular, sizeof(float) * 3);
-			stream->read((char*) &ambient, sizeof(float) * 3);
-			stream->read((char*) &toon_index, sizeof(uint8_t));
-			stream->read((char*) &edge_flag, sizeof(uint8_t));
-			stream->read((char*) &index_count, sizeof(uint32_t));
-			stream->read((char*) &buffer, sizeof(char) * 20);
-			char* pstar = strchr(buffer, '*');
-			if (NULL == pstar)
-			{
-				texture_filename = std::string(buffer);
-				sphere_filename.clear();
-			}
-			else {
-				*pstar = 0;
-				texture_filename = std::string(buffer);
-				sphere_filename = std::string(pstar+1);
-			}
-			return true;
-		}
-	};
-
-	enum class BoneType : uint8_t
-	{
-		Rotation,
-		RotationAndMove,
-		IkEffector,
-		Unknown,
-		IkEffectable,
-		RotationEffectable,
-		IkTarget,
-		Invisible,
-		Twist,
-		RotationMovement
-	};
-
-	class PmdBone
-	{
-	public:
-		std::string name;
-		std::string name_english;
-		uint16_t parent_bone_index;
-		uint16_t tail_pos_bone_index;
-		BoneType bone_type;
-		uint16_t ik_parent_bone_index;
-		float bone_head_pos[3];
-
-		void Read(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read(buffer, 20);
-			name = std::string(buffer);
-			stream->read((char*) &parent_bone_index, sizeof(uint16_t));
-			stream->read((char*) &tail_pos_bone_index, sizeof(uint16_t));
-			stream->read((char*) &bone_type, sizeof(uint8_t));
-			stream->read((char*) &ik_parent_bone_index, sizeof(uint16_t));
-			stream->read((char*) &bone_head_pos, sizeof(float) * 3);
-		}
-
-		void ReadExpantion(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read(buffer, 20);
-			name_english = std::string(buffer);
-		}
-	};
-
-	class PmdIk
-	{
-	public:
-		uint16_t ik_bone_index;
-		uint16_t target_bone_index;
-		uint16_t interations;
-		float angle_limit;
-		std::vector<uint16_t> ik_child_bone_index;
-
-		void Read(std::istream *stream)
-		{
-			stream->read((char *) &ik_bone_index, sizeof(uint16_t));
-			stream->read((char *) &target_bone_index, sizeof(uint16_t));
-			uint8_t ik_chain_length;
-			stream->read((char*) &ik_chain_length, sizeof(uint8_t));
-			stream->read((char *) &interations, sizeof(uint16_t));
-			stream->read((char *) &angle_limit, sizeof(float));
-			ik_child_bone_index.resize(ik_chain_length);
-			for (int i = 0; i < ik_chain_length; i++)
-			{
-				stream->read((char *) &ik_child_bone_index[i], sizeof(uint16_t));
-			}
-		}
-	};
-
-	class PmdFaceVertex
-	{
-	public:
-		int vertex_index;
-		float position[3];
-
-		void Read(std::istream *stream)
-		{
-			stream->read((char *) &vertex_index, sizeof(int));
-			stream->read((char *) position, sizeof(float) * 3);
-		}
-	};
-
-	enum class FaceCategory : uint8_t
-	{
-		Base,
-		Eyebrow,
-		Eye,
-		Mouth,
-		Other
-	};
-
-	class PmdFace
-	{
-	public:
-		std::string name;
-		FaceCategory type;
-		std::vector<PmdFaceVertex> vertices;
-		std::string name_english;
-
-		void Read(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read(buffer, 20);
-			name = std::string(buffer);
-			int vertex_count;
-			stream->read((char*) &vertex_count, sizeof(int));
-			stream->read((char*) &type, sizeof(uint8_t));
-			vertices.resize(vertex_count);
-			for (int i = 0; i < vertex_count; i++)
-			{
-				vertices[i].Read(stream);
-			}
-		}
-
-		void ReadExpantion(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read(buffer, 20);
-			name_english = std::string(buffer);
-		}
-	};
-
-	class PmdBoneDispName
-	{
-	public:
-		std::string bone_disp_name;
-		std::string bone_disp_name_english;
-
-		void Read(std::istream *stream)
-		{
-			char buffer[50];
-			stream->read(buffer, 50);
-			bone_disp_name = std::string(buffer);
-			bone_disp_name_english.clear();
-		}
-		void ReadExpantion(std::istream *stream)
-		{
-			char buffer[50];
-			stream->read(buffer, 50);
-			bone_disp_name_english = std::string(buffer);
-		}
-	};
-
-	class PmdBoneDisp
-	{
-	public:
-		uint16_t bone_index;
-		uint8_t bone_disp_index;
-
-		void Read(std::istream *stream)
-		{
-			stream->read((char*) &bone_index, sizeof(uint16_t));
-			stream->read((char*) &bone_disp_index, sizeof(uint8_t));
-		}
-	};
-
-	enum class RigidBodyShape : uint8_t
-	{
-		Sphere = 0,
-		Box = 1,
-		Cpusel = 2
-	};
-
-	enum class RigidBodyType : uint8_t
-	{
-		BoneConnected = 0,
-		Physics = 1,
-		ConnectedPhysics = 2
-	};
-
-	class PmdRigidBody
-	{
-	public:
-		std::string name;
-		uint16_t related_bone_index;
-		uint8_t group_index;
-		uint16_t mask;
-		RigidBodyShape shape;
-		float size[3];
-		float position[3];
-		float orientation[3];
-		float weight;
-		float linear_damping;
-		float anglar_damping;
-		float restitution;
-		float friction;
-		RigidBodyType rigid_type;
-
-		void Read(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read(buffer, sizeof(char) * 20);
-			name = (std::string(buffer));
-			stream->read((char*) &related_bone_index, sizeof(uint16_t));
-			stream->read((char*) &group_index, sizeof(uint8_t));
-			stream->read((char*) &mask, sizeof(uint16_t));
-			stream->read((char*) &shape, sizeof(uint8_t));
-			stream->read((char*) size, sizeof(float) * 3);
-			stream->read((char*) position, sizeof(float) * 3);
-			stream->read((char*) orientation, sizeof(float) * 3);
-			stream->read((char*) &weight, sizeof(float));
-			stream->read((char*) &linear_damping, sizeof(float));
-			stream->read((char*) &anglar_damping, sizeof(float));
-			stream->read((char*) &restitution, sizeof(float));
-			stream->read((char*) &friction, sizeof(float));
-			stream->read((char*) &rigid_type, sizeof(char));
-		}
-	};
-
-	class PmdConstraint
-	{
-	public:
-		std::string name;
-		uint32_t rigid_body_index_a;
-		uint32_t rigid_body_index_b;
-		float position[3];
-		float orientation[3];
-		float linear_lower_limit[3];
-		float linear_upper_limit[3];
-		float angular_lower_limit[3];
-		float angular_upper_limit[3];
-		float linear_stiffness[3];
-		float angular_stiffness[3];
-
-		void Read(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read(buffer, 20);
-			name = std::string(buffer);
-			stream->read((char *) &rigid_body_index_a, sizeof(uint32_t));
-			stream->read((char *) &rigid_body_index_b, sizeof(uint32_t));
-			stream->read((char *) position, sizeof(float) * 3);
-			stream->read((char *) orientation, sizeof(float) * 3);
-			stream->read((char *) linear_lower_limit, sizeof(float) * 3);
-			stream->read((char *) linear_upper_limit, sizeof(float) * 3);
-			stream->read((char *) angular_lower_limit, sizeof(float) * 3);
-			stream->read((char *) angular_upper_limit, sizeof(float) * 3);
-			stream->read((char *) linear_stiffness, sizeof(float) * 3);
-			stream->read((char *) angular_stiffness, sizeof(float) * 3);
-		}
-	};
-
-	class PmdModel
-	{
-	public:
-		float version;
-		PmdHeader header;
-		std::vector<PmdVertex> vertices;
-		std::vector<uint16_t> indices;
-		std::vector<PmdMaterial> materials;
-		std::vector<PmdBone> bones;
-		std::vector<PmdIk> iks;
-		std::vector<PmdFace> faces;
-		std::vector<uint16_t> faces_indices;
-		std::vector<PmdBoneDispName> bone_disp_name;
-		std::vector<PmdBoneDisp> bone_disp;
-		std::vector<std::string> toon_filenames;
-		std::vector<PmdRigidBody> rigid_bodies;
-		std::vector<PmdConstraint> constraints;
-
-		static std::unique_ptr<PmdModel> LoadFromFile(const char *filename)
-		{
-			std::ifstream stream(filename, std::ios::binary);
-			if (stream.fail())
-			{
-				std::cerr << "could not open \"" << filename << "\"" << std::endl;
-				return nullptr;
-			}
-			auto result = LoadFromStream(&stream);
-			stream.close();
-			return result;
-		}
-
-		static std::unique_ptr<PmdModel> LoadFromStream(std::ifstream *stream)
-		{
-			auto result = mmd::make_unique<PmdModel>();
-			char buffer[100];
-
-			// magic
-			char magic[3];
-			stream->read(magic, 3);
-			if (magic[0] != 'P' || magic[1] != 'm' || magic[2] != 'd')
-			{
-				std::cerr << "invalid file" << std::endl;
-				return nullptr;
-			}
-
-			// version
-			stream->read((char*) &(result->version), sizeof(float));
-			if (result ->version != 1.0f)
-			{
-				std::cerr << "invalid version" << std::endl;
-				return nullptr;
-			}
-
-			// header
-			result->header.Read(stream);
-
-			// vertices
-			uint32_t vertex_num;
-			stream->read((char*) &vertex_num, sizeof(uint32_t));
-			result->vertices.resize(vertex_num);
-			for (uint32_t i = 0; i < vertex_num; i++)
-			{
-				result->vertices[i].Read(stream);
-			}
-
-			// indices
-			uint32_t index_num;
-			stream->read((char*) &index_num, sizeof(uint32_t));
-			result->indices.resize(index_num);
-			for (uint32_t i = 0; i < index_num; i++)
-			{
-				stream->read((char*) &result->indices[i], sizeof(uint16_t));
-			}
-
-			// materials
-			uint32_t material_num;
-			stream->read((char*) &material_num, sizeof(uint32_t));
-			result->materials.resize(material_num);
-			for (uint32_t i = 0; i < material_num; i++)
-			{
-				result->materials[i].Read(stream);
-			}
-
-			// bones
-			uint16_t bone_num;
-			stream->read((char*) &bone_num, sizeof(uint16_t));
-			result->bones.resize(bone_num);
-			for (uint32_t i = 0; i < bone_num; i++)
-			{
-				result->bones[i].Read(stream);
-			}
-
-			// iks
-			uint16_t ik_num;
-			stream->read((char*) &ik_num, sizeof(uint16_t));
-			result->iks.resize(ik_num);
-			for (uint32_t i = 0; i < ik_num; i++)
-			{
-				result->iks[i].Read(stream);
-			}
-
-			// faces
-			uint16_t face_num;
-			stream->read((char*) &face_num, sizeof(uint16_t));
-			result->faces.resize(face_num);
-			for (uint32_t i = 0; i < face_num; i++)
-			{
-				result->faces[i].Read(stream);
-			}
-
-			// face frames
-			uint8_t face_frame_num;
-			stream->read((char*) &face_frame_num, sizeof(uint8_t));
-			result->faces_indices.resize(face_frame_num);
-			for (uint32_t i = 0; i < face_frame_num; i++)
-			{
-				stream->read((char*) &result->faces_indices[i], sizeof(uint16_t));
-			}
-
-			// bone names
-			uint8_t bone_disp_num;
-			stream->read((char*) &bone_disp_num, sizeof(uint8_t));
-			result->bone_disp_name.resize(bone_disp_num);
-			for (uint32_t i = 0; i < bone_disp_num; i++)
-			{
-				result->bone_disp_name[i].Read(stream);
-			}
-
-			// bone frame
-			uint32_t bone_frame_num;
-			stream->read((char*) &bone_frame_num, sizeof(uint32_t));
-			result->bone_disp.resize(bone_frame_num);
-			for (uint32_t i = 0; i < bone_frame_num; i++)
-			{
-				result->bone_disp[i].Read(stream);
-			}
-
-			// english name
-			bool english;
-			stream->read((char*) &english, sizeof(char));
-			if (english)
-			{
-				result->header.ReadExtension(stream);
-				for (uint32_t i = 0; i < bone_num; i++)
-				{
-					result->bones[i].ReadExpantion(stream);
-				}
-				for (uint32_t i = 0; i < face_num; i++)
-				{
-					if (result->faces[i].type == pmd::FaceCategory::Base)
-					{
-						continue;
-					}
-					result->faces[i].ReadExpantion(stream);
-				}
-				for (uint32_t i = 0; i < result->bone_disp_name.size(); i++)
-				{
-					result->bone_disp_name[i].ReadExpantion(stream);
-				}
-			}
-
-			// toon textures
-			if (stream->peek() == std::ios::traits_type::eof())
-			{
-				result->toon_filenames.clear();
-			}
-			else {
-				result->toon_filenames.resize(10);
-				for (uint32_t i = 0; i < 10; i++)
-				{
-					stream->read(buffer, 100);
-					result->toon_filenames[i] = std::string(buffer);
-				}
-			}
-
-			// physics
-			if (stream->peek() == std::ios::traits_type::eof())
-			{
-				result->rigid_bodies.clear();
-				result->constraints.clear();
-			}
-			else {
-				uint32_t rigid_body_num;
-				stream->read((char*) &rigid_body_num, sizeof(uint32_t));
-				result->rigid_bodies.resize(rigid_body_num);
-				for (uint32_t i = 0; i < rigid_body_num; i++)
-				{
-					result->rigid_bodies[i].Read(stream);
-				}
-				uint32_t constraint_num;
-				stream->read((char*) &constraint_num, sizeof(uint32_t));
-				result->constraints.resize(constraint_num);
-				for (uint32_t i = 0; i < constraint_num; i++)
-				{
-					result->constraints[i].Read(stream);
-				}
-			}
-
-			if (stream->peek() != std::ios::traits_type::eof())
-			{
-				std::cerr << "there is unknown data" << std::endl;
-			}
-
-			return result;
-		}
-	};
-}

+ 0 - 608
thirdparty/assimp/code/MMD/MMDPmxParser.cpp

@@ -1,608 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#include <utility>
-#include "MMDPmxParser.h"
-#include <assimp/StringUtils.h>
-#ifdef ASSIMP_USE_HUNTER
-#  include <utf8/utf8.h>
-#else
-#  include "../contrib/utf8cpp/source/utf8.h"
-#endif
-#include <assimp/Exceptional.h>
-
-namespace pmx
-{
-	int ReadIndex(std::istream *stream, int size)
-	{
-		switch (size)
-		{
-		case 1:
-			uint8_t tmp8;
-			stream->read((char*) &tmp8, sizeof(uint8_t));
-			if (255 == tmp8)
-			{
-				return -1;
-			}
-			else {
-				return (int) tmp8;
-			}
-		case 2:
-			uint16_t tmp16;
-			stream->read((char*) &tmp16, sizeof(uint16_t));
-			if (65535 == tmp16)
-			{
-				return -1;
-			}
-			else {
-				return (int) tmp16;
-			}
-		case 4:
-			int tmp32;
-			stream->read((char*) &tmp32, sizeof(int));
-			return tmp32;
-		default:
-			return -1;
-		}
-	}
-
-	std::string ReadString(std::istream *stream, uint8_t encoding)
-	{
-		int size;
-		stream->read((char*) &size, sizeof(int));
-		std::vector<char> buffer;
-		if (size == 0)
-		{
-			return std::string("");
-		}
-		buffer.reserve(size);
-		stream->read((char*) buffer.data(), size);
-		if (encoding == 0)
-		{
-			// UTF16 to UTF8
-			const uint16_t* sourceStart = (uint16_t*)buffer.data();
-			const unsigned int targetSize = size * 3; // enough to encode
-			char *targetStart = new char[targetSize];
-            std::memset(targetStart, 0, targetSize * sizeof(char));
-            
-            utf8::utf16to8( sourceStart, sourceStart + size/2, targetStart );
-
-			std::string result(targetStart);
-            delete [] targetStart;
-			return result;
-		}
-		else
-		{
-			// the name is already UTF8
-			return std::string((const char*)buffer.data(), size);
-		}
-	}
-
-	void PmxSetting::Read(std::istream *stream)
-	{
-		uint8_t count;
-		stream->read((char*) &count, sizeof(uint8_t));
-		if (count < 8)
-		{
-			throw DeadlyImportError("MMD: invalid size");
-		}
-		stream->read((char*) &encoding, sizeof(uint8_t));
-		stream->read((char*) &uv, sizeof(uint8_t));
-		stream->read((char*) &vertex_index_size, sizeof(uint8_t));
-		stream->read((char*) &texture_index_size, sizeof(uint8_t));
-		stream->read((char*) &material_index_size, sizeof(uint8_t));
-		stream->read((char*) &bone_index_size, sizeof(uint8_t));
-		stream->read((char*) &morph_index_size, sizeof(uint8_t));
-		stream->read((char*) &rigidbody_index_size, sizeof(uint8_t));
-		uint8_t temp;
-		for (int i = 8; i < count; i++)
-		{
-			stream->read((char*)&temp, sizeof(uint8_t));
-		}
-	}
-
-	void PmxVertexSkinningBDEF1::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_index = ReadIndex(stream, setting->bone_index_size);
-	}
-
-	void PmxVertexSkinningBDEF2::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->bone_weight, sizeof(float));
-	}
-
-	void PmxVertexSkinningBDEF4::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->bone_weight1, sizeof(float));
-		stream->read((char*) &this->bone_weight2, sizeof(float));
-		stream->read((char*) &this->bone_weight3, sizeof(float));
-		stream->read((char*) &this->bone_weight4, sizeof(float));
-	}
-
-	void PmxVertexSkinningSDEF::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->bone_weight, sizeof(float));
-		stream->read((char*) this->sdef_c, sizeof(float) * 3);
-		stream->read((char*) this->sdef_r0, sizeof(float) * 3);
-		stream->read((char*) this->sdef_r1, sizeof(float) * 3);
-	}
-
-	void PmxVertexSkinningQDEF::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_index1 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index2 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index3 = ReadIndex(stream, setting->bone_index_size);
-		this->bone_index4 = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->bone_weight1, sizeof(float));
-		stream->read((char*) &this->bone_weight2, sizeof(float));
-		stream->read((char*) &this->bone_weight3, sizeof(float));
-		stream->read((char*) &this->bone_weight4, sizeof(float));
-	}
-
-	void PmxVertex::Read(std::istream *stream, PmxSetting *setting)
-	{
-		stream->read((char*) this->position, sizeof(float) * 3);
-		stream->read((char*) this->normal, sizeof(float) * 3);
-		stream->read((char*) this->uv, sizeof(float) * 2);
-		for (int i = 0; i < setting->uv; ++i)
-		{
-			stream->read((char*) this->uva[i], sizeof(float) * 4);
-		}
-		stream->read((char*) &this->skinning_type, sizeof(PmxVertexSkinningType));
-		switch (this->skinning_type)
-		{
-		case PmxVertexSkinningType::BDEF1:
-			this->skinning = mmd::make_unique<PmxVertexSkinningBDEF1>();
-			break;
-		case PmxVertexSkinningType::BDEF2:
-			this->skinning = mmd::make_unique<PmxVertexSkinningBDEF2>();
-			break;
-		case PmxVertexSkinningType::BDEF4:
-			this->skinning = mmd::make_unique<PmxVertexSkinningBDEF4>();
-			break;
-		case PmxVertexSkinningType::SDEF:
-			this->skinning = mmd::make_unique<PmxVertexSkinningSDEF>();
-			break;
-		case PmxVertexSkinningType::QDEF:
-			this->skinning = mmd::make_unique<PmxVertexSkinningQDEF>();
-			break;
-		default:
-			throw "invalid skinning type";
-		}
-		this->skinning->Read(stream, setting);
-		stream->read((char*) &this->edge, sizeof(float));
-	}
-
-	void PmxMaterial::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->material_name = ReadString(stream, setting->encoding);
-		this->material_english_name = ReadString(stream, setting->encoding);
-		stream->read((char*) this->diffuse, sizeof(float) * 4);
-		stream->read((char*) this->specular, sizeof(float) * 3);
-		stream->read((char*) &this->specularlity, sizeof(float));
-		stream->read((char*) this->ambient, sizeof(float) * 3);
-		stream->read((char*) &this->flag, sizeof(uint8_t));
-		stream->read((char*) this->edge_color, sizeof(float) * 4);
-		stream->read((char*) &this->edge_size, sizeof(float));
-		this->diffuse_texture_index = ReadIndex(stream, setting->texture_index_size);
-		this->sphere_texture_index = ReadIndex(stream, setting->texture_index_size);
-		stream->read((char*) &this->sphere_op_mode, sizeof(uint8_t));
-		stream->read((char*) &this->common_toon_flag, sizeof(uint8_t));
-		if (this->common_toon_flag)
-		{
-			stream->read((char*) &this->toon_texture_index, sizeof(uint8_t));
-		}
-		else {
-			this->toon_texture_index = ReadIndex(stream, setting->texture_index_size);
-		}
-		this->memo = ReadString(stream, setting->encoding);
-		stream->read((char*) &this->index_count, sizeof(int));
-	}
-
-	void PmxIkLink::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->link_target = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->angle_lock, sizeof(uint8_t));
-		if (angle_lock == 1)
-		{
-			stream->read((char*) this->max_radian, sizeof(float) * 3);
-			stream->read((char*) this->min_radian, sizeof(float) * 3);
-		}
-	}
-
-	void PmxBone::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_name = ReadString(stream, setting->encoding);
-		this->bone_english_name = ReadString(stream, setting->encoding);
-		stream->read((char*) this->position, sizeof(float) * 3);
-		this->parent_index = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->level, sizeof(int));
-		stream->read((char*) &this->bone_flag, sizeof(uint16_t));
-		if (this->bone_flag & 0x0001) {
-			this->target_index = ReadIndex(stream, setting->bone_index_size);
-		}
-		else {
-			stream->read((char*)this->offset, sizeof(float) * 3);
-		}
-		if (this->bone_flag & (0x0100 | 0x0200)) {
-			this->grant_parent_index = ReadIndex(stream, setting->bone_index_size);
-			stream->read((char*) &this->grant_weight, sizeof(float));
-		}
-		if (this->bone_flag & 0x0400) {
-			stream->read((char*)this->lock_axis_orientation, sizeof(float) * 3);
-		}
-		if (this->bone_flag & 0x0800) {
-			stream->read((char*)this->local_axis_x_orientation, sizeof(float) * 3);
-			stream->read((char*)this->local_axis_y_orientation, sizeof(float) * 3);
-		}
-		if (this->bone_flag & 0x2000) {
-			stream->read((char*) &this->key, sizeof(int));
-		}
-		if (this->bone_flag & 0x0020) {
-			this->ik_target_bone_index = ReadIndex(stream, setting->bone_index_size);
-			stream->read((char*) &ik_loop, sizeof(int));
-			stream->read((char*) &ik_loop_angle_limit, sizeof(float));
-			stream->read((char*) &ik_link_count, sizeof(int));
-			this->ik_links = mmd::make_unique<PmxIkLink []>(ik_link_count);
-			for (int i = 0; i < ik_link_count; i++) {
-				ik_links[i].Read(stream, setting);
-			}
-		}
-	}
-
-	void PmxMorphVertexOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
-		stream->read((char*)this->position_offset, sizeof(float) * 3);
-	}
-
-	void PmxMorphUVOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->vertex_index = ReadIndex(stream, setting->vertex_index_size);
-		stream->read((char*)this->uv_offset, sizeof(float) * 4);
-	}
-
-	void PmxMorphBoneOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->bone_index = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*)this->translation, sizeof(float) * 3);
-		stream->read((char*)this->rotation, sizeof(float) * 4);
-	}
-
-	void PmxMorphMaterialOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->material_index = ReadIndex(stream, setting->material_index_size);
-		stream->read((char*) &this->offset_operation, sizeof(uint8_t));
-		stream->read((char*)this->diffuse, sizeof(float) * 4);
-		stream->read((char*)this->specular, sizeof(float) * 3);
-		stream->read((char*) &this->specularity, sizeof(float));
-		stream->read((char*)this->ambient, sizeof(float) * 3);
-		stream->read((char*)this->edge_color, sizeof(float) * 4);
-		stream->read((char*) &this->edge_size, sizeof(float));
-		stream->read((char*)this->texture_argb, sizeof(float) * 4);
-		stream->read((char*)this->sphere_texture_argb, sizeof(float) * 4);
-		stream->read((char*)this->toon_texture_argb, sizeof(float) * 4);
-	}
-
-	void PmxMorphGroupOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->morph_index = ReadIndex(stream, setting->morph_index_size);
-		stream->read((char*) &this->morph_weight, sizeof(float));
-	}
-
-	void PmxMorphFlipOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->morph_index = ReadIndex(stream, setting->morph_index_size);
-		stream->read((char*) &this->morph_value, sizeof(float));
-	}
-
-	void PmxMorphImplusOffset::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->rigid_body_index = ReadIndex(stream, setting->rigidbody_index_size);
-		stream->read((char*) &this->is_local, sizeof(uint8_t));
-		stream->read((char*)this->velocity, sizeof(float) * 3);
-		stream->read((char*)this->angular_torque, sizeof(float) * 3);
-	}
-
-	void PmxMorph::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->morph_name = ReadString(stream, setting->encoding);
-		this->morph_english_name = ReadString(stream, setting->encoding);
-		stream->read((char*) &category, sizeof(MorphCategory));
-		stream->read((char*) &morph_type, sizeof(MorphType));
-		stream->read((char*) &this->offset_count, sizeof(int));
-		switch (this->morph_type)
-		{
-		case MorphType::Group:
-			group_offsets = mmd::make_unique<PmxMorphGroupOffset []>(this->offset_count);
-			for (int i = 0; i < offset_count; i++)
-			{
-				group_offsets[i].Read(stream, setting);
-			}
-			break;
-		case MorphType::Vertex:
-			vertex_offsets = mmd::make_unique<PmxMorphVertexOffset []>(this->offset_count);
-			for (int i = 0; i < offset_count; i++)
-			{
-				vertex_offsets[i].Read(stream, setting);
-			}
-			break;
-		case MorphType::Bone:
-			bone_offsets = mmd::make_unique<PmxMorphBoneOffset []>(this->offset_count);
-			for (int i = 0; i < offset_count; i++)
-			{
-				bone_offsets[i].Read(stream, setting);
-			}
-			break;
-		case MorphType::Matrial:
-			material_offsets = mmd::make_unique<PmxMorphMaterialOffset []>(this->offset_count);
-			for (int i = 0; i < offset_count; i++)
-			{
-				material_offsets[i].Read(stream, setting);
-			}
-			break;
-		case MorphType::UV:
-		case MorphType::AdditionalUV1:
-		case MorphType::AdditionalUV2:
-		case MorphType::AdditionalUV3:
-		case MorphType::AdditionalUV4:
-			uv_offsets = mmd::make_unique<PmxMorphUVOffset []>(this->offset_count);
-			for (int i = 0; i < offset_count; i++)
-			{
-				uv_offsets[i].Read(stream, setting);
-			}
-			break;
-		default:
-            throw DeadlyImportError("MMD: unknown morth type");
-		}
-	}
-
-	void PmxFrameElement::Read(std::istream *stream, PmxSetting *setting)
-	{
-		stream->read((char*) &this->element_target, sizeof(uint8_t));
-		if (this->element_target == 0x00)
-		{
-			this->index = ReadIndex(stream, setting->bone_index_size);
-		}
-		else {
-			this->index = ReadIndex(stream, setting->morph_index_size);
-		}
-	}
-
-	void PmxFrame::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->frame_name = ReadString(stream, setting->encoding);
-		this->frame_english_name = ReadString(stream, setting->encoding);
-		stream->read((char*) &this->frame_flag, sizeof(uint8_t));
-		stream->read((char*) &this->element_count, sizeof(int));
-		this->elements = mmd::make_unique<PmxFrameElement []>(this->element_count);
-		for (int i = 0; i < this->element_count; i++)
-		{
-			this->elements[i].Read(stream, setting);
-		}
-	}
-
-	void PmxRigidBody::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->girid_body_name = ReadString(stream, setting->encoding);
-		this->girid_body_english_name = ReadString(stream, setting->encoding);
-		this->target_bone = ReadIndex(stream, setting->bone_index_size);
-		stream->read((char*) &this->group, sizeof(uint8_t));
-		stream->read((char*) &this->mask, sizeof(uint16_t));
-		stream->read((char*) &this->shape, sizeof(uint8_t));
-		stream->read((char*) this->size, sizeof(float) * 3);
-		stream->read((char*) this->position, sizeof(float) * 3);
-		stream->read((char*) this->orientation, sizeof(float) * 3);
-		stream->read((char*) &this->mass, sizeof(float));
-		stream->read((char*) &this->move_attenuation, sizeof(float));
-		stream->read((char*) &this->rotation_attenuation, sizeof(float));
-		stream->read((char*) &this->repulsion, sizeof(float));
-		stream->read((char*) &this->friction, sizeof(float));
-		stream->read((char*) &this->physics_calc_type, sizeof(uint8_t));
-	}
-
-	void PmxJointParam::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->rigid_body1 = ReadIndex(stream, setting->rigidbody_index_size);
-		this->rigid_body2 = ReadIndex(stream, setting->rigidbody_index_size);
-		stream->read((char*) this->position, sizeof(float) * 3);
-		stream->read((char*) this->orientaiton, sizeof(float) * 3);
-		stream->read((char*) this->move_limitation_min, sizeof(float) * 3);
-		stream->read((char*) this->move_limitation_max, sizeof(float) * 3);
-		stream->read((char*) this->rotation_limitation_min, sizeof(float) * 3);
-		stream->read((char*) this->rotation_limitation_max, sizeof(float) * 3);
-		stream->read((char*) this->spring_move_coefficient, sizeof(float) * 3);
-		stream->read((char*) this->spring_rotation_coefficient, sizeof(float) * 3);
-	}
-
-	void PmxJoint::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->joint_name = ReadString(stream, setting->encoding);
-		this->joint_english_name = ReadString(stream, setting->encoding);
-		stream->read((char*) &this->joint_type, sizeof(uint8_t));
-		this->param.Read(stream, setting);
-	}
-
-	void PmxAncherRigidBody::Read(std::istream *stream, PmxSetting *setting)
-	{
-		this->related_rigid_body = ReadIndex(stream, setting->rigidbody_index_size);
-		this->related_vertex = ReadIndex(stream, setting->vertex_index_size);
-		stream->read((char*) &this->is_near, sizeof(uint8_t));
-	}
-
-    void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
-	{
-		std::cerr << "Not Implemented Exception" << std::endl;
-        throw DeadlyImportError("MMD: Not Implemented Exception");
-    }
-
-	void PmxModel::Init()
-	{
-		this->version = 0.0f;
-		this->model_name.clear();
-		this->model_english_name.clear();
-		this->model_comment.clear();
-		this->model_english_comment.clear();
-		this->vertex_count = 0;
-		this->vertices = nullptr;
-		this->index_count = 0;
-		this->indices = nullptr;
-		this->texture_count = 0;
-		this->textures = nullptr;
-		this->material_count = 0;
-		this->materials = nullptr;
-		this->bone_count = 0;
-		this->bones = nullptr;
-		this->morph_count = 0;
-		this->morphs = nullptr;
-		this->frame_count = 0;
-		this->frames = nullptr;
-		this->rigid_body_count = 0;
-		this->rigid_bodies = nullptr;
-		this->joint_count = 0;
-		this->joints = nullptr;
-		this->soft_body_count = 0;
-		this->soft_bodies = nullptr;
-	}
-
-	void PmxModel::Read(std::istream *stream)
-	{
-		char magic[4];
-		stream->read((char*) magic, sizeof(char) * 4);
-		if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
-		{
-			std::cerr << "invalid magic number." << std::endl;
-      throw DeadlyImportError("MMD: invalid magic number.");
-    }
-		stream->read((char*) &version, sizeof(float));
-		if (version != 2.0f && version != 2.1f)
-		{
-			std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
-            throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but " + to_string(version));
-    }
-		this->setting.Read(stream);
-
-		this->model_name = ReadString(stream, setting.encoding);
-		this->model_english_name = ReadString(stream, setting.encoding);
-		this->model_comment = ReadString(stream, setting.encoding);
-		this->model_english_comment = ReadString(stream, setting.encoding);
-
-		// read vertices
-		stream->read((char*) &vertex_count, sizeof(int));
-		this->vertices = mmd::make_unique<PmxVertex []>(vertex_count);
-		for (int i = 0; i < vertex_count; i++)
-		{
-			vertices[i].Read(stream, &setting);
-		}
-
-		// read indices
-		stream->read((char*) &index_count, sizeof(int));
-		this->indices = mmd::make_unique<int []>(index_count);
-		for (int i = 0; i < index_count; i++)
-		{
-			this->indices[i] = ReadIndex(stream, setting.vertex_index_size);
-		}
-
-		// read texture names
-		stream->read((char*) &texture_count, sizeof(int));
-		this->textures = mmd::make_unique<std::string []>(texture_count);
-		for (int i = 0; i < texture_count; i++)
-		{
-			this->textures[i] = ReadString(stream, setting.encoding);
-		}
-
-		// read materials
-		stream->read((char*) &material_count, sizeof(int));
-		this->materials = mmd::make_unique<PmxMaterial []>(material_count);
-		for (int i = 0; i < material_count; i++)
-		{
-			this->materials[i].Read(stream, &setting);
-		}
-
-		// read bones
-		stream->read((char*) &this->bone_count, sizeof(int));
-		this->bones = mmd::make_unique<PmxBone []>(this->bone_count);
-		for (int i = 0; i < this->bone_count; i++)
-		{
-			this->bones[i].Read(stream, &setting);
-		}
-
-		// read morphs
-		stream->read((char*) &this->morph_count, sizeof(int));
-		this->morphs = mmd::make_unique<PmxMorph []>(this->morph_count);
-		for (int i = 0; i < this->morph_count; i++)
-		{
-			this->morphs[i].Read(stream, &setting);
-		}
-
-		// read display frames
-		stream->read((char*) &this->frame_count, sizeof(int));
-		this->frames = mmd::make_unique<PmxFrame []>(this->frame_count);
-		for (int i = 0; i < this->frame_count; i++)
-		{
-			this->frames[i].Read(stream, &setting);
-		}
-
-		// read rigid bodies
-		stream->read((char*) &this->rigid_body_count, sizeof(int));
-		this->rigid_bodies = mmd::make_unique<PmxRigidBody []>(this->rigid_body_count);
-		for (int i = 0; i < this->rigid_body_count; i++)
-		{
-			this->rigid_bodies[i].Read(stream, &setting);
-		}
-
-		// read joints
-		stream->read((char*) &this->joint_count, sizeof(int));
-		this->joints = mmd::make_unique<PmxJoint []>(this->joint_count);
-		for (int i = 0; i < this->joint_count; i++)
-		{
-			this->joints[i].Read(stream, &setting);
-		}
-	}
-}

+ 0 - 782
thirdparty/assimp/code/MMD/MMDPmxParser.h

@@ -1,782 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <iostream>
-#include <fstream>
-#include <memory>
-#include "MMDCpp14.h"
-
-namespace pmx
-{
-	class PmxSetting
-	{
-	public:
-		PmxSetting()
-			: encoding(0)
-			, uv(0)
-			, vertex_index_size(0)
-			, texture_index_size(0)
-			, material_index_size(0)
-			, bone_index_size(0)
-			, morph_index_size(0)
-			, rigidbody_index_size(0)
-		{}
-
-		uint8_t encoding;
-		uint8_t uv;
-		uint8_t vertex_index_size;
-		uint8_t texture_index_size;
-		uint8_t material_index_size;
-		uint8_t bone_index_size;
-		uint8_t morph_index_size;
-		uint8_t rigidbody_index_size;
-		void Read(std::istream *stream);
-	};
-
-	enum class PmxVertexSkinningType : uint8_t
-	{
-		BDEF1 = 0,
-		BDEF2 = 1,
-		BDEF4 = 2,
-		SDEF = 3,
-		QDEF = 4,
-	};
-
-	class PmxVertexSkinning
-	{
-	public:
-		virtual void Read(std::istream *stream, PmxSetting *setting) = 0;
-		virtual ~PmxVertexSkinning() {}
-	};
-
-	class PmxVertexSkinningBDEF1 : public PmxVertexSkinning
-	{
-	public:
-		PmxVertexSkinningBDEF1()
-			: bone_index(0)
-		{}
-
-		int bone_index;
-		void Read(std::istream *stresam, PmxSetting *setting);
-	};
-
-	class PmxVertexSkinningBDEF2 : public PmxVertexSkinning
-	{
-	public:
-		PmxVertexSkinningBDEF2()
-			: bone_index1(0)
-			, bone_index2(0)
-			, bone_weight(0.0f)
-		{}
-
-		int bone_index1;
-		int bone_index2;
-		float bone_weight;
-		void Read(std::istream *stresam, PmxSetting *setting);
-	};
-
-	class PmxVertexSkinningBDEF4 : public PmxVertexSkinning
-	{
-	public:
-		PmxVertexSkinningBDEF4()
-			: bone_index1(0)
-			, bone_index2(0)
-			, bone_index3(0)
-			, bone_index4(0)
-			, bone_weight1(0.0f)
-			, bone_weight2(0.0f)
-			, bone_weight3(0.0f)
-			, bone_weight4(0.0f)
-		{}
-
-		int bone_index1;
-		int bone_index2;
-		int bone_index3;
-		int bone_index4;
-		float bone_weight1;
-		float bone_weight2;
-		float bone_weight3;
-		float bone_weight4;
-		void Read(std::istream *stresam, PmxSetting *setting);
-	};
-
-	class PmxVertexSkinningSDEF : public PmxVertexSkinning
-	{
-	public:
-		PmxVertexSkinningSDEF()
-			: bone_index1(0)
-			, bone_index2(0)
-			, bone_weight(0.0f)
-		{
-			for (int i = 0; i < 3; ++i) {
-				sdef_c[i] = 0.0f;
-				sdef_r0[i] = 0.0f;
-				sdef_r1[i] = 0.0f;
-			}
-		}
-
-		int bone_index1;
-		int bone_index2;
-		float bone_weight;
-		float sdef_c[3];
-		float sdef_r0[3];
-		float sdef_r1[3];
-		void Read(std::istream *stresam, PmxSetting *setting);
-	};
-
-	class PmxVertexSkinningQDEF : public PmxVertexSkinning
-	{
-	public:
-		PmxVertexSkinningQDEF()
-			: bone_index1(0)
-			, bone_index2(0)
-			, bone_index3(0)
-			, bone_index4(0)
-			, bone_weight1(0.0f)
-			, bone_weight2(0.0f)
-			, bone_weight3(0.0f)
-			, bone_weight4(0.0f)
-		{}
-
-		int bone_index1;
-		int bone_index2;
-		int bone_index3;
-		int bone_index4;
-		float bone_weight1;
-		float bone_weight2;
-		float bone_weight3;
-		float bone_weight4;
-		void Read(std::istream *stresam, PmxSetting *setting);
-	};
-
-	class PmxVertex
-	{
-	public:
-		PmxVertex()
-			: edge(0.0f)
-		{
-			uv[0] = uv[1] = 0.0f;
-			for (int i = 0; i < 3; ++i) {
-				position[i] = 0.0f;
-				normal[i] = 0.0f;
-			}
-			for (int i = 0; i < 4; ++i) {
-				for (int k = 0; k < 4; ++k) {
-					uva[i][k] = 0.0f;
-				}
-			}
-		}
-
-		float position[3];
-		float normal[3];
-		float uv[2];
-		float uva[4][4];
-		PmxVertexSkinningType skinning_type;
-		std::unique_ptr<PmxVertexSkinning> skinning;
-		float edge;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxMaterial
-	{
-	public:
-		PmxMaterial()
-			: specularlity(0.0f)
-			, flag(0)
-			, edge_size(0.0f)
-			, diffuse_texture_index(0)
-			, sphere_texture_index(0)
-			, sphere_op_mode(0)
-			, common_toon_flag(0)
-			, toon_texture_index(0)
-			, index_count(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				specular[i] = 0.0f;
-				ambient[i] = 0.0f;
-				edge_color[i] = 0.0f;
-			}
-			for (int i = 0; i < 4; ++i) {
-				diffuse[i] = 0.0f;
-			}
-		}
-
-		std::string material_name;
-		std::string material_english_name;
-		float diffuse[4];
-		float specular[3];
-		float specularlity;
-		float ambient[3];
-		uint8_t flag;
-		float edge_color[4];
-		float edge_size;
-		int diffuse_texture_index;
-		int sphere_texture_index;
-		uint8_t sphere_op_mode;
-		uint8_t common_toon_flag;
-		int toon_texture_index;
-		std::string memo;
-		int index_count;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxIkLink
-	{
-	public:
-		PmxIkLink()
-			: link_target(0)
-			, angle_lock(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				max_radian[i] = 0.0f;
-				min_radian[i] = 0.0f;
-			}
-		}
-
-		int link_target;
-		uint8_t angle_lock;
-		float max_radian[3];
-		float min_radian[3];
-		void Read(std::istream *stream, PmxSetting *settingn);
-	};
-
-	class PmxBone
-	{
-	public:
-		PmxBone()
-			: parent_index(0)
-			, level(0)
-			, bone_flag(0)
-			, target_index(0)
-			, grant_parent_index(0)
-			, grant_weight(0.0f)
-			, key(0)
-			, ik_target_bone_index(0)
-			, ik_loop(0)
-			, ik_loop_angle_limit(0.0f)
-			, ik_link_count(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				position[i] = 0.0f;
-				offset[i] = 0.0f;
-				lock_axis_orientation[i] = 0.0f;
-				local_axis_x_orientation[i] = 0.0f;
-				local_axis_y_orientation[i] = 0.0f;
-			}
-		}
-
-		std::string bone_name;
-		std::string bone_english_name;
-		float position[3];
-		int parent_index;
-		int level;
-		uint16_t bone_flag;
-		float offset[3];
-		int target_index;
-		int grant_parent_index;
-		float grant_weight;
-		float lock_axis_orientation[3];
-		float local_axis_x_orientation[3];
-		float local_axis_y_orientation[3];
-		int key;
-		int ik_target_bone_index;
-		int ik_loop;
-		float ik_loop_angle_limit;
-		int ik_link_count;
-		std::unique_ptr<PmxIkLink []> ik_links;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	enum class MorphType : uint8_t
-	{
-		Group = 0,
-		Vertex = 1,
-		Bone = 2,
-		UV = 3,
-		AdditionalUV1 = 4,
-		AdditionalUV2 = 5,
-		AdditionalUV3 = 6,
-		AdditionalUV4 = 7,
-		Matrial = 8,
-		Flip = 9,
-		Implus = 10,
-	};
-
-	enum class MorphCategory : uint8_t
-	{
-		ReservedCategory = 0,
-		Eyebrow = 1,
-		Eye = 2,
-		Mouth = 3,
-		Other = 4,
-	};
-
-	class PmxMorphOffset
-	{
-	public:
-		void virtual Read(std::istream *stream, PmxSetting *setting) = 0;
-	};
-
-	class PmxMorphVertexOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphVertexOffset()
-			: vertex_index(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				position_offset[i] = 0.0f;
-			}
-		}
-		int vertex_index;
-		float position_offset[3];
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorphUVOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphUVOffset()
-			: vertex_index(0)
-		{
-			for (int i = 0; i < 4; ++i) {
-				uv_offset[i] = 0.0f;
-			}
-		}
-		int vertex_index;
-		float uv_offset[4];
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorphBoneOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphBoneOffset()
-			: bone_index(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				translation[i] = 0.0f;
-			}
-			for (int i = 0; i < 4; ++i) {
-				rotation[i] = 0.0f;
-			}
-		}
-		int bone_index;
-		float translation[3];
-		float rotation[4];
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorphMaterialOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphMaterialOffset()
-			: specularity(0.0f)
-			, edge_size(0.0f)
-		{
-			for (int i = 0; i < 3; ++i) {
-				specular[i] = 0.0f;
-				ambient[i] = 0.0f;
-			}
-			for (int i = 0; i < 4; ++i) {
-				diffuse[i] = 0.0f;
-				edge_color[i] = 0.0f;
-				texture_argb[i] = 0.0f;
-				sphere_texture_argb[i] = 0.0f;
-				toon_texture_argb[i] = 0.0f;
-			}
-		}
-		int material_index;
-		uint8_t offset_operation;
-		float diffuse[4];
-		float specular[3];
-		float specularity;
-		float ambient[3];
-		float edge_color[4];
-		float edge_size;
-		float texture_argb[4];
-		float sphere_texture_argb[4];
-		float toon_texture_argb[4];
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorphGroupOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphGroupOffset()
-			: morph_index(0)
-			, morph_weight(0.0f)
-		{}
-		int morph_index;
-		float morph_weight;
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorphFlipOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphFlipOffset()
-			: morph_index(0)
-			, morph_value(0.0f)
-		{}
-		int morph_index;
-		float morph_value;
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorphImplusOffset : public PmxMorphOffset
-	{
-	public:
-		PmxMorphImplusOffset()
-			: rigid_body_index(0)
-			, is_local(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				velocity[i] = 0.0f;
-				angular_torque[i] = 0.0f;
-			}
-		}
-		int rigid_body_index;
-		uint8_t is_local;
-		float velocity[3];
-		float angular_torque[3];
-		void Read(std::istream *stream, PmxSetting *setting); //override;
-	};
-
-	class PmxMorph
-	{
-	public:
-		PmxMorph()
-			: offset_count(0)
-		{
-		}
-		std::string morph_name;
-		std::string morph_english_name;
-		MorphCategory category;
-		MorphType morph_type;
-		int offset_count;
-		std::unique_ptr<PmxMorphVertexOffset []> vertex_offsets;
-		std::unique_ptr<PmxMorphUVOffset []> uv_offsets;
-		std::unique_ptr<PmxMorphBoneOffset []> bone_offsets;
-		std::unique_ptr<PmxMorphMaterialOffset []> material_offsets;
-		std::unique_ptr<PmxMorphGroupOffset []> group_offsets;
-		std::unique_ptr<PmxMorphFlipOffset []> flip_offsets;
-		std::unique_ptr<PmxMorphImplusOffset []> implus_offsets;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxFrameElement
-	{
-	public:
-		PmxFrameElement()
-			: element_target(0)
-			, index(0)
-		{
-		}
-		uint8_t element_target;
-		int index;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxFrame
-	{
-	public:
-		PmxFrame()
-			: frame_flag(0)
-			, element_count(0)
-		{
-		}
-		std::string frame_name;
-		std::string frame_english_name;
-		uint8_t frame_flag;
-		int element_count;
-		std::unique_ptr<PmxFrameElement []> elements;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxRigidBody
-	{
-	public:
-		PmxRigidBody()
-			: target_bone(0)
-			, group(0)
-			, mask(0)
-			, shape(0)
-			, mass(0.0f)
-			, move_attenuation(0.0f)
-			, rotation_attenuation(0.0f)
-			, repulsion(0.0f)
-			, friction(0.0f)
-			, physics_calc_type(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				size[i] = 0.0f;
-				position[i] = 0.0f;
-				orientation[i] = 0.0f;
-			}
-		}
-		std::string girid_body_name;
-		std::string girid_body_english_name;
-		int target_bone;
-		uint8_t group;
-		uint16_t mask;
-		uint8_t shape;
-		float size[3];
-		float position[3];
-		float orientation[3];
-		float mass;
-		float move_attenuation;
-		float rotation_attenuation;
-		float repulsion;
-		float friction;
-		uint8_t physics_calc_type;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	enum class PmxJointType : uint8_t
-	{
-		Generic6DofSpring = 0,
-		Generic6Dof = 1,
-		Point2Point = 2,
-		ConeTwist = 3,
-		Slider = 5,
-		Hinge = 6
-	};
-
-	class PmxJointParam
-	{
-	public:
-		PmxJointParam()
-			: rigid_body1(0)
-			, rigid_body2(0)
-		{
-			for (int i = 0; i < 3; ++i) {
-				position[i] = 0.0f;
-				orientaiton[i] = 0.0f;
-				move_limitation_min[i] = 0.0f;
-				move_limitation_max[i] = 0.0f;
-				rotation_limitation_min[i] = 0.0f;
-				rotation_limitation_max[i] = 0.0f;
-				spring_move_coefficient[i] = 0.0f;
-				spring_rotation_coefficient[i] = 0.0f;
-			}
-		}
-		int rigid_body1;
-		int rigid_body2;
-		float position[3];
-		float orientaiton[3];
-		float move_limitation_min[3];
-		float move_limitation_max[3];
-		float rotation_limitation_min[3];
-		float rotation_limitation_max[3];
-		float spring_move_coefficient[3];
-		float spring_rotation_coefficient[3];
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxJoint
-	{
-	public:
-		std::string joint_name;
-		std::string joint_english_name;
-		PmxJointType joint_type;
-		PmxJointParam param;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	enum PmxSoftBodyFlag : uint8_t
-	{
-		BLink = 0x01,
-		Cluster = 0x02,
-		Link = 0x04
-	};
-
-	class PmxAncherRigidBody
-	{
-	public:
-		PmxAncherRigidBody()
-			: related_rigid_body(0)
-			, related_vertex(0)
-			, is_near(false)
-		{}
-		int related_rigid_body;
-		int related_vertex;
-		bool is_near;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxSoftBody
-	{
-	public:
-		PmxSoftBody()
-			: shape(0)
-			, target_material(0)
-			, group(0)
-			, mask(0)
-			, blink_distance(0)
-			, cluster_count(0)
-			, mass(0.0)
-			, collisioni_margin(0.0)
-			, aero_model(0)
-			, VCF(0.0f)
-			, DP(0.0f)
-			, DG(0.0f)
-			, LF(0.0f)
-			, PR(0.0f)
-			, VC(0.0f)
-			, DF(0.0f)
-			, MT(0.0f)
-			, CHR(0.0f)
-			, KHR(0.0f)
-			, SHR(0.0f)
-			, AHR(0.0f)
-			, SRHR_CL(0.0f)
-			, SKHR_CL(0.0f)
-			, SSHR_CL(0.0f)
-			, SR_SPLT_CL(0.0f)
-			, SK_SPLT_CL(0.0f)
-			, SS_SPLT_CL(0.0f)
-			, V_IT(0)
-			, P_IT(0)
-			, D_IT(0)
-			, C_IT(0)
-			, LST(0.0f)
-			, AST(0.0f)
-			, VST(0.0f)
-			, anchor_count(0)
-			, pin_vertex_count(0)
-		{}
-		std::string soft_body_name;
-		std::string soft_body_english_name;
-		uint8_t shape;
-		int target_material;
-		uint8_t group;
-		uint16_t mask;
-		PmxSoftBodyFlag flag;
-		int blink_distance;
-		int cluster_count;
-		float mass;
-		float collisioni_margin;
-		int aero_model;
-		float VCF;
-		float DP;
-		float DG;
-		float LF;
-		float PR;
-		float VC;
-		float DF;
-		float MT;
-		float CHR;
-		float KHR;
-		float SHR;
-		float AHR;
-		float SRHR_CL;
-		float SKHR_CL;
-		float SSHR_CL;
-		float SR_SPLT_CL;
-		float SK_SPLT_CL;
-		float SS_SPLT_CL;
-		int V_IT;
-		int P_IT;
-		int D_IT;
-		int C_IT;
-		float LST;
-		float AST;
-		float VST;
-		int anchor_count;
-		std::unique_ptr<PmxAncherRigidBody []> anchers;
-		int pin_vertex_count;
-		std::unique_ptr<int []> pin_vertices;
-		void Read(std::istream *stream, PmxSetting *setting);
-	};
-
-	class PmxModel
-	{
-	public:
-		PmxModel()
-			: version(0.0f)
-			, vertex_count(0)
-			, index_count(0)
-			, texture_count(0)
-			, material_count(0)
-			, bone_count(0)
-			, morph_count(0)
-			, frame_count(0)
-			, rigid_body_count(0)
-			, joint_count(0)
-			, soft_body_count(0)
-		{}
-
-		float version;
-		PmxSetting setting;
-		std::string model_name;
-		std::string model_english_name;
-		std::string model_comment;
-		std::string model_english_comment;
-		int vertex_count;
-		std::unique_ptr<PmxVertex []> vertices;
-		int index_count;
-		std::unique_ptr<int []> indices;
-		int texture_count;
-		std::unique_ptr< std::string []> textures;
-		int material_count;
-		std::unique_ptr<PmxMaterial []> materials;
-		int bone_count;
-		std::unique_ptr<PmxBone []> bones;
-		int morph_count;
-		std::unique_ptr<PmxMorph []> morphs;
-		int frame_count;
-		std::unique_ptr<PmxFrame [] > frames;
-		int rigid_body_count;
-		std::unique_ptr<PmxRigidBody []> rigid_bodies;
-		int joint_count;
-		std::unique_ptr<PmxJoint []> joints;
-		int soft_body_count;
-		std::unique_ptr<PmxSoftBody []> soft_bodies;
-		void Init();
-		void Read(std::istream *stream);
-		//static std::unique_ptr<PmxModel> ReadFromFile(const char *filename);
-		//static std::unique_ptr<PmxModel> ReadFromStream(std::istream *stream);
-	};
-}

+ 0 - 376
thirdparty/assimp/code/MMD/MMDVmdParser.h

@@ -1,376 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-#pragma once
-
-#include <vector>
-#include <string>
-#include <memory>
-#include <iostream>
-#include <fstream>
-#include <ostream>
-#include "MMDCpp14.h"
-
-namespace vmd
-{
-	class VmdBoneFrame
-	{
-	public:
-		std::string name;
-		int frame;
-		float position[3];
-		float orientation[4];
-		char interpolation[4][4][4];
-
-		void Read(std::istream* stream)
-		{
-			char buffer[15];
-			stream->read((char*) buffer, sizeof(char)*15);
-			name = std::string(buffer);
-			stream->read((char*) &frame, sizeof(int));
-			stream->read((char*) position, sizeof(float)*3);
-			stream->read((char*) orientation, sizeof(float)*4);
-			stream->read((char*) interpolation, sizeof(char) * 4 * 4 * 4);
-		}
-
-		void Write(std::ostream* stream)
-		{
-			stream->write((char*)name.c_str(), sizeof(char) * 15);
-			stream->write((char*)&frame, sizeof(int));
-			stream->write((char*)position, sizeof(float) * 3);
-			stream->write((char*)orientation, sizeof(float) * 4);
-			stream->write((char*)interpolation, sizeof(char) * 4 * 4 * 4);
-		}
-	};
-
-	class VmdFaceFrame
-	{
-	public:
-		std::string face_name;
-		float weight;
-		uint32_t frame;
-
-		void Read(std::istream* stream)
-		{
-			char buffer[15];
-			stream->read((char*) &buffer, sizeof(char) * 15);
-			face_name = std::string(buffer);
-			stream->read((char*) &frame, sizeof(int));
-			stream->read((char*) &weight, sizeof(float));
-		}
-
-		void Write(std::ostream* stream)
-		{
-			stream->write((char*)face_name.c_str(), sizeof(char) * 15);
-			stream->write((char*)&frame, sizeof(int));
-			stream->write((char*)&weight, sizeof(float));
-		}
-	};
-
-	class VmdCameraFrame
-	{
-	public:
-		int frame;
-		float distance;
-		float position[3];
-		float orientation[3];
-		char interpolation[6][4];
-		float angle;
-		char unknown[3];
-
-		void Read(std::istream *stream)
-		{
-			stream->read((char*) &frame, sizeof(int));
-			stream->read((char*) &distance, sizeof(float));
-			stream->read((char*) position, sizeof(float) * 3);
-			stream->read((char*) orientation, sizeof(float) * 3);
-			stream->read((char*) interpolation, sizeof(char) * 24);
-			stream->read((char*) &angle, sizeof(float));
-			stream->read((char*) unknown, sizeof(char) * 3);
-		}
-
-		void Write(std::ostream *stream)
-		{
-			stream->write((char*)&frame, sizeof(int));
-			stream->write((char*)&distance, sizeof(float));
-			stream->write((char*)position, sizeof(float) * 3);
-			stream->write((char*)orientation, sizeof(float) * 3);
-			stream->write((char*)interpolation, sizeof(char) * 24);
-			stream->write((char*)&angle, sizeof(float));
-			stream->write((char*)unknown, sizeof(char) * 3);
-		}
-	};
-
-	class VmdLightFrame
-	{
-	public:
-		int frame;
-		float color[3];
-		float position[3];
-
-		void Read(std::istream* stream)
-		{
-			stream->read((char*) &frame, sizeof(int));
-			stream->read((char*) color, sizeof(float) * 3);
-			stream->read((char*) position, sizeof(float) * 3);
-		}
-
-		void Write(std::ostream* stream)
-		{
-			stream->write((char*)&frame, sizeof(int));
-			stream->write((char*)color, sizeof(float) * 3);
-			stream->write((char*)position, sizeof(float) * 3);
-		}
-	};
-
-	class VmdIkEnable
-	{
-	public:
-		std::string ik_name;
-		bool enable;
-	};
-
-	class VmdIkFrame
-	{
-	public:
-		int frame;
-		bool display;
-		std::vector<VmdIkEnable> ik_enable;
-
-		void Read(std::istream *stream)
-		{
-			char buffer[20];
-			stream->read((char*) &frame, sizeof(int));
-			stream->read((char*) &display, sizeof(uint8_t));
-			int ik_count;
-			stream->read((char*) &ik_count, sizeof(int));
-			ik_enable.resize(ik_count);
-			for (int i = 0; i < ik_count; i++)
-			{
-				stream->read(buffer, 20);
-				ik_enable[i].ik_name = std::string(buffer);
-				stream->read((char*) &ik_enable[i].enable, sizeof(uint8_t));
-			}
-		}
-
-		void Write(std::ostream *stream)
-		{
-			stream->write((char*)&frame, sizeof(int));
-			stream->write((char*)&display, sizeof(uint8_t));
-			int ik_count = static_cast<int>(ik_enable.size());
-			stream->write((char*)&ik_count, sizeof(int));
-			for (int i = 0; i < ik_count; i++)
-			{
-				const VmdIkEnable& ik_enable = this->ik_enable.at(i);
-				stream->write(ik_enable.ik_name.c_str(), 20);
-				stream->write((char*)&ik_enable.enable, sizeof(uint8_t));
-			}
-		}
-	};
-
-	class VmdMotion
-	{
-	public:
-		std::string model_name;
-		int version;
-		std::vector<VmdBoneFrame> bone_frames;
-		std::vector<VmdFaceFrame> face_frames;
-		std::vector<VmdCameraFrame> camera_frames;
-		std::vector<VmdLightFrame> light_frames;
-		std::vector<VmdIkFrame> ik_frames;
-
-		static std::unique_ptr<VmdMotion> LoadFromFile(char const *filename)
-		{
-			std::ifstream stream(filename, std::ios::binary);
-			auto result = LoadFromStream(&stream);
-			stream.close();
-			return result;
-		}
-
-		static std::unique_ptr<VmdMotion> LoadFromStream(std::ifstream *stream)
-		{
-
-			char buffer[30];
-			auto result = mmd::make_unique<VmdMotion>();
-
-			// magic and version
-			stream->read((char*) buffer, 30);
-			if (strncmp(buffer, "Vocaloid Motion Data", 20))
-			{
-				std::cerr << "invalid vmd file." << std::endl;
-				return nullptr;
-			}
-			result->version = std::atoi(buffer + 20);
-
-			// name
-			stream->read(buffer, 20);
-			result->model_name = std::string(buffer);
-
-			// bone frames
-			int bone_frame_num;
-			stream->read((char*) &bone_frame_num, sizeof(int));
-			result->bone_frames.resize(bone_frame_num);
-			for (int i = 0; i < bone_frame_num; i++)
-			{
-				result->bone_frames[i].Read(stream);
-			}
-
-			// face frames
-			int face_frame_num;
-			stream->read((char*) &face_frame_num, sizeof(int));
-			result->face_frames.resize(face_frame_num);
-			for (int i = 0; i < face_frame_num; i++)
-			{
-				result->face_frames[i].Read(stream);
-			}
-
-			// camera frames
-			int camera_frame_num;
-			stream->read((char*) &camera_frame_num, sizeof(int));
-			result->camera_frames.resize(camera_frame_num);
-			for (int i = 0; i < camera_frame_num; i++)
-			{
-				result->camera_frames[i].Read(stream);
-			}
-
-			// light frames
-			int light_frame_num;
-			stream->read((char*) &light_frame_num, sizeof(int));
-			result->light_frames.resize(light_frame_num);
-			for (int i = 0; i < light_frame_num; i++)
-			{
-				result->light_frames[i].Read(stream);
-			}
-
-			// unknown2
-			stream->read(buffer, 4);
-
-			// ik frames
-			if (stream->peek() != std::ios::traits_type::eof())
-			{
-				int ik_num;
-				stream->read((char*) &ik_num, sizeof(int));
-				result->ik_frames.resize(ik_num);
-				for (int i = 0; i < ik_num; i++)
-				{
-					result->ik_frames[i].Read(stream);
-				}
-			}
-
-			if (stream->peek() != std::ios::traits_type::eof())
-			{
-				std::cerr << "vmd stream has unknown data." << std::endl;
-			}
-
-			return result;
-		}
-
-        bool SaveToFile(const std::u16string& /*filename*/)
-		{
-			// TODO: How to adapt u16string to string?
-			/*
-			std::ofstream stream(filename.c_str(), std::ios::binary);
-			auto result = SaveToStream(&stream);
-			stream.close();
-			return result;
-			*/
-			return false;
-		}
-
-		bool SaveToStream(std::ofstream *stream)
-		{
-			std::string magic = "Vocaloid Motion Data 0002\0";
-			magic.resize(30);
-
-			// magic and version
-			stream->write(magic.c_str(), 30);
-
-			// name
-			stream->write(model_name.c_str(), 20);
-
-			// bone frames
-			const int bone_frame_num = static_cast<int>(bone_frames.size());
-			stream->write(reinterpret_cast<const char*>(&bone_frame_num), sizeof(int));
-			for (int i = 0; i < bone_frame_num; i++)
-			{
-				bone_frames[i].Write(stream);
-			}
-
-			// face frames
-			const int face_frame_num = static_cast<int>(face_frames.size());
-			stream->write(reinterpret_cast<const char*>(&face_frame_num), sizeof(int));
-			for (int i = 0; i < face_frame_num; i++)
-			{
-				face_frames[i].Write(stream);
-			}
-
-			// camera frames
-			const int camera_frame_num = static_cast<int>(camera_frames.size());
-			stream->write(reinterpret_cast<const char*>(&camera_frame_num), sizeof(int));
-			for (int i = 0; i < camera_frame_num; i++)
-			{
-				camera_frames[i].Write(stream);
-			}
-
-			// light frames
-			const int light_frame_num = static_cast<int>(light_frames.size());
-			stream->write(reinterpret_cast<const char*>(&light_frame_num), sizeof(int));
-			for (int i = 0; i < light_frame_num; i++)
-			{
-				light_frames[i].Write(stream);
-			}
-
-			// self shadow datas
-			const int self_shadow_num = 0;
-			stream->write(reinterpret_cast<const char*>(&self_shadow_num), sizeof(int));
-
-			// ik frames
-			const int ik_num = static_cast<int>(ik_frames.size());
-			stream->write(reinterpret_cast<const char*>(&ik_num), sizeof(int));
-			for (int i = 0; i < ik_num; i++)
-			{
-				ik_frames[i].Write(stream);
-			}
-
-			return true;
-		}
-	};
-}

+ 1 - 18
thirdparty/assimp/code/Material/MaterialSystem.cpp

@@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/types.h>
 #include <assimp/material.h>
 #include <assimp/DefaultLogger.hpp>
-#include <assimp/Macros.h>
 
 using namespace Assimp;
 
@@ -545,23 +544,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
     unsigned int type,
     unsigned int index)
 {
-    // We don't want to add the whole buffer .. write a 32 bit length
-    // prefix followed by the zero-terminated UTF8 string.
-    // (HACK) I don't want to break the ABI now, but we definitely
-    // ought to change aiString::mLength to uint32_t one day.
-    if (sizeof(size_t) == 8) {
-        aiString copy = *pInput;
-        uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
-        s[1] = static_cast<uint32_t>(pInput->length);
-
-        return AddBinaryProperty(s+1,
-            static_cast<unsigned int>(pInput->length+1+4),
-            pKey,
-            type,
-            index,
-            aiPTI_String);
-    }
-    ai_assert(sizeof(size_t)==4);
+    ai_assert(sizeof(ai_uint32)==4);
     return AddBinaryProperty(pInput,
         static_cast<unsigned int>(pInput->length+1+4),
         pKey,

+ 268 - 0
thirdparty/assimp/code/PostProcessing/ArmaturePopulate.cpp

@@ -0,0 +1,268 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#include "ArmaturePopulate.h"
+
+#include <assimp/BaseImporter.h>
+#include <assimp/DefaultLogger.hpp>
+#include <assimp/postprocess.h>
+#include <assimp/scene.h>
+#include <iostream>
+
+namespace Assimp {
+
+/// The default class constructor.
+ArmaturePopulate::ArmaturePopulate() : BaseProcess()
+{}
+
+/// The class destructor.
+ArmaturePopulate::~ArmaturePopulate() 
+{}
+
+bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
+  return (pFlags & aiProcess_PopulateArmatureData) != 0;
+}
+
+void ArmaturePopulate::SetupProperties(const Importer *pImp) {
+  // do nothing
+}
+
+void ArmaturePopulate::Execute(aiScene *out) {
+
+  // Now convert all bone positions to the correct mOffsetMatrix
+  std::vector<aiBone *> bones;
+  std::vector<aiNode *> nodes;
+  std::map<aiBone *, aiNode *> bone_stack;
+  BuildBoneList(out->mRootNode, out->mRootNode, out, bones);
+  BuildNodeList(out->mRootNode, nodes);
+
+  BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes);
+
+  ASSIMP_LOG_DEBUG_F("Bone stack size: ", bone_stack.size());
+
+  for (std::pair<aiBone *, aiNode *> kvp : bone_stack) {
+    aiBone *bone = kvp.first;
+    aiNode *bone_node = kvp.second;
+    ASSIMP_LOG_DEBUG_F("active node lookup: ", bone->mName.C_Str());
+    // lcl transform grab - done in generate_nodes :)
+
+    // bone->mOffsetMatrix = bone_node->mTransformation;
+    aiNode *armature = GetArmatureRoot(bone_node, bones);
+
+    ai_assert(armature);
+
+    // set up bone armature id
+    bone->mArmature = armature;
+
+    // set this bone node to be referenced properly
+    ai_assert(bone_node);
+    bone->mNode = bone_node;
+  }
+}
+
+
+/* Reprocess all nodes to calculate bone transforms properly based on the REAL
+ * mOffsetMatrix not the local. */
+/* Before this would use mesh transforms which is wrong for bone transforms */
+/* Before this would work for simple character skeletons but not complex meshes
+ * with multiple origins */
+/* Source: sketch fab log cutter fbx */
+void ArmaturePopulate::BuildBoneList(aiNode *current_node,
+                                     const aiNode *root_node,
+                                     const aiScene *scene,
+                                     std::vector<aiBone *> &bones) {
+  ai_assert(scene);
+  for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
+    aiNode *child = current_node->mChildren[nodeId];
+    ai_assert(child);
+
+    // check for bones
+    for (unsigned int meshId = 0; meshId < child->mNumMeshes; ++meshId) {
+      ai_assert(child->mMeshes);
+      unsigned int mesh_index = child->mMeshes[meshId];
+      aiMesh *mesh = scene->mMeshes[mesh_index];
+      ai_assert(mesh);
+
+      for (unsigned int boneId = 0; boneId < mesh->mNumBones; ++boneId) {
+        aiBone *bone = mesh->mBones[boneId];
+        ai_assert(bone);
+
+        // duplicate meshes exist with the same bones sometimes :)
+        // so this must be detected
+        if (std::find(bones.begin(), bones.end(), bone) == bones.end()) {
+          // add the element once
+          bones.push_back(bone);
+        }
+      }
+
+      // find mesh and get bones
+      // then do recursive lookup for bones in root node hierarchy
+    }
+
+    BuildBoneList(child, root_node, scene, bones);
+  }
+}
+
+/* Prepare flat node list which can be used for non recursive lookups later */
+void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
+                                     std::vector<aiNode *> &nodes) {
+  ai_assert(current_node);
+
+  for (unsigned int nodeId = 0; nodeId < current_node->mNumChildren; ++nodeId) {
+    aiNode *child = current_node->mChildren[nodeId];
+    ai_assert(child);
+
+    nodes.push_back(child);
+
+    BuildNodeList(child, nodes);
+  }
+}
+
+/* A bone stack allows us to have multiple armatures, with the same bone names
+ * A bone stack allows us also to retrieve bones true transform even with
+ * duplicate names :)
+ */
+void ArmaturePopulate::BuildBoneStack(aiNode *current_node,
+                                      const aiNode *root_node,
+                                      const aiScene *scene,
+                                      const std::vector<aiBone *> &bones,
+                                      std::map<aiBone *, aiNode *> &bone_stack,
+                                      std::vector<aiNode *> &node_stack) {
+  ai_assert(scene);
+  ai_assert(root_node);
+  ai_assert(!node_stack.empty());
+
+  for (aiBone *bone : bones) {
+    ai_assert(bone);
+    aiNode *node = GetNodeFromStack(bone->mName, node_stack);
+    if (node == nullptr) {
+      node_stack.clear();
+      BuildNodeList(root_node, node_stack);
+      ASSIMP_LOG_DEBUG_F("Resetting bone stack: nullptr element ", bone->mName.C_Str());
+
+      node = GetNodeFromStack(bone->mName, node_stack);
+
+      if (!node) {
+        ASSIMP_LOG_ERROR("serious import issue node for bone was not detected");
+        continue;
+      }
+    }
+
+    ASSIMP_LOG_DEBUG_F("Successfully added bone[", bone->mName.C_Str(), "] to stack and bone node is: ", node->mName.C_Str());
+
+    bone_stack.insert(std::pair<aiBone *, aiNode *>(bone, node));
+  }
+}
+
+
+/* Returns the armature root node */
+/* This is required to be detected for a bone initially, it will recurse up
+ * until it cannot find another bone and return the node No known failure
+ * points. (yet)
+ */
+aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
+                                          std::vector<aiBone *> &bone_list) {
+  while (bone_node) {
+    if (!IsBoneNode(bone_node->mName, bone_list)) {
+      ASSIMP_LOG_DEBUG_F("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str());
+      return bone_node;
+    }
+
+    bone_node = bone_node->mParent;
+  }
+  
+  ASSIMP_LOG_ERROR("GetArmatureRoot() can't find armature!");
+  
+  return nullptr;
+}
+
+
+
+/* Simple IsBoneNode check if this could be a bone */
+bool ArmaturePopulate::IsBoneNode(const aiString &bone_name,
+                                  std::vector<aiBone *> &bones) {
+  for (aiBone *bone : bones) {
+    if (bone->mName == bone_name) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+/* Pop this node by name from the stack if found */
+/* Used in multiple armature situations with duplicate node / bone names */
+/* Known flaw: cannot have nodes with bone names, will be fixed in later release
+ */
+/* (serious to be fixed) Known flaw: nodes which have more than one bone could
+ * be prematurely dropped from stack */
+aiNode *ArmaturePopulate::GetNodeFromStack(const aiString &node_name,
+                                           std::vector<aiNode *> &nodes) {
+  std::vector<aiNode *>::iterator iter;
+  aiNode *found = nullptr;
+  for (iter = nodes.begin(); iter < nodes.end(); ++iter) {
+    aiNode *element = *iter;
+    ai_assert(element);
+    // node valid and node name matches
+    if (element->mName == node_name) {
+      found = element;
+      break;
+    }
+  }
+
+  if (found != nullptr) {
+    ASSIMP_LOG_INFO_F("Removed node from stack: ", found->mName.C_Str());
+    // now pop the element from the node list
+    nodes.erase(iter);
+
+    return found;
+  }
+
+  // unique names can cause this problem
+  ASSIMP_LOG_ERROR("[Serious] GetNodeFromStack() can't find node from stack!");
+
+  return nullptr;
+}
+
+
+
+
+} // Namespace Assimp

+ 112 - 0
thirdparty/assimp/code/PostProcessing/ArmaturePopulate.h

@@ -0,0 +1,112 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#ifndef ARMATURE_POPULATE_H_
+#define ARMATURE_POPULATE_H_
+
+#include "Common/BaseProcess.h"
+#include <assimp/BaseImporter.h>
+#include <vector>
+#include <map>
+
+
+struct aiNode;
+struct aiBone;
+
+namespace Assimp {
+
+// ---------------------------------------------------------------------------
+/** Armature Populate: This is a post process designed
+ * To save you time when importing models into your game engines
+ * This was originally designed only for fbx but will work with other formats
+ * it is intended to auto populate aiBone data with armature and the aiNode
+ * This is very useful when dealing with skinned meshes
+ * or when dealing with many different skeletons
+ * It's off by default but recommend that you try it and use it
+ * It should reduce down any glue code you have in your
+ * importers
+ * You can contact RevoluPowered <[email protected]>
+ * For more info about this
+*/
+class ASSIMP_API ArmaturePopulate : public BaseProcess {
+public:
+    /// The default class constructor.
+    ArmaturePopulate();
+
+    /// The class destructor.
+    virtual ~ArmaturePopulate();
+
+    /// Overwritten, @see BaseProcess
+    virtual bool IsActive( unsigned int pFlags ) const;
+
+    /// Overwritten, @see BaseProcess
+    virtual void SetupProperties( const Importer* pImp );
+
+    /// Overwritten, @see BaseProcess
+    virtual void Execute( aiScene* pScene );
+
+    static aiNode *GetArmatureRoot(aiNode *bone_node,
+                                      std::vector<aiBone *> &bone_list);
+
+    static bool IsBoneNode(const aiString &bone_name,
+                              std::vector<aiBone *> &bones);
+
+    static aiNode *GetNodeFromStack(const aiString &node_name,
+                                       std::vector<aiNode *> &nodes);
+
+    static void BuildNodeList(const aiNode *current_node,
+                                 std::vector<aiNode *> &nodes);
+
+    static void BuildBoneList(aiNode *current_node, const aiNode *root_node,
+                                 const aiScene *scene,
+                                 std::vector<aiBone *> &bones);                        
+
+    static void BuildBoneStack(aiNode *current_node, const aiNode *root_node,
+                                  const aiScene *scene,
+                                  const std::vector<aiBone *> &bones,
+                                  std::map<aiBone *, aiNode *> &bone_stack,
+                                  std::vector<aiNode *> &node_stack);
+};
+
+} // Namespace Assimp
+
+
+#endif // SCALE_PROCESS_H_

+ 3 - 3
thirdparty/assimp/code/PostProcessing/ComputeUVMappingProcess.cpp

@@ -354,12 +354,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
     }
     else if (axis * base_axis_z >= angle_epsilon)   {
         FindMeshCenter(mesh, center, min, max);
-        diffu = max.y - min.y;
-        diffv = max.z - min.z;
+        diffu = max.x - min.x;
+        diffv = max.y - min.y;
 
         for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt)  {
             const aiVector3D& pos = mesh->mVertices[pnt];
-            out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.0);
+            out[pnt].Set((pos.x - min.x) / diffu,(pos.y - min.y) / diffv,0.0);
         }
     }
     // slower code path in case the mapping axis is not one of the coordinate system axes

+ 0 - 1
thirdparty/assimp/code/PostProcessing/FindInvalidDataProcess.cpp

@@ -52,7 +52,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FindInvalidDataProcess.h"
 #include "ProcessHelper.h"
 
-#include <assimp/Macros.h>
 #include <assimp/Exceptional.h>
 #include <assimp/qnan.h>
 

+ 0 - 25
thirdparty/assimp/code/PostProcessing/JoinVerticesProcess.cpp

@@ -431,31 +431,6 @@ int JoinVerticesProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
             bone->mWeights = new aiVertexWeight[bone->mNumWeights];
             memcpy( bone->mWeights, &newWeights[0], bone->mNumWeights * sizeof( aiVertexWeight));
         }
-        else {
-
-            /*  NOTE:
-             *
-             *  In the algorithm above we're assuming that there are no vertices
-             *  with a different bone weight setup at the same position. That wouldn't
-             *  make sense, but it is not absolutely impossible. SkeletonMeshBuilder
-             *  for example generates such input data if two skeleton points
-             *  share the same position. Again this doesn't make sense but is
-             *  reality for some model formats (MD5 for example uses these special
-             *  nodes as attachment tags for its weapons).
-             *
-             *  Then it is possible that a bone has no weights anymore .... as a quick
-             *  workaround, we're just removing these bones. If they're animated,
-             *  model geometry might be modified but at least there's no risk of a crash.
-             */
-            delete bone;
-            --pMesh->mNumBones;
-            for (unsigned int n = a; n < pMesh->mNumBones; ++n)  {
-                pMesh->mBones[n] = pMesh->mBones[n+1];
-            }
-
-            --a;
-            ASSIMP_LOG_WARN("Removing bone -> no weights remaining");
-        }
     }
     return pMesh->mNumVertices;
 }

+ 29 - 0
thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.cpp

@@ -224,3 +224,32 @@ bool MakeVerboseFormatProcess::MakeVerboseFormat(aiMesh* pcMesh)
     }
     return (pcMesh->mNumVertices != iOldNumVertices);
 }
+
+
+// ------------------------------------------------------------------------------------------------
+bool IsMeshInVerboseFormat(const aiMesh* mesh) {
+    // avoid slow vector<bool> specialization
+    std::vector<unsigned int> seen(mesh->mNumVertices,0);
+    for(unsigned int i = 0; i < mesh->mNumFaces; ++i) {
+        const aiFace& f = mesh->mFaces[i];
+        for(unsigned int j = 0; j < f.mNumIndices; ++j) {
+            if(++seen[f.mIndices[j]] == 2) {
+                // found a duplicate index
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+// ------------------------------------------------------------------------------------------------
+bool MakeVerboseFormatProcess::IsVerboseFormat(const aiScene* pScene) {
+    for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
+        if(!IsMeshInVerboseFormat(pScene->mMeshes[i])) {
+            return false;
+        }
+    }
+
+    return true;
+}

+ 7 - 0
thirdparty/assimp/code/PostProcessing/MakeVerboseFormat.h

@@ -94,6 +94,13 @@ public:
     * @param pScene The imported data to work at. */
     void Execute( aiScene* pScene);
 
+public:
+
+    // -------------------------------------------------------------------
+    /** Checks whether the scene is already in verbose format.
+    * @param pScene The data to check. 
+    * @return true if the scene is already in verbose format. */
+    static bool IsVerboseFormat(const aiScene* pScene);
 
 private:
 

+ 59 - 4
thirdparty/assimp/code/PostProcessing/ValidateDataStructure.cpp

@@ -538,13 +538,17 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
 {
     Validate(&pAnimation->mName);
 
-    // validate all materials
-    if (pAnimation->mNumChannels)
+    // validate all animations
+    if (pAnimation->mNumChannels || pAnimation->mNumMorphMeshChannels)
     {
-        if (!pAnimation->mChannels) {
+        if (!pAnimation->mChannels && pAnimation->mNumChannels) {
             ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
                 pAnimation->mNumChannels);
         }
+        if (!pAnimation->mMorphMeshChannels && pAnimation->mNumMorphMeshChannels) {
+            ReportError("aiAnimation::mMorphMeshChannels is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
+                pAnimation->mNumMorphMeshChannels);
+        }
         for (unsigned int i = 0; i < pAnimation->mNumChannels;++i)
         {
             if (!pAnimation->mChannels[i])
@@ -554,6 +558,15 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
             }
             Validate(pAnimation, pAnimation->mChannels[i]);
         }
+        for (unsigned int i = 0; i < pAnimation->mNumMorphMeshChannels;++i)
+        {
+            if (!pAnimation->mMorphMeshChannels[i])
+            {
+                ReportError("aiAnimation::mMorphMeshChannels[%i] is NULL (aiAnimation::mNumMorphMeshChannels is %i)",
+                    i, pAnimation->mNumMorphMeshChannels);
+            }
+            Validate(pAnimation, pAnimation->mMorphMeshChannels[i]);
+        }
     }
     else {
     	ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
@@ -903,6 +916,48 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
     }
 }
 
+void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
+     const aiMeshMorphAnim* pMeshMorphAnim)
+{
+    Validate(&pMeshMorphAnim->mName);
+
+    if (!pMeshMorphAnim->mNumKeys) {
+        ReportError("Empty mesh morph animation channel");
+    }
+
+    // otherwise check whether one of the keys exceeds the total duration of the animation
+    if (pMeshMorphAnim->mNumKeys)
+    {
+        if (!pMeshMorphAnim->mKeys)
+        {
+            ReportError("aiMeshMorphAnim::mKeys is NULL (aiMeshMorphAnim::mNumKeys is %i)",
+                pMeshMorphAnim->mNumKeys);
+        }
+        double dLast = -10e10;
+        for (unsigned int i = 0; i < pMeshMorphAnim->mNumKeys;++i)
+        {
+            // ScenePreprocessor will compute the duration if still the default value
+            // (Aramis) Add small epsilon, comparison tended to fail if max_time == duration,
+            //  seems to be due the compilers register usage/width.
+            if (pAnimation->mDuration > 0. && pMeshMorphAnim->mKeys[i].mTime > pAnimation->mDuration+0.001)
+            {
+                ReportError("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is larger "
+                    "than aiAnimation::mDuration (which is %.5f)",i,
+                    (float)pMeshMorphAnim->mKeys[i].mTime,
+                    (float)pAnimation->mDuration);
+            }
+            if (i && pMeshMorphAnim->mKeys[i].mTime <= dLast)
+            {
+                ReportWarning("aiMeshMorphAnim::mKeys[%i].mTime (%.5f) is smaller "
+                    "than aiMeshMorphAnim::mKeys[%i] (which is %.5f)",i,
+                    (float)pMeshMorphAnim->mKeys[i].mTime,
+                    i-1, (float)dLast);
+            }
+            dLast = pMeshMorphAnim->mKeys[i].mTime;
+        }
+    }
+}
+
 // ------------------------------------------------------------------------------------------------
 void ValidateDSProcess::Validate( const aiNode* pNode)
 {
@@ -958,7 +1013,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
 {
     if (pString->length > MAXLEN)
     {
-        ReportError("aiString::length is too large (%lu, maximum is %lu)",
+        ReportError("aiString::length is too large (%u, maximum is %lu)",
             pString->length,MAXLEN);
     }
     const char* sz = pString->data;

+ 8 - 0
thirdparty/assimp/code/PostProcessing/ValidateDataStructure.h

@@ -55,6 +55,7 @@ struct aiBone;
 struct aiMesh;
 struct aiAnimation;
 struct aiNodeAnim;
+struct aiMeshMorphAnim;
 struct aiTexture;
 struct aiMaterial;
 struct aiNode;
@@ -150,6 +151,13 @@ protected:
     void Validate( const aiAnimation* pAnimation,
         const aiNodeAnim* pBoneAnim);
 
+    /** Validates a mesh morph animation channel.
+     * @param pAnimation Input animation.
+     * @param pMeshMorphAnim Mesh morph animation channel.
+     * */
+    void Validate( const aiAnimation* pAnimation,
+        const aiMeshMorphAnim* pMeshMorphAnim);
+
     // -------------------------------------------------------------------
     /** Validates a node and all of its subnodes
      * @param Node Input node*/

+ 22 - 1
thirdparty/assimp/code/revision.h

@@ -1,7 +1,28 @@
 #ifndef ASSIMP_REVISION_H_INC
 #define ASSIMP_REVISION_H_INC
 
-#define GitVersion 0x00000000
+#define GitVersion 0x308db73d
 #define GitBranch "master"
 
+#define VER_MAJOR 5
+#define VER_MINOR 0
+#define VER_PATCH 0
+#define VER_BUILD 0
+
+#define STR_HELP(x) #x
+#define STR(x) STR_HELP(x)
+
+#define VER_FILEVERSION             VER_MAJOR,VER_MINOR,VER_PATCH,VER_BUILD
+#if (GitVersion == 0)
+#define VER_FILEVERSION_STR         STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD)
+#else
+#define VER_FILEVERSION_STR         STR(VER_MAJOR) "." STR(VER_MINOR) "." STR(VER_PATCH) "." STR(VER_BUILD) " (Commit 308db73d)"
+#endif
+
+#ifdef  NDEBUG
+#define VER_ORIGINAL_FILENAME_STR   "assimp.dll"
+#else
+#define VER_ORIGINAL_FILENAME_STR   "assimp.dll"
+#endif //  NDEBUG
+
 #endif // ASSIMP_REVISION_H_INC

+ 8 - 0
thirdparty/assimp/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

+ 11 - 9
thirdparty/assimp/include/assimp/BaseImporter.h

@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** @file Definition of the base class for all importer worker classes. */
+#pragma once
 #ifndef INCLUDED_AI_BASEIMPORTER_H
 #define INCLUDED_AI_BASEIMPORTER_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include "Exceptional.h"
 
 #include <vector>
@@ -191,16 +196,13 @@ public:
     /**
      * Assimp Importer
      * unit conversions available 
-     * if you need another measurment unit add it below.
-     * it's currently defined in assimp that we prefer meters.
+     * NOTE: Valid options are initialised in the
+     * constructor in the implementation file to
+     * work around a VS2013 compiler bug if support
+     * for that compiler is dropped in the future
+     * initialisation can be moved back here
      * */
-    std::map<ImporterUnits, double> importerUnits = {
-        {ImporterUnits::M, 1},
-        {ImporterUnits::CM, 0.01},
-        {ImporterUnits::MM, 0.001},
-        {ImporterUnits::INCHES, 0.0254},
-        {ImporterUnits::FEET, 0.3048}
-    };
+    std::map<ImporterUnits, double> importerUnits;
 
     virtual void SetApplicationUnits( const ImporterUnits& unit )
     {

+ 5 - 1
thirdparty/assimp/include/assimp/Bitmap.h

@@ -46,10 +46,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * Used for file formats which embed their textures into the model file.
  */
-
+#pragma once
 #ifndef AI_BITMAP_H_INC
 #define AI_BITMAP_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include "defs.h"
 #include <stdint.h>
 #include <cstddef>

+ 5 - 0
thirdparty/assimp/include/assimp/ByteSwapper.h

@@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** @file Helper class tp perform various byte oder swappings
    (e.g. little to big endian) */
+#pragma once
 #ifndef AI_BYTESWAPPER_H_INC
 #define AI_BYTESWAPPER_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/ai_assert.h>
 #include <assimp/types.h>
 #include <stdint.h>

+ 12 - 2
thirdparty/assimp/include/assimp/CreateAnimMesh.h

@@ -43,16 +43,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file CreateAnimMesh.h
  *  Create AnimMesh from Mesh
  */
+#pragma once
 #ifndef INCLUDED_AI_CREATE_ANIM_MESH_H
 #define INCLUDED_AI_CREATE_ANIM_MESH_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/mesh.h>
 
-namespace Assimp    {
+namespace Assimp {
 
-/** Create aiAnimMesh from aiMesh. */
+/**
+ *  Create aiAnimMesh from aiMesh.
+ *  @param  mesh    The input mesh to create an animated mesh from.
+ *  @return The new created animated mesh.
+ */
 ASSIMP_API aiAnimMesh *aiCreateAnimMesh(const aiMesh *mesh);
 
 } // end of namespace Assimp
+
 #endif // INCLUDED_AI_CREATE_ANIM_MESH_H
 

+ 9 - 10
thirdparty/assimp/include/assimp/DefaultIOStream.h

@@ -41,15 +41,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** @file Default file I/O using fXXX()-family of functions */
+#pragma once
 #ifndef AI_DEFAULTIOSTREAM_H_INC
 #define AI_DEFAULTIOSTREAM_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <stdio.h>
 #include <assimp/IOStream.hpp>
 #include <assimp/importerdesc.h>
 #include <assimp/Defines.h>
 
-namespace Assimp    {
+namespace Assimp {
 
 // ----------------------------------------------------------------------------------
 //! @class  DefaultIOStream
@@ -57,8 +62,7 @@ namespace Assimp    {
 //! @note   An instance of this class can exist without a valid file handle
 //!         attached to it. All calls fail, but the instance can nevertheless be
 //!         used with no restrictions.
-class ASSIMP_API DefaultIOStream : public IOStream
-{
+class ASSIMP_API DefaultIOStream : public IOStream {
     friend class DefaultIOSystem;
 #if __ANDROID__
 # if __ANDROID_API__ > 9
@@ -82,7 +86,6 @@ public:
         size_t pSize,
         size_t pCount);
 
-
     // -------------------------------------------------------------------
     /// Write to stream
     size_t Write(const void* pvBuffer,
@@ -107,16 +110,13 @@ public:
     void Flush();
 
 private:
-    //  File data-structure, using clib
     FILE* mFile;
-    //  Filename
     std::string mFilename;
-    // Cached file size
     mutable size_t mCachedSize;
 };
 
 // ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
 DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
 : mFile(nullptr)
 , mFilename("")
@@ -125,7 +125,7 @@ DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
 }
 
 // ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
 DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
 : mFile(pFile)
 , mFilename(strFilename)
@@ -137,4 +137,3 @@ DefaultIOStream::DefaultIOStream (FILE* pFile, const std::string &strFilename)
 } // ns assimp
 
 #endif //!!AI_DEFAULTIOSTREAM_H_INC
-

+ 5 - 0
thirdparty/assimp/include/assimp/DefaultIOSystem.h

@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** @file Default implementation of IOSystem using the standard C file functions */
+#pragma once
 #ifndef AI_DEFAULTIOSYSTEM_H_INC
 #define AI_DEFAULTIOSYSTEM_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/IOSystem.hpp>
 
 namespace Assimp    {

+ 9 - 0
thirdparty/assimp/include/assimp/Defines.h

@@ -38,6 +38,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
+#pragma once
+#ifndef AI_DEFINES_H_INC
+#define AI_DEFINES_H_INC
+
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 // We need those constants, workaround for any platforms where nobody defined them yet
 #if (!defined SIZE_MAX)
 #   define SIZE_MAX (~((size_t)0))
@@ -47,3 +55,4 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   define UINT_MAX (~((unsigned int)0))
 #endif
 
+#endif // AI_DEINES_H_INC

+ 13 - 10
thirdparty/assimp/include/assimp/Exceptional.h

@@ -38,11 +38,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
-#ifndef INCLUDED_EXCEPTIONAL_H
-#define INCLUDED_EXCEPTIONAL_H
+#pragma once
+#ifndef AI_INCLUDED_EXCEPTIONAL_H
+#define AI_INCLUDED_EXCEPTIONAL_H
+
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
 
 #include <stdexcept>
 #include <assimp/DefaultIOStream.h>
+
 using std::runtime_error;
 
 #ifdef _MSC_VER
@@ -53,17 +59,14 @@ using std::runtime_error;
 /** FOR IMPORTER PLUGINS ONLY: Simple exception class to be thrown if an
  *  unrecoverable error occurs while importing. Loading APIs return
  *  NULL instead of a valid aiScene then.  */
-class DeadlyImportError
-    : public runtime_error
-{
+class DeadlyImportError : public runtime_error {
 public:
     /** Constructor with arguments */
     explicit DeadlyImportError( const std::string& errorText)
-        : runtime_error(errorText)
-    {
+    : runtime_error(errorText) {
+        // empty
     }
 
-private:
 };
 
 typedef DeadlyImportError DeadlyExportError;
@@ -84,7 +87,7 @@ struct ExceptionSwallower   {
 template <typename T>
 struct ExceptionSwallower<T*>   {
     T* operator ()() const {
-        return NULL;
+        return nullptr;
     }
 };
 
@@ -122,4 +125,4 @@ struct ExceptionSwallower<void> {
     }\
 }
 
-#endif // INCLUDED_EXCEPTIONAL_H
+#endif // AI_INCLUDED_EXCEPTIONAL_H

+ 4 - 0
thirdparty/assimp/include/assimp/Exporter.hpp

@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_EXPORT_HPP_INC
 #define AI_EXPORT_HPP_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
 #include "cexport.h"

+ 6 - 1
thirdparty/assimp/include/assimp/GenericProperty.h

@@ -40,12 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
+#pragma once
 #ifndef AI_GENERIC_PROPERTY_H_INCLUDED
 #define AI_GENERIC_PROPERTY_H_INCLUDED
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/Importer.hpp>
 #include <assimp/ai_assert.h>
-#include "Hash.h"
+#include <assimp/Hash.h>
 
 #include <map>
 

+ 5 - 1
thirdparty/assimp/include/assimp/Hash.h

@@ -39,10 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ----------------------------------------------------------------------
 */
-
+#pragma once
 #ifndef AI_HASH_H_INCLUDED
 #define AI_HASH_H_INCLUDED
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <stdint.h>
 #include <string.h>
 

+ 8 - 4
thirdparty/assimp/include/assimp/IOStream.hpp

@@ -48,14 +48,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_IOSTREAM_H_INC
 #define AI_IOSTREAM_H_INC
 
-#include "types.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
 
 #ifndef __cplusplus
 #   error This header requires C++ to be used. aiFileIO.h is the \
     corresponding C interface.
 #endif
 
-namespace Assimp    {
+namespace Assimp {
 
 // ----------------------------------------------------------------------------------
 /** @brief CPP-API: Class to handle file I/O for C++
@@ -125,13 +129,13 @@ public:
 }; //! class IOStream
 
 // ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
 IOStream::IOStream() AI_NO_EXCEPT {
     // empty
 }
 
 // ----------------------------------------------------------------------------------
-inline
+AI_FORCE_INLINE
 IOStream::~IOStream() {
     // empty
 }

+ 25 - 18
thirdparty/assimp/include/assimp/IOStreamBuffer.h

@@ -1,5 +1,3 @@
-#pragma once
-
 /*
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
@@ -42,10 +40,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
+#pragma once
+#ifndef AI_IOSTREAMBUFFER_H_INC
+#define AI_IOSTREAMBUFFER_H_INC
+
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
 #include <assimp/IOStream.hpp>
-
-#include "ParsingUtils.h"
+#include <assimp/ParsingUtils.h>
 
 #include <vector>
 
@@ -124,7 +129,7 @@ private:
 };
 
 template<class T>
-inline
+AI_FORCE_INLINE
 IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
 : m_stream( nullptr )
 , m_filesize( 0 )
@@ -138,13 +143,13 @@ IOStreamBuffer<T>::IOStreamBuffer( size_t cache )
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 IOStreamBuffer<T>::~IOStreamBuffer() {
     // empty
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 bool IOStreamBuffer<T>::open( IOStream *stream ) {
     //  file still opened!
     if ( nullptr != m_stream ) {
@@ -174,7 +179,7 @@ bool IOStreamBuffer<T>::open( IOStream *stream ) {
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 bool IOStreamBuffer<T>::close() {
     if ( nullptr == m_stream ) {
         return false;
@@ -192,19 +197,19 @@ bool IOStreamBuffer<T>::close() {
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 size_t IOStreamBuffer<T>::size() const {
     return m_filesize;
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 size_t IOStreamBuffer<T>::cacheSize() const {
     return m_cacheSize;
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 bool IOStreamBuffer<T>::readNextBlock() {
     m_stream->Seek( m_filePos, aiOrigin_SET );
     size_t readLen = m_stream->Read( &m_cache[ 0 ], sizeof( T ), m_cacheSize );
@@ -222,25 +227,25 @@ bool IOStreamBuffer<T>::readNextBlock() {
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 size_t IOStreamBuffer<T>::getNumBlocks() const {
     return m_numBlocks;
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 size_t IOStreamBuffer<T>::getCurrentBlockIndex() const {
     return m_blockIdx;
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 size_t IOStreamBuffer<T>::getFilePos() const {
     return m_filePos;
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationToken ) {
     buffer.resize( m_cacheSize );
     if ( m_cachePos >= m_cacheSize || 0 == m_filePos ) {
@@ -289,13 +294,13 @@ bool IOStreamBuffer<T>::getNextDataLine( std::vector<T> &buffer, T continuationT
     return true;
 }
 
-static inline
+static AI_FORCE_INLINE
 bool isEndOfCache( size_t pos, size_t cacheSize ) {
     return ( pos == cacheSize );
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
     buffer.resize(m_cacheSize);
     if ( isEndOfCache( m_cachePos, m_cacheSize ) || 0 == m_filePos) {
@@ -335,7 +340,7 @@ bool IOStreamBuffer<T>::getNextLine(std::vector<T> &buffer) {
 }
 
 template<class T>
-inline
+AI_FORCE_INLINE
 bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
     // Return the last block-value if getNextLine was used before
     if ( 0 != m_cachePos ) {      
@@ -353,3 +358,5 @@ bool IOStreamBuffer<T>::getNextBlock( std::vector<T> &buffer) {
 }
 
 } // !ns Assimp
+
+#endif // AI_IOSTREAMBUFFER_H_INC

+ 4 - 0
thirdparty/assimp/include/assimp/IOSystem.hpp

@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_IOSYSTEM_H_INC
 #define AI_IOSYSTEM_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifndef __cplusplus
 #   error This header requires C++ to be used. aiFileIO.h is the \
     corresponding C interface.

+ 4 - 0
thirdparty/assimp/include/assimp/Importer.hpp

@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASSIMP_HPP_INC
 #define AI_ASSIMP_HPP_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifndef __cplusplus
 #   error This header requires C++ to be used. Use assimp.h for plain C.
 #endif // __cplusplus

+ 20 - 16
thirdparty/assimp/include/assimp/LineSplitter.h

@@ -48,9 +48,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_LINE_SPLITTER_H
 #define INCLUDED_LINE_SPLITTER_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <stdexcept>
-#include "StreamReader.h"
-#include "ParsingUtils.h"
+#include <assimp/StreamReader.h>
+#include <assimp/ParsingUtils.h>
 
 namespace Assimp {
 
@@ -140,7 +144,7 @@ private:
     bool mSwallow, mSkip_empty_lines, mTrim;
 };
 
-inline
+AI_FORCE_INLINE
 LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool trim )
 : mIdx(0)
 , mCur()
@@ -153,12 +157,12 @@ LineSplitter::LineSplitter(StreamReaderLE& stream, bool skip_empty_lines, bool t
     mIdx = 0;
 }
 
-inline
+AI_FORCE_INLINE
 LineSplitter::~LineSplitter() {
     // empty
 }
 
-inline
+AI_FORCE_INLINE
 LineSplitter& LineSplitter::operator++() {
     if (mSwallow) {
         mSwallow = false;
@@ -199,12 +203,12 @@ LineSplitter& LineSplitter::operator++() {
     return *this;
 }
 
-inline
+AI_FORCE_INLINE
 LineSplitter &LineSplitter::operator++(int) {
     return ++(*this);
 }
 
-inline
+AI_FORCE_INLINE
 const char *LineSplitter::operator[] (size_t idx) const {
     const char* s = operator->()->c_str();
 
@@ -222,7 +226,7 @@ const char *LineSplitter::operator[] (size_t idx) const {
 }
 
 template <size_t N>
-inline
+AI_FORCE_INLINE
 void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
     const char* s = operator->()->c_str();
 
@@ -238,44 +242,44 @@ void LineSplitter::get_tokens(const char* (&tokens)[N]) const {
     }
 }
 
-inline
+AI_FORCE_INLINE
 const std::string* LineSplitter::operator -> () const {
     return &mCur;
 }
 
-inline
+AI_FORCE_INLINE
 std::string LineSplitter::operator* () const {
     return mCur;
 }
 
-inline
+AI_FORCE_INLINE
 LineSplitter::operator bool() const {
     return mStream.GetRemainingSize() > 0;
 }
 
-inline
+AI_FORCE_INLINE
 LineSplitter::operator line_idx() const {
     return mIdx;
 }
 
-inline
+AI_FORCE_INLINE
 LineSplitter::line_idx LineSplitter::get_index() const {
     return mIdx;
 }
 
-inline
+AI_FORCE_INLINE
 StreamReaderLE &LineSplitter::get_stream() {
     return mStream;
 }
 
-inline
+AI_FORCE_INLINE
 bool LineSplitter::match_start(const char* check) {
     const size_t len = ::strlen(check);
 
     return len <= mCur.length() && std::equal(check, check + len, mCur.begin());
 }
 
-inline
+AI_FORCE_INLINE
 void LineSplitter::swallow_next_increment() {
     mSwallow = true;
 }

+ 5 - 0
thirdparty/assimp/include/assimp/LogAux.h

@@ -43,9 +43,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file  LogAux.h
  *  @brief Common logging usage patterns for importer implementations
  */
+#pragma once
 #ifndef INCLUDED_AI_LOGAUX_H
 #define INCLUDED_AI_LOGAUX_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/TinyFormatter.h>
 #include <assimp/Exceptional.h>
 #include <assimp/DefaultLogger.hpp>

+ 0 - 49
thirdparty/assimp/include/assimp/Macros.h

@@ -1,49 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2019, assimp team
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-  copyright notice, this list of conditions and the
-  following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-  copyright notice, this list of conditions and the
-  following disclaimer in the documentation and/or other
-  materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-  contributors may be used to endorse or promote products
-  derived from this software without specific prior
-  written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-/* Helper macro to set a pointer to NULL in debug builds
- */
-#if (defined ASSIMP_BUILD_DEBUG)
-#   define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
-#else
-#   define AI_DEBUG_INVALIDATE_PTR(x)
-#endif
-

+ 23 - 10
thirdparty/assimp/include/assimp/MathFunctions.h

@@ -39,22 +39,28 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ---------------------------------------------------------------------------
 */
 
+#pragma once
+
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 /** @file  MathFunctions.h
- *  @brief Implementation of the math functions (gcd and lcm)
+*  @brief Implementation of math utility functions.
  *
- *  Copied from BoostWorkaround/math
- */
+*/
+
+#include <limits>
 
 namespace Assimp {
 namespace Math {
 
 // TODO: use binary GCD for unsigned integers ....
 template < typename IntegerType >
-IntegerType  gcd( IntegerType a, IntegerType b )
-{
+inline
+IntegerType gcd( IntegerType a, IntegerType b ) {
 	const IntegerType zero = (IntegerType)0;
-	while ( true )
-	{
+	while ( true ) {
 		if ( a == zero )
 			return b;
 		b %= a;
@@ -66,12 +72,19 @@ IntegerType  gcd( IntegerType a, IntegerType b )
 }
 
 template < typename IntegerType >
-IntegerType  lcm( IntegerType a, IntegerType b )
-{
+inline
+IntegerType lcm( IntegerType a, IntegerType b ) {
 	const IntegerType t = gcd (a,b);
-	if (!t)return t;
+	if (!t)
+        return t;
 	return a / t * b;
 }
 
+template<class T>
+inline
+T getEpsilon() {
+    return std::numeric_limits<T>::epsilon();
+}
+
 }
 }

+ 6 - 0
thirdparty/assimp/include/assimp/MemoryIOWrapper.h

@@ -42,12 +42,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** @file MemoryIOWrapper.h
  *  Handy IOStream/IOSystem implemetation to read directly from a memory buffer */
+#pragma once
 #ifndef AI_MEMORYIOSTREAM_H_INC
 #define AI_MEMORYIOSTREAM_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/ai_assert.h>
+
 #include <stdint.h>
 
 namespace Assimp    {

+ 7 - 2
thirdparty/assimp/include/assimp/ParsingUtils.h

@@ -44,11 +44,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file ParsingUtils.h
  *  @brief Defines helper functions for text parsing
  */
+#pragma once
 #ifndef AI_PARSING_UTILS_H_INC
 #define AI_PARSING_UTILS_H_INC
 
-#include "StringComparison.h"
-#include "StringUtils.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/StringComparison.h>
+#include <assimp/StringUtils.h>
 #include <assimp/defs.h>
 
 namespace Assimp {

+ 9 - 5
thirdparty/assimp/include/assimp/Profiler.h

@@ -43,12 +43,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Profiler.h
  *  @brief Utility to measure the respective runtime of each import step
  */
-#ifndef INCLUDED_PROFILER_H
-#define INCLUDED_PROFILER_H
+#pragma once
+#ifndef AI_INCLUDED_PROFILER_H
+#define AI_INCLUDED_PROFILER_H
+
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
 
 #include <chrono>
 #include <assimp/DefaultLogger.hpp>
-#include "TinyFormatter.h"
+#include <assimp/TinyFormatter.h>
 
 #include <map>
 
@@ -67,7 +72,6 @@ public:
         // empty
     }
 
-public:
 
     /** Start a named timer */
     void BeginRegion(const std::string& region) {
@@ -95,5 +99,5 @@ private:
 }
 }
 
-#endif
+#endif // AI_INCLUDED_PROFILER_H
 

+ 6 - 2
thirdparty/assimp/include/assimp/ProgressHandler.hpp

@@ -47,9 +47,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_PROGRESSHANDLER_H_INC
 #define AI_PROGRESSHANDLER_H_INC
 
-#include "types.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
 
-namespace Assimp    {
+namespace Assimp {
 
 // ------------------------------------------------------------------------------------
 /** @brief CPP-API: Abstract interface for custom progress report receivers.

+ 5 - 3
thirdparty/assimp/include/assimp/RemoveComments.h

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -43,9 +42,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Declares a helper class, "CommentRemover", which can be
  *  used to remove comments (single and multi line) from a text file.
  */
+#pragma once
 #ifndef AI_REMOVE_COMMENTS_H_INC
 #define AI_REMOVE_COMMENTS_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
 
 #include <assimp/defs.h>
 
@@ -58,8 +61,7 @@ namespace Assimp    {
  *  to those in C or C++ so this code has been moved to a separate
  *  module.
  */
-class ASSIMP_API CommentRemover
-{
+class ASSIMP_API CommentRemover {
     // class cannot be instanced
     CommentRemover() {}
 

+ 5 - 0
thirdparty/assimp/include/assimp/SGSpatialSort.h

@@ -42,9 +42,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** Small helper classes to optimize finding vertices close to a given location
  */
+#pragma once
 #ifndef AI_D3DSSPATIALSORT_H_INC
 #define AI_D3DSSPATIALSORT_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
 #include <vector>
 #include <stdint.h>

+ 10 - 1
thirdparty/assimp/include/assimp/SceneCombiner.h

@@ -43,17 +43,22 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Declares a helper class, "SceneCombiner" providing various
  *  utilities to merge scenes.
  */
+#pragma once
 #ifndef AI_SCENE_COMBINER_H_INC
 #define AI_SCENE_COMBINER_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/ai_assert.h>
 #include <assimp/types.h>
 #include <assimp/Defines.h>
+
 #include <stddef.h>
 #include <set>
 #include <list>
 #include <stdint.h>
-
 #include <vector>
 
 struct aiScene;
@@ -65,8 +70,10 @@ struct aiLight;
 struct aiMetadata;
 struct aiBone;
 struct aiMesh;
+struct aiAnimMesh;
 struct aiAnimation;
 struct aiNodeAnim;
+struct aiMeshMorphAnim;
 
 namespace Assimp    {
 
@@ -363,6 +370,7 @@ public:
     static void Copy     (aiMesh** dest, const aiMesh* src);
 
     // similar to Copy():
+    static void Copy  (aiAnimMesh** dest, const aiAnimMesh* src);
     static void Copy  (aiMaterial** dest, const aiMaterial* src);
     static void Copy  (aiTexture** dest, const aiTexture* src);
     static void Copy  (aiAnimation** dest, const aiAnimation* src);
@@ -370,6 +378,7 @@ public:
     static void Copy  (aiBone** dest, const aiBone* src);
     static void Copy  (aiLight** dest, const aiLight* src);
     static void Copy  (aiNodeAnim** dest, const aiNodeAnim* src);
+    static void Copy  (aiMeshMorphAnim** dest, const aiMeshMorphAnim* src);
     static void Copy  (aiMetadata** dest, const aiMetadata* src);
 
     // recursive, of course

+ 5 - 0
thirdparty/assimp/include/assimp/SkeletonMeshBuilder.h

@@ -47,9 +47,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  for animation skeletons.
  */
 
+#pragma once
 #ifndef AI_SKELETONMESHBUILDER_H_INC
 #define AI_SKELETONMESHBUILDER_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <vector>
 #include <assimp/mesh.h>
 

+ 6 - 0
thirdparty/assimp/include/assimp/SmoothingGroups.h

@@ -43,10 +43,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Defines the helper data structures for importing 3DS files.
 http://www.jalix.org/ressources/graphics/3DS/_unofficials/3ds-unofficial.txt */
 
+#pragma once
 #ifndef AI_SMOOTHINGGROUPS_H_INC
 #define AI_SMOOTHINGGROUPS_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/vector3.h>
+
 #include <stdint.h>
 #include <vector>
 

+ 5 - 2
thirdparty/assimp/include/assimp/SmoothingGroups.inl

@@ -41,13 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** @file Generation of normal vectors basing on smoothing groups */
 
+#pragma once
 #ifndef AI_SMOOTHINGGROUPS_INL_INCLUDED
 #define AI_SMOOTHINGGROUPS_INL_INCLUDED
 
-// internal headers
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/SGSpatialSort.h>
 
-// CRT header
 #include <algorithm>
 
 using namespace Assimp;

+ 5 - 0
thirdparty/assimp/include/assimp/SpatialSort.h

@@ -41,9 +41,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** Small helper classes to optimise finding vertizes close to a given location */
+#pragma once
 #ifndef AI_SPATIALSORT_H_INC
 #define AI_SPATIALSORT_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <vector>
 #include <assimp/types.h>
 

+ 6 - 1
thirdparty/assimp/include/assimp/StandardShapes.h

@@ -41,11 +41,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
 
 /** @file Declares a helper class, "StandardShapes" which generates
- *  vertices for standard shapes, such as cylnders, cones, spheres ..
+ *  vertices for standard shapes, such as cylinders, cones, spheres ..
  */
+#pragma once
 #ifndef AI_STANDARD_SHAPES_H_INC
 #define AI_STANDARD_SHAPES_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/vector3.h>
 #include <vector>
 

+ 7 - 3
thirdparty/assimp/include/assimp/StreamReader.h

@@ -44,15 +44,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file Defines the StreamReader class which reads data from
  *  a binary stream with a well-defined endianness.
  */
-
+#pragma once
 #ifndef AI_STREAMREADER_H_INCLUDED
 #define AI_STREAMREADER_H_INCLUDED
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/IOStream.hpp>
 #include <assimp/Defines.h>
+#include <assimp/ByteSwapper.h>
+#include <assimp/Exceptional.h>
 
-#include "ByteSwapper.h"
-#include "Exceptional.h"
 #include <memory>
 
 namespace Assimp {

+ 6 - 2
thirdparty/assimp/include/assimp/StreamWriter.h

@@ -43,11 +43,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 /** @file Defines the StreamWriter class which writes data to
  *  a binary stream with a well-defined endianness. */
-
+#pragma once
 #ifndef AI_STREAMWRITER_H_INCLUDED
 #define AI_STREAMWRITER_H_INCLUDED
 
-#include "ByteSwapper.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/ByteSwapper.h>
 #include <assimp/IOStream.hpp>
 
 #include <memory>

+ 6 - 1
thirdparty/assimp/include/assimp/StringComparison.h

@@ -49,12 +49,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    These functions are not consistently available on all platforms,
    or the provided implementations behave too differently.
 */
+#pragma once
 #ifndef INCLUDED_AI_STRING_WORKERS_H
 #define INCLUDED_AI_STRING_WORKERS_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/ai_assert.h>
 #include <assimp/defs.h>
-#include "StringComparison.h"
+#include <assimp/StringComparison.h>
 
 #include <string.h>
 #include <stdint.h>

+ 5 - 0
thirdparty/assimp/include/assimp/StringUtils.h

@@ -39,9 +39,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 ----------------------------------------------------------------------
 */
+#pragma once
 #ifndef INCLUDED_AI_STRINGUTILS_H
 #define INCLUDED_AI_STRINGUTILS_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/defs.h>
 
 #include <sstream>

+ 4 - 1
thirdparty/assimp/include/assimp/Subdivision.h

@@ -45,7 +45,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_SUBDISIVION_H_INC
 #define AI_SUBDISIVION_H_INC
 
-#include <cstddef>
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
 
 struct aiMesh;

+ 12 - 20
thirdparty/assimp/include/assimp/TinyFormatter.h

@@ -45,9 +45,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *    to get rid of the boost::format dependency. Much slinker,
  *    basically just extends stringstream.
  */
+#pragma once
 #ifndef INCLUDED_TINY_FORMATTER_H
 #define INCLUDED_TINY_FORMATTER_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <sstream>
 
 namespace Assimp {
@@ -65,24 +70,15 @@ namespace Formatter {
  *  @endcode */
 template < typename T,
     typename CharTraits = std::char_traits<T>,
-    typename Allocator  = std::allocator<T>
->
-class basic_formatter
-{
-
-public:
-
-    typedef class std::basic_string<
-        T,CharTraits,Allocator
-    > string;
-
-    typedef class std::basic_ostringstream<
-        T,CharTraits,Allocator
-    > stringstream;
-
+    typename Allocator  = std::allocator<T> >
+class basic_formatter {
 public:
+    typedef class std::basic_string<T,CharTraits,Allocator> string;
+    typedef class std::basic_ostringstream<T,CharTraits,Allocator> stringstream;
 
-    basic_formatter() {}
+    basic_formatter() {
+        // empty
+    }
 
     /* Allow basic_formatter<T>'s to be used almost interchangeably
      * with std::(w)string or const (w)char* arguments because the
@@ -104,14 +100,10 @@ public:
     }
 #endif
 
-
-public:
-
     operator string () const {
         return underlying.str();
     }
 
-
     /* note - this is declared const because binding temporaries does only
      * work for const references, so many function prototypes will
      * include const basic_formatter<T>& s but might still want to

+ 8 - 59
thirdparty/assimp/include/assimp/Vertex.h

@@ -47,12 +47,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   that are not currently well-defined (and would cause compile errors
   due to missing operators in the math library), are commented.
   */
+#pragma once
 #ifndef AI_VERTEX_H_INC
 #define AI_VERTEX_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/vector3.h>
 #include <assimp/mesh.h>
 #include <assimp/ai_assert.h>
+
 #include <functional>
 
 namespace Assimp    {
@@ -91,23 +97,14 @@ namespace Assimp    {
  *  to *all* vertex components equally. This is useful for stuff like interpolation
  *  or subdivision, but won't work if special handling is required for some vertex components. */
 // ------------------------------------------------------------------------------------------------
-class Vertex
-{
+class Vertex {
     friend Vertex operator + (const Vertex&,const Vertex&);
     friend Vertex operator - (const Vertex&,const Vertex&);
-
-//  friend Vertex operator + (const Vertex&,ai_real);
-//  friend Vertex operator - (const Vertex&,ai_real);
     friend Vertex operator * (const Vertex&,ai_real);
     friend Vertex operator / (const Vertex&,ai_real);
-
-//  friend Vertex operator + (ai_real, const Vertex&);
-//  friend Vertex operator - (ai_real, const Vertex&);
     friend Vertex operator * (ai_real, const Vertex&);
-//  friend Vertex operator / (ai_real, const Vertex&);
 
 public:
-
     Vertex() {}
 
     // ----------------------------------------------------------------------------
@@ -158,8 +155,6 @@ public:
         }
     }
 
-public:
-
     Vertex& operator += (const Vertex& v) {
         *this = *this+v;
         return *this;
@@ -170,18 +165,6 @@ public:
         return *this;
     }
 
-
-/*
-    Vertex& operator += (ai_real v) {
-        *this = *this+v;
-        return *this;
-    }
-
-    Vertex& operator -= (ai_real v) {
-        *this = *this-v;
-        return *this;
-    }
-*/
     Vertex& operator *= (ai_real v) {
         *this = *this*v;
         return *this;
@@ -192,12 +175,9 @@ public:
         return *this;
     }
 
-public:
-
     // ----------------------------------------------------------------------------
     /** Convert back to non-interleaved storage */
     void SortBack(aiMesh* out, unsigned int idx) const {
-
         ai_assert(idx<out->mNumVertices);
         out->mVertices[idx] = position;
 
@@ -291,8 +271,6 @@ public:
     aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
 };
 
-
-
 // ------------------------------------------------------------------------------------------------
 AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
     return Vertex::BinaryOp<std::plus>(v0,v1);
@@ -302,19 +280,6 @@ AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
     return Vertex::BinaryOp<std::minus>(v0,v1);
 }
 
-
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (const Vertex& v0,ai_real f) {
-    return Vertex::BinaryOp<Intern::plus>(v0,f);
-}
-
-AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) {
-    return Vertex::BinaryOp<Intern::minus>(v0,f);
-}
-
-*/
-
 AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) {
     return Vertex::BinaryOp<Intern::multiplies>(v0,f);
 }
@@ -323,26 +288,10 @@ AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) {
     return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
 }
 
-// ------------------------------------------------------------------------------------------------
-/*
-AI_FORCE_INLINE Vertex operator + (ai_real f,const Vertex& v0) {
-    return Vertex::BinaryOp<Intern::plus>(f,v0);
-}
-
-AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) {
-    return Vertex::BinaryOp<Intern::minus>(f,v0);
-}
-*/
-
 AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) {
     return Vertex::BinaryOp<Intern::multiplies>(f,v0);
 }
 
-/*
-AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) {
-    return Vertex::BinaryOp<Intern::divides>(f,v0);
 }
-*/
 
-}
-#endif
+#endif // AI_VERTEX_H_INC

+ 5 - 0
thirdparty/assimp/include/assimp/XMLTools.h

@@ -40,9 +40,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 */
 
+#pragma once
 #ifndef INCLUDED_ASSIMP_XML_TOOLS_H
 #define INCLUDED_ASSIMP_XML_TOOLS_H
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <string>
 
 namespace Assimp {

+ 7 - 4
thirdparty/assimp/include/assimp/aabb.h

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -45,6 +43,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_AABB_H_INC
 #define AI_AABB_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/vector3.h>
 
 struct aiAABB {
@@ -69,8 +71,9 @@ struct aiAABB {
         // empty
     }
 
-#endif 
+#endif // __cplusplus
+
 };
 
 
-#endif
+#endif // AI_AABB_H_INC

+ 4 - 0
thirdparty/assimp/include/assimp/ai_assert.h

@@ -44,6 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASSERT_H_INC
 #define AI_ASSERT_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifdef ASSIMP_BUILD_DEBUG
 #   include <assert.h>
 #   define ai_assert(expression) assert( expression )

+ 4 - 0
thirdparty/assimp/include/assimp/anim.h

@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ANIM_H_INC
 #define AI_ANIM_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
 #include <assimp/quaternion.h>
 

+ 4 - 2
thirdparty/assimp/include/assimp/camera.h

@@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_CAMERA_H_INC
 #define AI_CAMERA_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include "types.h"
 
 #ifdef __cplusplus
@@ -113,7 +117,6 @@ struct aiCamera
      */
     C_STRUCT aiVector3D mPosition;
 
-
     /** 'Up' - vector of the camera coordinate system relative to
      *  the coordinate space defined by the corresponding node.
      *
@@ -134,7 +137,6 @@ struct aiCamera
      */
     C_STRUCT aiVector3D mLookAt;
 
-
     /** Half horizontal field of view angle, in radians.
      *
      *  The field of view angle is the angle between the center

+ 5 - 1
thirdparty/assimp/include/assimp/cexport.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 
-Copyright (c) 2006-2011, assimp team
+Copyright (c) 2006-2019, assimp team
 
 All rights reserved.
 
@@ -46,6 +46,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_EXPORT_H_INC
 #define AI_EXPORT_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifndef ASSIMP_BUILD_NO_EXPORT
 
 // Public ASSIMP data structures

+ 6 - 0
thirdparty/assimp/include/assimp/cfileio.h

@@ -48,10 +48,16 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_FILEIO_H_INC
 #define AI_FILEIO_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
+
 struct aiFileIO;
 struct aiFile;
 

+ 5 - 1
thirdparty/assimp/include/assimp/cimport.h

@@ -48,8 +48,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_ASSIMP_H_INC
 #define AI_ASSIMP_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
-#include "importerdesc.h"
+#include <assimp/importerdesc.h>
 
 #ifdef __cplusplus
 extern "C" {

+ 6 - 7
thirdparty/assimp/include/assimp/color4.h

@@ -47,7 +47,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_COLOR4D_H_INC
 #define AI_COLOR4D_H_INC
 
-#include "defs.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
 
 #ifdef __cplusplus
 
@@ -56,8 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *   alpha component. Color values range from 0 to 1. */
 // ----------------------------------------------------------------------------------
 template <typename TReal>
-class aiColor4t
-{
+class aiColor4t {
 public:
     aiColor4t() AI_NO_EXCEPT : r(), g(), b(), a() {}
     aiColor4t (TReal _r, TReal _g, TReal _b, TReal _a)
@@ -65,14 +68,12 @@ public:
     explicit aiColor4t (TReal _r) : r(_r), g(_r), b(_r), a(_r) {}
     aiColor4t (const aiColor4t& o) = default;
 
-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;
@@ -85,8 +86,6 @@ public:
     /** 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;
 };  // !struct aiColor4D

+ 68 - 26
thirdparty/assimp/include/assimp/color4.inl

@@ -48,36 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_COLOR4D_INL_INC
 #define AI_COLOR4D_INL_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifdef __cplusplus
-#include "color4.h"
+#include <assimp/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;
+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;
+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;
+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;
+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 {
+AI_FORCE_INLINE
+TReal aiColor4t<TReal>::operator[](unsigned int i) const {
     switch ( i ) {
         case 0:
             return r;
@@ -94,7 +119,8 @@ AI_FORCE_INLINE TReal aiColor4t<TReal>::operator[](unsigned int i) const {
 }
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
+AI_FORCE_INLINE
+TReal& aiColor4t<TReal>::operator[](unsigned int i) {
     switch ( i ) {
         case 0:
             return r;
@@ -111,17 +137,20 @@ AI_FORCE_INLINE TReal& aiColor4t<TReal>::operator[](unsigned int i) {
 }
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-AI_FORCE_INLINE bool aiColor4t<TReal>::operator== (const aiColor4t<TReal>& other) const {
+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 {
+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 {
+AI_FORCE_INLINE
+bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other) const {
     return r < other.r || (
         r == other.r && (
             g < other.g || (
@@ -136,14 +165,17 @@ AI_FORCE_INLINE bool aiColor4t<TReal>::operator< (const aiColor4t<TReal>& other)
         )
     );
 }
+
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator + (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)    {
+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)    {
+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);
 }
 // ------------------------------------------------------------------------------------------------
@@ -153,53 +185,63 @@ AI_FORCE_INLINE aiColor4t<TReal> operator * (const aiColor4t<TReal>& v1, const a
 }
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-AI_FORCE_INLINE aiColor4t<TReal> operator / (const aiColor4t<TReal>& v1, const aiColor4t<TReal>& v2)    {
+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)   {
+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)  {
+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)  {
+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)   {
+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)  {
+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)  {
+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)  {
+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)  {
+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 {
+AI_FORCE_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;

+ 30 - 13
thirdparty/assimp/include/assimp/defs.h

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -50,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_DEFINES_H_INC
 #define AI_DEFINES_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/config.h>
 
 //////////////////////////////////////////////////////////////////////////
@@ -126,16 +128,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * GENBOUNDINGBOXES */
 //////////////////////////////////////////////////////////////////////////
 
-#ifdef _MSC_VER
+#ifdef _WIN32
 #   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
@@ -148,7 +148,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #       define ASSIMP_API
 #       define ASSIMP_API_WINONLY
 #   endif
+#elif defined(SWIG)
+
+    /* Do nothing, the relevant defines are all in AssimpSwigPort.i */
 
+#else
+#   define ASSIMP_API __attribute__ ((visibility("default")))
+#   define ASSIMP_API_WINONLY
+#endif
+
+#ifdef _MSC_VER
+#   ifdef ASSIMP_BUILD_DLL_EXPORT
+#       pragma warning (disable : 4251)
+#   endif
     /* Force the compiler to inline a function, if possible
      */
 #   define AI_FORCE_INLINE __forceinline
@@ -156,17 +168,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     /* 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)
 
@@ -291,9 +298,10 @@ static const ai_real ai_epsilon = (ai_real) 0.00001;
 #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
+/**
+ *  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))
 
@@ -307,4 +315,13 @@ static const ai_real ai_epsilon = (ai_real) 0.00001;
 #  endif
 #endif // _MSC_VER
 
+/**
+ *  Helper macro to set a pointer to NULL in debug builds
+ */
+#if (defined ASSIMP_BUILD_DEBUG)
+#   define AI_DEBUG_INVALIDATE_PTR(x) x = NULL;
+#else
+#   define AI_DEBUG_INVALIDATE_PTR(x)
+#endif
+
 #endif // !! AI_DEFINES_H_INC

+ 5 - 1
thirdparty/assimp/include/assimp/fast_atof.h

@@ -13,10 +13,14 @@
 //     to ensure long numbers are handled correctly
 // ------------------------------------------------------------------------------------
 
-
+#pragma once
 #ifndef FAST_A_TO_F_H_INCLUDED
 #define FAST_A_TO_F_H_INCLUDED
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <cmath>
 #include <limits>
 #include <stdint.h>

+ 6 - 4
thirdparty/assimp/include/assimp/importerdesc.h

@@ -48,11 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_IMPORTER_DESC_H_INC
 #define AI_IMPORTER_DESC_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 
 /** Mixed set of flags for #aiImporterDesc, indicating some features
   *  common to many importers*/
-enum aiImporterFlags
-{
+enum aiImporterFlags {
     /** Indicates that there is a textual encoding of the
      *  file format; and that it is supported.*/
     aiImporterFlags_SupportTextFlavour = 0x1,
@@ -87,8 +90,7 @@ enum aiImporterFlags
  *  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
-{
+struct aiImporterDesc {
     /** Full name of the importer (i.e. Blender3D importer)*/
     const char* mName;
 

+ 5 - 1
thirdparty/assimp/include/assimp/light.h

@@ -49,7 +49,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_LIGHT_H_INC
 #define AI_LIGHT_H_INC
 
-#include "types.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
 
 #ifdef __cplusplus
 extern "C" {

+ 5 - 1
thirdparty/assimp/include/assimp/material.h

@@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_MATERIAL_H_INC
 #define AI_MATERIAL_H_INC
 
-#include "types.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/types.h>
 
 #ifdef __cplusplus
 extern "C" {

+ 132 - 133
thirdparty/assimp/include/assimp/material.inl

@@ -49,14 +49,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_MATERIAL_INL_INC
 #define AI_MATERIAL_INL_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 // ---------------------------------------------------------------------------
-inline aiPropertyTypeInfo ai_real_to_property_type_info(float)
-{
+AI_FORCE_INLINE
+aiPropertyTypeInfo ai_real_to_property_type_info(float) {
 	return aiPTI_Float;
 }
 
-inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
-{
+AI_FORCE_INLINE
+aiPropertyTypeInfo ai_real_to_property_type_info(double) {
 	return aiPTI_Double;
 }
 // ---------------------------------------------------------------------------
@@ -64,30 +68,30 @@ inline aiPropertyTypeInfo ai_real_to_property_type_info(double)
 //! @cond never
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::GetTexture( aiTextureType type,
-   unsigned int  index,
-   C_STRUCT aiString* path,
-   aiTextureMapping* mapping    /*= NULL*/,
-   unsigned int* uvindex        /*= NULL*/,
-   ai_real* blend               /*= NULL*/,
-   aiTextureOp* op              /*= NULL*/,
-   aiTextureMapMode* mapmode    /*= NULL*/) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::GetTexture( aiTextureType type,
+       unsigned int  index,
+       C_STRUCT aiString* path,
+       aiTextureMapping* mapping    /*= NULL*/,
+       unsigned int* uvindex        /*= NULL*/,
+       ai_real* 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
-{
+AI_FORCE_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
-{
+AI_FORCE_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;
@@ -114,9 +118,9 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
 
 // ---------------------------------------------------------------------------
 template <typename Type>
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
-    unsigned int idx,Type& pOut) const
-{
+AI_FORCE_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);
@@ -136,60 +140,56 @@ inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
-    unsigned int idx,ai_real* pOut,
-    unsigned int* pMax) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+        unsigned int idx,ai_real* 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
-{
+AI_FORCE_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,ai_real& pOut) const
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::Get(const char* pKey,unsigned int type,
+        unsigned int idx,ai_real& 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
-{
+AI_FORCE_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
-{
+AI_FORCE_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
-{
+AI_FORCE_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
-{
+AI_FORCE_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
-{
+AI_FORCE_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,
@@ -204,84 +204,83 @@ aiReturn aiMaterial::AddProperty (const TYPE* pInput,
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const float* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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 double* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty(const double* pInput,
+        const unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type,
+        unsigned int index) {
     return AddBinaryProperty((const void*)pInput,
         pNumValues * sizeof(double),
         pKey,type,index,aiPTI_Double);
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiUVTransform* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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,ai_real_to_property_type_info(pInput->mRotation));
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiColor4D* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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,ai_real_to_property_type_info(pInput->a));
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiColor3D* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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,ai_real_to_property_type_info(pInput->b));
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const aiVector3D* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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,ai_real_to_property_type_info(pInput->x));
 }
 
 // ---------------------------------------------------------------------------
-inline aiReturn aiMaterial::AddProperty(const int* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);
@@ -296,12 +295,12 @@ inline aiReturn aiMaterial::AddProperty(const int* pInput,
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);
@@ -309,12 +308,12 @@ inline aiReturn aiMaterial::AddProperty<float>(const float* pInput,
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_INLINE
+aiReturn aiMaterial::AddProperty<double>(const double* pInput,
+        const unsigned int pNumValues,
+        const char* pKey,
+        unsigned int type,
+        unsigned int index) {
     return AddBinaryProperty((const void*)pInput,
         pNumValues * sizeof(double),
         pKey,type,index,aiPTI_Double);
@@ -322,12 +321,12 @@ inline aiReturn aiMaterial::AddProperty<double>(const double* pInput,
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);
@@ -335,12 +334,12 @@ inline aiReturn aiMaterial::AddProperty<aiUVTransform>(const aiUVTransform* pInp
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);
@@ -348,12 +347,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor4D>(const aiColor4D* pInput,
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);
@@ -361,12 +360,12 @@ inline aiReturn aiMaterial::AddProperty<aiColor3D>(const aiColor3D* pInput,
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);
@@ -374,12 +373,12 @@ inline aiReturn aiMaterial::AddProperty<aiVector3D>(const aiVector3D* pInput,
 
 // ---------------------------------------------------------------------------
 template<>
-inline aiReturn aiMaterial::AddProperty<int>(const int* pInput,
-    const unsigned int pNumValues,
-    const char* pKey,
-    unsigned int type,
-    unsigned int index)
-{
+AI_FORCE_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);

+ 6 - 9
thirdparty/assimp/include/assimp/matrix3x3.h

@@ -48,7 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_MATRIX3X3_H_INC
 #define AI_MATRIX3X3_H_INC
 
-#include "defs.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/defs.h>
 
 #ifdef __cplusplus
 
@@ -65,10 +69,8 @@ template <typename T> class aiVector2t;
  *  defined thereby.
  */
 template <typename TReal>
-class aiMatrix3x3t
-{
+class aiMatrix3x3t {
 public:
-
     aiMatrix3x3t() AI_NO_EXCEPT :
         a1(static_cast<TReal>(1.0f)), a2(), a3(),
         b1(), b2(static_cast<TReal>(1.0f)), b3(),
@@ -82,8 +84,6 @@ public:
         c1(_c1), c2(_c2), c3(_c3)
     {}
 
-public:
-
     // matrix multiplication.
     aiMatrix3x3t& operator *= (const aiMatrix3x3t& m);
     aiMatrix3x3t  operator  * (const aiMatrix3x3t& m) const;
@@ -101,8 +101,6 @@ public:
     template <typename TOther>
     operator aiMatrix3x3t<TOther> () const;
 
-public:
-
     // -------------------------------------------------------------------
     /** @brief Construction from a 4x4 matrix. The remaining parts
      *  of the matrix are ignored.
@@ -122,7 +120,6 @@ public:
     aiMatrix3x3t& Inverse();
     TReal Determinant() const;
 
-public:
     // -------------------------------------------------------------------
     /** @brief Returns a rotation matrix for a rotation around z
      *  @param a Rotation angle, in radians

+ 37 - 33
thirdparty/assimp/include/assimp/matrix3x3.inl

@@ -48,10 +48,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_MATRIX3X3_INL_INC
 #define AI_MATRIX3X3_INL_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #ifdef __cplusplus
-#include "matrix3x3.h"
+#include <assimp/matrix3x3.h>
+#include <assimp/matrix4x4.h>
 
-#include "matrix4x4.h"
 #include <algorithm>
 #include <cmath>
 #include <limits>
@@ -59,8 +63,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // ------------------------------------------------------------------------------------------------
 // Construction from a 4x4 matrix. The remaining parts of the matrix are ignored.
 template <typename TReal>
-inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
-{
+AI_FORCE_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;
@@ -68,8 +72,8 @@ inline aiMatrix3x3t<TReal>::aiMatrix3x3t( const aiMatrix4x4t<TReal>& pMatrix)
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t<TReal>& m)
-{
+AI_FORCE_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,
@@ -85,8 +89,7 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::operator *= (const aiMatrix3x3t
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
 template <typename TOther>
-aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
-{
+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));
@@ -94,8 +97,8 @@ aiMatrix3x3t<TReal>::operator aiMatrix3x3t<TOther> () const
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TReal>& m) const {
     aiMatrix3x3t<TReal> temp( *this);
     temp *= m;
     return temp;
@@ -103,7 +106,8 @@ inline aiMatrix3x3t<TReal> aiMatrix3x3t<TReal>::operator* (const aiMatrix3x3t<TR
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
+AI_FORCE_INLINE
+TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
     switch ( p_iIndex ) {
         case 0:
             return &a1;
@@ -119,7 +123,8 @@ inline TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) {
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
+AI_FORCE_INLINE
+const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) const {
     switch ( p_iIndex ) {
         case 0:
             return &a1;
@@ -135,8 +140,8 @@ inline const TReal* aiMatrix3x3t<TReal>::operator[] (unsigned int p_iIndex) cons
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_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;
@@ -144,14 +149,15 @@ inline bool aiMatrix3x3t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix3x3t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_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 {
+AI_FORCE_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 &&
@@ -166,8 +172,8 @@ inline bool aiMatrix3x3t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
-{
+AI_FORCE_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);
@@ -177,15 +183,15 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Transpose()
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline TReal aiMatrix3x3t<TReal>::Determinant() const
-{
+AI_FORCE_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()
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse() {
     // Compute the reciprocal determinant
     TReal det = Determinant();
     if(det == static_cast<TReal>(0.0))
@@ -219,8 +225,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Inverse()
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_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;
@@ -234,8 +240,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::RotationZ(TReal a, aiMatrix3x3t
 // ------------------------------------------------------------------------------------------------
 // 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)
-{
+AI_FORCE_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;
 
@@ -249,8 +255,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Rotation( TReal a, const aiVect
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<TReal>& v, aiMatrix3x3t<TReal>& out) {
     out = aiMatrix3x3t<TReal>();
     out.a3 = v.x;
     out.b3 = v.y;
@@ -268,9 +274,8 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::Translation( const aiVector2t<T
  */
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
-    const aiVector3t<TReal>& to, aiMatrix3x3t<TReal>& mtx)
-{
+AI_FORCE_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;
 
@@ -352,6 +357,5 @@ inline aiMatrix3x3t<TReal>& aiMatrix3x3t<TReal>::FromToMatrix(const aiVector3t<T
     return mtx;
 }
 
-
 #endif // __cplusplus
 #endif // AI_MATRIX3X3_INL_INC

+ 7 - 11
thirdparty/assimp/include/assimp/matrix4x4.h

@@ -47,8 +47,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_MATRIX4X4_H_INC
 #define AI_MATRIX4X4_H_INC
 
-#include "vector3.h"
-#include "defs.h"
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
+#include <assimp/vector3.h>
+#include <assimp/defs.h>
 
 #ifdef __cplusplus
 
@@ -66,8 +70,7 @@ template<typename TReal> class aiQuaterniont;
  *  defined thereby.
  */
 template<typename TReal>
-class aiMatrix4x4t
-{
+class aiMatrix4x4t {
 public:
 
     /** set to identity */
@@ -91,8 +94,6 @@ public:
     aiMatrix4x4t(const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation,
         const aiVector3t<TReal>& position);
 
-public:
-
     // array access operators
 	/** @fn TReal* operator[] (unsigned int p_iIndex)
 	 *  @param [in] p_iIndex - index of the row.
@@ -120,8 +121,6 @@ public:
     template <typename TOther>
     operator aiMatrix4x4t<TOther> () const;
 
-public:
-
     // -------------------------------------------------------------------
     /** @brief Transpose the matrix */
     aiMatrix4x4t& Transpose();
@@ -182,7 +181,6 @@ public:
     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
@@ -192,7 +190,6 @@ public:
     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
@@ -256,7 +253,6 @@ public:
     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;

+ 85 - 94
thirdparty/assimp/include/assimp/matrix4x4.inl

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -53,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "matrix4x4.h"
 #include "matrix3x3.h"
 #include "quaternion.h"
+#include "MathFunctions.h"
 
 #include <algorithm>
 #include <limits>
@@ -61,12 +60,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
 aiMatrix4x4t<TReal>::aiMatrix4x4t() AI_NO_EXCEPT :
-    a1(1.0f), a2(), a3(), a4(),
-    b1(), b2(1.0f), b3(), b4(),
-    c1(), c2(), c3(1.0f), c4(),
-    d1(), d2(), d3(), d4(1.0f)
-{
-
+        a1(1.0f), a2(), a3(), a4(),
+        b1(), b2(1.0f), b3(), b4(),
+        c1(), c2(), c3(1.0f), c4(),
+        d1(), d2(), d3(), d4(1.0f) {
+    // empty
 }
 
 // ----------------------------------------------------------------------------------------
@@ -75,19 +73,17 @@ 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)
-{
-
+        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) {
+    // empty
 }
 
 // ------------------------------------------------------------------------------------------------
 template <typename TReal>
 template <typename TOther>
-aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
-{
+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),
@@ -97,8 +93,8 @@ aiMatrix4x4t<TReal>::operator aiMatrix4x4t<TOther> () const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
-{
+AI_FORCE_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);
@@ -107,8 +103,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiMatrix3x3t<TReal>& m)
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, const aiQuaterniont<TReal>& rotation, const aiVector3t<TReal>& position)
-{
+AI_FORCE_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();
 
@@ -135,8 +131,8 @@ inline aiMatrix4x4t<TReal>::aiMatrix4x4t (const aiVector3t<TReal>& scaling, cons
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t<TReal>& m)
-{
+AI_FORCE_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,
@@ -159,8 +155,7 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::operator *= (const aiMatrix4x4t
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat) const {
     aiMatrix4x4t<TReal> temp(
         a1 * aFloat,
         a2 * aFloat,
@@ -183,8 +178,8 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const TReal& aFloat)
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TReal>& m) const {
     aiMatrix4x4t<TReal> temp(
         m.a1 + a1,
         m.a2 + a2,
@@ -207,18 +202,16 @@ inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator+ (const aiMatrix4x4t<TR
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal> aiMatrix4x4t<TReal>::operator* (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_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()
-{
+AI_FORCE_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);
@@ -229,11 +222,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Transpose()
     return *this;
 }
 
-
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline TReal aiMatrix4x4t<TReal>::Determinant() const
-{
+AI_FORCE_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
@@ -244,8 +236,8 @@ inline TReal aiMatrix4x4t<TReal>::Determinant() const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse() {
     // Compute the reciprocal determinant
     const TReal det = Determinant();
     if(det == static_cast<TReal>(0.0))
@@ -289,9 +281,10 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Inverse()
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
+AI_FORCE_INLINE
+TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
     if (p_iIndex > 3) {
-        return NULL;
+        return nullptr;
     }
     switch ( p_iIndex ) {
         case 0:
@@ -310,9 +303,10 @@ inline TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) {
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
+AI_FORCE_INLINE
+const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const {
     if (p_iIndex > 3) {
-        return NULL;
+        return nullptr;
     }
 
     switch ( p_iIndex ) {
@@ -332,8 +326,8 @@ inline const TReal* aiMatrix4x4t<TReal>::operator[](unsigned int p_iIndex) const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_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 &&
@@ -342,14 +336,15 @@ inline bool aiMatrix4x4t<TReal>::operator== (const aiMatrix4x4t<TReal>& m) const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::operator!= (const aiMatrix4x4t<TReal>& m) const
-{
+AI_FORCE_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 {
+AI_FORCE_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 &&
@@ -401,13 +396,10 @@ inline bool aiMatrix4x4t<TReal>::Equal(const aiMatrix4x4t<TReal>& m, TReal epsil
 	\
 	do {} while(false)
 
-
-
-
 template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
-    aiVector3t<TReal>& pPosition) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuaterniont<TReal>& pRotation,
+        aiVector3t<TReal>& pPosition) const {
 	ASSIMP_MATRIX4_4_DECOMPOSE_PART;
 
     // build a 3x3 rotation matrix
@@ -420,8 +412,8 @@ inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuate
 }
 
 template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const {
 	ASSIMP_MATRIX4_4_DECOMPOSE_PART;
 
     /*
@@ -442,7 +434,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
 	*/
 
 	// Use a small epsilon to solve floating-point inaccuracies
-    const TReal epsilon = 10e-3f;
+    const TReal epsilon = Assimp::Math::getEpsilon<TReal>();
 
 	pRotation.y  = std::asin(-vCols[0].z);// D. Angle around oY.
 
@@ -475,10 +467,10 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
 #undef ASSIMP_MATRIX4_4_DECOMPOSE_PART
 
 template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
-											aiVector3t<TReal>& pPosition) const
-{
-aiQuaterniont<TReal> pRotation;
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotationAxis, TReal& pRotationAngle,
+											aiVector3t<TReal>& pPosition) const {
+    aiQuaterniont<TReal> pRotation;
 
 	Decompose(pScaling, pRotation, pPosition);
 	pRotation.Normalize();
@@ -500,9 +492,9 @@ aiQuaterniont<TReal> pRotation;
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
-    aiVector3t<TReal>& position) const
-{
+AI_FORCE_INLINE
+void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotation,
+        aiVector3t<TReal>& position) const {
     const aiMatrix4x4t<TReal>& _this = *this;
 
     // extract translation
@@ -516,15 +508,15 @@ inline void aiMatrix4x4t<TReal>::DecomposeNoScaling (aiQuaterniont<TReal>& rotat
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(const aiVector3t<TReal>& blubb)
-{
+AI_FORCE_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)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TReal y, TReal z) {
     aiMatrix4x4t<TReal>& _this = *this;
 
     TReal cx = std::cos(x);
@@ -552,8 +544,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromEulerAnglesXYZ(TReal x, TRe
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline bool aiMatrix4x4t<TReal>::IsIdentity() const
-{
+AI_FORCE_INLINE
+bool aiMatrix4x4t<TReal>::IsIdentity() const {
     // Use a small epsilon to solve floating-point inaccuracies
     const static TReal epsilon = 10e-3f;
 
@@ -577,8 +569,8 @@ inline bool aiMatrix4x4t<TReal>::IsIdentity() const
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t<TReal>& out) {
     /*
          |  1  0       0       0 |
      M = |  0  cos(A) -sin(A)  0 |
@@ -592,8 +584,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationX(TReal a, aiMatrix4x4t
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t<TReal>& out) {
     /*
          |  cos(A)  0   sin(A)  0 |
      M = |  0       1   0       0 |
@@ -608,8 +600,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationY(TReal a, aiMatrix4x4t
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t<TReal>& out) {
     /*
          |  cos(A)  -sin(A)   0   0 |
      M = |  sin(A)   cos(A)   0   0 |
@@ -624,26 +616,25 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::RotationZ(TReal a, aiMatrix4x4t
 // ----------------------------------------------------------------------------------------
 // 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;
+AI_FORCE_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)
-{
+AI_FORCE_INLINE aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
     out = aiMatrix4x4t<TReal>();
     out.a4 = v.x;
     out.b4 = v.y;
@@ -653,8 +644,8 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Translation( const aiVector3t<T
 
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out)
-{
+AI_FORCE_INLINE
+aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal>& v, aiMatrix4x4t<TReal>& out) {
     out = aiMatrix4x4t<TReal>();
     out.a1 = v.x;
     out.b2 = v.y;
@@ -673,9 +664,9 @@ inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::Scaling( const aiVector3t<TReal
  */
 // ----------------------------------------------------------------------------------------
 template <typename TReal>
-inline aiMatrix4x4t<TReal>& aiMatrix4x4t<TReal>::FromToMatrix(const aiVector3t<TReal>& from,
-    const aiVector3t<TReal>& to, aiMatrix4x4t<TReal>& mtx)
-{
+AI_FORCE_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);

+ 30 - 10
thirdparty/assimp/include/assimp/mesh.h

@@ -48,6 +48,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef AI_MESH_H_INC
 #define AI_MESH_H_INC
 
+#ifdef __GNUC__
+#   pragma GCC system_header
+#endif
+
 #include <assimp/types.h>
 #include <assimp/aabb.h>
 
@@ -248,6 +252,9 @@ struct aiVertexWeight {
 };
 
 
+// Forward declare aiNode (pointer use only)
+struct aiNode;
+
 // ---------------------------------------------------------------------------
 /** @brief A single bone of a mesh.
  *
@@ -264,6 +271,16 @@ struct aiBone {
     //! The maximum value for this member is #AI_MAX_BONE_WEIGHTS.
     unsigned int mNumWeights;
 
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
+    // The bone armature node - used for skeleton conversion
+    // you must enable aiProcess_PopulateArmatureData to populate this
+    C_STRUCT aiNode* mArmature;
+
+    // The bone node in the scene - used for skeleton conversion
+    // you must enable aiProcess_PopulateArmatureData to populate this
+    C_STRUCT aiNode* mNode;
+
+#endif
     //! The influence weights of this bone, by vertex index.
     C_STRUCT aiVertexWeight* mWeights;
 
@@ -418,11 +435,11 @@ struct aiAnimMesh
     /**Anim Mesh name */
     C_STRUCT aiString mName;
 
-    /** Replacement for aiMesh::mVertices. If this array is non-NULL,
+    /** Replacement for aiMesh::mVertices. If this array is non-nullptr,
      *  it *must* contain mNumVertices entries. The corresponding
-     *  array in the host mesh must be non-NULL as well - animation
+     *  array in the host mesh must be non-nullptr as well - animation
      *  meshes may neither add or nor remove vertex components (if
-     *  a replacement array is NULL and the corresponding source
+     *  a replacement array is nullptr and the corresponding source
      *  array is not, the source data is taken instead)*/
     C_STRUCT aiVector3D* mVertices;
 
@@ -596,7 +613,7 @@ struct aiMesh
     C_STRUCT aiVector3D* mVertices;
 
     /** Vertex normals.
-    * The array contains normalized vectors, NULL if not present.
+    * The array contains normalized vectors, nullptr 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
@@ -619,7 +636,7 @@ struct aiMesh
 
     /** Vertex tangents.
     * The tangent of a vertex points in the direction of the positive
-    * X texture axis. The array contains normalized vectors, NULL if
+    * X texture axis. The array contains normalized vectors, nullptr 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
@@ -633,7 +650,7 @@ struct aiMesh
 
     /** 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
+    * Y texture axis. The array contains normalized vectors, nullptr if not
     * present. The array is mNumVertices in size.
     * @note If the mesh contains tangents, it automatically also contains
     * bitangents.
@@ -642,14 +659,14 @@ struct aiMesh
 
     /** 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
+    * colors per vertex. nullptr 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.
+    * vertex. nullptr if not present. The array is mNumVertices in size.
     */
     C_STRUCT aiVector3D* mTextureCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
 
@@ -671,7 +688,7 @@ struct aiMesh
     C_STRUCT aiFace* mFaces;
 
     /** The number of bones this mesh contains.
-    * Can be 0, in which case the mBones array is NULL.
+    * Can be 0, in which case the mBones array is nullptr.
     */
     unsigned int mNumBones;
 
@@ -769,7 +786,10 @@ struct aiMesh
         // DO NOT REMOVE THIS ADDITIONAL CHECK
         if (mNumBones && mBones)    {
             for( unsigned int a = 0; a < mNumBones; a++) {
-                delete mBones[a];
+                if(mBones[a])
+                {
+                    delete mBones[a];
+                }
             }
             delete [] mBones;
         }

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels