Przeglądaj źródła

Merge pull request #1338 from marauder2k9-torque/AssimpImporter-update

Assimp importer update
Brian Roberts 9 miesięcy temu
rodzic
commit
70f546aafe
100 zmienionych plików z 2228 dodań i 1716 usunięć
  1. 3 2
      Engine/lib/CMakeLists.txt
  2. 47 48
      Engine/lib/assimp/Build.md
  3. 171 98
      Engine/lib/assimp/CMakeLists.txt
  4. 128 0
      Engine/lib/assimp/CODE_OF_CONDUCT.md
  5. 7 10
      Engine/lib/assimp/Dockerfile
  6. 41 47
      Engine/lib/assimp/Readme.md
  7. 0 29
      Engine/lib/assimp/cmake-modules/HunterGate.cmake
  8. 0 8
      Engine/lib/assimp/code/.editorconfig
  9. 17 9
      Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp
  10. 2 1
      Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp
  11. 3 5
      Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.h
  12. 8 124
      Engine/lib/assimp/code/AssetLib/3DS/3DSHelper.h
  13. 13 8
      Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp
  14. 2 3
      Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.h
  15. 22 8
      Engine/lib/assimp/code/AssetLib/3MF/3MFTypes.h
  16. 6 1
      Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h
  17. 6 6
      Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.cpp
  18. 1 1
      Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.h
  19. 10 9
      Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp
  20. 3 3
      Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.h
  21. 9 12
      Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp
  22. 1 1
      Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.h
  23. 142 34
      Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp
  24. 4 1
      Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.h
  25. 121 120
      Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp
  26. 5 5
      Engine/lib/assimp/code/AssetLib/AC/ACLoader.h
  27. 14 37
      Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.cpp
  28. 50 52
      Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.hpp
  29. 4 4
      Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Geometry.cpp
  30. 7 8
      Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Material.cpp
  31. 5 22
      Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Node.hpp
  32. 6 4
      Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Postprocess.cpp
  33. 22 39
      Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp
  34. 5 6
      Engine/lib/assimp/code/AssetLib/ASE/ASELoader.h
  35. 215 190
      Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp
  36. 14 14
      Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h
  37. 1 1
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.cpp
  38. 2 2
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.h
  39. 5 9
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp
  40. 1 1
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.h
  41. 7 3
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp
  42. 1 1
      Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.h
  43. 1 1
      Engine/lib/assimp/code/AssetLib/Assjson/cencode.c
  44. 67 54
      Engine/lib/assimp/code/AssetLib/Assjson/json_exporter.cpp
  45. 1 1
      Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.cpp
  46. 1 1
      Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.h
  47. 2 2
      Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp
  48. 1 1
      Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.h
  49. 19 18
      Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp
  50. 1 1
      Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.h
  51. 29 29
      Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp
  52. 1 1
      Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.h
  53. 3 4
      Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.cpp
  54. 2 2
      Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.h
  55. 2 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.cpp
  56. 2 2
      Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp
  57. 13 4
      Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h
  58. 1 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.inl
  59. 1 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderIntermediate.h
  60. 75 74
      Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.cpp
  61. 14 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.h
  62. 6 1
      Engine/lib/assimp/code/AssetLib/Blender/BlenderModifier.cpp
  63. 2 4
      Engine/lib/assimp/code/AssetLib/Blender/BlenderModifier.h
  64. 2 6
      Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.cpp
  65. 8 19
      Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.h
  66. 6 13
      Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.cpp
  67. 2 7
      Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.h
  68. 11 21
      Engine/lib/assimp/code/AssetLib/C4D/C4DImporter.cpp
  69. 2 0
      Engine/lib/assimp/code/AssetLib/C4D/C4DImporter.h
  70. 39 39
      Engine/lib/assimp/code/AssetLib/COB/COBLoader.cpp
  71. 10 10
      Engine/lib/assimp/code/AssetLib/COB/COBLoader.h
  72. 1 1
      Engine/lib/assimp/code/AssetLib/COB/COBScene.h
  73. 48 54
      Engine/lib/assimp/code/AssetLib/CSM/CSMLoader.cpp
  74. 4 5
      Engine/lib/assimp/code/AssetLib/CSM/CSMLoader.h
  75. 5 5
      Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.cpp
  76. 2 2
      Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.h
  77. 1 1
      Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.cpp
  78. 2 2
      Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.h
  79. 24 32
      Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.cpp
  80. 3 2
      Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.h
  81. 134 108
      Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.cpp
  82. 1 1
      Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.h
  83. 2 4
      Engine/lib/assimp/code/AssetLib/DXF/DXFHelper.h
  84. 292 54
      Engine/lib/assimp/code/AssetLib/DXF/DXFLoader.cpp
  85. 3 3
      Engine/lib/assimp/code/AssetLib/DXF/DXFLoader.h
  86. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXAnimation.cpp
  87. 7 7
      Engine/lib/assimp/code/AssetLib/FBX/FBXBinaryTokenizer.cpp
  88. 2 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXCommon.h
  89. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXCompileConfig.h
  90. 142 57
      Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.cpp
  91. 2 2
      Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.h
  92. 10 6
      Engine/lib/assimp/code/AssetLib/FBX/FBXDeformer.cpp
  93. 34 16
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.cpp
  94. 30 20
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.h
  95. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.cpp
  96. 2 3
      Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.h
  97. 2 2
      Engine/lib/assimp/code/AssetLib/FBX/FBXExportNode.cpp
  98. 15 18
      Engine/lib/assimp/code/AssetLib/FBX/FBXExportNode.h
  99. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXExportProperty.cpp
  100. 1 1
      Engine/lib/assimp/code/AssetLib/FBX/FBXExportProperty.h

+ 3 - 2
Engine/lib/CMakeLists.txt

@@ -6,6 +6,8 @@ set(ZLIB_ROOT "${ZLIB_ROOT}" CACHE STRING "ZLib root location" FORCE)
 mark_as_advanced(ZLIB_ROOT)
 mark_as_advanced(ZLIB_ROOT)
 # Png depends on zlib
 # Png depends on zlib
 add_subdirectory(zlib ${TORQUE_LIB_TARG_DIRECTORY}/zlib EXCLUDE_FROM_ALL)
 add_subdirectory(zlib ${TORQUE_LIB_TARG_DIRECTORY}/zlib EXCLUDE_FROM_ALL)
+set(ZLIB_FOUND 1)
+set(ZLIB_LIBRARIES zlib)
 
 
 if(APPLE)
 if(APPLE)
     enable_language(OBJC)
     enable_language(OBJC)
@@ -116,8 +118,7 @@ add_subdirectory(convexMath ${TORQUE_LIB_TARG_DIRECTORY}/convexMath EXCLUDE_FROM
 
 
 # Assimp
 # Assimp
 advanced_option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
 advanced_option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
-set(ASSIMP_BUILD_NO_OWN_ZLIB ON CACHE BOOL "" FORCE)
-mark_as_advanced(ASSIMP_BUILD_NO_OWN_ZLIB)
+advanced_option(ASSIMP_BUILD_NO_OWN_ZLIB "" ON)
 advanced_option(BUILD_SHARED_LIBS "Build package with shared libraries." OFF )
 advanced_option(BUILD_SHARED_LIBS "Build package with shared libraries." OFF )
 advanced_option(ASSIMP_BUILD_FRAMEWORK "Build package as Mac OS X Framework bundle." OFF )
 advanced_option(ASSIMP_BUILD_FRAMEWORK "Build package as Mac OS X Framework bundle." OFF )
 advanced_option(ASSIMP_DOUBLE_PRECISION "Set to ON to enable double precision processing" OFF )
 advanced_option(ASSIMP_DOUBLE_PRECISION "Set to ON to enable double precision processing" OFF )

+ 47 - 48
Engine/lib/assimp/Build.md

@@ -1,36 +1,10 @@
 # Build / Install Instructions
 # Build / Install Instructions
 
 
-## Install on all platforms using vcpkg
-You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
-```bash
-    git clone https://github.com/Microsoft/vcpkg.git
-    cd vcpkg
-    ./bootstrap-vcpkg.sh
-    ./vcpkg integrate install
-    vcpkg install assimp
-```
-The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
-
-## Install on Ubuntu
-You can install the Asset-Importer-Lib via apt:
-```
-sudo apt-get update
-sudo apt-get install libassimp-dev
-```
-
-## Install pyassimp
-You need to have pip installed:
-```
-pip install pyassimp
-```
-
 ## Manual build instructions
 ## Manual build instructions
-
-### Install CMake
-Asset-Importer-Lib can be build for a lot of different platforms. We are using cmake to generate the build environment for these via cmake. So you have to make sure that you have a working cmake-installation on your system. You can download it at https://cmake.org/ or for linux install it via
-```bash
-sudo apt-get install cmake
-```
+### Install prerequisites
+You need to install
+* cmake
+* Your compiler
 
 
 ### Get the source
 ### Get the source
 Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
 Make sure you have a working git-installation. Open a command prompt and clone the Asset-Importer-Lib via:
@@ -38,35 +12,32 @@ Make sure you have a working git-installation. Open a command prompt and clone t
 git clone https://github.com/assimp/assimp.git
 git clone https://github.com/assimp/assimp.git
 ```
 ```
 ### Build from source:
 ### Build from source:
+* For *assimp.lib* without any tools:
 ```bash
 ```bash
 cd assimp
 cd assimp
-cmake CMakeLists.txt 
+cmake CMakeLists.txt
 cmake --build .
 cmake --build .
 ```
 ```
 
 
-### Build instructions for Windows with Visual-Studio
+* For assimp with the common tools like *assimp-cmd*
+```bash
+cd assimp
+cmake CMakeLists.txt -DASSIMP_BUILD_ASSIMP_TOOLS=ON
+cmake --build .
+```
+Note that by default this builds a shared library into the `bin` directory. If you want to build it as a static library see the build options at the bottom of this file.
 
 
-First you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
+### Build instructions for Windows with Visual-Studio
+First, you have to install Visual-Studio on your windows-system. You can get the Community-Version for free here: https://visualstudio.microsoft.com/de/downloads/
 To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
 To generate the build environment for your IDE open a command prompt, navigate to your repo and type:
 ```bash
 ```bash
 cmake CMakeLists.txt
 cmake CMakeLists.txt
 ```
 ```
-This will generate the project files for the visual studio. All dependencies used to build Asset-IMporter-Lib shall be part of the repo. If you want to use you own zlib.installation this is possible as well. Check the options for it.
+This will generate the project files for the visual studio. All dependencies used to build Asset-Importer-Lib shall be part of the repo. If you want to use you own zlib installation this is possible as well. Check the options for it.
 
 
 ### Build instructions for Windows with UWP
 ### Build instructions for Windows with UWP
 See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
 See <https://stackoverflow.com/questions/40803170/cmake-uwp-using-cmake-to-build-universal-windows-app>
 
 
-### Build instructions for Linux / Unix
-Open a terminal and got to your repository. You can generate the makefiles and build the library via:
-
-```bash
-cmake CMakeLists.txt
-make -j4
-```
-The option -j descripes the number of parallel processes for the build. In this case make will try to use 4 cores for the build.
-
-If you want to use a IDE for linux you can try QTCreator for instance. 
-
 ### Build instructions for MinGW
 ### Build instructions for MinGW
  Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag 
  Older versions of MinGW's compiler (e.g. 5.1.0) do not support the -mbig_obj flag 
 required to compile some of assimp's files, especially for debug builds.
 required to compile some of assimp's files, especially for debug builds.
@@ -93,9 +64,9 @@ The cmake-build-environment provides options to configure the build. The followi
 - **ASSIMP_ANDROID_JNIIOSYSTEM (default OFF)**: Android JNI IOSystem support is active.
 - **ASSIMP_ANDROID_JNIIOSYSTEM (default OFF)**: Android JNI IOSystem support is active.
 - **ASSIMP_NO_EXPORT (default OFF)**: Disable Assimp's export functionality.
 - **ASSIMP_NO_EXPORT (default OFF)**: Disable Assimp's export functionality.
 - **ASSIMP_BUILD_ZLIB (default OFF)**: Build our own zlib.
 - **ASSIMP_BUILD_ZLIB (default OFF)**: Build our own zlib.
-- **ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all exporter senabled.
-- **ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all importer senabled.
-- **ASSIMP_BUILD_ASSIMP_TOOLS (default ON)**: If the supplementary tools for Assimp are built in addition to the library.
+- **ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all exporters enabled.
+- **ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT (default ON)**: Build Assimp with all importers enabled.
+- **ASSIMP_BUILD_ASSIMP_TOOLS (default OFF)**: If the supplementary tools for Assimp are built in addition to the library.
 - **ASSIMP_BUILD_SAMPLES (default OFF)**: If the official samples are built as well (needs Glut).
 - **ASSIMP_BUILD_SAMPLES (default OFF)**: If the official samples are built as well (needs Glut).
 - **ASSIMP_BUILD_TESTS (default ON)**: If the test suite for Assimp is built in addition to the library.
 - **ASSIMP_BUILD_TESTS (default ON)**: If the test suite for Assimp is built in addition to the library.
 - **ASSIMP_COVERALLS (default OFF)**: Enable this to measure test coverage.
 - **ASSIMP_COVERALLS (default OFF)**: Enable this to measure test coverage.
@@ -110,3 +81,31 @@ The cmake-build-environment provides options to configure the build. The followi
 - **USE_STATIC_CRT (default OFF)**: Link against the static MSVC runtime libraries.
 - **USE_STATIC_CRT (default OFF)**: Link against the static MSVC runtime libraries.
 - **ASSIMP_BUILD_DRACO (default OFF)**: Build Draco libraries. Primarily for glTF.
 - **ASSIMP_BUILD_DRACO (default OFF)**: Build Draco libraries. Primarily for glTF.
 - **ASSIMP_BUILD_ASSIMP_VIEW (default ON, if DirectX found, OFF otherwise)**: Build Assimp view tool (requires DirectX).
 - **ASSIMP_BUILD_ASSIMP_VIEW (default ON, if DirectX found, OFF otherwise)**: Build Assimp view tool (requires DirectX).
+
+### Install prebuild binaries
+## Install on all platforms using vcpkg
+You can download and install assimp using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
+```bash
+    git clone https://github.com/Microsoft/vcpkg.git
+    cd vcpkg
+    ./bootstrap-vcpkg.sh
+    ./vcpkg integrate install
+    ./vcpkg install assimp
+```
+The assimp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
+
+### Install on Ubuntu
+You can install the Asset-Importer-Lib via apt:
+```
+sudo apt-get update
+sudo apt-get install libassimp-dev
+```
+
+### Install pyassimp
+You need to have pip installed:
+```
+pip install pyassimp
+```
+
+### Get the SDK from itchi.io
+Just check [itchi.io](https://kimkulling.itch.io/the-asset-importer-lib)

+ 171 - 98
Engine/lib/assimp/CMakeLists.txt

@@ -1,6 +1,6 @@
 # Open Asset Import Library (assimp)
 # Open Asset Import Library (assimp)
 # ----------------------------------------------------------------------
 # ----------------------------------------------------------------------
-# Copyright (c) 2006-2022, assimp team
+# Copyright (c) 2006-2024, assimp team
 #
 #
 # All rights reserved.
 # All rights reserved.
 #
 #
@@ -38,25 +38,50 @@ SET(CMAKE_POLICY_DEFAULT_CMP0012 NEW)
 SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
 SET(CMAKE_POLICY_DEFAULT_CMP0074 NEW)
 SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
 SET(CMAKE_POLICY_DEFAULT_CMP0092 NEW)
 
 
-CMAKE_MINIMUM_REQUIRED( VERSION 3.10 )
+CMAKE_MINIMUM_REQUIRED( VERSION 3.22 )
+
+# Experimental USD importer: disabled, need to opt-in
+# Note: assimp github PR automatic checks will fail the PR due to compiler warnings in
+# the external, 3rd party tinyusdz code which isn't technically part of the PR since it's
+# auto-cloned during build; so MUST disable the feature or the PR will be rejected
+option(ASSIMP_BUILD_USD_IMPORTER "Enable USD file import" off)
+option(ASSIMP_BUILD_USD_VERBOSE_LOGS "Enable verbose USD import debug logging" off)
+option(ASSIMP_BUILD_USE_CCACHE "Use ccache to speed up compilation." on)
+
+if(ASSIMP_BUILD_USE_CCACHE)
+  find_program(CCACHE_PATH ccache)
+  if (CCACHE_PATH)
+    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE_PATH})
+    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE_PATH})
+  endif()
+endif()
+
+# User may override these in their CMake script to provide M3D import/export support
+# (M3D importer/exporter was disabled for assimp release 5.1 or later)
+option(ASSIMP_BUILD_M3D_IMPORTER "Enable M3D file import" off)
+option(ASSIMP_BUILD_M3D_EXPORTER "Enable M3D file export" off)
+
+# Internal/private M3D logic
+if (NOT ASSIMP_BUILD_M3D_IMPORTER)
+    ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
+endif () # if (not ASSIMP_BUILD_M3D_IMPORTER)
+if (NOT ASSIMP_BUILD_M3D_EXPORTER)
+    ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
+endif () # if (not ASSIMP_BUILD_M3D_EXPORTER)
 
 
-# Disabled importers: m3d for 5.1
-ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_IMPORTER)
-ADD_DEFINITIONS( -DASSIMP_BUILD_NO_M3D_EXPORTER)
 # Toggles the use of the hunter package manager
 # Toggles the use of the hunter package manager
 option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
 option(ASSIMP_HUNTER_ENABLED "Enable Hunter package manager support" OFF)
 
 
 IF(ASSIMP_HUNTER_ENABLED)
 IF(ASSIMP_HUNTER_ENABLED)
   include("cmake-modules/HunterGate.cmake")
   include("cmake-modules/HunterGate.cmake")
   HunterGate(
   HunterGate(
-    URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz"
-    SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd"
+    URL "https://github.com/cpp-pm/hunter/archive/v0.25.8.tar.gz"
+    SHA1 "26c79d587883ec910bce168e25f6ac4595f97033"
   )
   )
-
   add_definitions(-DASSIMP_USE_HUNTER)
   add_definitions(-DASSIMP_USE_HUNTER)
 ENDIF()
 ENDIF()
 
 
-PROJECT(Assimp VERSION 5.2.4)
+PROJECT(Assimp VERSION 5.4.3)
 
 
 # All supported options ###############################################
 # All supported options ###############################################
 
 
@@ -84,10 +109,6 @@ OPTION( ASSIMP_NO_EXPORT
   "Disable Assimp's export functionality."
   "Disable Assimp's export functionality."
   OFF
   OFF
 )
 )
-OPTION( ASSIMP_BUILD_ZLIB
-  "Build your own zlib"
-  OFF
-)
 OPTION( ASSIMP_BUILD_ASSIMP_TOOLS
 OPTION( ASSIMP_BUILD_ASSIMP_TOOLS
   "If the supplementary tools for Assimp are built in addition to the library."
   "If the supplementary tools for Assimp are built in addition to the library."
   OFF
   OFF
@@ -135,24 +156,36 @@ OPTION ( ASSIMP_IGNORE_GIT_HASH
 )
 )
 
 
 IF (WIN32)
 IF (WIN32)
-  # Use subset of Windows.h
+  OPTION( ASSIMP_BUILD_ZLIB
+    "Build your zlib"
+    ON
+  )
+ELSE()
+  OPTION( ASSIMP_BUILD_ZLIB
+    "Build your zlib"
+    OFF
+  )
+ENDIF()
+
+IF (WIN32)
+  # Use a subset of Windows.h
   ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
   ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN )
 
 
   IF(MSVC)
   IF(MSVC)
     OPTION( ASSIMP_INSTALL_PDB
     OPTION( ASSIMP_INSTALL_PDB
-      "Install MSVC debug files."
+      "Create MSVC debug symbol files and add to Install target."
       ON )
       ON )
     IF(NOT (MSVC_VERSION LESS 1900))
     IF(NOT (MSVC_VERSION LESS 1900))
-      # Multibyte character set is deprecated since at least MSVC2015 (possibly earlier)
+      # Multibyte character set has been deprecated since at least MSVC2015 (possibly earlier)
       ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
       ADD_DEFINITIONS( -DUNICODE -D_UNICODE )
     ENDIF()
     ENDIF()
 
 
-    # Link statically against c/c++ lib to avoid missing redistriburable such as
+    # Link statically against c/c++ lib to avoid missing redistributable such as
     # "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
     # "VCRUNTIME140.dll not found. Try reinstalling the app.", but give users
     # a choice to opt for the shared runtime if they want.
     # a choice to opt for the shared runtime if they want.
     option(USE_STATIC_CRT "Link against the static runtime libraries." OFF)
     option(USE_STATIC_CRT "Link against the static runtime libraries." OFF)
 
 
-    # The CMAKE_CXX_FLAGS vars can be overriden by some Visual Studio generators, so we use an alternative
+    # The CMAKE_CXX_FLAGS vars can be overridden by some Visual Studio generators, so we use an alternative
     # global method here:
     # global method here:
     if (${USE_STATIC_CRT})
     if (${USE_STATIC_CRT})
       add_compile_options(
       add_compile_options(
@@ -193,12 +226,9 @@ SET (ASSIMP_VERSION ${ASSIMP_VERSION_MAJOR}.${ASSIMP_VERSION_MINOR}.${ASSIMP_VER
 SET (ASSIMP_SOVERSION 5)
 SET (ASSIMP_SOVERSION 5)
 
 
 SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
 SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
-if(NOT ASSIMP_HUNTER_ENABLED)
-  # Enable C++17 support globally
-  set(CMAKE_CXX_STANDARD 17)
-  set(CMAKE_CXX_STANDARD_REQUIRED ON)
-  set(CMAKE_C_STANDARD 99)
-endif()
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_C_STANDARD 99)
 
 
 IF(NOT ASSIMP_IGNORE_GIT_HASH)
 IF(NOT ASSIMP_IGNORE_GIT_HASH)
   # Get the current working branch
   # Get the current working branch
@@ -245,49 +275,60 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
 IF( UNIX )
 IF( UNIX )
   # Use GNUInstallDirs for Unix predefined directories
   # Use GNUInstallDirs for Unix predefined directories
   INCLUDE(GNUInstallDirs)
   INCLUDE(GNUInstallDirs)
-  # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
-  IF( ${OPERATING_SYSTEM} MATCHES "Android")
-  ELSE()
-    IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
+  # Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit Linux
+  IF(NOT ${OPERATING_SYSTEM} MATCHES "Android")
+    IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit Linux
       ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
       ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
     ENDIF()
     ENDIF()
   ENDIF()
   ENDIF()
 ENDIF()
 ENDIF()
 
 
 # Grouped compiler settings ########################################
 # Grouped compiler settings ########################################
-IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW)
+IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT MINGW AND NOT HAIKU)
   IF(NOT ASSIMP_HUNTER_ENABLED)
   IF(NOT ASSIMP_HUNTER_ENABLED)
-    SET(CMAKE_CXX_STANDARD 17)
     SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
     SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
   ENDIF()
   ENDIF()
+
+  IF(CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 13 AND CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+    MESSAGE(STATUS "GCC13 detected disabling \"-Wdangling-reference\" in Cpp files as it appears to be a false positive")
+    ADD_COMPILE_OPTIONS("$<$<COMPILE_LANGUAGE:CXX>:-Wno-dangling-reference>")
+  ENDIF()
   # hide all not-exported symbols
   # hide all not-exported symbols
   IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" )
   IF(CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "mips64" )
-	SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
-	SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
-	SET(LIBSTDC++_LIBRARIES -lstdc++)
+    SET(CMAKE_CXX_FLAGS "-mxgot -fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
+    SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
+    SET(LIBSTDC++_LIBRARIES -lstdc++)
   ELSE()
   ELSE()
-	SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
-	SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
-	SET(LIBSTDC++_LIBRARIES -lstdc++)
+    SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall ${CMAKE_CXX_FLAGS}")
+    SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
+    SET(LIBSTDC++_LIBRARIES -lstdc++)
   ENDIF()
   ENDIF()
 ELSEIF(MSVC)
 ELSEIF(MSVC)
   # enable multi-core compilation with MSVC
   # enable multi-core compilation with MSVC
   IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
   IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang" ) # clang-cl
-    ADD_COMPILE_OPTIONS(/bigobj /W4 /WX )
+    ADD_COMPILE_OPTIONS(/bigobj)
   ELSE() # msvc
   ELSE() # msvc
-    ADD_COMPILE_OPTIONS(/MP /bigobj /W4 /WX)
+    ADD_COMPILE_OPTIONS(/MP /bigobj)
   ENDIF()
   ENDIF()
+
   # disable "elements of array '' will be default initialized" warning on MSVC2013
   # disable "elements of array '' will be default initialized" warning on MSVC2013
   IF(MSVC12)
   IF(MSVC12)
-    ADD_COMPILE_OPTIONS(/wd4351)	
+    ADD_COMPILE_OPTIONS(/wd4351)
   ENDIF()
   ENDIF()
-  ADD_COMPILE_OPTIONS(/wd4244) #supress warning for double to float conversion if Double precission is activated
+  # supress warning for double to float conversion if Double precision is activated
+  ADD_COMPILE_OPTIONS(/wd4244)
   SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
   SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
-  SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
-  SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
+  # Allow user to disable PDBs
+  if(ASSIMP_INSTALL_PDB)
+    SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
+    SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
+  elseif((GENERATOR_IS_MULTI_CONFIG) OR (CMAKE_BUILD_TYPE MATCHES Release))
+    message("-- MSVC PDB generation disabled. Release binary will not be debuggable.")
+  endif()
+  # Source code is encoded in UTF-8
+  ADD_COMPILE_OPTIONS(/source-charset:utf-8)
 ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
 ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
   IF(NOT ASSIMP_HUNTER_ENABLED)
   IF(NOT ASSIMP_HUNTER_ENABLED)
-    SET(CMAKE_CXX_STANDARD 17)
     SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
     SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
   ENDIF()
   ENDIF()
   SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
   SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long ${CMAKE_CXX_FLAGS}" )
@@ -303,26 +344,26 @@ ELSEIF( MINGW )
     SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
     SET(CMAKE_C_FLAGS "-fPIC ${CMAKE_C_FLAGS}")
   ENDIF()
   ENDIF()
     IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
     IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
-      SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
+      SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -g ${CMAKE_CXX_FLAGS}")
     ELSE()
     ELSE()
-      SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
+      SET(CMAKE_CXX_FLAGS "-fvisibility=hidden -fno-strict-aliasing -Wno-dangling-reference -Wall -Wno-long-long -Wa,-mbig-obj -O3 ${CMAKE_CXX_FLAGS}")
     ENDIF()
     ENDIF()
     SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
     SET(CMAKE_C_FLAGS "-fno-strict-aliasing ${CMAKE_C_FLAGS}")
 ENDIF()
 ENDIF()
 
 
 IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
 IF ( IOS AND NOT ASSIMP_HUNTER_ENABLED)
   IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
   IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
-    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
+    SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
   ELSE()
   ELSE()
-    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
+    SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
     SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
-    # Experimental for pdb generation
   ENDIF()
   ENDIF()
 ENDIF()
 ENDIF()
 
 
 IF (ASSIMP_COVERALLS)
 IF (ASSIMP_COVERALLS)
   MESSAGE(STATUS "Coveralls enabled")
   MESSAGE(STATUS "Coveralls enabled")
+
   INCLUDE(Coveralls)
   INCLUDE(Coveralls)
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
   SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
   SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
@@ -330,14 +371,16 @@ ENDIF()
 
 
 IF (ASSIMP_ASAN)
 IF (ASSIMP_ASAN)
   MESSAGE(STATUS "AddressSanitizer enabled")
   MESSAGE(STATUS "AddressSanitizer enabled")
+
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
+  SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -fsanitize=address")
 ENDIF()
 ENDIF()
 
 
 IF (ASSIMP_UBSAN)
 IF (ASSIMP_UBSAN)
   MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
   MESSAGE(STATUS "Undefined Behavior sanitizer enabled")
+
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
+  SET(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS} -fsanitize=undefined,shift,shift-exponent,integer-divide-by-zero,unreachable,vla-bound,null,return,signed-integer-overflow,bounds,float-divide-by-zero,float-cast-overflow,nonnull-attribute,returns-nonnull-attribute,bool,enum,vptr,pointer-overflow,builtin -fno-sanitize-recover=all")
 ENDIF()
 ENDIF()
 
 
 INCLUDE (FindPkgMacros)
 INCLUDE (FindPkgMacros)
@@ -388,13 +431,6 @@ IF (NOT TARGET uninstall AND ASSIMP_INSTALL)
   ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
   ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
 ENDIF()
 ENDIF()
 
 
-# cmake configuration files
-if(${BUILD_SHARED_LIBS})
-  set(BUILD_LIB_TYPE SHARED)
-else()
-  set(BUILD_LIB_TYPE STATIC)
-endif()
-
 IF( UNIX )
 IF( UNIX )
   # Use GNUInstallDirs for Unix predefined directories
   # Use GNUInstallDirs for Unix predefined directories
   INCLUDE(GNUInstallDirs)
   INCLUDE(GNUInstallDirs)
@@ -449,18 +485,20 @@ configure_package_config_file(
     INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
     INSTALL_DESTINATION "${CONFIG_INSTALL_DIR}"
 )
 )
 
 
-install(
-    FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
-    DESTINATION "${CONFIG_INSTALL_DIR}"
-    COMPONENT ${LIBASSIMP-DEV_COMPONENT}
-)
+if(ASSIMP_INSTALL)
+  install(
+      FILES "${PROJECT_CONFIG}" "${VERSION_CONFIG}"
+      DESTINATION "${CONFIG_INSTALL_DIR}"
+      COMPONENT ${LIBASSIMP-DEV_COMPONENT}
+  )
 
 
-install(
-    EXPORT "${TARGETS_EXPORT_NAME}"
-    NAMESPACE "${NAMESPACE}"
-    DESTINATION "${CONFIG_INSTALL_DIR}"
-    COMPONENT ${LIBASSIMP-DEV_COMPONENT}
-)
+  install(
+      EXPORT "${TARGETS_EXPORT_NAME}"
+      NAMESPACE "${NAMESPACE}"
+      DESTINATION "${CONFIG_INSTALL_DIR}"
+      COMPONENT ${LIBASSIMP-DEV_COMPONENT}
+  )
+endif()
 
 
 IF( ASSIMP_BUILD_DOCS )
 IF( ASSIMP_BUILD_DOCS )
   ADD_SUBDIRECTORY(doc)
   ADD_SUBDIRECTORY(doc)
@@ -478,7 +516,7 @@ IF(ASSIMP_HUNTER_ENABLED)
   set(ASSIMP_BUILD_MINIZIP TRUE)
   set(ASSIMP_BUILD_MINIZIP TRUE)
 ELSE()
 ELSE()
   # If the zlib is already found outside, add an export in case assimpTargets can't find it.
   # If the zlib is already found outside, add an export in case assimpTargets can't find it.
-  IF( ZLIB_FOUND )
+  IF( ZLIB_FOUND AND ASSIMP_INSTALL)
     INSTALL( TARGETS zlib zlibstatic
     INSTALL( TARGETS zlib zlibstatic
         EXPORT "${TARGETS_EXPORT_NAME}")
         EXPORT "${TARGETS_EXPORT_NAME}")
   ENDIF()
   ENDIF()
@@ -487,7 +525,11 @@ ELSE()
     FIND_PACKAGE(ZLIB)
     FIND_PACKAGE(ZLIB)
   ENDIF()
   ENDIF()
 
 
-  IF( NOT ZLIB_FOUND )
+  IF ( NOT ZLIB_FOUND AND NOT ASSIMP_BUILD_ZLIB )
+    message( FATAL_ERROR
+      "Build configured with -DASSIMP_BUILD_ZLIB=OFF but unable to find zlib"
+    )
+  ELSEIF( NOT ZLIB_FOUND )
     MESSAGE(STATUS "compiling zlib from sources")
     MESSAGE(STATUS "compiling zlib from sources")
     INCLUDE(CheckIncludeFile)
     INCLUDE(CheckIncludeFile)
     INCLUDE(CheckTypeSize)
     INCLUDE(CheckTypeSize)
@@ -556,11 +598,15 @@ SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
 )
 )
 
 
 IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
 IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
-  IF ( MSVC )
-    SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes")
+  SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes")
 
 
+  IF (WIN32)
     # pick the correct prebuilt library
     # pick the correct prebuilt library
-    IF(MSVC15)
+    IF(MSVC143)
+      SET(C4D_LIB_POSTFIX "_2022")
+    ELSEIF(MSV142)
+      SET(C4D_LIB_POSTFIX "_2019")
+    ELSEIF(MSVC15)
       SET(C4D_LIB_POSTFIX "_2017")
       SET(C4D_LIB_POSTFIX "_2017")
     ELSEIF(MSVC14)
     ELSEIF(MSVC14)
       SET(C4D_LIB_POSTFIX "_2015")
       SET(C4D_LIB_POSTFIX "_2015")
@@ -572,7 +618,7 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
       SET(C4D_LIB_POSTFIX "_2010")
       SET(C4D_LIB_POSTFIX "_2010")
     ELSE()
     ELSE()
       MESSAGE( FATAL_ERROR
       MESSAGE( FATAL_ERROR
-        "C4D is currently only supported with MSVC 10, 11, 12, 14"
+        "C4D for Windows is currently only supported with MSVC 10, 11, 12, 14, 14.2, 14.3"
       )
       )
     ENDIF()
     ENDIF()
 
 
@@ -590,15 +636,30 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
     # winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because
     # winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because
     # it can be used to communicate with a running Cinema 4D instance
     # it can be used to communicate with a running Cinema 4D instance
     SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
     SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
+  ELSEIF (APPLE)
+    SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/libraries/osx")
+
+    SET(C4D_DEBUG_LIBRARIES
+      "${C4D_LIB_BASE_PATH}/debug/libcinewarelib.a"
+      "${C4D_LIB_BASE_PATH}/debug/libjpeglib.a"
+    )
+    SET(C4D_RELEASE_LIBRARIES
+      "${C4D_LIB_BASE_PATH}/release/libcinewarelib.a"
+      "${C4D_LIB_BASE_PATH}/release/libjpeglib.a"
+    )
   ELSE ()
   ELSE ()
     MESSAGE( FATAL_ERROR
     MESSAGE( FATAL_ERROR
-      "C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware"
+      "C4D is currently only available on Windows and macOS with Cineware SDK installed in contrib/Cineware"
     )
     )
   ENDIF ()
   ENDIF ()
 ELSE ()
 ELSE ()
   ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
   ADD_DEFINITIONS( -DASSIMP_BUILD_NO_C4D_IMPORTER )
 ENDIF ()
 ENDIF ()
 
 
+if(ASSIMP_BUILD_DRACO_STATIC)
+  set(ASSIMP_BUILD_DRACO ON)
+endif()
+
 # Draco requires cmake 3.12
 # Draco requires cmake 3.12
 IF (DEFINED CMAKE_VERSION AND "${CMAKE_VERSION}" VERSION_LESS "3.12")
 IF (DEFINED CMAKE_VERSION AND "${CMAKE_VERSION}" VERSION_LESS "3.12")
   message(NOTICE "draco requires cmake 3.12 or newer, cmake is ${CMAKE_VERSION} . Draco is disabled")
   message(NOTICE "draco requires cmake 3.12 or newer, cmake is ${CMAKE_VERSION} . Draco is disabled")
@@ -608,7 +669,7 @@ ELSE()
   IF ( ASSIMP_BUILD_DRACO )
   IF ( ASSIMP_BUILD_DRACO )
     # Primarily for glTF v2
     # Primarily for glTF v2
     # Enable Draco glTF feature set
     # Enable Draco glTF feature set
-    set(DRACO_GLTF ON CACHE BOOL "" FORCE)
+    set(DRACO_GLTF_BITSTREAM ON CACHE BOOL "" FORCE)
     # Disable unnecessary or omitted components
     # Disable unnecessary or omitted components
     set(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE)
     set(DRACO_JS_GLUE OFF CACHE BOOL "" FORCE)
     set(DRACO_WASM OFF CACHE BOOL "" FORCE)
     set(DRACO_WASM OFF CACHE BOOL "" FORCE)
@@ -634,22 +695,29 @@ ELSE()
           "-Wno-sign-compare"
           "-Wno-sign-compare"
           "-Wno-unused-local-typedefs"
           "-Wno-unused-local-typedefs"
         )
         )
-        # Draco 1.4.1 does not explicitly export any symbols under GCC/clang
-        list(APPEND DRACO_CXX_FLAGS
-          "-fvisibility=default"
-        )
+
+        if(NOT ASSIMP_BUILD_DRACO_STATIC)
+          # Draco 1.4.1 does not explicitly export any symbols under GCC/clang
+          list(APPEND DRACO_CXX_FLAGS
+            "-fvisibility=default"
+          )
+        endif()
       ENDIF()
       ENDIF()
 
 
       # Don't build or install all of Draco by default
       # Don't build or install all of Draco by default
       ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL )
       ADD_SUBDIRECTORY( "contrib/draco" EXCLUDE_FROM_ALL )
 
 
+      if(ASSIMP_BUILD_DRACO_STATIC)
+        set_property(DIRECTORY "contrib/draco" PROPERTY BUILD_SHARED_LIBS OFF)
+      endif()
+
       if(MSVC OR WIN32)
       if(MSVC OR WIN32)
         set(draco_LIBRARIES "draco")
         set(draco_LIBRARIES "draco")
       else()
       else()
-        if(BUILD_SHARED_LIBS)
-          set(draco_LIBRARIES "draco_shared")
-        else()
+        if(ASSIMP_BUILD_DRACO_STATIC)
           set(draco_LIBRARIES "draco_static")
           set(draco_LIBRARIES "draco_static")
+        else()
+          set(draco_LIBRARIES "draco_shared")
         endif()
         endif()
       endif()
       endif()
 
 
@@ -657,13 +725,13 @@ ELSE()
       set_target_properties(draco_encoder draco_decoder PROPERTIES
       set_target_properties(draco_encoder draco_decoder PROPERTIES
         EXCLUDE_FROM_ALL TRUE
         EXCLUDE_FROM_ALL TRUE
         EXCLUDE_FROM_DEFAULT_BUILD TRUE
         EXCLUDE_FROM_DEFAULT_BUILD TRUE
-        )
+      )
 
 
       # Do build the draco shared library
       # Do build the draco shared library
       set_target_properties(${draco_LIBRARIES} PROPERTIES
       set_target_properties(${draco_LIBRARIES} PROPERTIES
         EXCLUDE_FROM_ALL FALSE
         EXCLUDE_FROM_ALL FALSE
         EXCLUDE_FROM_DEFAULT_BUILD FALSE
         EXCLUDE_FROM_DEFAULT_BUILD FALSE
-        )
+      )
 
 
       TARGET_USE_COMMON_OUTPUT_DIRECTORY(${draco_LIBRARIES})
       TARGET_USE_COMMON_OUTPUT_DIRECTORY(${draco_LIBRARIES})
       TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_encoder)
       TARGET_USE_COMMON_OUTPUT_DIRECTORY(draco_encoder)
@@ -672,16 +740,17 @@ ELSE()
       set(draco_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/draco/src")
       set(draco_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/contrib/draco/src")
 
 
       # This is probably wrong
       # This is probably wrong
-      INSTALL( TARGETS ${draco_LIBRARIES}
-        EXPORT "${TARGETS_EXPORT_NAME}"
-        LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-        ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-        RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
-        FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
-        COMPONENT ${LIBASSIMP_COMPONENT}
-        INCLUDES DESTINATION include
-    )
-
+      if (ASSIMP_INSTALL)
+        INSTALL( TARGETS ${draco_LIBRARIES}
+          EXPORT "${TARGETS_EXPORT_NAME}"
+          LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+          ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+          RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
+          FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
+          COMPONENT ${LIBASSIMP_COMPONENT}
+          INCLUDES DESTINATION include
+        )
+      endif()
     ENDIF()
     ENDIF()
   ENDIF()
   ENDIF()
 ENDIF()
 ENDIF()
@@ -725,8 +794,8 @@ IF ( ASSIMP_INSTALL )
 ENDIF()
 ENDIF()
 
 
 CONFIGURE_FILE(
 CONFIGURE_FILE(
-  ${CMAKE_CURRENT_LIST_DIR}/revision.h.in
-  ${CMAKE_CURRENT_BINARY_DIR}/revision.h
+  ${CMAKE_CURRENT_LIST_DIR}/include/assimp/revision.h.in
+  ${CMAKE_CURRENT_BINARY_DIR}/include/assimp/revision.h
 )
 )
 
 
 CONFIGURE_FILE(
 CONFIGURE_FILE(
@@ -767,7 +836,7 @@ IF ( ASSIMP_INSTALL )
     SET(CPACK_DEBIAN_PACKAGE_SECTION  "libs" )
     SET(CPACK_DEBIAN_PACKAGE_SECTION  "libs" )
     SET(CPACK_DEBIAN_PACKAGE_DEPENDS  "${CPACK_COMPONENTS_ALL}")
     SET(CPACK_DEBIAN_PACKAGE_DEPENDS  "${CPACK_COMPONENTS_ALL}")
     SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
     SET(CPACK_DEBIAN_PACKAGE_SUGGESTS)
-    SET(cPACK_DEBIAN_PACKAGE_NAME     "assimp")
+    SET(CPACK_DEBIAN_PACKAGE_NAME     "assimp")
     SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging)
     SET(CPACK_DEBIAN_PACKAGE_REMOVE_SOURCE_FILES contrib/gtest contrib/zlib workspaces test doc obj samples packaging)
     SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
     SET(CPACK_DEBIAN_PACKAGE_SOURCE_COPY svn export --force)
     SET(CPACK_DEBIAN_CHANGELOG)
     SET(CPACK_DEBIAN_CHANGELOG)
@@ -804,6 +873,10 @@ if(WIN32)
       SET(ASSIMP_MSVC_VERSION "vc140")
       SET(ASSIMP_MSVC_VERSION "vc140")
     ELSEIF(MSVC15)
     ELSEIF(MSVC15)
       SET(ASSIMP_MSVC_VERSION "vc141")
       SET(ASSIMP_MSVC_VERSION "vc141")
+    ELSEIF(MSV142)
+      SET(ASSIMP_MSVC_VERSION "vc142")
+    ELSEIF(MSVC143)
+      SET(ASSIMP_MSVC_VERSION "vc143")
     ENDIF()
     ENDIF()
   ENDIF()
   ENDIF()
 
 

+ 128 - 0
Engine/lib/assimp/CODE_OF_CONDUCT.md

@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+  professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.

+ 7 - 10
Engine/lib/assimp/Dockerfile

@@ -1,16 +1,12 @@
-FROM ubuntu:14.04
+FROM ubuntu:22.04
 
 
-RUN apt-get update && apt-get install -y \
+RUN apt-get update && apt-get install --no-install-recommends -y ninja-build \
     git cmake build-essential software-properties-common
     git cmake build-essential software-properties-common
 
 
-RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update && apt-get install -y gcc-4.9 g++-4.9 && \
-    cd /usr/bin && \
-    rm gcc g++ cpp && \
-    ln -s gcc-4.9 gcc && \
-    ln -s g++-4.9 g++ && \
-    ln -s cpp-4.9 cpp
+RUN add-apt-repository ppa:ubuntu-toolchain-r/test && apt-get update 
 
 
 WORKDIR /opt
 WORKDIR /opt
+RUN apt install zlib1g-dev
 
 
 # Build Assimp
 # Build Assimp
 RUN git clone https://github.com/assimp/assimp.git /opt/assimp
 RUN git clone https://github.com/assimp/assimp.git /opt/assimp
@@ -19,7 +15,8 @@ WORKDIR /opt/assimp
 
 
 RUN git checkout master \
 RUN git checkout master \
     && mkdir build && cd build && \
     && mkdir build && cd build && \
-    cmake \
+    cmake -G 'Ninja' \
     -DCMAKE_BUILD_TYPE=Release \
     -DCMAKE_BUILD_TYPE=Release \
+    -DASSIMP_BUILD_ASSIMP_TOOLS=ON \
     .. && \
     .. && \
-    make && make install
+    ninja -j4 && ninja install

+ 41 - 47
Engine/lib/assimp/Readme.md

@@ -1,42 +1,45 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ==================================
 ==================================
-A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
-### Current project status ###
-[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp) 
+
+Open Asset Import Library is a library that loads various 3D file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
+
+### Current project status ### 
 ![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
 ![C/C++ CI](https://github.com/assimp/assimp/workflows/C/C++%20CI/badge.svg)
-<a href="https://scan.coverity.com/projects/5607">
-  <img alt="Coverity Scan Build Status"
-       src="https://scan.coverity.com/projects/5607/badge.svg"/>
-</a>
 [![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
 [![Codacy Badge](https://app.codacy.com/project/badge/Grade/9973693b7bdd4543b07084d5d9cf4745)](https://www.codacy.com/gh/assimp/assimp/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=assimp/assimp&amp;utm_campaign=Badge_Grade)
-
-[![Coverage Status](https://coveralls.io/repos/github/assimp/assimp/badge.svg?branch=master)](https://coveralls.io/github/assimp/assimp?branch=master)
-[![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=assimp_assimp&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=assimp_assimp)
 [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
 [![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Average time to resolve an issue")
 [![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
 [![Percentage of issues still open](http://isitmaintained.com/badge/open/assimp/assimp.svg)](http://isitmaintained.com/project/assimp/assimp "Percentage of issues still open")
-[![Total alerts](https://img.shields.io/lgtm/alerts/g/assimp/assimp.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/assimp/assimp/alerts/)
+[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20assimp%20Guru-006BFF)](https://gurubase.io/g/assimp)
+[![Financial Contributors on Open Collective](https://opencollective.com/assimp/all/badge.svg?label=financial+contributors)](https://opencollective.com/assimp)
 <br>
 <br>
 
 
-APIs are provided for C and C++. There are various bindings to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
-Additionally, assimp features various __mesh post processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
+APIs are provided for C and C++. Various bindings exist to other languages (C#, Java, Python, Delphi, D). Assimp also runs on Android and iOS.
+Additionally, assimp features various __mesh post-processing tools__: normals and tangent space generation, triangulation, vertex cache locality optimization, removal of degenerate primitives and duplicate vertices, sorting by primitive type, merging of redundant materials and many more.
 
 
-### Latest Doc's ###
-Please check the latest documents at [Asset-Importer-Lib-Doc](https://assimp-docs.readthedocs.io/en/latest/). 
+## Project activity ##
+![Alt](https://repobeats.axiom.co/api/embed/997f84e5f9fcf772da1e687f3a4f3a8afdbf4cf0.svg "Repobeats analytics image")
 
 
-### Get involved ###
-This is the development repo containing the latest features and bugfixes. For productive use though, we recommend one of the stable releases available from [Github Assimp Releases](https://github.com/assimp/assimp/releases).
-<br>
-You find a bug in the docs? Use [Doc-Repo](https://github.com/assimp/assimp-docs).
-<br>
-Please check our Wiki as well: https://github.com/assimp/assimp/wiki
+### Documentation ###
+Read [our latest documentation](https://assimp-docs.readthedocs.io/en/latest/).
+
+### Pre-built binaries ###
+Download binaries from [our Itchi Projectspace](https://kimkulling.itch.io/the-asset-importer-lib).
 
 
-If you want to check our Model-Database, use the following repo: https://github.com/assimp/assimp-mdb
+### Test data ###
+Clone [our model database](https://github.com/assimp/assimp-mdb).
+
+### Communities ###
+- Ask questions at [the Assimp Discussion Board](https://github.com/assimp/assimp/discussions).
+- Find us on [https://discord.gg/s9KJfaem](https://discord.gg/kKazXMXDy2)
+- Ask [the Assimp community on Reddit](https://www.reddit.com/r/Assimp/).
+- Ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). 
+- Nothing has worked? File a question or an issue report at [The Assimp-Issue Tracker](https://github.com/assimp/assimp/issues)
 
 
 #### Supported file formats ####
 #### Supported file formats ####
-You can find the complete list of supported file-formats [here](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md)
+See [the complete list of supported formats](https://github.com/assimp/assimp/blob/master/doc/Fileformats.md).
 
 
 ### Building ###
 ### Building ###
-Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
+Start by reading [our build instructions](https://github.com/assimp/assimp/blob/master/Build.md). We are available in vcpkg, and our build system is CMake; if you used CMake before there is a good chance you know what to do.
 
 
 ### Ports ###
 ### Ports ###
 * [Android](port/AndroidJNI/README.md)
 * [Android](port/AndroidJNI/README.md)
@@ -47,46 +50,40 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
 * [Javascript/Node.js Interface](https://github.com/kovacsv/assimpjs)
 * [Javascript/Node.js Interface](https://github.com/kovacsv/assimpjs)
 * [Unity 3d Plugin](https://ricardoreis.net/trilib-2/)
 * [Unity 3d Plugin](https://ricardoreis.net/trilib-2/)
 * [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/)
 * [Unreal Engine Plugin](https://github.com/irajsb/UE4_Assimp/)
-* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
+* [JVM](https://github.com/kotlin-graphics/assimp) Full JVM port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
 * [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
 * [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
 * [Rust](https://github.com/jkvargas/russimp)
 * [Rust](https://github.com/jkvargas/russimp)
 
 
 ### Other tools ###
 ### Other tools ###
 [open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
 [open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.
+[Assimp-Viewer](https://github.com/assimp/assimp_view) is an experimental implementation for an Asset-Viewer based on ImGUI and Assimp (experimental).
 
 
 #### Repository structure ####
 #### Repository structure ####
-Open Asset Import Library is implemented in C++. The directory structure looks like:
+Open Asset Import Library is implemented in C++. The directory structure looks like this:
 
 
 	/code		Source code
 	/code		Source code
 	/contrib	Third-party libraries
 	/contrib	Third-party libraries
-	/doc		Documentation (doxysource and pre-compiled docs)
-	/fuzz           Contains the test-code for the Google-Fuzzer project
+	/doc		Documentation (Doxygen source and pre-compiled docs)
+	/fuzz           Contains the test code for the Google Fuzzer project
 	/include	Public header C and C++ header files
 	/include	Public header C and C++ header files
-	/scripts 	Scripts used to generate the loading code for some formats
+	/scripts 	Scripts are used to generate the loading code for some formats
 	/port		Ports to other languages and scripts to maintain those.
 	/port		Ports to other languages and scripts to maintain those.
 	/test		Unit- and regression tests, test suite of models
 	/test		Unit- and regression tests, test suite of models
 	/tools		Tools (old assimp viewer, command line `assimp`)
 	/tools		Tools (old assimp viewer, command line `assimp`)
-	/samples	A small number of samples to illustrate possible
-                        use cases for Assimp
+	/samples	A small number of samples to illustrate possible use cases for Assimp
 
 
 The source code is organized in the following way:
 The source code is organized in the following way:
 
 
 	code/Common			The base implementation for importers and the infrastructure
 	code/Common			The base implementation for importers and the infrastructure
+	code/CApi                       Special implementations which are only used for the C-API
+	code/Geometry                   A collection of geometry tools
+	code/Material                   The material system
+	code/PBR                        An exporter for physical-based models
 	code/PostProcessing		The post-processing steps
 	code/PostProcessing		The post-processing steps
-	code/AssetLib/<FormatName>	Implementation for import and export for the format
-
-### Where to get help ###
-For more information, visit [our website](http://assimp.org/). Or check out the `./doc`- folder, which contains the official documentation in HTML format.
-(CHMs for Windows are included in some release packages and should be located right here in the root folder).
-
-If the docs don't solve your problem, ask on [StackOverflow with the assimp-tag](http://stackoverflow.com/questions/tagged/assimp?sort=newest). If you think you found a bug, please open an issue on Github.
-
-Open Asset Import Library is a library to load various 3d file formats into a shared, in-memory format. It supports more than __40 file formats__ for import and a growing selection of file formats for export.
-
-And we also have a Gitter-channel:Gitter [![Join the chat at https://gitter.im/assimp/assimp](https://badges.gitter.im/assimp/assimp.svg)](https://gitter.im/assimp/assimp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)<br>
+	code/AssetLib/<FormatName>	Implementation for import and export of the format
 
 
 ### Contributing ###
 ### Contributing ###
-Contributions to assimp are highly appreciated. The easiest way to get involved is to submit
+I would greatly appreciate contributing to assimp. The easiest way to get involved is to submit
 a pull request with your changes against the main repository's `master` branch.
 a pull request with your changes against the main repository's `master` branch.
 
 
 ## Contributors
 ## Contributors
@@ -108,7 +105,7 @@ Become a financial contributor and help us sustain our community. [[Contribute](
 
 
 #### Organizations
 #### Organizations
 
 
-Support this project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
+You can support the project with your organization. Your logo will show up here with a link to your website. [[Contribute](https://opencollective.com/assimp/contribute)]
 
 
 <a href="https://opencollective.com/assimp/organization/0/website"><img src="https://opencollective.com/assimp/organization/0/avatar.svg"></a>
 <a href="https://opencollective.com/assimp/organization/0/website"><img src="https://opencollective.com/assimp/organization/0/avatar.svg"></a>
 
 
@@ -118,6 +115,3 @@ Our license is based on the modified, __3-clause BSD__-License.
 An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
 An _informal_ summary is: do whatever you want, but include Assimp's license text with your product -
 and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
 and don't sue us if our code doesn't work. Note that, unlike LGPLed code, you may link statically to Assimp.
 For the legal details, see the `LICENSE` file.
 For the legal details, see the `LICENSE` file.
-
-### Why this name ###
-Sorry, we're germans :-), no english native speakers ...

+ 0 - 29
Engine/lib/assimp/cmake-modules/HunterGate.cmake

@@ -22,38 +22,9 @@
 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # 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.
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
-# This is a gate file to Hunter package manager.
-# Include this file using `include` command and add package you need, example:
-#
-#     cmake_minimum_required(VERSION 3.2)
-#
-#     include("cmake/HunterGate.cmake")
-#     HunterGate(
-#         URL "https://github.com/path/to/hunter/archive.tar.gz"
-#         SHA1 "798501e983f14b28b10cda16afa4de69eee1da1d"
-#     )
-#
-#     project(MyProject)
-#
-#     hunter_add_package(Foo)
-#     hunter_add_package(Boo COMPONENTS Bar Baz)
-#
-# Projects:
-#     * https://github.com/hunter-packages/gate/
-#     * https://github.com/ruslo/hunter
 
 
 option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
 option(HUNTER_ENABLED "Enable Hunter package manager support" ON)
 
 
-if(HUNTER_ENABLED)
-  if(CMAKE_VERSION VERSION_LESS "3.2")
-    message(
-        FATAL_ERROR
-        "At least CMake version 3.2 required for Hunter dependency management."
-        " Update CMake or set HUNTER_ENABLED to OFF."
-    )
-  endif()
-endif()
-
 include(CMakeParseArguments) # cmake_parse_arguments
 include(CMakeParseArguments) # cmake_parse_arguments
 
 
 option(HUNTER_STATUS_PRINT "Print working status" ON)
 option(HUNTER_STATUS_PRINT "Print working status" ON)

+ 0 - 8
Engine/lib/assimp/code/.editorconfig

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

+ 17 - 9
Engine/lib/assimp/code/AssetLib/3DS/3DSConverter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -52,9 +52,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <cctype>
 #include <cctype>
 #include <memory>
 #include <memory>
 
 
-using namespace Assimp;
+namespace Assimp {
 
 
-static const unsigned int NotSet = 0xcdcdcdcd;
+static constexpr unsigned int NotSet = 0xcdcdcdcd;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Setup final material indices, generae a default material if necessary
 // Setup final material indices, generae a default material if necessary
@@ -68,7 +68,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
     unsigned int idx(NotSet);
     unsigned int idx(NotSet);
     for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
     for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
         std::string s = mScene->mMaterials[i].mName;
         std::string s = mScene->mMaterials[i].mName;
-        for (char & it : s) {
+        for (char &it : s) {
             it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
             it = static_cast<char>(::tolower(static_cast<unsigned char>(it)));
         }
         }
 
 
@@ -262,7 +262,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
         unsigned int iWire = 1;
         unsigned int iWire = 1;
         mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
         mat.AddProperty<int>((int *)&iWire, 1, AI_MATKEY_ENABLE_WIREFRAME);
     }
     }
-    [[fallthrough]];
+        [[fallthrough]];
 
 
     case D3DS::Discreet3DS::Gouraud:
     case D3DS::Discreet3DS::Gouraud:
         eShading = aiShadingMode_Gouraud;
         eShading = aiShadingMode_Gouraud;
@@ -593,7 +593,7 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
 
 
         // Cameras or lights define their transformation in their parent node and in the
         // Cameras or lights define their transformation in their parent node and in the
         // corresponding light or camera chunks. However, we read and process the latter
         // corresponding light or camera chunks. However, we read and process the latter
-        // to to be able to return valid cameras/lights even if no scenegraph is given.
+        // to be able to return valid cameras/lights even if no scenegraph is given.
         for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) {
         for (unsigned int n = 0; n < pcSOut->mNumCameras; ++n) {
             if (pcSOut->mCameras[n]->mName == pcOut->mName) {
             if (pcSOut->mCameras[n]->mName == pcOut->mName) {
                 pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f);
                 pcSOut->mCameras[n]->mLookAt = aiVector3D(0.f, 0.f, 1.f);
@@ -643,11 +643,17 @@ void Discreet3DSImporter::AddNodeToGraph(aiScene *pcSOut, aiNode *pcOut,
     }
     }
 
 
     // Allocate storage for children
     // Allocate storage for children
-    pcOut->mNumChildren = (unsigned int)pcIn->mChildren.size();
+    const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
+
+    pcOut->mNumChildren = size;
+    if (size == 0) {
+        return;
+    }
+
     pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
     pcOut->mChildren = new aiNode *[pcIn->mChildren.size()];
 
 
     // Recursively process all children
     // Recursively process all children
-    const unsigned int size = static_cast<unsigned int>(pcIn->mChildren.size());
+    
     for (unsigned int i = 0; i < size; ++i) {
     for (unsigned int i = 0; i < size; ++i) {
         pcOut->mChildren[i] = new aiNode();
         pcOut->mChildren[i] = new aiNode();
         pcOut->mChildren[i]->mParent = pcOut;
         pcOut->mChildren[i]->mParent = pcOut;
@@ -709,7 +715,7 @@ void Discreet3DSImporter::GenerateNodeGraph(aiScene *pcOut) {
             pcNode->mNumMeshes = 1;
             pcNode->mNumMeshes = 1;
 
 
             // Build a name for the node
             // Build a name for the node
-            pcNode->mName.length = ai_snprintf(pcNode->mName.data, MAXLEN, "3DSMesh_%u", i);
+            pcNode->mName.length = ai_snprintf(pcNode->mName.data, AI_MAXLEN, "3DSMesh_%u", i);
         }
         }
 
 
         // Build dummy nodes for all cameras
         // Build dummy nodes for all cameras
@@ -805,4 +811,6 @@ void Discreet3DSImporter::ConvertScene(aiScene *pcOut) {
     }
     }
 }
 }
 
 
+} // namespace Assimp
+
 #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
 #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER

+ 2 - 1
Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
+#include <assimp/Exceptional.h>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 
 
 #include <memory>
 #include <memory>

+ 3 - 5
Engine/lib/assimp/code/AssetLib/3DS/3DSExporter.h

@@ -2,8 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -57,8 +56,7 @@ struct aiNode;
 struct aiMaterial;
 struct aiMaterial;
 struct aiMesh;
 struct aiMesh;
 
 
-namespace Assimp
-{
+namespace Assimp {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 /**
 /**
@@ -88,7 +86,7 @@ private:
 
 
     std::map<const aiNode*, aiMatrix4x4> trafos;
     std::map<const aiNode*, aiMatrix4x4> trafos;
 
 
-    typedef std::multimap<const aiNode*, unsigned int> MeshesByNodeMap;
+    using MeshesByNodeMap = std::multimap<const aiNode*, unsigned int>;
     MeshesByNodeMap meshes;
     MeshesByNodeMap meshes;
 
 
 };
 };

+ 8 - 124
Engine/lib/assimp/code/AssetLib/3DS/3DSHelper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -322,7 +322,6 @@ struct Texture {
     //! Default constructor
     //! Default constructor
     Texture() AI_NO_EXCEPT
     Texture() AI_NO_EXCEPT
             : mTextureBlend(0.0f),
             : mTextureBlend(0.0f),
-              mMapName(),
               mOffsetU(0.0),
               mOffsetU(0.0),
               mOffsetV(0.0),
               mOffsetV(0.0),
               mScaleU(1.0),
               mScaleU(1.0),
@@ -334,51 +333,11 @@ struct Texture {
         mTextureBlend = get_qnan();
         mTextureBlend = get_qnan();
     }
     }
 
 
-    Texture(const Texture &other) :
-            mTextureBlend(other.mTextureBlend),
-            mMapName(other.mMapName),
-            mOffsetU(other.mOffsetU),
-            mOffsetV(other.mOffsetV),
-            mScaleU(other.mScaleU),
-            mScaleV(other.mScaleV),
-            mRotation(other.mRotation),
-            mMapMode(other.mMapMode),
-            bPrivate(other.bPrivate),
-            iUVSrc(other.iUVSrc) {
-        // empty
-    }
-
-    Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
-                                            mMapName(std::move(other.mMapName)),
-                                            mOffsetU(other.mOffsetU),
-                                            mOffsetV(other.mOffsetV),
-                                            mScaleU(other.mScaleU),
-                                            mScaleV(other.mScaleV),
-                                            mRotation(other.mRotation),
-                                            mMapMode(other.mMapMode),
-                                            bPrivate(other.bPrivate),
-                                            iUVSrc(other.iUVSrc) {
-        // empty
-    }
+    Texture(const Texture &other) = default;
 
 
-    Texture &operator=(Texture &&other) AI_NO_EXCEPT {
-        if (this == &other) {
-            return *this;
-        }
-
-        mTextureBlend = other.mTextureBlend;
-        mMapName = std::move(other.mMapName);
-        mOffsetU = other.mOffsetU;
-        mOffsetV = other.mOffsetV;
-        mScaleU = other.mScaleU;
-        mScaleV = other.mScaleV;
-        mRotation = other.mRotation;
-        mMapMode = other.mMapMode;
-        bPrivate = other.bPrivate;
-        iUVSrc = other.iUVSrc;
+    Texture(Texture &&other) AI_NO_EXCEPT = default;
 
 
-        return *this;
-    }
+    Texture &operator=(Texture &&other) AI_NO_EXCEPT = default;
 
 
     //! Specifies the blend factor for the texture
     //! Specifies the blend factor for the texture
     ai_real mTextureBlend;
     ai_real mTextureBlend;
@@ -406,14 +365,13 @@ struct Texture {
 #ifdef _MSC_VER
 #ifdef _MSC_VER
 #pragma warning(pop)
 #pragma warning(pop)
 #endif // _MSC_VER
 #endif // _MSC_VER
-
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 /** Helper structure representing a 3ds material */
 /** Helper structure representing a 3ds material */
 struct Material {
 struct Material {
     //! Default constructor has been deleted
     //! Default constructor has been deleted
     Material() :
     Material() :
             mName(),
             mName(),
-            mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
+            mDiffuse(0.6f, 0.6f, 0.6f),
             mSpecularExponent(ai_real(0.0)),
             mSpecularExponent(ai_real(0.0)),
             mShininessStrength(ai_real(1.0)),
             mShininessStrength(ai_real(1.0)),
             mShading(Discreet3DS::Gouraud),
             mShading(Discreet3DS::Gouraud),
@@ -426,7 +384,7 @@ struct Material {
     //! Constructor with explicit name
     //! Constructor with explicit name
     explicit Material(const std::string &name) :
     explicit Material(const std::string &name) :
             mName(name),
             mName(name),
-            mDiffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
+            mDiffuse(0.6f, 0.6f, 0.6f),
             mSpecularExponent(ai_real(0.0)),
             mSpecularExponent(ai_real(0.0)),
             mShininessStrength(ai_real(1.0)),
             mShininessStrength(ai_real(1.0)),
             mShading(Discreet3DS::Gouraud),
             mShading(Discreet3DS::Gouraud),
@@ -436,83 +394,9 @@ struct Material {
         // empty
         // empty
     }
     }
 
 
-    Material(const Material &other) :
-            mName(other.mName),
-            mDiffuse(other.mDiffuse),
-            mSpecularExponent(other.mSpecularExponent),
-            mShininessStrength(other.mShininessStrength),
-            mSpecular(other.mSpecular),
-            mAmbient(other.mAmbient),
-            mShading(other.mShading),
-            mTransparency(other.mTransparency),
-            sTexDiffuse(other.sTexDiffuse),
-            sTexOpacity(other.sTexOpacity),
-            sTexSpecular(other.sTexSpecular),
-            sTexReflective(other.sTexReflective),
-            sTexBump(other.sTexBump),
-            sTexEmissive(other.sTexEmissive),
-            sTexShininess(other.sTexShininess),
-            mBumpHeight(other.mBumpHeight),
-            mEmissive(other.mEmissive),
-            sTexAmbient(other.sTexAmbient),
-            mTwoSided(other.mTwoSided) {
-        // empty
-    }
+    Material(const Material &other) = default;
 
 
-    //! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
-    Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
-                                              mDiffuse(other.mDiffuse),
-                                              mSpecularExponent(other.mSpecularExponent),
-                                              mShininessStrength(other.mShininessStrength),
-                                              mSpecular(other.mSpecular),
-                                              mAmbient(other.mAmbient),
-                                              mShading(other.mShading),
-                                              mTransparency(other.mTransparency),
-                                              sTexDiffuse(std::move(other.sTexDiffuse)),
-                                              sTexOpacity(std::move(other.sTexOpacity)),
-                                              sTexSpecular(std::move(other.sTexSpecular)),
-                                              sTexReflective(std::move(other.sTexReflective)),
-                                              sTexBump(std::move(other.sTexBump)),
-                                              sTexEmissive(std::move(other.sTexEmissive)),
-                                              sTexShininess(std::move(other.sTexShininess)),
-                                              mBumpHeight(other.mBumpHeight),
-                                              mEmissive(other.mEmissive),
-                                              sTexAmbient(std::move(other.sTexAmbient)),
-                                              mTwoSided(other.mTwoSided) {
-        // empty
-    }
-
-    Material &operator=(Material &&other) AI_NO_EXCEPT {
-        if (this == &other) {
-            return *this;
-        }
-
-        mName = std::move(other.mName);
-        mDiffuse = other.mDiffuse;
-        mSpecularExponent = other.mSpecularExponent;
-        mShininessStrength = other.mShininessStrength,
-        mSpecular = other.mSpecular;
-        mAmbient = other.mAmbient;
-        mShading = other.mShading;
-        mTransparency = other.mTransparency;
-        sTexDiffuse = std::move(other.sTexDiffuse);
-        sTexOpacity = std::move(other.sTexOpacity);
-        sTexSpecular = std::move(other.sTexSpecular);
-        sTexReflective = std::move(other.sTexReflective);
-        sTexBump = std::move(other.sTexBump);
-        sTexEmissive = std::move(other.sTexEmissive);
-        sTexShininess = std::move(other.sTexShininess);
-        mBumpHeight = other.mBumpHeight;
-        mEmissive = other.mEmissive;
-        sTexAmbient = std::move(other.sTexAmbient);
-        mTwoSided = other.mTwoSided;
-
-        return *this;
-    }
-
-    virtual ~Material() {
-        // empty
-    }
+    virtual ~Material() = default;
 
 
     //! Name of the material
     //! Name of the material
     std::string mName;
     std::string mName;

+ 13 - 8
Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -54,9 +54,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 
 
-using namespace Assimp;
+namespace Assimp {
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "Discreet 3DS Importer",
     "Discreet 3DS Importer",
     "",
     "",
     "",
     "",
@@ -103,10 +103,6 @@ Discreet3DSImporter::Discreet3DSImporter() :
     // empty
     // empty
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-Discreet3DSImporter::~Discreet3DSImporter() = default;
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
 bool Discreet3DSImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@@ -266,8 +262,15 @@ void Discreet3DSImporter::ParseMainChunk() {
     };
     };
 
 
     ASSIMP_3DS_END_CHUNK();
     ASSIMP_3DS_END_CHUNK();
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunreachable-code-return"
+#endif
     // recursively continue processing this hierarchy level
     // recursively continue processing this hierarchy level
     return ParseMainChunk();
     return ParseMainChunk();
+#if defined(__clang__)
+#pragma clang diagnostic pop
+#endif
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -362,7 +365,7 @@ void Discreet3DSImporter::ParseChunk(const char *name, unsigned int num) {
     // IMPLEMENTATION NOTE;
     // IMPLEMENTATION NOTE;
     // Cameras or lights define their transformation in their parent node and in the
     // Cameras or lights define their transformation in their parent node and in the
     // corresponding light or camera chunks. However, we read and process the latter
     // corresponding light or camera chunks. However, we read and process the latter
-    // to to be able to return valid cameras/lights even if no scenegraph is given.
+    // to be able to return valid cameras/lights even if no scenegraph is given.
 
 
     // get chunk type
     // get chunk type
     switch (chunk.Flag) {
     switch (chunk.Flag) {
@@ -1332,4 +1335,6 @@ void Discreet3DSImporter::ParseColorChunk(aiColor3D *out, bool acceptPercent) {
     (void)bGamma;
     (void)bGamma;
 }
 }
 
 
+} // namespace Assimp
+
 #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER
 #endif // !! ASSIMP_BUILD_NO_3DS_IMPORTER

+ 2 - 3
Engine/lib/assimp/code/AssetLib/3DS/3DSLoader.h

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -59,7 +59,6 @@ struct aiNode;
 
 
 namespace Assimp    {
 namespace Assimp    {
 
 
-
 using namespace D3DS;
 using namespace D3DS;
 
 
 // ---------------------------------------------------------------------------------
 // ---------------------------------------------------------------------------------
@@ -68,7 +67,7 @@ using namespace D3DS;
 class Discreet3DSImporter : public BaseImporter {
 class Discreet3DSImporter : public BaseImporter {
 public:
 public:
     Discreet3DSImporter();
     Discreet3DSImporter();
-    ~Discreet3DSImporter();
+    ~Discreet3DSImporter() override = default;
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Returns whether the class can handle the format of the given file.
     /** Returns whether the class can handle the format of the given file.

+ 22 - 8
Engine/lib/assimp/code/AssetLib/3MF/3MFTypes.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -57,6 +57,7 @@ enum class ResourceType {
     RT_BaseMaterials,
     RT_BaseMaterials,
     RT_EmbeddedTexture2D,
     RT_EmbeddedTexture2D,
     RT_Texture2DGroup,
     RT_Texture2DGroup,
+    RT_ColorGroup,
     RT_Unknown
     RT_Unknown
 }; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
 }; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
 
 
@@ -69,9 +70,7 @@ public:
         // empty
         // empty
     }
     }
 
 
-    virtual ~Resource() {
-        // empty
-    }
+    virtual ~Resource() = default;
 
 
     virtual ResourceType getType() const {
     virtual ResourceType getType() const {
         return ResourceType::RT_Unknown;
         return ResourceType::RT_Unknown;
@@ -95,7 +94,7 @@ public:
         // empty
         // empty
     }
     }
 
 
-    ~EmbeddedTexture() = default;
+    ~EmbeddedTexture() override = default;
 
 
     ResourceType getType() const override {
     ResourceType getType() const override {
         return ResourceType::RT_EmbeddedTexture2D;
         return ResourceType::RT_EmbeddedTexture2D;
@@ -112,13 +111,28 @@ public:
         // empty
         // empty
     }
     }
 
 
-    ~Texture2DGroup() = default;
+    ~Texture2DGroup() override = default;
 
 
     ResourceType getType() const override {
     ResourceType getType() const override {
         return ResourceType::RT_Texture2DGroup;
         return ResourceType::RT_Texture2DGroup;
     }
     }
 };
 };
 
 
+class ColorGroup : public Resource {
+public:
+    std::vector<aiColor4D> mColors;
+    ColorGroup(int id) :
+            Resource(id){
+        // empty
+    }
+
+    ~ColorGroup() override = default;
+
+    ResourceType getType() const override {
+        return ResourceType::RT_ColorGroup;
+    }
+};
+
 class BaseMaterials : public Resource {
 class BaseMaterials : public Resource {
 public:
 public:
     std::vector<unsigned int> mMaterialIndex;
     std::vector<unsigned int> mMaterialIndex;
@@ -129,7 +143,7 @@ public:
         // empty
         // empty
     }
     }
 
 
-    ~BaseMaterials() = default;
+    ~BaseMaterials() override = default;
 
 
     ResourceType getType() const override {
     ResourceType getType() const override {
         return ResourceType::RT_BaseMaterials;
         return ResourceType::RT_BaseMaterials;
@@ -154,7 +168,7 @@ public:
         // empty
         // empty
     }
     }
 
 
-    ~Object() = default;
+    ~Object() override = default;
 
 
     ResourceType getType() const override {
     ResourceType getType() const override {
         return ResourceType::RT_Object;
         return ResourceType::RT_Object;

+ 6 - 1
Engine/lib/assimp/code/AssetLib/3MF/3MFXmlTags.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -98,6 +98,11 @@ namespace XmlTag {
     const char *const texture_cuurd_u = "u";
     const char *const texture_cuurd_u = "u";
     const char *const texture_cuurd_v = "v";
     const char *const texture_cuurd_v = "v";
 
 
+    // vertex color definitions
+    const char *const colorgroup = "m:colorgroup";
+    const char *const color_item = "m:color";
+    const char *const color_vaule = "color";
+
     // Meta info tags
     // Meta info tags
     const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
     const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
     const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
     const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";

+ 6 - 6
Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -83,7 +83,7 @@ void ExportScene3MF(const char *pFile, IOSystem *pIOSystem, const aiScene *pScen
 namespace D3MF {
 namespace D3MF {
 
 
 D3MFExporter::D3MFExporter(const char *pFile, const aiScene *pScene) :
 D3MFExporter::D3MFExporter(const char *pFile, const aiScene *pScene) :
-        mArchiveName(pFile), m_zipArchive(nullptr), mScene(pScene), mModelOutput(), mRelOutput(), mContentOutput(), mBuildItems(), mRelations() {
+        mArchiveName(pFile), m_zipArchive(nullptr), mScene(pScene) {
     // empty
     // empty
 }
 }
 
 
@@ -249,10 +249,10 @@ void D3MFExporter::writeBaseMaterials() {
             if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) {
             if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) {
 
 
                 hexDiffuseColor = ai_rgba2hex(
                 hexDiffuseColor = ai_rgba2hex(
-                        (int)((ai_real)color.r) * 255,
-                        (int)((ai_real)color.g) * 255,
-                        (int)((ai_real)color.b) * 255,
-                        (int)((ai_real)color.a) * 255,
+                        (int)(((ai_real)color.r) * 255),
+                        (int)(((ai_real)color.g) * 255),
+                        (int)(((ai_real)color.b) * 255),
+                        (int)(((ai_real)color.a) * 255),
                         true);
                         true);
 
 
             } else {
             } else {

+ 1 - 1
Engine/lib/assimp/code/AssetLib/3MF/D3MFExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 10 - 9
Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -68,7 +68,7 @@ namespace Assimp {
 
 
 using namespace D3MF;
 using namespace D3MF;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "3mf Importer",
     "3mf Importer",
     "",
     "",
     "",
     "",
@@ -81,16 +81,17 @@ static const aiImporterDesc desc = {
     "3mf"
     "3mf"
 };
 };
 
 
-D3MFImporter::D3MFImporter() = default;
-
-D3MFImporter::~D3MFImporter() = default;
-
-bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool /*checkSig*/) const {
+bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool ) const {
     if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
     if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
         return false;
         return false;
     }
     }
-    D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
-    return opcPackage.validate();
+    static const char *const ModelRef = "3D/3dmodel.model";
+    ZipArchiveIOSystem archive(pIOHandler, filename);
+    if (!archive.Exists(ModelRef)) {
+        return false;
+    }
+
+    return true;
 }
 }
 
 
 void D3MFImporter::SetupProperties(const Importer*) {
 void D3MFImporter::SetupProperties(const Importer*) {

+ 3 - 3
Engine/lib/assimp/code/AssetLib/3MF/D3MFImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -56,10 +56,10 @@ namespace Assimp {
 class D3MFImporter : public BaseImporter {
 class D3MFImporter : public BaseImporter {
 public:
 public:
     /// @brief The default class constructor.
     /// @brief The default class constructor.
-    D3MFImporter();
+    D3MFImporter() = default;
 
 
     ///	@brief  The class destructor.
     ///	@brief  The class destructor.
-    ~D3MFImporter() override;
+    ~D3MFImporter() override = default;
 
 
     /// @brief Performs the data format detection.
     /// @brief Performs the data format detection.
     /// @param pFile        The filename to check.
     /// @param pFile        The filename to check.

+ 9 - 12
Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -68,7 +68,7 @@ using OpcPackageRelationshipPtr = std::shared_ptr<OpcPackageRelationship>;
 class OpcPackageRelationshipReader {
 class OpcPackageRelationshipReader {
 public:
 public:
     OpcPackageRelationshipReader(XmlParser &parser) :
     OpcPackageRelationshipReader(XmlParser &parser) :
-            m_relationShips() {
+            mRelations() {
         XmlNode root = parser.getRootNode();
         XmlNode root = parser.getRootNode();
         ParseRootNode(root);
         ParseRootNode(root);
     }
     }
@@ -108,20 +108,20 @@ public:
                 relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
                 relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
                 relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
                 relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
                 if (validateRels(relPtr)) {
                 if (validateRels(relPtr)) {
-                    m_relationShips.push_back(relPtr);
+                    mRelations.push_back(relPtr);
                 }
                 }
             }
             }
         }
         }
     }
     }
 
 
-    std::vector<OpcPackageRelationshipPtr> m_relationShips;
+    std::vector<OpcPackageRelationshipPtr> mRelations;
 };
 };
 
 
 static bool IsEmbeddedTexture( const std::string &filename ) {
 static bool IsEmbeddedTexture( const std::string &filename ) {
     const std::string extension = BaseImporter::GetExtension(filename);
     const std::string extension = BaseImporter::GetExtension(filename);
-    if (extension == "jpg" || extension == "png") {
+    if (extension == "jpg" || extension == "png" || extension == "jpeg") {
         std::string::size_type pos = filename.find("thumbnail");
         std::string::size_type pos = filename.find("thumbnail");
-        if (pos == std::string::npos) {
+        if (pos != std::string::npos) {
             return false;
             return false;
         }
         }
         return true;
         return true;
@@ -160,7 +160,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
                     // deal with zip-bug
                     // deal with zip-bug
                     rootFile = rootFile.substr(1);
                     rootFile = rootFile.substr(1);
                 }
                 }
-            } 
+            }
 
 
             ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
             ASSIMP_LOG_VERBOSE_DEBUG(rootFile);
 
 
@@ -186,9 +186,6 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem *pIOHandler, const std::string &rFile) :
 D3MFOpcPackage::~D3MFOpcPackage() {
 D3MFOpcPackage::~D3MFOpcPackage() {
     mZipArchive->Close(mRootStream);
     mZipArchive->Close(mRootStream);
     delete mZipArchive;
     delete mZipArchive;
-    for (auto tex : mEmbeddedTextures) {
-        delete tex;
-    }
 }
 }
 
 
 IOStream *D3MFOpcPackage::RootStream() const {
 IOStream *D3MFOpcPackage::RootStream() const {
@@ -217,11 +214,11 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
 
 
     OpcPackageRelationshipReader reader(xmlParser);
     OpcPackageRelationshipReader reader(xmlParser);
 
 
-    auto itr = std::find_if(reader.m_relationShips.begin(), reader.m_relationShips.end(), [](const OpcPackageRelationshipPtr &rel) {
+    auto itr = std::find_if(reader.mRelations.begin(), reader.mRelations.end(), [](const OpcPackageRelationshipPtr &rel) {
         return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
         return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
     });
     });
 
 
-    if (itr == reader.m_relationShips.end()) {
+    if (itr == reader.mRelations.end()) {
         throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
         throw DeadlyImportError("Cannot find ", XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
     }
     }
 
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/3MF/D3MFOpcPackage.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 142 - 34
Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -44,19 +44,21 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "3MFTypes.h"
 #include "3MFTypes.h"
 #include <assimp/scene.h>
 #include <assimp/scene.h>
 
 
+#include <utility>
+
 namespace Assimp {
 namespace Assimp {
 namespace D3MF {
 namespace D3MF {
 
 
-static const int IdNotSet = -1;
+static constexpr int IdNotSet = -1;
 
 
 namespace {
 namespace {
 
 
-static const size_t ColRGBA_Len = 9;
-static const size_t ColRGB_Len = 7;
+static constexpr size_t ColRGBA_Len = 9;
+static constexpr size_t ColRGB_Len = 7;
 
 
 // format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
 // format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
-bool validateColorString(const char *color) {
-    const size_t len = strlen(color);
+bool validateColorString(const std::string color) {
+    const size_t len = color.size();
     if (ColRGBA_Len != len && ColRGB_Len != len) {
     if (ColRGBA_Len != len && ColRGB_Len != len) {
         return false;
         return false;
     }
     }
@@ -73,7 +75,7 @@ aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
     face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
     face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
     face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
     face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
 
 
-    texId0 = texId1 = texId2 = -1;
+    texId0 = texId1 = texId2 = IdNotSet;
     XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
     XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
     XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
     XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
     XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
     XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
@@ -155,8 +157,8 @@ aiMatrix4x4 parseTransformMatrix(const std::string& matrixStr) {
     return transformMatrix;
     return transformMatrix;
 }
 }
 
 
-bool parseColor(const char *color, aiColor4D &diffuse) {
-    if (nullptr == color) {
+bool parseColor(const std::string &color, aiColor4D &diffuse) {
+    if (color.empty()) {
         return false;
         return false;
     }
     }
 
 
@@ -176,7 +178,7 @@ bool parseColor(const char *color, aiColor4D &diffuse) {
 
 
     char b[3] = { color[5], color[6], '\0' };
     char b[3] = { color[5], color[6], '\0' };
     diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
     diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
-    const size_t len = strlen(color);
+    const size_t len = color.size();
     if (ColRGB_Len == len) {
     if (ColRGB_Len == len) {
         return true;
         return true;
     }
     }
@@ -214,7 +216,7 @@ void XmlSerializer::ImportXml(aiScene *scene) {
     if (nullptr == scene) {
     if (nullptr == scene) {
         return;
         return;
     }
     }
-    
+
     scene->mRootNode = new aiNode(XmlTag::RootTag);
     scene->mRootNode = new aiNode(XmlTag::RootTag);
     XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
     XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
     if (node.empty()) {
     if (node.empty()) {
@@ -234,6 +236,8 @@ void XmlSerializer::ImportXml(aiScene *scene) {
             ReadBaseMaterials(currentNode);
             ReadBaseMaterials(currentNode);
         } else if (currentNodeName == XmlTag::meta) {
         } else if (currentNodeName == XmlTag::meta) {
             ReadMetadata(currentNode);
             ReadMetadata(currentNode);
+        } else if (currentNodeName == XmlTag::colorgroup) {
+            ReadColorGroup(currentNode);
         }
         }
     }
     }
     StoreMaterialsInScene(scene);
     StoreMaterialsInScene(scene);
@@ -329,9 +333,49 @@ void XmlSerializer::ReadObject(XmlNode &node) {
 
 
             if (hasPid) {
             if (hasPid) {
                 auto it = mResourcesDictionnary.find(pid);
                 auto it = mResourcesDictionnary.find(pid);
-                if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
-                    BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
-                    mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
+                if (hasPindex && it != mResourcesDictionnary.end()) {
+                    if (it->second->getType() == ResourceType::RT_BaseMaterials) {
+                        BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
+                        mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
+                    } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
+                        Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
+                        if (mesh->mTextureCoords[0] == nullptr) {
+                            mesh->mNumUVComponents[0] = 2;
+                            for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
+                                mesh->mNumUVComponents[i] = 0;
+                            }
+
+                            const std::string name = ai_to_string(group->mTexId);
+                            for (size_t i = 0; i < mMaterials.size(); ++i) {
+                                if (name == mMaterials[i]->GetName().C_Str()) {
+                                    mesh->mMaterialIndex = static_cast<unsigned int>(i);
+                                }
+                            }
+
+                            mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
+                            for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
+                                mesh->mTextureCoords[0][vertex_idx] =
+                                        aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
+                            }
+                        } else {
+                            for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
+                                if (mesh->mTextureCoords[0][vertex_idx].z < 0) {
+                                    // use default
+                                    mesh->mTextureCoords[0][vertex_idx] =
+                                            aiVector3D(group->mTex2dCoords[pindex].x, group->mTex2dCoords[pindex].y, 0.0f);
+                                }
+                            }
+                        }
+                    }else if (it->second->getType() == ResourceType::RT_ColorGroup) {
+                        if (mesh->mColors[0] == nullptr) {
+                            mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
+
+                            ColorGroup *group = static_cast<ColorGroup *>(it->second);
+                            for (unsigned int vertex_idx = 0; vertex_idx < mesh->mNumVertices; vertex_idx++) {
+                                mesh->mColors[0][vertex_idx] = group->mColors[pindex];
+                            }
+                        }
+                    }
                 }
                 }
             }
             }
 
 
@@ -413,27 +457,36 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
     for (XmlNode &currentNode : node.children()) {
     for (XmlNode &currentNode : node.children()) {
         const std::string currentName = currentNode.name();
         const std::string currentName = currentNode.name();
         if (currentName == XmlTag::triangle) {
         if (currentName == XmlTag::triangle) {
-            int pid = IdNotSet, p1 = IdNotSet;
+            int pid = IdNotSet;
             bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
             bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
-            bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
 
 
-            int texId[3];
-            Texture2DGroup *group = nullptr;
-            aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
-            if (hasPid && hasP1) {
+            int pindex[3];
+            aiFace face = ReadTriangle(currentNode, pindex[0], pindex[1], pindex[2]);
+            if (hasPid && (pindex[0] != IdNotSet || pindex[1] != IdNotSet || pindex[2] != IdNotSet)) {
                 auto it = mResourcesDictionnary.find(pid);
                 auto it = mResourcesDictionnary.find(pid);
                 if (it != mResourcesDictionnary.end()) {
                 if (it != mResourcesDictionnary.end()) {
                     if (it->second->getType() == ResourceType::RT_BaseMaterials) {
                     if (it->second->getType() == ResourceType::RT_BaseMaterials) {
                         BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
                         BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
-                        mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
+
+                        auto update_material = [&](int idx) {
+                            if (pindex[idx] != IdNotSet) {
+                                mesh->mMaterialIndex = baseMaterials->mMaterialIndex[pindex[idx]];
+                            }
+                        };
+
+                        update_material(0);
+                        update_material(1);
+                        update_material(2);
+
                     } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
                     } else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
+                        // Load texture coordinates into mesh, when any
+                        Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second); // fix bug
                         if (mesh->mTextureCoords[0] == nullptr) {
                         if (mesh->mTextureCoords[0] == nullptr) {
                             mesh->mNumUVComponents[0] = 2;
                             mesh->mNumUVComponents[0] = 2;
                             for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
                             for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
                                 mesh->mNumUVComponents[i] = 0;
                                 mesh->mNumUVComponents[i] = 0;
                             }
                             }
 
 
-                            group = static_cast<Texture2DGroup *>(it->second);
                             const std::string name = ai_to_string(group->mTexId);
                             const std::string name = ai_to_string(group->mTexId);
                             for (size_t i = 0; i < mMaterials.size(); ++i) {
                             for (size_t i = 0; i < mMaterials.size(); ++i) {
                                 if (name == mMaterials[i]->GetName().C_Str()) {
                                 if (name == mMaterials[i]->GetName().C_Str()) {
@@ -441,19 +494,42 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
                                 }
                                 }
                             }
                             }
                             mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
                             mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
+                            for (unsigned int vertex_index = 0; vertex_index < mesh->mNumVertices; vertex_index++) {
+                                mesh->mTextureCoords[0][vertex_index].z = IdNotSet;//mark not set
+                            }
                         }
                         }
-                    } 
-                }
-            }
 
 
-            // Load texture coordinates into mesh, when any
-            if (group != nullptr) {
-                size_t i0 = face.mIndices[0];
-                size_t i1 = face.mIndices[1];
-                size_t i2 = face.mIndices[2];
-                mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
-                mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
-                mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
+                        auto update_texture = [&](int idx) {
+                            if (pindex[idx] != IdNotSet) {
+                                size_t vertex_index = face.mIndices[idx];
+                                mesh->mTextureCoords[0][vertex_index] =
+                                        aiVector3D(group->mTex2dCoords[pindex[idx]].x, group->mTex2dCoords[pindex[idx]].y, 0.0f);
+                            }
+                        };
+
+                        update_texture(0);
+                        update_texture(1);
+                        update_texture(2);
+
+                    } else if (it->second->getType() == ResourceType::RT_ColorGroup) {
+                        // Load vertex color into mesh, when any
+                        ColorGroup *group = static_cast<ColorGroup *>(it->second);
+                        if (mesh->mColors[0] == nullptr) {
+                            mesh->mColors[0] = new aiColor4D[mesh->mNumVertices];
+                        }
+
+                        auto update_color = [&](int idx) {
+                            if (pindex[idx] != IdNotSet) {
+                                size_t vertex_index = face.mIndices[idx];
+                                mesh->mColors[0][vertex_index] = group->mColors[pindex[idx]];
+                            }
+                        };
+
+                        update_color(0);
+                        update_color(1);
+                        update_color(2);
+                    }
+                }
             }
             }
 
 
             faces.push_back(face);
             faces.push_back(face);
@@ -582,7 +658,7 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
     stdMaterialName += strId;
     stdMaterialName += strId;
     stdMaterialName += "_";
     stdMaterialName += "_";
     if (hasName) {
     if (hasName) {
-        stdMaterialName += std::string(name);
+        stdMaterialName += name;
     } else {
     } else {
         stdMaterialName += "basemat_";
         stdMaterialName += "basemat_";
         stdMaterialName += ai_to_string(mMaterials.size());
         stdMaterialName += ai_to_string(mMaterials.size());
@@ -596,6 +672,38 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
     return material;
     return material;
 }
 }
 
 
+void XmlSerializer::ReadColor(XmlNode &node, ColorGroup *colorGroup) {
+    if (node.empty() || nullptr == colorGroup) {
+        return;
+    }
+
+    for (XmlNode currentNode : node.children()) {
+        const std::string currentName = currentNode.name();
+        if (currentName == XmlTag::color_item) {
+            const char *color = currentNode.attribute(XmlTag::color_vaule).as_string();
+            aiColor4D color_value;
+            if (parseColor(color, color_value)) {
+                colorGroup->mColors.push_back(color_value);
+            }
+        }
+    }
+}
+
+void XmlSerializer::ReadColorGroup(XmlNode &node) {
+    if (node.empty()) {
+        return;
+    }
+
+    int id = IdNotSet;
+    if (!XmlParser::getIntAttribute(node, XmlTag::id, id)) {
+        return;
+    }
+
+    ColorGroup *group = new ColorGroup(id);
+    ReadColor(node, group);
+    mResourcesDictionnary.insert(std::make_pair(id, group));
+}
+
 void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
 void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
     if (nullptr == scene) {
     if (nullptr == scene) {
         return;
         return;

+ 4 - 1
Engine/lib/assimp/code/AssetLib/3MF/XmlSerializer.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -57,6 +57,7 @@ class D3MFOpcPackage;
 class Object;
 class Object;
 class Texture2DGroup;
 class Texture2DGroup;
 class EmbeddedTexture;
 class EmbeddedTexture;
+class ColorGroup;
 
 
 class XmlSerializer {
 class XmlSerializer {
 public:
 public:
@@ -78,6 +79,8 @@ private:
     void ReadTextureGroup(XmlNode &node);
     void ReadTextureGroup(XmlNode &node);
     aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
     aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId);
     void StoreMaterialsInScene(aiScene *scene);
     void StoreMaterialsInScene(aiScene *scene);
+    void ReadColorGroup(XmlNode &node);
+    void ReadColor(XmlNode &node, ColorGroup *colorGroup);
 
 
 private:
 private:
     struct MetaEntry {
     struct MetaEntry {

+ 121 - 120
Engine/lib/assimp/code/AssetLib/AC/ACLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -60,9 +60,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/Importer.hpp>
 #include <assimp/Importer.hpp>
 #include <memory>
 #include <memory>
 
 
-using namespace Assimp;
+namespace Assimp {
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "AC3D Importer",
     "AC3D Importer",
     "",
     "",
     "",
     "",
@@ -77,8 +77,8 @@ static const aiImporterDesc desc = {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // skip to the next token
 // skip to the next token
-inline const char *AcSkipToNextToken(const char *buffer) {
-    if (!SkipSpaces(&buffer)) {
+inline const char *AcSkipToNextToken(const char *buffer, const char *end) {
+    if (!SkipSpaces(&buffer, end)) {
         ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
         ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL");
     }
     }
     return buffer;
     return buffer;
@@ -86,13 +86,13 @@ inline const char *AcSkipToNextToken(const char *buffer) {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // read a string (may be enclosed in double quotation marks). buffer must point to "
 // read a string (may be enclosed in double quotation marks). buffer must point to "
-inline const char *AcGetString(const char *buffer, std::string &out) {
+inline const char *AcGetString(const char *buffer, const char *end, std::string &out) {
     if (*buffer == '\0') {
     if (*buffer == '\0') {
         throw DeadlyImportError("AC3D: Unexpected EOF in string");
         throw DeadlyImportError("AC3D: Unexpected EOF in string");
     }
     }
     ++buffer;
     ++buffer;
     const char *sz = buffer;
     const char *sz = buffer;
-    while ('\"' != *buffer) {
+    while ('\"' != *buffer && buffer != end) {
         if (IsLineEnd(*buffer)) {
         if (IsLineEnd(*buffer)) {
             ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
             ASSIMP_LOG_ERROR("AC3D: Unexpected EOF/EOL in string");
             out = "ERROR";
             out = "ERROR";
@@ -112,8 +112,8 @@ inline const char *AcGetString(const char *buffer, std::string &out) {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // read 1 to n floats prefixed with an optional predefined identifier
 // read 1 to n floats prefixed with an optional predefined identifier
 template <class T>
 template <class T>
-inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name, size_t name_length, size_t num, T *out) {
-    buffer = AcSkipToNextToken(buffer);
+inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *end, const char *name, size_t name_length, size_t num, T *out) {
+    buffer = AcSkipToNextToken(buffer, end);
     if (0 != name_length) {
     if (0 != name_length) {
         if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
         if (0 != strncmp(buffer, name, name_length) || !IsSpace(buffer[name_length])) {
             ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
             ASSIMP_LOG_ERROR("AC3D: Unexpected token. ", name, " was expected.");
@@ -122,7 +122,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
         buffer += name_length + 1;
         buffer += name_length + 1;
     }
     }
     for (unsigned int _i = 0; _i < num; ++_i) {
     for (unsigned int _i = 0; _i < num; ++_i) {
-        buffer = AcSkipToNextToken(buffer);
+        buffer = AcSkipToNextToken(buffer, end);
         buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
         buffer = fast_atoreal_move<float>(buffer, ((float *)out)[_i]);
     }
     }
 
 
@@ -132,7 +132,7 @@ inline const char *TAcCheckedLoadFloatArray(const char *buffer, const char *name
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 // Constructor to be privately used by Importer
 AC3DImporter::AC3DImporter() :
 AC3DImporter::AC3DImporter() :
-        buffer(),
+        mBuffer(),
         configSplitBFCull(),
         configSplitBFCull(),
         configEvalSubdivision(),
         configEvalSubdivision(),
         mNumMeshes(),
         mNumMeshes(),
@@ -164,17 +164,17 @@ const aiImporterDesc *AC3DImporter::GetInfo() const {
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Get a pointer to the next line from the file
 // Get a pointer to the next line from the file
 bool AC3DImporter::GetNextLine() {
 bool AC3DImporter::GetNextLine() {
-    SkipLine(&buffer);
-    return SkipSpaces(&buffer);
+    SkipLine(&mBuffer.data, mBuffer.end);
+    return SkipSpaces(&mBuffer.data, mBuffer.end);
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Parse an object section in an AC file
 // Parse an object section in an AC file
-void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
-    if (!TokenMatch(buffer, "OBJECT", 6))
-        return;
+bool AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
+    if (!TokenMatch(mBuffer.data, "OBJECT", 6))
+        return false;
 
 
-    SkipSpaces(&buffer);
+    SkipSpaces(&mBuffer.data, mBuffer.end);
 
 
     ++mNumMeshes;
     ++mNumMeshes;
 
 
@@ -182,7 +182,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
     Object &obj = objects.back();
     Object &obj = objects.back();
 
 
     aiLight *light = nullptr;
     aiLight *light = nullptr;
-    if (!ASSIMP_strincmp(buffer, "light", 5)) {
+    if (!ASSIMP_strincmp(mBuffer.data, "light", 5)) {
         // This is a light source. Add it to the list
         // This is a light source. Add it to the list
         mLights->push_back(light = new aiLight());
         mLights->push_back(light = new aiLight());
 
 
@@ -193,65 +193,71 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
 
 
         // Generate a default name for both the light source and the node
         // Generate a default name for both the light source and the node
         // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
         // FIXME - what's the right way to print a size_t? Is 'zu' universally available? stick with the safe version.
-        light->mName.length = ::ai_snprintf(light->mName.data, MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1);
+        light->mName.length = ::ai_snprintf(light->mName.data, AI_MAXLEN, "ACLight_%i", static_cast<unsigned int>(mLights->size()) - 1);
         obj.name = std::string(light->mName.data);
         obj.name = std::string(light->mName.data);
 
 
         ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
         ASSIMP_LOG_VERBOSE_DEBUG("AC3D: Light source encountered");
         obj.type = Object::Light;
         obj.type = Object::Light;
-    } else if (!ASSIMP_strincmp(buffer, "group", 5)) {
+    } else if (!ASSIMP_strincmp(mBuffer.data, "group", 5)) {
         obj.type = Object::Group;
         obj.type = Object::Group;
-    } else if (!ASSIMP_strincmp(buffer, "world", 5)) {
+    } else if (!ASSIMP_strincmp(mBuffer.data, "world", 5)) {
         obj.type = Object::World;
         obj.type = Object::World;
     } else
     } else
         obj.type = Object::Poly;
         obj.type = Object::Poly;
     while (GetNextLine()) {
     while (GetNextLine()) {
-        if (TokenMatch(buffer, "kids", 4)) {
-            SkipSpaces(&buffer);
-            unsigned int num = strtoul10(buffer, &buffer);
+        if (TokenMatch(mBuffer.data, "kids", 4)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            unsigned int num = strtoul10(mBuffer.data, &mBuffer.data);
             GetNextLine();
             GetNextLine();
             if (num) {
             if (num) {
                 // load the children of this object recursively
                 // load the children of this object recursively
                 obj.children.reserve(num);
                 obj.children.reserve(num);
-                for (unsigned int i = 0; i < num; ++i)
-                    LoadObjectSection(obj.children);
+                for (unsigned int i = 0; i < num; ++i) {
+                    if (!LoadObjectSection(obj.children)) {
+                        ASSIMP_LOG_WARN("AC3D: wrong number of kids");
+                        break;
+                    }
+                }
             }
             }
-            return;
-        } else if (TokenMatch(buffer, "name", 4)) {
-            SkipSpaces(&buffer);
-            buffer = AcGetString(buffer, obj.name);
+            return true;
+        } else if (TokenMatch(mBuffer.data, "name", 4)) {
+            SkipSpaces(&mBuffer.data, mBuffer.data);
+            mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, obj.name);
 
 
             // If this is a light source, we'll also need to store
             // If this is a light source, we'll also need to store
             // the name of the node in it.
             // the name of the node in it.
             if (light) {
             if (light) {
                 light->mName.Set(obj.name);
                 light->mName.Set(obj.name);
             }
             }
-        } else if (TokenMatch(buffer, "texture", 7)) {
-            SkipSpaces(&buffer);
-            buffer = AcGetString(buffer, obj.texture);
-        } else if (TokenMatch(buffer, "texrep", 6)) {
-            SkipSpaces(&buffer);
-            buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texRepeat);
+        } else if (TokenMatch(mBuffer.data, "texture", 7)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            std::string texture;
+            mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, texture);
+            obj.textures.push_back(texture);
+        } else if (TokenMatch(mBuffer.data, "texrep", 6)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texRepeat);
             if (!obj.texRepeat.x || !obj.texRepeat.y)
             if (!obj.texRepeat.x || !obj.texRepeat.y)
                 obj.texRepeat = aiVector2D(1.f, 1.f);
                 obj.texRepeat = aiVector2D(1.f, 1.f);
-        } else if (TokenMatch(buffer, "texoff", 6)) {
-            SkipSpaces(&buffer);
-            buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &obj.texOffset);
-        } else if (TokenMatch(buffer, "rot", 3)) {
-            SkipSpaces(&buffer);
-            buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 9, &obj.rotation);
-        } else if (TokenMatch(buffer, "loc", 3)) {
-            SkipSpaces(&buffer);
-            buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &obj.translation);
-        } else if (TokenMatch(buffer, "subdiv", 6)) {
-            SkipSpaces(&buffer);
-            obj.subDiv = strtoul10(buffer, &buffer);
-        } else if (TokenMatch(buffer, "crease", 6)) {
-            SkipSpaces(&buffer);
-            obj.crease = fast_atof(buffer);
-        } else if (TokenMatch(buffer, "numvert", 7)) {
-            SkipSpaces(&buffer);
-
-            unsigned int t = strtoul10(buffer, &buffer);
+        } else if (TokenMatch(mBuffer.data, "texoff", 6)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &obj.texOffset);
+        } else if (TokenMatch(mBuffer.data, "rot", 3)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 9, &obj.rotation);
+        } else if (TokenMatch(mBuffer.data, "loc", 3)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &obj.translation);
+        } else if (TokenMatch(mBuffer.data, "subdiv", 6)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            obj.subDiv = strtoul10(mBuffer.data, &mBuffer.data);
+        } else if (TokenMatch(mBuffer.data, "crease", 6)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+            obj.crease = fast_atof(mBuffer.data);
+        } else if (TokenMatch(mBuffer.data, "numvert", 7)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
+
+            unsigned int t = strtoul10(mBuffer.data, &mBuffer.data);
             if (t >= AI_MAX_ALLOC(aiVector3D)) {
             if (t >= AI_MAX_ALLOC(aiVector3D)) {
                 throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
                 throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
             }
             }
@@ -260,59 +266,59 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                 if (!GetNextLine()) {
                 if (!GetNextLine()) {
                     ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
                     ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: not all vertices have been parsed yet");
                     break;
                     break;
-                } else if (!IsNumeric(*buffer)) {
+                } else if (!IsNumeric(*mBuffer.data)) {
                     ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
                     ASSIMP_LOG_ERROR("AC3D: Unexpected token: not all vertices have been parsed yet");
-                    --buffer; // make sure the line is processed a second time
+                    --mBuffer.data; // make sure the line is processed a second time
                     break;
                     break;
                 }
                 }
                 obj.vertices.emplace_back();
                 obj.vertices.emplace_back();
                 aiVector3D &v = obj.vertices.back();
                 aiVector3D &v = obj.vertices.back();
-                buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 3, &v.x);
+                mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 3, &v.x);
             }
             }
-        } else if (TokenMatch(buffer, "numsurf", 7)) {
-            SkipSpaces(&buffer);
+        } else if (TokenMatch(mBuffer.data, "numsurf", 7)) {
+            SkipSpaces(&mBuffer.data, mBuffer.end);
 
 
             bool Q3DWorkAround = false;
             bool Q3DWorkAround = false;
 
 
-            const unsigned int t = strtoul10(buffer, &buffer);
+            const unsigned int t = strtoul10(mBuffer.data, &mBuffer.data);
             obj.surfaces.reserve(t);
             obj.surfaces.reserve(t);
             for (unsigned int i = 0; i < t; ++i) {
             for (unsigned int i = 0; i < t; ++i) {
                 GetNextLine();
                 GetNextLine();
-                if (!TokenMatch(buffer, "SURF", 4)) {
+                if (!TokenMatch(mBuffer.data, "SURF", 4)) {
                     // FIX: this can occur for some files - Quick 3D for
                     // FIX: this can occur for some files - Quick 3D for
                     // example writes no surf chunks
                     // example writes no surf chunks
                     if (!Q3DWorkAround) {
                     if (!Q3DWorkAround) {
                         ASSIMP_LOG_WARN("AC3D: SURF token was expected");
                         ASSIMP_LOG_WARN("AC3D: SURF token was expected");
                         ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled");
                         ASSIMP_LOG_VERBOSE_DEBUG("Continuing with Quick3D Workaround enabled");
                     }
                     }
-                    --buffer; // make sure the line is processed a second time
+                    --mBuffer.data; // make sure the line is processed a second time
                     // break; --- see fix notes above
                     // break; --- see fix notes above
 
 
                     Q3DWorkAround = true;
                     Q3DWorkAround = true;
                 }
                 }
-                SkipSpaces(&buffer);
+                SkipSpaces(&mBuffer.data, mBuffer.end);
                 obj.surfaces.emplace_back();
                 obj.surfaces.emplace_back();
                 Surface &surf = obj.surfaces.back();
                 Surface &surf = obj.surfaces.back();
-                surf.flags = strtoul_cppstyle(buffer);
+                surf.flags = strtoul_cppstyle(mBuffer.data);
 
 
-                while (1) {
+                while (true) {
                     if (!GetNextLine()) {
                     if (!GetNextLine()) {
                         throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
                         throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
                     }
                     }
-                    if (TokenMatch(buffer, "mat", 3)) {
-                        SkipSpaces(&buffer);
-                        surf.mat = strtoul10(buffer);
-                    } else if (TokenMatch(buffer, "refs", 4)) {
+                    if (TokenMatch(mBuffer.data, "mat", 3)) {
+                        SkipSpaces(&mBuffer.data, mBuffer.end);
+                        surf.mat = strtoul10(mBuffer.data);
+                    } else if (TokenMatch(mBuffer.data, "refs", 4)) {
                         // --- see fix notes above
                         // --- see fix notes above
                         if (Q3DWorkAround) {
                         if (Q3DWorkAround) {
                             if (!surf.entries.empty()) {
                             if (!surf.entries.empty()) {
-                                buffer -= 6;
+                                mBuffer.data -= 6;
                                 break;
                                 break;
                             }
                             }
                         }
                         }
 
 
-                        SkipSpaces(&buffer);
-                        const unsigned int m = strtoul10(buffer);
+                        SkipSpaces(&mBuffer.data, mBuffer.end);
+                        const unsigned int m = strtoul10(mBuffer.data);
                         surf.entries.reserve(m);
                         surf.entries.reserve(m);
 
 
                         obj.numRefs += m;
                         obj.numRefs += m;
@@ -325,12 +331,12 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
                             surf.entries.emplace_back();
                             surf.entries.emplace_back();
                             Surface::SurfaceEntry &entry = surf.entries.back();
                             Surface::SurfaceEntry &entry = surf.entries.back();
 
 
-                            entry.first = strtoul10(buffer, &buffer);
-                            SkipSpaces(&buffer);
-                            buffer = TAcCheckedLoadFloatArray(buffer, "", 0, 2, &entry.second);
+                            entry.first = strtoul10(mBuffer.data, &mBuffer.data);
+                            SkipSpaces(&mBuffer.data, mBuffer.end);
+                            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "", 0, 2, &entry.second);
                         }
                         }
                     } else {
                     } else {
-                        --buffer; // make sure the line is processed a second time
+                        --mBuffer.data; // make sure the line is processed a second time
                         break;
                         break;
                     }
                     }
                 }
                 }
@@ -338,6 +344,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object> &objects) {
         }
         }
     }
     }
     ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
     ASSIMP_LOG_ERROR("AC3D: Unexpected EOF: \'kids\' line was expected");
+    return false;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -351,8 +358,8 @@ void AC3DImporter::ConvertMaterial(const Object &object,
         s.Set(matSrc.name);
         s.Set(matSrc.name);
         matDest.AddProperty(&s, AI_MATKEY_NAME);
         matDest.AddProperty(&s, AI_MATKEY_NAME);
     }
     }
-    if (object.texture.length()) {
-        s.Set(object.texture);
+    if (!object.textures.empty()) {
+        s.Set(object.textures[0]);
         matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
         matDest.AddProperty(&s, AI_MATKEY_TEXTURE_DIFFUSE(0));
 
 
         // UV transformation
         // UV transformation
@@ -443,7 +450,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
                     idx = 0;
                     idx = 0;
                 }
                 }
                 if ((*it).entries.empty()) {
                 if ((*it).entries.empty()) {
-                    ASSIMP_LOG_WARN("AC3D: surface her zero vertex references");
+                    ASSIMP_LOG_WARN("AC3D: surface has zero vertex references");
                 }
                 }
 
 
                 // validate all vertex indices to make sure we won't crash here
                 // validate all vertex indices to make sure we won't crash here
@@ -461,16 +468,15 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
                 }
                 }
 
 
                 switch ((*it).GetType()) {
                 switch ((*it).GetType()) {
-                    // closed line
-                case Surface::ClosedLine:
-                    needMat[idx].first += (unsigned int)(*it).entries.size();
-                    needMat[idx].second += (unsigned int)(*it).entries.size() << 1u;
+                case Surface::ClosedLine: // closed line
+                    needMat[idx].first += static_cast<unsigned int>((*it).entries.size());
+                    needMat[idx].second += static_cast<unsigned int>((*it).entries.size() << 1u);
                     break;
                     break;
 
 
                     // unclosed line
                     // unclosed line
                 case Surface::OpenLine:
                 case Surface::OpenLine:
-                    needMat[idx].first += (unsigned int)(*it).entries.size() - 1;
-                    needMat[idx].second += ((unsigned int)(*it).entries.size() - 1) << 1u;
+                    needMat[idx].first += static_cast<unsigned int>((*it).entries.size() - 1);
+                    needMat[idx].second += static_cast<unsigned int>(((*it).entries.size() - 1) << 1u);
                     break;
                     break;
 
 
                     // triangle strip
                     // triangle strip
@@ -532,7 +538,7 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
                 // allocate UV coordinates, but only if the texture name for the
                 // allocate UV coordinates, but only if the texture name for the
                 // surface is not empty
                 // surface is not empty
                 aiVector3D *uv = nullptr;
                 aiVector3D *uv = nullptr;
-                if (object.texture.length()) {
+                if (!object.textures.empty()) {
                     uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
                     uv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
                     mesh->mNumUVComponents[0] = 2;
                     mesh->mNumUVComponents[0] = 2;
                 }
                 }
@@ -572,15 +578,6 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
                                 const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
                                 const Surface::SurfaceEntry &entry2 = src.entries[i + 1];
                                 const Surface::SurfaceEntry &entry3 = src.entries[i + 2];
                                 const Surface::SurfaceEntry &entry3 = src.entries[i + 2];
 
 
-                                // skip degenerate triangles
-                                if (object.vertices[entry1.first] == object.vertices[entry2.first] ||
-                                        object.vertices[entry1.first] == object.vertices[entry3.first] ||
-                                        object.vertices[entry2.first] == object.vertices[entry3.first]) {
-                                    mesh->mNumFaces--;
-                                    mesh->mNumVertices -= 3;
-                                    continue;
-                                }
-
                                 aiFace &face = *faces++;
                                 aiFace &face = *faces++;
                                 face.mNumIndices = 3;
                                 face.mNumIndices = 3;
                                 face.mIndices = new unsigned int[face.mNumIndices];
                                 face.mIndices = new unsigned int[face.mNumIndices];
@@ -699,18 +696,18 @@ aiNode *AC3DImporter::ConvertObjectSection(Object &object,
         // generate a name depending on the type of the node
         // generate a name depending on the type of the node
         switch (object.type) {
         switch (object.type) {
         case Object::Group:
         case Object::Group:
-            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACGroup_%i", mGroupsCounter++);
+            node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACGroup_%i", mGroupsCounter++);
             break;
             break;
         case Object::Poly:
         case Object::Poly:
-            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACPoly_%i", mPolysCounter++);
+            node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACPoly_%i", mPolysCounter++);
             break;
             break;
         case Object::Light:
         case Object::Light:
-            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACLight_%i", mLightsCounter++);
+            node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACLight_%i", mLightsCounter++);
             break;
             break;
 
 
             // there shouldn't be more than one world, but we don't care
             // there shouldn't be more than one world, but we don't care
         case Object::World:
         case Object::World:
-            node->mName.length = ::ai_snprintf(node->mName.data, MAXLEN, "ACWorld_%i", mWorldsCounter++);
+            node->mName.length = ::ai_snprintf(node->mName.data, AI_MAXLEN, "ACWorld_%i", mWorldsCounter++);
             break;
             break;
         }
         }
     }
     }
@@ -750,7 +747,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
 
 
     // Check whether we can read from the file
     // Check whether we can read from the file
-    if (file.get() == nullptr) {
+    if (file == nullptr) {
         throw DeadlyImportError("Failed to open AC3D file ", pFile, ".");
         throw DeadlyImportError("Failed to open AC3D file ", pFile, ".");
     }
     }
 
 
@@ -758,17 +755,18 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
     std::vector<char> mBuffer2;
     std::vector<char> mBuffer2;
     TextFileToBuffer(file.get(), mBuffer2);
     TextFileToBuffer(file.get(), mBuffer2);
 
 
-    buffer = &mBuffer2[0];
+    mBuffer.data = &mBuffer2[0];
+    mBuffer.end = &mBuffer2[0] + mBuffer2.size();
     mNumMeshes = 0;
     mNumMeshes = 0;
 
 
     mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
     mLightsCounter = mPolysCounter = mWorldsCounter = mGroupsCounter = 0;
 
 
-    if (::strncmp(buffer, "AC3D", 4)) {
+    if (::strncmp(mBuffer.data, "AC3D", 4)) {
         throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
         throw DeadlyImportError("AC3D: No valid AC3D file, magic sequence not found");
     }
     }
 
 
     // print the file format version to the console
     // print the file format version to the console
-    unsigned int version = HexDigitToDecimal(buffer[4]);
+    unsigned int version = HexDigitToDecimal(mBuffer.data[4]);
     char msg[3];
     char msg[3];
     ASSIMP_itoa10(msg, 3, version);
     ASSIMP_itoa10(msg, 3, version);
     ASSIMP_LOG_INFO("AC3D file format version: ", msg);
     ASSIMP_LOG_INFO("AC3D file format version: ", msg);
@@ -783,30 +781,31 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
     mLights = &lights;
     mLights = &lights;
 
 
     while (GetNextLine()) {
     while (GetNextLine()) {
-        if (TokenMatch(buffer, "MATERIAL", 8)) {
+        if (TokenMatch(mBuffer.data, "MATERIAL", 8)) {
             materials.emplace_back();
             materials.emplace_back();
             Material &mat = materials.back();
             Material &mat = materials.back();
 
 
             // manually parse the material ... sscanf would use the buldin atof ...
             // manually parse the material ... sscanf would use the buldin atof ...
             // Format: (name) rgb %f %f %f  amb %f %f %f  emis %f %f %f  spec %f %f %f  shi %d  trans %f
             // Format: (name) rgb %f %f %f  amb %f %f %f  emis %f %f %f  spec %f %f %f  shi %d  trans %f
 
 
-            buffer = AcSkipToNextToken(buffer);
-            if ('\"' == *buffer) {
-                buffer = AcGetString(buffer, mat.name);
-                buffer = AcSkipToNextToken(buffer);
+            mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end);
+            if ('\"' == *mBuffer.data) {
+                mBuffer.data = AcGetString(mBuffer.data, mBuffer.end, mat.name);
+                mBuffer.data = AcSkipToNextToken(mBuffer.data, mBuffer.end);
             }
             }
 
 
-            buffer = TAcCheckedLoadFloatArray(buffer, "rgb", 3, 3, &mat.rgb);
-            buffer = TAcCheckedLoadFloatArray(buffer, "amb", 3, 3, &mat.amb);
-            buffer = TAcCheckedLoadFloatArray(buffer, "emis", 4, 3, &mat.emis);
-            buffer = TAcCheckedLoadFloatArray(buffer, "spec", 4, 3, &mat.spec);
-            buffer = TAcCheckedLoadFloatArray(buffer, "shi", 3, 1, &mat.shin);
-            buffer = TAcCheckedLoadFloatArray(buffer, "trans", 5, 1, &mat.trans);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "rgb", 3, 3, &mat.rgb);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "amb", 3, 3, &mat.amb);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "emis", 4, 3, &mat.emis);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "spec", 4, 3, &mat.spec);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "shi", 3, 1, &mat.shin);
+            mBuffer.data = TAcCheckedLoadFloatArray(mBuffer.data, mBuffer.end, "trans", 5, 1, &mat.trans);
+        } else {
+            LoadObjectSection(rootObjects);
         }
         }
-        LoadObjectSection(rootObjects);
     }
     }
 
 
-    if (rootObjects.empty() || !mNumMeshes) {
+    if (rootObjects.empty() || mNumMeshes == 0u) {
         throw DeadlyImportError("AC3D: No meshes have been loaded");
         throw DeadlyImportError("AC3D: No meshes have been loaded");
     }
     }
     if (materials.empty()) {
     if (materials.empty()) {
@@ -822,7 +821,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
     materials.reserve(mNumMeshes);
     materials.reserve(mNumMeshes);
 
 
     // generate a dummy root if there are multiple objects on the top layer
     // generate a dummy root if there are multiple objects on the top layer
-    Object *root;
+    Object *root = nullptr;
     if (1 == rootObjects.size())
     if (1 == rootObjects.size())
         root = &rootObjects[0];
         root = &rootObjects[0];
     else {
     else {
@@ -835,7 +834,7 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
         delete root;
         delete root;
     }
     }
 
 
-    if (!::strncmp(pScene->mRootNode->mName.data, "Node", 4)) {
+    if (::strncmp(pScene->mRootNode->mName.data, "Node", 4) == 0) {
         pScene->mRootNode->mName.Set("<AC3DWorld>");
         pScene->mRootNode->mName.Set("<AC3DWorld>");
     }
     }
 
 
@@ -854,10 +853,12 @@ void AC3DImporter::InternReadFile(const std::string &pFile,
 
 
     // copy lights
     // copy lights
     pScene->mNumLights = (unsigned int)lights.size();
     pScene->mNumLights = (unsigned int)lights.size();
-    if (lights.size()) {
+    if (!lights.empty()) {
         pScene->mLights = new aiLight *[lights.size()];
         pScene->mLights = new aiLight *[lights.size()];
         ::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
         ::memcpy(pScene->mLights, &lights[0], lights.size() * sizeof(void *));
     }
     }
 }
 }
 
 
+} // namespace Assimp
+
 #endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER
 #endif //!defined ASSIMP_BUILD_NO_AC_IMPORTER

+ 5 - 5
Engine/lib/assimp/code/AssetLib/AC/ACLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -125,7 +125,6 @@ public:
                 type(World),
                 type(World),
                 name(),
                 name(),
                 children(),
                 children(),
-                texture(),
                 texRepeat(1.f, 1.f),
                 texRepeat(1.f, 1.f),
                 texOffset(0.0f, 0.0f),
                 texOffset(0.0f, 0.0f),
                 rotation(),
                 rotation(),
@@ -151,7 +150,8 @@ public:
         std::vector<Object> children;
         std::vector<Object> children;
 
 
         // texture to be assigned to all surfaces of the object
         // texture to be assigned to all surfaces of the object
-        std::string texture;
+        // the .acc format supports up to 4 textures
+        std::vector<std::string> textures;
 
 
         // texture repat factors (scaling for all coordinates)
         // texture repat factors (scaling for all coordinates)
         aiVector2D texRepeat, texOffset;
         aiVector2D texRepeat, texOffset;
@@ -216,7 +216,7 @@ private:
      *  load subobjects, the method returns after a 'kids 0' was
      *  load subobjects, the method returns after a 'kids 0' was
      *  encountered.
      *  encountered.
      *  @objects List of output objects*/
      *  @objects List of output objects*/
-    void LoadObjectSection(std::vector<Object> &objects);
+    bool LoadObjectSection(std::vector<Object> &objects);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Convert all objects into meshes and nodes.
     /** Convert all objects into meshes and nodes.
@@ -242,7 +242,7 @@ private:
 
 
 private:
 private:
     // points to the next data line
     // points to the next data line
-    const char *buffer;
+    aiBuffer mBuffer;
 
 
     // Configuration option: if enabled, up to two meshes
     // Configuration option: if enabled, up to two meshes
     // are generated per material: those faces who have
     // are generated per material: those faces who have

+ 14 - 37
Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -53,7 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 namespace Assimp {
 namespace Assimp {
 
 
-const aiImporterDesc AMFImporter::Description = {
+static constexpr aiImporterDesc Description = {
     "Additive manufacturing file format(AMF) Importer",
     "Additive manufacturing file format(AMF) Importer",
     "smalcom",
     "smalcom",
     "",
     "",
@@ -83,11 +83,7 @@ void AMFImporter::Clear() {
 
 
 AMFImporter::AMFImporter() AI_NO_EXCEPT :
 AMFImporter::AMFImporter() AI_NO_EXCEPT :
         mNodeElement_Cur(nullptr),
         mNodeElement_Cur(nullptr),
-        mXmlParser(nullptr),
-        mUnit(),
-        mVersion(),
-        mMaterial_Converted(),
-        mTexture_Converted() {
+        mXmlParser(nullptr) {
     // empty
     // empty
 }
 }
 
 
@@ -182,28 +178,6 @@ bool AMFImporter::XML_SearchNode(const std::string &nodeName) {
     return nullptr != mXmlParser->findNode(nodeName);
     return nullptr != mXmlParser->findNode(nodeName);
 }
 }
 
 
-void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString) {
-    size_t instr_len;
-
-    pOutString.clear();
-    instr_len = strlen(pInStr);
-    if (!instr_len) return;
-
-    pOutString.reserve(instr_len * 3 / 2);
-    // check and correct floats in format ".x". Must be "x.y".
-    if (pInStr[0] == '.') pOutString.push_back('0');
-
-    pOutString.push_back(pInStr[0]);
-    for (size_t ci = 1; ci < instr_len; ci++) {
-        if ((pInStr[ci] == '.') && ((pInStr[ci - 1] == ' ') || (pInStr[ci - 1] == '-') || (pInStr[ci - 1] == '+') || (pInStr[ci - 1] == '\t'))) {
-            pOutString.push_back('0');
-            pOutString.push_back('.');
-        } else {
-            pOutString.push_back(pInStr[ci]);
-        }
-    }
-}
-
 static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
 static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
     return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
     return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
 }
 }
@@ -217,7 +191,10 @@ void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std
     uint8_t arr4[4], arr3[3];
     uint8_t arr4[4], arr3[3];
 
 
     // check input data
     // check input data
-    if (pInputBase64.size() % 4) throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
+    if (pInputBase64.size() % 4) {
+        throw DeadlyImportError("Base64-encoded data must have size multiply of four.");
+    }
+
     // prepare output place
     // prepare output place
     pOutputData.clear();
     pOutputData.clear();
     pOutputData.reserve(pInputBase64.size() / 4 * 3);
     pOutputData.reserve(pInputBase64.size() / 4 * 3);
@@ -261,7 +238,7 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
 
 
     // Check whether we can read from the file
     // Check whether we can read from the file
-    if (file.get() == nullptr) {
+    if (file == nullptr) {
         throw DeadlyImportError("Failed to open AMF file ", pFile, ".");
         throw DeadlyImportError("Failed to open AMF file ", pFile, ".");
     }
     }
 
 
@@ -407,17 +384,17 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
         for (auto &currentNode : node.children()) {
         for (auto &currentNode : node.children()) {
             const std::string &currentName = currentNode.name();
             const std::string &currentName = currentNode.name();
             if (currentName == "deltax") {
             if (currentName == "deltax") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.x);
+                XmlParser::getValueAsReal(currentNode, als.Delta.x);
             } else if (currentName == "deltay") {
             } else if (currentName == "deltay") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.y);
+                XmlParser::getValueAsReal(currentNode, als.Delta.y);
             } else if (currentName == "deltaz") {
             } else if (currentName == "deltaz") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.z);
+                XmlParser::getValueAsReal(currentNode, als.Delta.z);
             } else if (currentName == "rx") {
             } else if (currentName == "rx") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.x);
+                XmlParser::getValueAsReal(currentNode, als.Delta.x);
             } else if (currentName == "ry") {
             } else if (currentName == "ry") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.y);
+                XmlParser::getValueAsReal(currentNode, als.Delta.y);
             } else if (currentName == "rz") {
             } else if (currentName == "rz") {
-                XmlParser::getValueAsFloat(currentNode, als.Delta.z);
+                XmlParser::getValueAsReal(currentNode, als.Delta.z);
             }
             }
         }
         }
         ParseHelper_Node_Exit();
         ParseHelper_Node_Exit();

+ 50 - 52
Engine/lib/assimp/code/AssetLib/AMF/AMFImporter.hpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -98,8 +98,12 @@ namespace Assimp {
 ///            old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
 ///            old - <map> and children <u1>, <u2>, <u3>, <v1>, <v2>, <v3>
 ///
 ///
 class AMFImporter : public BaseImporter {
 class AMFImporter : public BaseImporter {
-private:
-    struct SPP_Material; // forward declaration
+    using AMFMetaDataArray = std::vector<AMFMetadata *>;
+    using MeshArray = std::vector<aiMesh *>;
+    using NodeArray = std::vector<aiNode *>;
+
+public:
+    struct SPP_Material;
 
 
     /// Data type for post-processing step. More suitable container for part of material's composition.
     /// Data type for post-processing step. More suitable container for part of material's composition.
     struct SPP_Composite {
     struct SPP_Composite {
@@ -107,7 +111,22 @@ private:
         std::string Formula; ///< Formula for calculating ratio of \ref Material.
         std::string Formula; ///< Formula for calculating ratio of \ref Material.
     };
     };
 
 
-    /// \struct SPP_Material
+    /// Data type for post-processing step. More suitable container for texture.
+    struct SPP_Texture {
+        std::string ID;
+        size_t Width, Height, Depth;
+        bool Tiled;
+        char FormatHint[9]; // 8 for string + 1 for terminator.
+        uint8_t *Data;
+    };
+
+    /// Data type for post-processing step. Contain face data.
+    struct SComplexFace {
+        aiFace Face; ///< Face vertices.
+        const AMFColor *Color; ///< Face color. Equal to nullptr if color is not set for the face.
+        const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
+    };
+
     /// Data type for post-processing step. More suitable container for material.
     /// Data type for post-processing step. More suitable container for material.
     struct SPP_Material {
     struct SPP_Material {
         std::string ID; ///< Material ID.
         std::string ID; ///< Material ID.
@@ -123,26 +142,36 @@ private:
         aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
         aiColor4D GetColor(const float pX, const float pY, const float pZ) const;
     };
     };
 
 
-    /// Data type for post-processing step. More suitable container for texture.
-    struct SPP_Texture {
-        std::string ID;
-        size_t Width, Height, Depth;
-        bool Tiled;
-        char FormatHint[9]; // 8 for string + 1 for terminator.
-        uint8_t *Data;
-    };
+    /// Default constructor.
+    AMFImporter() AI_NO_EXCEPT;
 
 
-    /// Data type for post-processing step. Contain face data.
-    struct SComplexFace {
-        aiFace Face; ///< Face vertices.
-        const AMFColor *Color; ///< Face color. Equal to nullptr if color is not set for the face.
-        const AMFTexMap *TexMap; ///< Face texture mapping data. Equal to nullptr if texture mapping is not set for the face.
-    };
+    /// Default destructor.
+    ~AMFImporter() override;
 
 
-    using AMFMetaDataArray = std::vector<AMFMetadata*>;
-    using MeshArray = std::vector<aiMesh*>;
-    using NodeArray = std::vector<aiNode*>;
+    /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
+    /// Also exception can be thrown if trouble will found.
+    /// \param [in] pFile - name of file to be parsed.
+    /// \param [in] pIOHandler - pointer to IO helper object.
+    void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
+    void ParseHelper_Node_Enter(AMFNodeElementBase *child);
+    void ParseHelper_Node_Exit();
+    bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
+    void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
+    const aiImporterDesc *GetInfo() const override;
+    bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
+    bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
+    bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
+    AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
+    AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
+    AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
+    AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
+    AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
+    void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
+    bool XML_SearchNode(const std::string &nodeName);
+    AMFImporter(const AMFImporter &pScene) = delete;
+    AMFImporter &operator=(const AMFImporter &pScene) = delete;
 
 
+private:
     /// Clear all temporary data.
     /// Clear all temporary data.
     void Clear();
     void Clear();
 
 
@@ -262,40 +291,9 @@ private:
     /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
     /// \param [in] pUseOldName - if true then use old name of node(and children) - <map>, instead of new name - <texmap>.
     void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
     void ParseNode_TexMap(XmlNode &node, const bool pUseOldName = false);
 
 
-public:
-    /// Default constructor.
-    AMFImporter() AI_NO_EXCEPT;
 
 
-    /// Default destructor.
-    ~AMFImporter() override;
-
-    /// Parse AMF file and fill scene graph. The function has no return value. Result can be found by analyzing the generated graph.
-    /// Also exception can be thrown if trouble will found.
-    /// \param [in] pFile - name of file to be parsed.
-    /// \param [in] pIOHandler - pointer to IO helper object.
-    void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
-    void ParseHelper_Node_Enter(AMFNodeElementBase *child);
-    void ParseHelper_Node_Exit();
-    bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const override;
-    void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) override;
-    const aiImporterDesc *GetInfo() const override;
-    bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
-    bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
-    bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
-    void Throw_CloseNotFound(const std::string &nodeName);
-    void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
-    void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
-    void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
-    void Throw_ID_NotFound(const std::string &pID) const;
-    void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
-    bool XML_SearchNode(const std::string &nodeName);
-    void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);
-    AMFImporter(const AMFImporter &pScene) = delete;
-    AMFImporter &operator=(const AMFImporter &pScene) = delete;
 
 
 private:
 private:
-    static const aiImporterDesc Description;
-
     AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
     AMFNodeElementBase *mNodeElement_Cur; ///< Current element.
     std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
     std::list<AMFNodeElementBase *> mNodeElement_List; ///< All elements of scene graph.
     XmlParser *mXmlParser;
     XmlParser *mXmlParser;

+ 4 - 4
Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Geometry.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -167,11 +167,11 @@ void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
             AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
             AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
             const std::string &currentName = ai_tolower(currentNode.name());
             const std::string &currentName = ai_tolower(currentNode.name());
             if (currentName == "x") {
             if (currentName == "x") {
-                XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
+                XmlParser::getValueAsReal(currentNode, als.Coordinate.x);
             } else if (currentName == "y") {
             } else if (currentName == "y") {
-                XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
+                XmlParser::getValueAsReal(currentNode, als.Coordinate.y);
             } else if (currentName == "z") {
             } else if (currentName == "z") {
-                XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
+                XmlParser::getValueAsReal(currentNode, als.Coordinate.z);
             }
             }
         }
         }
         ParseHelper_Node_Exit();
         ParseHelper_Node_Exit();

+ 7 - 8
Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Material.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -263,26 +263,25 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
             const std::string &name = currentNode.name();
             const std::string &name = currentNode.name();
             if (name == "utex1") {
             if (name == "utex1") {
 				read_flag[0] = true;
 				read_flag[0] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[0].x);
             } else if (name == "utex2") {
             } else if (name == "utex2") {
 				read_flag[1] = true;
 				read_flag[1] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[1].x);
             } else if (name == "utex3") {
             } else if (name == "utex3") {
 				read_flag[2] = true;
 				read_flag[2] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[2].x);
             } else if (name == "vtex1") {
             } else if (name == "vtex1") {
 				read_flag[3] = true;
 				read_flag[3] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[0].y);
             } else if (name == "vtex2") {
             } else if (name == "vtex2") {
 				read_flag[4] = true;
 				read_flag[4] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[1].y);
             } else if (name == "vtex3") {
             } else if (name == "vtex3") {
 				read_flag[5] = true;
 				read_flag[5] = true;
-                XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
+                XmlParser::getValueAsReal(node, als.TextureCoordinate[2].y);
 			}
 			}
 		}
 		}
         ParseHelper_Node_Exit();
         ParseHelper_Node_Exit();
-
 	} else {
 	} else {
 		for (pugi::xml_attribute &attr : node.attributes()) {
 		for (pugi::xml_attribute &attr : node.attributes()) {
             const std::string name = attr.name();
             const std::string name = attr.name();

+ 5 - 22
Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Node.hpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -56,7 +56,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
-/// \class CAMFImporter_NodeElement
 /// Base class for elements of nodes.
 /// Base class for elements of nodes.
 class AMFNodeElementBase {
 class AMFNodeElementBase {
 public:
 public:
@@ -88,9 +87,7 @@ public:
 	std::list<AMFNodeElementBase *> Child; ///< Child elements.
 	std::list<AMFNodeElementBase *> Child; ///< Child elements.
 
 
 public: /// Destructor, virtual..
 public: /// Destructor, virtual..
-	virtual ~AMFNodeElementBase() {
-		// empty
-	}
+	virtual ~AMFNodeElementBase() = default;
 
 
 	/// Disabled copy constructor and co.
 	/// Disabled copy constructor and co.
 	AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete;
 	AMFNodeElementBase(const AMFNodeElementBase &pNodeElement) = delete;
@@ -103,12 +100,11 @@ protected:
 	/// \param [in] pType - element type.
 	/// \param [in] pType - element type.
 	/// \param [in] pParent - parent element.
 	/// \param [in] pParent - parent element.
 	AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) :
 	AMFNodeElementBase(const EType pType, AMFNodeElementBase *pParent) :
-			Type(pType), ID(), Parent(pParent), Child() {
+			Type(pType), Parent(pParent) {
 		// empty
 		// empty
 	}
 	}
 }; // class IAMFImporter_NodeElement
 }; // class IAMFImporter_NodeElement
 
 
-/// \struct CAMFImporter_NodeElement_Constellation
 /// A collection of objects or constellations with specific relative locations.
 /// A collection of objects or constellations with specific relative locations.
 struct AMFConstellation : public AMFNodeElementBase {
 struct AMFConstellation : public AMFNodeElementBase {
 	/// Constructor.
 	/// Constructor.
@@ -118,7 +114,6 @@ struct AMFConstellation : public AMFNodeElementBase {
 
 
 }; // struct CAMFImporter_NodeElement_Constellation
 }; // struct CAMFImporter_NodeElement_Constellation
 
 
-/// \struct CAMFImporter_NodeElement_Instance
 /// Part of constellation.
 /// Part of constellation.
 struct AMFInstance : public AMFNodeElementBase {
 struct AMFInstance : public AMFNodeElementBase {
 
 
@@ -137,7 +132,6 @@ struct AMFInstance : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Instance, pParent) {}
 			AMFNodeElementBase(ENET_Instance, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Metadata
 /// Structure that define metadata node.
 /// Structure that define metadata node.
 struct AMFMetadata : public AMFNodeElementBase {
 struct AMFMetadata : public AMFNodeElementBase {
 
 
@@ -150,7 +144,6 @@ struct AMFMetadata : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Metadata, pParent) {}
 			AMFNodeElementBase(ENET_Metadata, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Root
 /// Structure that define root node.
 /// Structure that define root node.
 struct AMFRoot : public AMFNodeElementBase {
 struct AMFRoot : public AMFNodeElementBase {
 
 
@@ -163,7 +156,6 @@ struct AMFRoot : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Root, pParent) {}
 			AMFNodeElementBase(ENET_Root, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Color
 /// Structure that define object node.
 /// Structure that define object node.
 struct AMFColor : public AMFNodeElementBase {
 struct AMFColor : public AMFNodeElementBase {
 	bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
 	bool Composed; ///< Type of color stored: if true then look for formula in \ref Color_Composed[4], else - in \ref Color.
@@ -174,12 +166,11 @@ struct AMFColor : public AMFNodeElementBase {
 	/// @brief  Constructor.
 	/// @brief  Constructor.
 	/// @param [in] pParent - pointer to parent node.
 	/// @param [in] pParent - pointer to parent node.
 	AMFColor(AMFNodeElementBase *pParent) :
 	AMFColor(AMFNodeElementBase *pParent) :
-			AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color(), Profile() {
+			AMFNodeElementBase(ENET_Color, pParent), Composed(false), Color() {
 		// empty
 		// empty
 	}
 	}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Material
 /// Structure that define material node.
 /// Structure that define material node.
 struct AMFMaterial : public AMFNodeElementBase {
 struct AMFMaterial : public AMFNodeElementBase {
 
 
@@ -189,7 +180,6 @@ struct AMFMaterial : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Material, pParent) {}
 			AMFNodeElementBase(ENET_Material, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Object
 /// Structure that define object node.
 /// Structure that define object node.
 struct AMFObject : public AMFNodeElementBase {
 struct AMFObject : public AMFNodeElementBase {
 
 
@@ -208,7 +198,6 @@ struct AMFMesh : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Mesh, pParent) {}
 			AMFNodeElementBase(ENET_Mesh, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Vertex
 /// Structure that define vertex node.
 /// Structure that define vertex node.
 struct AMFVertex : public AMFNodeElementBase {
 struct AMFVertex : public AMFNodeElementBase {
 	/// Constructor.
 	/// Constructor.
@@ -217,7 +206,6 @@ struct AMFVertex : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Vertex, pParent) {}
 			AMFNodeElementBase(ENET_Vertex, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Edge
 /// Structure that define edge node.
 /// Structure that define edge node.
 struct AMFEdge : public AMFNodeElementBase {
 struct AMFEdge : public AMFNodeElementBase {
 	/// Constructor.
 	/// Constructor.
@@ -226,7 +214,6 @@ struct AMFEdge : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Edge, pParent) {}
 			AMFNodeElementBase(ENET_Edge, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Vertices
 /// Structure that define vertices node.
 /// Structure that define vertices node.
 struct AMFVertices : public AMFNodeElementBase {
 struct AMFVertices : public AMFNodeElementBase {
 	/// Constructor.
 	/// Constructor.
@@ -235,7 +222,6 @@ struct AMFVertices : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Vertices, pParent) {}
 			AMFNodeElementBase(ENET_Vertices, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Volume
 /// Structure that define volume node.
 /// Structure that define volume node.
 struct AMFVolume : public AMFNodeElementBase {
 struct AMFVolume : public AMFNodeElementBase {
 	std::string MaterialID; ///< Which material to use.
 	std::string MaterialID; ///< Which material to use.
@@ -247,7 +233,6 @@ struct AMFVolume : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Volume, pParent) {}
 			AMFNodeElementBase(ENET_Volume, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Coordinates
 /// Structure that define coordinates node.
 /// Structure that define coordinates node.
 struct AMFCoordinates : public AMFNodeElementBase {
 struct AMFCoordinates : public AMFNodeElementBase {
 	aiVector3D Coordinate; ///< Coordinate.
 	aiVector3D Coordinate; ///< Coordinate.
@@ -258,7 +243,6 @@ struct AMFCoordinates : public AMFNodeElementBase {
 			AMFNodeElementBase(ENET_Coordinates, pParent) {}
 			AMFNodeElementBase(ENET_Coordinates, pParent) {}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_TexMap
 /// Structure that define texture coordinates node.
 /// Structure that define texture coordinates node.
 struct AMFTexMap : public AMFNodeElementBase {
 struct AMFTexMap : public AMFNodeElementBase {
 	aiVector3D TextureCoordinate[3]; ///< Texture coordinates.
 	aiVector3D TextureCoordinate[3]; ///< Texture coordinates.
@@ -270,12 +254,11 @@ struct AMFTexMap : public AMFNodeElementBase {
 	/// Constructor.
 	/// Constructor.
 	/// \param [in] pParent - pointer to parent node.
 	/// \param [in] pParent - pointer to parent node.
 	AMFTexMap(AMFNodeElementBase *pParent) :
 	AMFTexMap(AMFNodeElementBase *pParent) :
-			AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{}, TextureID_R(), TextureID_G(), TextureID_B(), TextureID_A() {
+			AMFNodeElementBase(ENET_TexMap, pParent), TextureCoordinate{} {
 		// empty
 		// empty
 	}
 	}
 };
 };
 
 
-/// \struct CAMFImporter_NodeElement_Triangle
 /// Structure that define triangle node.
 /// Structure that define triangle node.
 struct AMFTriangle : public AMFNodeElementBase {
 struct AMFTriangle : public AMFNodeElementBase {
 	size_t V[3]; ///< Triangle vertices.
 	size_t V[3]; ///< Triangle vertices.

+ 6 - 4
Engine/lib/assimp/code/AssetLib/AMF/AMFImporter_Postprocess.cpp

@@ -1,9 +1,9 @@
-/*
+/*
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -224,7 +224,8 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string &
     }
     }
 
 
     // Create format hint.
     // Create format hint.
-    strcpy(converted_texture.FormatHint, "rgba0000"); // copy initial string.
+    constexpr char templateColor[] = "rgba0000";
+    memcpy(converted_texture.FormatHint, templateColor, 8);
     if (!r.empty()) converted_texture.FormatHint[4] = '8';
     if (!r.empty()) converted_texture.FormatHint[4] = '8';
     if (!g.empty()) converted_texture.FormatHint[5] = '8';
     if (!g.empty()) converted_texture.FormatHint[5] = '8';
     if (!b.empty()) converted_texture.FormatHint[6] = '8';
     if (!b.empty()) converted_texture.FormatHint[6] = '8';
@@ -815,6 +816,7 @@ nl_clean_loop:
             for (; next_it != nodeArray.end(); ++next_it) {
             for (; next_it != nodeArray.end(); ++next_it) {
                 if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
                 if ((*next_it)->FindNode((*nl_it)->mName) != nullptr) {
                     // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
                     // if current top node(nl_it) found in another top node then erase it from node_list and restart search loop.
+                    // FIXME: this leaks memory on test models test8.amf and test9.amf
                     nodeArray.erase(nl_it);
                     nodeArray.erase(nl_it);
 
 
                     goto nl_clean_loop;
                     goto nl_clean_loop;
@@ -866,7 +868,7 @@ nl_clean_loop:
             pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
             pScene->mTextures[idx]->mHeight = static_cast<unsigned int>(tex_convd.Height);
             pScene->mTextures[idx]->pcData = (aiTexel *)tex_convd.Data;
             pScene->mTextures[idx]->pcData = (aiTexel *)tex_convd.Data;
             // texture format description.
             // texture format description.
-            strcpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint);
+            strncpy(pScene->mTextures[idx]->achFormatHint, tex_convd.FormatHint, HINTMAXTEXTURELEN);
             idx++;
             idx++;
         } // for(const SPP_Texture& tex_convd: mTexture_Converted)
         } // for(const SPP_Texture& tex_convd: mTexture_Converted)
 
 

+ 22 - 39
Engine/lib/assimp/code/AssetLib/ASE/ASELoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -44,7 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  */
 
 
 #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
 #ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
-
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 #ifndef ASSIMP_BUILD_NO_3DS_IMPORTER
 
 
 // internal headers
 // internal headers
@@ -64,10 +63,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // utilities
 // utilities
 #include <assimp/fast_atof.h>
 #include <assimp/fast_atof.h>
 
 
-using namespace Assimp;
+namespace Assimp {
 using namespace Assimp::ASE;
 using namespace Assimp::ASE;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "ASE Importer",
     "ASE Importer",
     "",
     "",
     "",
     "",
@@ -87,10 +86,6 @@ ASEImporter::ASEImporter() :
     // empty
     // empty
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ASEImporter::~ASEImporter() = default;
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
 bool ASEImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@@ -122,14 +117,14 @@ void ASEImporter::InternReadFile(const std::string &pFile,
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile, "rb"));
 
 
     // Check whether we can read from the file
     // Check whether we can read from the file
-    if (file.get() == nullptr) {
+    if (file == nullptr) {
         throw DeadlyImportError("Failed to open ASE file ", pFile, ".");
         throw DeadlyImportError("Failed to open ASE file ", pFile, ".");
     }
     }
 
 
     // Allocate storage and copy the contents of the file to a memory buffer
     // Allocate storage and copy the contents of the file to a memory buffer
     std::vector<char> mBuffer2;
     std::vector<char> mBuffer2;
     TextFileToBuffer(file.get(), mBuffer2);
     TextFileToBuffer(file.get(), mBuffer2);
-
+    const size_t fileSize = mBuffer2.size();
     this->mBuffer = &mBuffer2[0];
     this->mBuffer = &mBuffer2[0];
     this->pcScene = pScene;
     this->pcScene = pScene;
 
 
@@ -151,7 +146,7 @@ void ASEImporter::InternReadFile(const std::string &pFile,
     };
     };
 
 
     // Construct an ASE parser and parse the file
     // Construct an ASE parser and parse the file
-    ASE::Parser parser(mBuffer, defaultFormat);
+    ASE::Parser parser(mBuffer, fileSize, defaultFormat);
     mParser = &parser;
     mParser = &parser;
     mParser->Parse();
     mParser->Parse();
 
 
@@ -326,21 +321,6 @@ void ASEImporter::BuildAnimations(const std::vector<BaseNode *> &nodes) {
                 aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
                 aiNodeAnim *nd = pcAnim->mChannels[iNum++] = new aiNodeAnim();
                 nd->mNodeName.Set(me->mName + ".Target");
                 nd->mNodeName.Set(me->mName + ".Target");
 
 
-                // If there is no input position channel we will need
-                // to supply the default position from the node's
-                // local transformation matrix.
-                /*TargetAnimationHelper helper;
-                if (me->mAnim.akeyPositions.empty())
-                {
-                    aiMatrix4x4& mat = (*i)->mTransform;
-                    helper.SetFixedMainAnimationChannel(aiVector3D(
-                        mat.a4, mat.b4, mat.c4));
-                }
-                else helper.SetMainAnimationChannel (&me->mAnim.akeyPositions);
-                helper.SetTargetAnimationChannel (&me->mTargetAnim.akeyPositions);
-
-                helper.Process(&me->mTargetAnim.akeyPositions);*/
-
                 // Allocate the key array and fill it
                 // Allocate the key array and fill it
                 nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
                 nd->mNumPositionKeys = (unsigned int)me->mTargetAnim.akeyPositions.size();
                 nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
                 nd->mPositionKeys = new aiVectorKey[nd->mNumPositionKeys];
@@ -466,10 +446,9 @@ void ASEImporter::BuildLights() {
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
-        aiNode *pcParent, const char *szName) {
+void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParent, const std::string &name) {
     aiMatrix4x4 m;
     aiMatrix4x4 m;
-    AddNodes(nodes, pcParent, szName, m);
+    AddNodes(nodes, pcParent, name, m);
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -526,10 +505,9 @@ void ASEImporter::AddMeshes(const ASE::BaseNode *snode, aiNode *node) {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Add child nodes to a given parent node
 // Add child nodes to a given parent node
-void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
-        aiNode *pcParent, const char *szName,
+void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes, aiNode *pcParent, const std::string &name,
         const aiMatrix4x4 &mat) {
         const aiMatrix4x4 &mat) {
-    const size_t len = szName ? ::strlen(szName) : 0;
+    const size_t len = name.size();
     ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
     ai_assert(4 <= AI_MAX_NUMBER_OF_COLOR_SETS);
 
 
     // Receives child nodes for the pcParent node
     // Receives child nodes for the pcParent node
@@ -539,16 +517,18 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
     // which has *us* as parent.
     // which has *us* as parent.
     for (std::vector<BaseNode *>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
     for (std::vector<BaseNode *>::const_iterator it = nodes.begin(), end = nodes.end(); it != end; ++it) {
         const BaseNode *snode = *it;
         const BaseNode *snode = *it;
-        if (szName) {
-            if (len != snode->mParent.length() || ::strcmp(szName, snode->mParent.c_str()))
+        if (!name.empty()) {
+            if (len != snode->mParent.length() || name != snode->mParent.c_str()) {
                 continue;
                 continue;
-        } else if (snode->mParent.length())
+            }
+        } else if (snode->mParent.length()) {
             continue;
             continue;
+        }
 
 
         (*it)->mProcessed = true;
         (*it)->mProcessed = true;
 
 
         // Allocate a new node and add it to the output data structure
         // Allocate a new node and add it to the output data structure
-        apcNodes.push_back(new aiNode());
+        apcNodes.push_back(new aiNode);
         aiNode *node = apcNodes.back();
         aiNode *node = apcNodes.back();
 
 
         node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
         node->mName.Set((snode->mName.length() ? snode->mName.c_str() : "Unnamed_Node"));
@@ -561,7 +541,7 @@ void ASEImporter::AddNodes(const std::vector<BaseNode *> &nodes,
 
 
         // Add sub nodes - prevent stack overflow due to recursive parenting
         // Add sub nodes - prevent stack overflow due to recursive parenting
         if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName) {
         if (node->mName != node->mParent->mName && node->mName != node->mParent->mParent->mName) {
-            AddNodes(nodes, node, node->mName.data, snode->mTransform);
+            AddNodes(nodes, node, node->mName.C_Str(), snode->mTransform);
         }
         }
 
 
         // Further processing depends on the type of the node
         // Further processing depends on the type of the node
@@ -639,7 +619,8 @@ void ASEImporter::BuildNodes(std::vector<BaseNode *> &nodes) {
     }
     }
 
 
     // add all nodes
     // add all nodes
-    AddNodes(nodes, ch, nullptr);
+    static const std::string none = "";
+    AddNodes(nodes, ch, none);
 
 
     // now iterate through al nodes and find those that have not yet
     // now iterate through al nodes and find those that have not yet
     // been added to the nodegraph (= their parent could not be recognized)
     // been added to the nodegraph (= their parent could not be recognized)
@@ -924,7 +905,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh &mesh, std::vector<aiMesh *> &avOutMes
         ASSIMP_LOG_WARN("Material index is out of range");
         ASSIMP_LOG_WARN("Material index is out of range");
     }
     }
 
 
-    // If the material the mesh is assigned to is consisting of submeshes, split it
+    // If the material the mesh is assigned to consists of submeshes, split it
     if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
     if (!mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials.empty()) {
         std::vector<ASE::Material> vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
         std::vector<ASE::Material> vSubMaterials = mParser->m_vMaterials[mesh.iMaterialIndex].avSubMaterials;
 
 
@@ -1282,6 +1263,8 @@ bool ASEImporter::GenerateNormals(ASE::Mesh &mesh) {
     return false;
     return false;
 }
 }
 
 
+}
+
 #endif // ASSIMP_BUILD_NO_3DS_IMPORTER
 #endif // ASSIMP_BUILD_NO_3DS_IMPORTER
 
 
 #endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER
 #endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

+ 5 - 6
Engine/lib/assimp/code/AssetLib/ASE/ASELoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -62,7 +62,7 @@ namespace Assimp {
 class ASEImporter : public BaseImporter {
 class ASEImporter : public BaseImporter {
 public:
 public:
     ASEImporter();
     ASEImporter();
-    ~ASEImporter() override;
+    ~ASEImporter() override = default;
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Returns whether the class can handle the format of the given file.
     /** Returns whether the class can handle the format of the given file.
@@ -153,13 +153,13 @@ private:
      *  \param matrix Current transform
      *  \param matrix Current transform
      */
      */
     void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
     void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
-        aiNode* pcParent,const char* szName);
+        aiNode* pcParent, const std::string &name);
 
 
     void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
     void AddNodes(const std::vector<ASE::BaseNode*>& nodes,
-        aiNode* pcParent,const char* szName,
+        aiNode* pcParent, const std::string &name,
         const aiMatrix4x4& matrix);
         const aiMatrix4x4& matrix);
 
 
-    void AddMeshes(const ASE::BaseNode* snode,aiNode* node);
+    void AddMeshes(const ASE::BaseNode* snode, aiNode* node);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Generate a default material and add it to the parser's list
     /** Generate a default material and add it to the parser's list
@@ -188,5 +188,4 @@ protected:
 
 
 } // end of namespace Assimp
 } // end of namespace Assimp
 
 
-
 #endif // AI_3DSIMPORTER_H_INC
 #endif // AI_3DSIMPORTER_H_INC

Plik diff jest za duży
+ 215 - 190
Engine/lib/assimp/code/AssetLib/ASE/ASEParser.cpp


+ 14 - 14
Engine/lib/assimp/code/AssetLib/ASE/ASEParser.h

@@ -2,8 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -385,20 +384,18 @@ struct Dummy : public BaseNode {
 /** \brief Class to parse ASE files
 /** \brief Class to parse ASE files
  */
  */
 class Parser {
 class Parser {
-private:
-    Parser() AI_NO_EXCEPT {
-        // empty
-    }
-
 public:
 public:
+    /// @brief No default constructor.
+    Parser() = delete;
+
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     //! Construct a parser from a given input file which is
     //! Construct a parser from a given input file which is
     //! guaranteed to be terminated with zero.
     //! guaranteed to be terminated with zero.
-    //! @param szFile Input file
+    //! @param file              The name of the input file.
     //! @param fileFormatDefault Assumed file format version. If the
     //! @param fileFormatDefault Assumed file format version. If the
     //!   file format is specified in the file the new value replaces
     //!   file format is specified in the file the new value replaces
     //!   the default value.
     //!   the default value.
-    Parser(const char *szFile, unsigned int fileFormatDefault);
+    Parser(const char *file, size_t fileLen, unsigned int fileFormatDefault);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     //! Parses the file into the parsers internal representation
     //! Parses the file into the parsers internal representation
@@ -556,13 +553,15 @@ private:
     //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
     //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
     //! \param apOut Output buffer (3 floats)
     //! \param apOut Output buffer (3 floats)
     //! \param rIndexOut Output index
     //! \param rIndexOut Output index
-    void ParseLV4MeshFloatTriple(ai_real *apOut, unsigned int &rIndexOut);
+    void ParseLV4MeshRealTriple(ai_real *apOut, unsigned int &rIndexOut);
+    void ParseLV4MeshFloatTriple(float *apOut, unsigned int &rIndexOut);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     //! Parse a *MESH_VERT block in a file
     //! Parse a *MESH_VERT block in a file
     //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
     //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
     //! \param apOut Output buffer (3 floats)
     //! \param apOut Output buffer (3 floats)
-    void ParseLV4MeshFloatTriple(ai_real *apOut);
+    void ParseLV4MeshRealTriple(ai_real *apOut);
+    void ParseLV4MeshFloatTriple(float *apOut);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     //! Parse a *MESH_TFACE block in a file
     //! Parse a *MESH_TFACE block in a file
@@ -580,7 +579,8 @@ private:
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     //! Parse a single float element
     //! Parse a single float element
     //! \param fOut Output float
     //! \param fOut Output float
-    void ParseLV4MeshFloat(ai_real &fOut);
+    void ParseLV4MeshReal(ai_real &fOut);
+    void ParseLV4MeshFloat(float &fOut);
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     //! Parse a single int element
     //! Parse a single int element
@@ -620,8 +620,8 @@ private:
     bool ParseString(std::string &out, const char *szName);
     bool ParseString(std::string &out, const char *szName);
 
 
 public:
 public:
-    //! Pointer to current data
-    const char *filePtr;
+    const char *mFilePtr; ////< Pointer to current data
+    const char *mEnd;     ///< The end pointer of the file data
 
 
     //! background color to be passed to the viewer
     //! background color to be passed to the viewer
     //! QNAN if none was found
     //! QNAN if none was found

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Assbin/AssbinExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -56,5 +56,5 @@ namespace Assimp {
 void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
 void ASSIMP_API ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/);
 
 
 }
 }
-#endif 
+#endif
 #endif // AI_ASSBINEXPORTER_H_INC
 #endif // AI_ASSBINEXPORTER_H_INC

+ 5 - 9
Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -50,11 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/version.h>
 #include <assimp/version.h>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOStream.hpp>
 
 
-#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-#include <zlib.h>
-#else
-#include "../contrib/zlib/zlib.h"
-#endif
+#include "zlib.h"
 
 
 #include <ctime>
 #include <ctime>
 
 
@@ -291,15 +287,15 @@ public:
     size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override {
     size_t Read(void * /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) override {
         return 0;
         return 0;
     }
     }
-    
+
     aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override {
     aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) override {
         return aiReturn_FAILURE;
         return aiReturn_FAILURE;
     }
     }
-    
+
     size_t Tell() const override {
     size_t Tell() const override {
         return cursor;
         return cursor;
     }
     }
-    
+
     void Flush() override {
     void Flush() override {
         // not implemented
         // not implemented
     }
     }

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assbin/AssbinFileWriter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 7 - 3
Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -65,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "Assimp Binary Importer",
     "Assimp Binary Importer",
     "Gargaj / Conspiracy",
     "Gargaj / Conspiracy",
     "",
     "",
@@ -91,9 +91,13 @@ bool AssbinImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, boo
     }
     }
 
 
     char s[32];
     char s[32];
-    in->Read(s, sizeof(char), 32);
+    const size_t read = in->Read(s, sizeof(char), 32);
 
 
     pIOHandler->Close(in);
     pIOHandler->Close(in);
+    
+    if (read < 19) {
+      return false;
+    }
 
 
     return strncmp(s, "ASSIMP.binary-dump.", 19) == 0;
     return strncmp(s, "ASSIMP.binary-dump.", 19) == 0;
 }
 }

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assbin/AssbinLoader.h

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

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assjson/cencode.c

@@ -7,7 +7,7 @@ For details, see http://sourceforge.net/projects/libb64
 
 
 #include "cencode.h" // changed from <B64/cencode.h>
 #include "cencode.h" // changed from <B64/cencode.h>
 
 
-const int CHARS_PER_LINE = 72;
+static const int CHARS_PER_LINE = 72;
 
 
 #ifdef _MSC_VER
 #ifdef _MSC_VER
 #pragma warning(push)
 #pragma warning(push)

+ 67 - 54
Engine/lib/assimp/code/AssetLib/Assjson/json_exporter.cpp

@@ -10,6 +10,7 @@ Licensed under a 3-clause BSD license. See the LICENSE file for more information
 #ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
 #ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER
 
 
 #include <assimp/scene.h>
 #include <assimp/scene.h>
+#include <assimp/ai_assert.h>
 #include <assimp/Exporter.hpp>
 #include <assimp/Exporter.hpp>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOStream.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
@@ -23,16 +24,15 @@ Licensed under a 3-clause BSD license. See the LICENSE file for more information
 
 
 #define CURRENT_FORMAT_VERSION 100
 #define CURRENT_FORMAT_VERSION 100
 
 
-// grab scoped_ptr from assimp to avoid a dependency on boost.
-//#include <assimp/../../code/BoostWorkaround/boost/scoped_ptr.hpp>
-
 #include "mesh_splitter.h"
 #include "mesh_splitter.h"
 
 
 extern "C" {
 extern "C" {
-#include "cencode.h"
+#   include "cencode.h"
 }
 }
+
 namespace Assimp {
 namespace Assimp {
 
 
+// Forward declarations
 void ExportAssimp2Json(const char *, Assimp::IOSystem *, const aiScene *, const Assimp::ExportProperties *);
 void ExportAssimp2Json(const char *, Assimp::IOSystem *, const aiScene *, const Assimp::ExportProperties *);
 
 
 // small utility class to simplify serializing the aiScene to Json
 // small utility class to simplify serializing the aiScene to Json
@@ -43,7 +43,7 @@ public:
         Flag_WriteSpecialFloats = 0x2,
         Flag_WriteSpecialFloats = 0x2,
         Flag_SkipWhitespaces = 0x4
         Flag_SkipWhitespaces = 0x4
     };
     };
-    
+
     JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
     JSONWriter(Assimp::IOStream &out, unsigned int flags = 0u) :
             out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
             out(out), indent (""), newline("\n"), space(" "), buff (), first(false), flags(flags) {
         // make sure that all formatting happens using the standard, C locale and not the user's current locale
         // make sure that all formatting happens using the standard, C locale and not the user's current locale
@@ -179,7 +179,6 @@ private:
         // escape backslashes and single quotes, both would render the JSON invalid if left as is
         // escape backslashes and single quotes, both would render the JSON invalid if left as is
         t.reserve(s.length);
         t.reserve(s.length);
         for (size_t i = 0; i < s.length; ++i) {
         for (size_t i = 0; i < s.length; ++i) {
-
             if (s.data[i] == '\\' || s.data[i] == '\'' || s.data[i] == '\"') {
             if (s.data[i] == '\\' || s.data[i] == '\'' || s.data[i] == '\"') {
                 t.push_back('\\');
                 t.push_back('\\');
             }
             }
@@ -241,7 +240,7 @@ private:
     unsigned int flags;
     unsigned int flags;
 };
 };
 
 
-void Write(JSONWriter &out, const aiVector3D &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiVector3D &ai, bool is_elem = true) {
     out.StartArray(is_elem);
     out.StartArray(is_elem);
     out.Element(ai.x);
     out.Element(ai.x);
     out.Element(ai.y);
     out.Element(ai.y);
@@ -249,7 +248,7 @@ void Write(JSONWriter &out, const aiVector3D &ai, bool is_elem = true) {
     out.EndArray();
     out.EndArray();
 }
 }
 
 
-void Write(JSONWriter &out, const aiQuaternion &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiQuaternion &ai, bool is_elem = true) {
     out.StartArray(is_elem);
     out.StartArray(is_elem);
     out.Element(ai.w);
     out.Element(ai.w);
     out.Element(ai.x);
     out.Element(ai.x);
@@ -258,7 +257,7 @@ void Write(JSONWriter &out, const aiQuaternion &ai, bool is_elem = true) {
     out.EndArray();
     out.EndArray();
 }
 }
 
 
-void Write(JSONWriter &out, const aiColor3D &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiColor3D &ai, bool is_elem = true) {
     out.StartArray(is_elem);
     out.StartArray(is_elem);
     out.Element(ai.r);
     out.Element(ai.r);
     out.Element(ai.g);
     out.Element(ai.g);
@@ -266,7 +265,7 @@ void Write(JSONWriter &out, const aiColor3D &ai, bool is_elem = true) {
     out.EndArray();
     out.EndArray();
 }
 }
 
 
-void Write(JSONWriter &out, const aiMatrix4x4 &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiMatrix4x4 &ai, bool is_elem = true) {
     out.StartArray(is_elem);
     out.StartArray(is_elem);
     for (unsigned int x = 0; x < 4; ++x) {
     for (unsigned int x = 0; x < 4; ++x) {
         for (unsigned int y = 0; y < 4; ++y) {
         for (unsigned int y = 0; y < 4; ++y) {
@@ -276,7 +275,7 @@ void Write(JSONWriter &out, const aiMatrix4x4 &ai, bool is_elem = true) {
     out.EndArray();
     out.EndArray();
 }
 }
 
 
-void Write(JSONWriter &out, const aiBone &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiBone &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -297,7 +296,7 @@ void Write(JSONWriter &out, const aiBone &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiFace &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiFace &ai, bool is_elem = true) {
     out.StartArray(is_elem);
     out.StartArray(is_elem);
     for (unsigned int i = 0; i < ai.mNumIndices; ++i) {
     for (unsigned int i = 0; i < ai.mNumIndices; ++i) {
         out.Element(ai.mIndices[i]);
         out.Element(ai.mIndices[i]);
@@ -305,7 +304,7 @@ void Write(JSONWriter &out, const aiFace &ai, bool is_elem = true) {
     out.EndArray();
     out.EndArray();
 }
 }
 
 
-void Write(JSONWriter &out, const aiMesh &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiMesh &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -416,7 +415,7 @@ void Write(JSONWriter &out, const aiMesh &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiNode &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiNode &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -446,7 +445,7 @@ void Write(JSONWriter &out, const aiNode &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("properties");
     out.Key("properties");
@@ -466,41 +465,55 @@ void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) {
 
 
         out.Key("value");
         out.Key("value");
         switch (prop->mType) {
         switch (prop->mType) {
-        case aiPTI_Float:
-            if (prop->mDataLength / sizeof(float) > 1) {
-                out.StartArray();
-                for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) {
-                    out.Element(reinterpret_cast<float *>(prop->mData)[ii]);
+            case aiPTI_Float:
+                if (prop->mDataLength / sizeof(float) > 1) {
+                    out.StartArray();
+                    for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(float); ++ii) {
+                        out.Element(reinterpret_cast<float *>(prop->mData)[ii]);
+                    }
+                    out.EndArray();
+                } else {
+                    out.SimpleValue(*reinterpret_cast<float *>(prop->mData));
                 }
                 }
-                out.EndArray();
-            } else {
-                out.SimpleValue(*reinterpret_cast<float *>(prop->mData));
-            }
-            break;
-
-        case aiPTI_Integer:
-            if (prop->mDataLength / sizeof(int) > 1) {
-                out.StartArray();
-                for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) {
-                    out.Element(reinterpret_cast<int *>(prop->mData)[ii]);
+                break;
+            case aiPTI_Double:
+                if (prop->mDataLength / sizeof(double) > 1) {
+                    out.StartArray();
+                    for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(double); ++ii) {
+                        out.Element(reinterpret_cast<double*>(prop->mData)[ii]);
+                    }
+                    out.EndArray();
+                } else {
+                    out.SimpleValue(*reinterpret_cast<double*>(prop->mData));
                 }
                 }
-                out.EndArray();
-            } else {
-                out.SimpleValue(*reinterpret_cast<int *>(prop->mData));
-            }
-            break;
+                break;
+            case aiPTI_Integer:
+                if (prop->mDataLength / sizeof(int) > 1) {
+                    out.StartArray();
+                    for (unsigned int ii = 0; ii < prop->mDataLength / sizeof(int); ++ii) {
+                        out.Element(reinterpret_cast<int *>(prop->mData)[ii]);
+                    }
+                    out.EndArray();
+                } else {
+                    out.SimpleValue(*reinterpret_cast<int *>(prop->mData));
+                }
+                break;
 
 
-        case aiPTI_String: {
-            aiString s;
-            aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
-            out.SimpleValue(s);
-        } break;
-        case aiPTI_Buffer: {
-            // binary data is written as series of hex-encoded octets
-            out.SimpleValue(prop->mData, prop->mDataLength);
-        } break;
-        default:
-            assert(false);
+            case aiPTI_String:
+                {
+                    aiString s;
+                    aiGetMaterialString(&ai, prop->mKey.data, prop->mSemantic, prop->mIndex, &s);
+                    out.SimpleValue(s);
+                }
+                break;
+            case aiPTI_Buffer:
+                {
+                    // binary data is written as series of hex-encoded octets
+                    out.SimpleValue(prop->mData, prop->mDataLength);
+                }
+                break;
+            default:
+                ai_assert(false);
         }
         }
 
 
         out.EndObj();
         out.EndObj();
@@ -510,7 +523,7 @@ void Write(JSONWriter &out, const aiMaterial &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiTexture &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiTexture &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("width");
     out.Key("width");
@@ -546,7 +559,7 @@ void Write(JSONWriter &out, const aiTexture &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiLight &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiLight &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -594,7 +607,7 @@ void Write(JSONWriter &out, const aiLight &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiNodeAnim &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiNodeAnim &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -647,7 +660,7 @@ void Write(JSONWriter &out, const aiNodeAnim &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiAnimation &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiAnimation &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -668,7 +681,7 @@ void Write(JSONWriter &out, const aiAnimation &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiCamera &ai, bool is_elem = true) {
+static void Write(JSONWriter &out, const aiCamera &ai, bool is_elem = true) {
     out.StartObj(is_elem);
     out.StartObj(is_elem);
 
 
     out.Key("name");
     out.Key("name");
@@ -695,7 +708,7 @@ void Write(JSONWriter &out, const aiCamera &ai, bool is_elem = true) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void WriteFormatInfo(JSONWriter &out) {
+static void WriteFormatInfo(JSONWriter &out) {
     out.StartObj();
     out.StartObj();
     out.Key("format");
     out.Key("format");
     out.SimpleValue("\"assimp2json\"");
     out.SimpleValue("\"assimp2json\"");
@@ -704,7 +717,7 @@ void WriteFormatInfo(JSONWriter &out) {
     out.EndObj();
     out.EndObj();
 }
 }
 
 
-void Write(JSONWriter &out, const aiScene &ai) {
+static void Write(JSONWriter &out, const aiScene &ai) {
     out.StartObj();
     out.StartObj();
 
 
     out.Key("__metadata__");
     out.Key("__metadata__");

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assxml/AssxmlExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -652,7 +652,7 @@ void DumpSceneToAssxml(
         const char *pFile, const char *cmd, IOSystem *pIOSystem,
         const char *pFile, const char *cmd, IOSystem *pIOSystem,
         const aiScene *pScene, bool shortened) {
         const aiScene *pScene, bool shortened) {
     std::unique_ptr<IOStream> file(pIOSystem->Open(pFile, "wt"));
     std::unique_ptr<IOStream> file(pIOSystem->Open(pFile, "wt"));
-    if (!file.get()) {
+    if (!file) {
         throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n');
         throw std::runtime_error("Unable to open output file " + std::string(pFile) + '\n');
     }
     }
 
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Assxml/AssxmlFileWriter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 19 - 18
Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -59,10 +59,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include <memory>
 #include <memory>
 
 
-using namespace Assimp;
+namespace Assimp {
 using namespace std;
 using namespace std;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "BlitzBasic 3D Importer",
     "BlitzBasic 3D Importer",
     "",
     "",
     "",
     "",
@@ -79,9 +79,9 @@ static const aiImporterDesc desc = {
 #pragma warning(disable : 4018)
 #pragma warning(disable : 4018)
 #endif
 #endif
 
 
-//#define DEBUG_B3D
+// #define DEBUG_B3D
 
 
-template<typename T>
+template <typename T>
 void DeleteAllBarePointers(std::vector<T> &x) {
 void DeleteAllBarePointers(std::vector<T> &x) {
     for (auto p : x) {
     for (auto p : x) {
         delete p;
         delete p;
@@ -116,7 +116,7 @@ void B3DImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
 
 
     // Check whether we can read from the file
     // Check whether we can read from the file
-    if (file.get() == nullptr) {
+    if (file == nullptr) {
         throw DeadlyImportError("Failed to open B3D file ", pFile, ".");
         throw DeadlyImportError("Failed to open B3D file ", pFile, ".");
     }
     }
 
 
@@ -150,7 +150,7 @@ AI_WONT_RETURN void B3DImporter::Fail(const string &str) {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 int B3DImporter::ReadByte() {
 int B3DImporter::ReadByte() {
-    if (_pos > _buf.size()) {
+    if (_pos >= _buf.size()) {
         Fail("EOF");
         Fail("EOF");
     }
     }
 
 
@@ -253,7 +253,7 @@ size_t B3DImporter::ChunkSize() {
 template <class T>
 template <class T>
 T *B3DImporter::to_array(const vector<T> &v) {
 T *B3DImporter::to_array(const vector<T> &v) {
     if (v.empty()) {
     if (v.empty()) {
-        return 0;
+        return nullptr;
     }
     }
     T *p = new T[v.size()];
     T *p = new T[v.size()];
     for (size_t i = 0; i < v.size(); ++i) {
     for (size_t i = 0; i < v.size(); ++i) {
@@ -266,7 +266,7 @@ T *B3DImporter::to_array(const vector<T> &v) {
 template <class T>
 template <class T>
 T **unique_to_array(vector<std::unique_ptr<T>> &v) {
 T **unique_to_array(vector<std::unique_ptr<T>> &v) {
     if (v.empty()) {
     if (v.empty()) {
-        return 0;
+        return nullptr;
     }
     }
     T **p = new T *[v.size()];
     T **p = new T *[v.size()];
     for (size_t i = 0; i < v.size(); ++i) {
     for (size_t i = 0; i < v.size(); ++i) {
@@ -329,7 +329,7 @@ void B3DImporter::ReadBRUS() {
             mat->AddProperty(&i, 1, AI_MATKEY_TWOSIDED);
             mat->AddProperty(&i, 1, AI_MATKEY_TWOSIDED);
         }
         }
 
 
-        //Textures
+        // Textures
         for (int i = 0; i < n_texs; ++i) {
         for (int i = 0; i < n_texs; ++i) {
             int texid = ReadInt();
             int texid = ReadInt();
             if (texid < -1 || (texid >= 0 && texid >= static_cast<int>(_textures.size()))) {
             if (texid < -1 || (texid >= 0 && texid >= static_cast<int>(_textures.size()))) {
@@ -372,7 +372,7 @@ void B3DImporter::ReadVRTS() {
         }
         }
 
 
         if (_vflags & 2) {
         if (_vflags & 2) {
-            ReadQuat(); //skip v 4bytes...
+            ReadQuat(); // skip v 4bytes...
         }
         }
 
 
         for (int j = 0; j < _tcsets; ++j) {
         for (int j = 0; j < _tcsets; ++j) {
@@ -418,7 +418,6 @@ void B3DImporter::ReadTRIS(int v0) {
             ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
             ASSIMP_LOG_ERROR("Bad triangle index: i0=", i0, ", i1=", i1, ", i2=", i2);
 #endif
 #endif
             Fail("Bad triangle index");
             Fail("Bad triangle index");
-            continue;
         }
         }
         face->mNumIndices = 3;
         face->mNumIndices = 3;
         face->mIndices = new unsigned[3];
         face->mIndices = new unsigned[3];
@@ -617,7 +616,7 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
             } else if (chunk == "BRUS") {
             } else if (chunk == "BRUS") {
                 ReadBRUS();
                 ReadBRUS();
             } else if (chunk == "NODE") {
             } else if (chunk == "NODE") {
-                ReadNODE(0);
+                ReadNODE(nullptr);
             }
             }
             ExitChunk();
             ExitChunk();
         }
         }
@@ -642,7 +641,7 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
             int n_tris = mesh->mNumFaces;
             int n_tris = mesh->mNumFaces;
             int n_verts = mesh->mNumVertices = n_tris * 3;
             int n_verts = mesh->mNumVertices = n_tris * 3;
 
 
-            aiVector3D *mv = mesh->mVertices = new aiVector3D[n_verts], *mn = 0, *mc = 0;
+            aiVector3D *mv = mesh->mVertices = new aiVector3D[n_verts], *mn = nullptr, *mc = nullptr;
             if (_vflags & 1) {
             if (_vflags & 1) {
                 mn = mesh->mNormals = new aiVector3D[n_verts];
                 mn = mesh->mNormals = new aiVector3D[n_verts];
             }
             }
@@ -705,22 +704,22 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
         }
         }
     }
     }
 
 
-    //nodes
+    // nodes
     scene->mRootNode = _nodes[0];
     scene->mRootNode = _nodes[0];
     _nodes.clear(); // node ownership now belongs to scene
     _nodes.clear(); // node ownership now belongs to scene
 
 
-    //material
+    // material
     if (!_materials.size()) {
     if (!_materials.size()) {
         _materials.emplace_back(std::unique_ptr<aiMaterial>(new aiMaterial));
         _materials.emplace_back(std::unique_ptr<aiMaterial>(new aiMaterial));
     }
     }
     scene->mNumMaterials = static_cast<unsigned int>(_materials.size());
     scene->mNumMaterials = static_cast<unsigned int>(_materials.size());
     scene->mMaterials = unique_to_array(_materials);
     scene->mMaterials = unique_to_array(_materials);
 
 
-    //meshes
+    // meshes
     scene->mNumMeshes = static_cast<unsigned int>(_meshes.size());
     scene->mNumMeshes = static_cast<unsigned int>(_meshes.size());
     scene->mMeshes = unique_to_array(_meshes);
     scene->mMeshes = unique_to_array(_meshes);
 
 
-    //animations
+    // animations
     if (_animations.size() == 1 && _nodeAnims.size()) {
     if (_animations.size() == 1 && _nodeAnims.size()) {
 
 
         aiAnimation *anim = _animations.back().get();
         aiAnimation *anim = _animations.back().get();
@@ -739,4 +738,6 @@ void B3DImporter::ReadBB3D(aiScene *scene) {
     flip.Execute(scene);
     flip.Execute(scene);
 }
 }
 
 
+} // namespace Assimp
+
 #endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
 #endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER

+ 1 - 1
Engine/lib/assimp/code/AssetLib/B3D/B3DImporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 29 - 29
Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.cpp

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 
 
@@ -55,10 +55,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <map>
 #include <map>
 #include <memory>
 #include <memory>
 
 
-using namespace Assimp;
+namespace Assimp {
+
 using namespace Assimp::Formatter;
 using namespace Assimp::Formatter;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "BVH Importer (MoCap)",
     "BVH Importer (MoCap)",
     "",
     "",
     "",
     "",
@@ -73,8 +74,8 @@ static const aiImporterDesc desc = {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Aborts the file reading with an exception
 // Aborts the file reading with an exception
-template<typename... T>
-AI_WONT_RETURN void BVHLoader::ThrowException(T&&... args) {
+template <typename... T>
+AI_WONT_RETURN void BVHLoader::ThrowException(T &&...args) {
     throw DeadlyImportError(mFileName, ":", mLine, " - ", args...);
     throw DeadlyImportError(mFileName, ":", mLine, " - ", args...);
 }
 }
 
 
@@ -115,7 +116,7 @@ void BVHLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IOSyst
 
 
     // read file into memory
     // read file into memory
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
     std::unique_ptr<IOStream> file(pIOHandler->Open(pFile));
-    if (file.get() == nullptr) {
+    if (file == nullptr) {
         throw DeadlyImportError("Failed to open file ", pFile, ".");
         throw DeadlyImportError("Failed to open file ", pFile, ".");
     }
     }
 
 
@@ -191,7 +192,7 @@ aiNode *BVHLoader::ReadNode() {
 
 
     // now read the node's contents
     // now read the node's contents
     std::string siteToken;
     std::string siteToken;
-    while (1) {
+    while (true) {
         std::string token = GetNextToken();
         std::string token = GetNextToken();
 
 
         // node offset to parent node
         // node offset to parent node
@@ -247,7 +248,7 @@ aiNode *BVHLoader::ReadEndSite(const std::string &pParentName) {
 
 
     // now read the node's contents. Only possible entry is "OFFSET"
     // now read the node's contents. Only possible entry is "OFFSET"
     std::string token;
     std::string token;
-    while (1) {
+    while (true) {
         token.clear();
         token.clear();
         token = GetNextToken();
         token = GetNextToken();
 
 
@@ -426,7 +427,7 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
         nodeAnim->mNodeName.Set(nodeName);
         nodeAnim->mNodeName.Set(nodeName);
         std::map<BVHLoader::ChannelType, int> channelMap;
         std::map<BVHLoader::ChannelType, int> channelMap;
 
 
-        //Build map of channels
+        // Build map of channels
         for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel) {
         for (unsigned int channel = 0; channel < node.mChannels.size(); ++channel) {
             channelMap[node.mChannels[channel]] = channel;
             channelMap[node.mChannels[channel]] = channel;
         }
         }
@@ -441,7 +442,7 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
 
 
                 // Now compute all translations
                 // Now compute all translations
                 for (BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel + 1)) {
                 for (BVHLoader::ChannelType channel = Channel_PositionX; channel <= Channel_PositionZ; channel = (BVHLoader::ChannelType)(channel + 1)) {
-                    //Find channel in node
+                    // Find channel in node
                     std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
                     std::map<BVHLoader::ChannelType, int>::iterator mapIter = channelMap.find(channel);
 
 
                     if (mapIter == channelMap.end())
                     if (mapIter == channelMap.end())
@@ -485,30 +486,27 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
             for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) {
             for (unsigned int fr = 0; fr < mAnimNumFrames; ++fr) {
                 aiMatrix4x4 temp;
                 aiMatrix4x4 temp;
                 aiMatrix3x3 rotMatrix;
                 aiMatrix3x3 rotMatrix;
-				for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++ channelIdx) {
-					switch (node.mChannels[channelIdx]) {
-                    case Channel_RotationX:
-                        {
+                for (unsigned int channelIdx = 0; channelIdx < node.mChannels.size(); ++channelIdx) {
+                    switch (node.mChannels[channelIdx]) {
+                    case Channel_RotationX: {
                         const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
                         const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
-                        aiMatrix4x4::RotationX( angle, temp); rotMatrix *= aiMatrix3x3( temp);
-                        }
-                        break;
-                    case Channel_RotationY:
-                        {
+                        aiMatrix4x4::RotationX(angle, temp);
+                        rotMatrix *= aiMatrix3x3(temp);
+                    } break;
+                    case Channel_RotationY: {
                         const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
                         const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
-                        aiMatrix4x4::RotationY( angle, temp); rotMatrix *= aiMatrix3x3( temp);
-                        }
-                        break;
-                    case Channel_RotationZ:
-                        {
+                        aiMatrix4x4::RotationY(angle, temp);
+                        rotMatrix *= aiMatrix3x3(temp);
+                    } break;
+                    case Channel_RotationZ: {
                         const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
                         const float angle = node.mChannelValues[fr * node.mChannels.size() + channelIdx] * float(AI_MATH_PI) / 180.0f;
-                        aiMatrix4x4::RotationZ( angle, temp); rotMatrix *= aiMatrix3x3( temp);
-                        }
-                        break;
+                        aiMatrix4x4::RotationZ(angle, temp);
+                        rotMatrix *= aiMatrix3x3(temp);
+                    } break;
                     default:
                     default:
                         break;
                         break;
-					}
-				}
+                    }
+                }
                 rotkey->mTime = double(fr);
                 rotkey->mTime = double(fr);
                 rotkey->mValue = aiQuaternion(rotMatrix);
                 rotkey->mValue = aiQuaternion(rotMatrix);
                 ++rotkey;
                 ++rotkey;
@@ -525,4 +523,6 @@ void BVHLoader::CreateAnimation(aiScene *pScene) {
     }
     }
 }
 }
 
 
+} // namespace Assimp
+
 #endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER
 #endif // !! ASSIMP_BUILD_NO_BVH_IMPORTER

+ 1 - 1
Engine/lib/assimp/code/AssetLib/BVH/BVHLoader.h

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

+ 3 - 4
Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -52,8 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 namespace Assimp {
 namespace Assimp {
 template <>
 template <>
 const char *LogFunctions<BlenderBMeshConverter>::Prefix() {
 const char *LogFunctions<BlenderBMeshConverter>::Prefix() {
-    static auto prefix = "BLEND_BMESH: ";
-    return prefix;
+    return "BLEND_BMESH: ";
 }
 }
 } // namespace Assimp
 } // namespace Assimp
 
 
@@ -140,7 +139,7 @@ void BlenderBMeshConverter::ConvertPolyToFaces(const MPoly &poly) {
                 ThrowException("BMesh uv loop array has incorrect size");
                 ThrowException("BMesh uv loop array has incorrect size");
             }
             }
             const MLoopUV *loopUV = &BMesh->mloopuv[poly.loopstart];
             const MLoopUV *loopUV = &BMesh->mloopuv[poly.loopstart];
-            AddTFace(loopUV[0].uv, loopUV[1].uv, loopUV[2].uv, poly.totloop == 4 ? loopUV[3].uv : 0);
+            AddTFace(loopUV[0].uv, loopUV[1].uv, loopUV[2].uv, poly.totloop == 4 ? loopUV[3].uv : nullptr);
         }
         }
     } else if (poly.totloop > 4) {
     } else if (poly.totloop > 4) {
 #if ASSIMP_BLEND_WITH_GLU_TESSELLATE
 #if ASSIMP_BLEND_WITH_GLU_TESSELLATE

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Blender/BlenderBMesh.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 All rights reserved.
 All rights reserved.
 
 
 Redistribution and use of this software in source and binary forms,
 Redistribution and use of this software in source and binary forms,
@@ -80,7 +80,7 @@ namespace Assimp
         void DestroyTriMesh( );
         void DestroyTriMesh( );
         void ConvertPolyToFaces( const Blender::MPoly& poly );
         void ConvertPolyToFaces( const Blender::MPoly& poly );
         void AddFace( int v1, int v2, int v3, int v4 = 0 );
         void AddFace( int v1, int v2, int v3, int v4 = 0 );
-        void AddTFace( const float* uv1, const float* uv2, const float *uv3, const float* uv4 = 0 );
+        void AddTFace(const float *uv1, const float *uv2, const float *uv3, const float *uv4 = nullptr);
 
 
         const Blender::Mesh* BMesh;
         const Blender::Mesh* BMesh;
         Blender::Mesh* triMesh;
         Blender::Mesh* triMesh;

+ 2 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderCustomData.cpp

@@ -96,7 +96,8 @@ struct CustomDataTypeDescription {
         *           other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
         *           other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
         *           use a special readfunction for that cases
         *           use a special readfunction for that cases
         */
         */
-std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
+static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
+        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
         DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
         DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
         DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
         DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
         DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
         DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -72,7 +72,7 @@ struct Type {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void DNAParser::Parse() {
 void DNAParser::Parse() {
-    StreamReaderAny &stream = *db.reader.get();
+    StreamReaderAny &stream = *db.reader;
     DNA &dna = db.dna;
     DNA &dna = db.dna;
 
 
     if (!match4(stream, "SDNA")) {
     if (!match4(stream, "SDNA")) {

+ 13 - 4
Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -106,9 +106,7 @@ struct ElemBase {
         // empty
         // empty
     }
     }
 
 
-    virtual ~ElemBase() {
-        // empty
-    }
+    virtual ~ElemBase() = default;
 
 
     /** Type name of the element. The type
     /** Type name of the element. The type
      * string points is the `c_str` of the `name` attribute of the
      * string points is the `c_str` of the `name` attribute of the
@@ -431,6 +429,17 @@ inline bool Structure ::ResolvePointer<std::shared_ptr, ElemBase>(std::shared_pt
         const Field &f,
         const Field &f,
         bool) const;
         bool) const;
 
 
+template <> bool Structure :: ResolvePointer<std::shared_ptr,ElemBase>(
+    std::shared_ptr<ElemBase>& out, const Pointer & ptrval,
+    const FileDatabase& db, const Field&, bool) const;
+template <> inline void Structure :: Convert<int>    (int& dest,const FileDatabase& db) const;
+template<> inline void Structure :: Convert<short>  (short& dest,const FileDatabase& db) const;
+template <> inline void Structure :: Convert<char>   (char& dest,const FileDatabase& db) const;
+template <> inline void Structure::Convert<unsigned char>(unsigned char& dest, const FileDatabase& db) const;
+template <> inline void Structure :: Convert<float>  (float& dest,const FileDatabase& db) const;
+template <> inline void Structure :: Convert<double> (double& dest,const FileDatabase& db) const;
+template <> inline void Structure :: Convert<Pointer> (Pointer& dest,const FileDatabase& db) const;
+
 // -------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------
 /** Represents the full data structure information for a single BLEND file.
 /** Represents the full data structure information for a single BLEND file.
  *  This data is extracted from the DNA1 chunk in the file.
  *  This data is extracted from the DNA1 chunk in the file.

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderDNA.inl

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderIntermediate.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 75 - 74
Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.cpp

@@ -1,10 +1,8 @@
-
 /*
 /*
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -63,23 +61,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
 
 
 #include <cctype>
 #include <cctype>
+#include <memory>
+#include <utility>
 
 
 // zlib is needed for compressed blend files
 // zlib is needed for compressed blend files
 #ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
 #ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
 #include "Common/Compression.h"
 #include "Common/Compression.h"
-/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
-#    include <zlib.h>
-#  else
-#    include "../contrib/zlib/zlib.h"
-#  endif*/
 #endif
 #endif
 
 
 namespace Assimp {
 namespace Assimp {
 
 
 template <>
 template <>
 const char *LogFunctions<BlenderImporter>::Prefix() {
 const char *LogFunctions<BlenderImporter>::Prefix() {
-    static auto prefix = "BLEND: ";
-    return prefix;
+    return "BLEND: ";
 }
 }
 
 
 } // namespace Assimp
 } // namespace Assimp
@@ -88,7 +82,7 @@ using namespace Assimp;
 using namespace Assimp::Blender;
 using namespace Assimp::Blender;
 using namespace Assimp::Formatter;
 using namespace Assimp::Formatter;
 
 
-static const aiImporterDesc blenderDesc = {
+static constexpr aiImporterDesc blenderDesc = {
     "Blender 3D Importer (http://www.blender3d.org)",
     "Blender 3D Importer (http://www.blender3d.org)",
     "",
     "",
     "",
     "",
@@ -114,15 +108,12 @@ BlenderImporter::~BlenderImporter() {
     delete modifier_cache;
     delete modifier_cache;
 }
 }
 
 
-static const char * const Tokens[] = { "BLENDER" };
+static const char Token[] = "BLENDER";
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
 bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
-    // note: this won't catch compressed files
-    static const char *tokens[] = { "<BLENDER", "blender" };
-
-    return SearchFileHeaderForToken(pIOHandler, pFile, tokens, AI_COUNT_OF(tokens));
+    return ParseMagicToken(pFile, pIOHandler).error.empty();
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -141,67 +132,25 @@ void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
 // Imports the given file into the given scene structure.
 // Imports the given file into the given scene structure.
 void BlenderImporter::InternReadFile(const std::string &pFile,
 void BlenderImporter::InternReadFile(const std::string &pFile,
         aiScene *pScene, IOSystem *pIOHandler) {
         aiScene *pScene, IOSystem *pIOHandler) {
-#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
-    std::vector<char> uncompressed;
-#endif
-
     FileDatabase file;
     FileDatabase file;
-    std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
-    if (!stream) {
-        ThrowException("Could not open file for reading");
-    }
-
-    char magic[8] = { 0 };
-    stream->Read(magic, 7, 1);
-    if (strcmp(magic, Tokens[0])) {
-        // Check for presence of the gzip header. If yes, assume it is a
-        // compressed blend file and try uncompressing it, else fail. This is to
-        // avoid uncompressing random files which our loader might end up with.
-#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
-        ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
-#else
-        if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
-            ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
-        }
-
-        LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
-        if (magic[2] != 8) {
-            ThrowException("Unsupported GZIP compression method");
-        }
-
-        // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
-        stream->Seek(0L, aiOrigin_SET);
-        std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
-
-        size_t total = 0;
-        Compression compression;
-        if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) {
-            total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), uncompressed);
-            compression.close();
-        }
-
-        // replace the input stream with a memory stream
-        stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
-
-        // .. and retry
-        stream->Read(magic, 7, 1);
-        if (strcmp(magic, "BLENDER")) {
-            ThrowException("Found no BLENDER magic word in decompressed GZIP file");
-        }
-#endif
+    StreamOrError streamOrError = ParseMagicToken(pFile, pIOHandler);
+    if (!streamOrError.error.empty()) {
+        ThrowException(streamOrError.error);
     }
     }
+    std::shared_ptr<IOStream> stream = std::move(streamOrError.stream);
 
 
-    file.i64bit = (stream->Read(magic, 1, 1), magic[0] == '-');
-    file.little = (stream->Read(magic, 1, 1), magic[0] == 'v');
+    char version[4] = { 0 };
+    file.i64bit = (stream->Read(version, 1, 1), version[0] == '-');
+    file.little = (stream->Read(version, 1, 1), version[0] == 'v');
 
 
-    stream->Read(magic, 3, 1);
-    magic[3] = '\0';
+    stream->Read(version, 3, 1);
+    version[3] = '\0';
 
 
-    LogInfo("Blender version is ", magic[0], ".", magic + 1,
+    LogInfo("Blender version is ", version[0], ".", version + 1,
             " (64bit: ", file.i64bit ? "true" : "false",
             " (64bit: ", file.i64bit ? "true" : "false",
             ", little endian: ", file.little ? "true" : "false", ")");
             ", little endian: ", file.little ? "true" : "false", ")");
 
 
-    ParseBlendFile(file, stream);
+    ParseBlendFile(file, std::move(stream));
 
 
     Scene scene;
     Scene scene;
     ExtractScene(scene, file);
     ExtractScene(scene, file);
@@ -218,7 +167,7 @@ void BlenderImporter::ParseBlendFile(FileDatabase &out, std::shared_ptr<IOStream
 
 
     out.entries.reserve(128);
     out.entries.reserve(128);
     { // even small BLEND files tend to consist of many file blocks
     { // even small BLEND files tend to consist of many file blocks
-        SectionParser parser(*out.reader.get(), out.i64bit);
+        SectionParser parser(*out.reader, out.i64bit);
 
 
         // first parse the file in search for the DNA and insert all other sections into the database
         // first parse the file in search for the DNA and insert all other sections into the database
         while ((parser.Next(), 1)) {
         while ((parser.Next(), 1)) {
@@ -408,7 +357,7 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
     // check if the file contents are bundled with the BLEND file
     // check if the file contents are bundled with the BLEND file
     if (img->packedfile) {
     if (img->packedfile) {
         name.data[0] = '*';
         name.data[0] = '*';
-        name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size()));
+        name.length = 1 + ASSIMP_itoa10(name.data + 1, static_cast<unsigned int>(AI_MAXLEN - 1), static_cast<int32_t>(conv_data.textures->size()));
 
 
         conv_data.textures->push_back(new aiTexture());
         conv_data.textures->push_back(new aiTexture());
         aiTexture *curTex = conv_data.textures->back();
         aiTexture *curTex = conv_data.textures->back();
@@ -482,7 +431,7 @@ void BlenderImporter::AddSentinelTexture(aiMaterial *out, const Material *mat, c
     (void)conv_data;
     (void)conv_data;
 
 
     aiString name;
     aiString name;
-    name.length = ai_snprintf(name.data, MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++,
+    name.length = ai_snprintf(name.data, AI_MAXLEN, "Procedural,num=%i,type=%s", conv_data.sentinel_cnt++,
             GetTextureTypeDisplayString(tex->tex->type));
             GetTextureTypeDisplayString(tex->tex->type));
     out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(
     out->AddProperty(&name, AI_MATKEY_TEXTURE_DIFFUSE(
                                     conv_data.next_texture[aiTextureType_DIFFUSE]++));
                                     conv_data.next_texture[aiTextureType_DIFFUSE]++));
@@ -544,8 +493,9 @@ void BlenderImporter::BuildDefaultMaterial(Blender::ConversionData &conv_data) {
             if (index == static_cast<unsigned int>(-1)) {
             if (index == static_cast<unsigned int>(-1)) {
                 // Setup a default material.
                 // Setup a default material.
                 std::shared_ptr<Material> p(new Material());
                 std::shared_ptr<Material> p(new Material());
-                ai_assert(::strlen(AI_DEFAULT_MATERIAL_NAME) < sizeof(p->id.name) - 2);
-                strcpy(p->id.name + 2, AI_DEFAULT_MATERIAL_NAME);
+                const size_t len = ::strlen(AI_DEFAULT_MATERIAL_NAME);
+                ai_assert(len < sizeof(p->id.name) - 2);
+                memcpy(p->id.name + 2, AI_DEFAULT_MATERIAL_NAME, len);
 
 
                 // Note: MSVC11 does not zero-initialize Material here, although it should.
                 // Note: MSVC11 does not zero-initialize Material here, although it should.
                 // Thus all relevant fields should be explicitly initialized. We cannot add
                 // Thus all relevant fields should be explicitly initialized. We cannot add
@@ -1337,4 +1287,55 @@ aiNode *BlenderImporter::ConvertNode(const Scene &in, const Object *obj, Convers
     return node.release();
     return node.release();
 }
 }
 
 
+BlenderImporter::StreamOrError BlenderImporter::ParseMagicToken(const std::string &pFile, IOSystem *pIOHandler) const {
+    std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
+    if (stream == nullptr) {
+        return {{}, {}, "Could not open file for reading"};
+    }
+
+    char magic[8] = { 0 };
+    stream->Read(magic, 7, 1);
+    if (strcmp(magic, Token) == 0) {
+        return {stream, {}, {}};
+    }
+
+    // Check for presence of the gzip header. If yes, assume it is a
+    // compressed blend file and try uncompressing it, else fail. This is to
+    // avoid uncompressing random files which our loader might end up with.
+#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
+    return {{}, {}, "BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?"};
+#else
+    if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
+        return {{}, {}, "BLENDER magic bytes are missing, couldn't find GZIP header either"};
+    }
+
+    LogDebug("Found no BLENDER magic word but a GZIP header, might be a compressed file");
+    if (magic[2] != 8) {
+        return {{}, {}, "Unsupported GZIP compression method"};
+    }
+
+    // http://www.gzip.org/zlib/rfc-gzip.html#header-trailer
+    stream->Seek(0L, aiOrigin_SET);
+    std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
+
+    size_t total = 0;
+    Compression compression;
+    auto uncompressed = std::make_shared<std::vector<char>>();
+    if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) {
+        total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), *uncompressed);
+        compression.close();
+    }
+
+    // replace the input stream with a memory stream
+    stream = std::make_shared<MemoryIOStream>(reinterpret_cast<uint8_t *>(uncompressed->data()), total);
+
+    // .. and retry
+    stream->Read(magic, 7, 1);
+    if (strcmp(magic, Token) == 0) {
+        return {stream, uncompressed, {}};
+    }
+    return {{}, {}, "Found no BLENDER magic word in decompressed GZIP file"};
+#endif
+}
+
 #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER
 #endif // ASSIMP_BUILD_NO_BLEND_IMPORTER

+ 14 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -180,6 +180,19 @@ private:
             const Blender::MTex *tex,
             const Blender::MTex *tex,
             Blender::ConversionData &conv_data);
             Blender::ConversionData &conv_data);
 
 
+    // TODO: Move to a std::variant, once c++17 is supported.
+    struct StreamOrError {
+        std::shared_ptr<IOStream> stream;
+        std::shared_ptr<std::vector<char>> input;
+        std::string error;
+    };
+
+    // Returns either a stream (and optional input data for the stream) or
+    // an error if it can't parse the magic token.
+    StreamOrError ParseMagicToken(
+            const std::string &pFile,
+            IOSystem *pIOHandler) const;
+
 private: // static stuff, mostly logging and error reporting.
 private: // static stuff, mostly logging and error reporting.
     // --------------------
     // --------------------
     static void CheckActualType(const Blender::ElemBase *dt,
     static void CheckActualType(const Blender::ElemBase *dt,

+ 6 - 1
Engine/lib/assimp/code/AssetLib/Blender/BlenderModifier.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -283,6 +283,11 @@ void BlenderModifier_Subdivision ::DoIt(aiNode &out, ConversionData &conv_data,
     if (conv_data.meshes->empty()) {
     if (conv_data.meshes->empty()) {
         return;
         return;
     }
     }
+    const size_t meshIndex = conv_data.meshes->size() - out.mNumMeshes;
+    if (meshIndex >= conv_data.meshes->size()) {
+        ASSIMP_LOG_ERROR("Invalid index detected.");
+        return;
+    }
     aiMesh **const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
     aiMesh **const meshes = &conv_data.meshes[conv_data.meshes->size() - out.mNumMeshes];
     std::unique_ptr<aiMesh *[]> tempmeshes(new aiMesh *[out.mNumMeshes]());
     std::unique_ptr<aiMesh *[]> tempmeshes(new aiMesh *[out.mNumMeshes]());
 
 

+ 2 - 4
Engine/lib/assimp/code/AssetLib/Blender/BlenderModifier.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -62,9 +62,7 @@ public:
     /**
     /**
      *  The class destructor, virtual.
      *  The class destructor, virtual.
      */
      */
-    virtual ~BlenderModifier() {
-        // empty
-    }
+    virtual ~BlenderModifier() = default;
 
 
     // --------------------
     // --------------------
     /**
     /**

+ 2 - 6
Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.cpp

@@ -102,10 +102,6 @@ void Structure::Convert<CollectionObject>(
 
 
     ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
     ReadFieldPtr<ErrorPolicy_Fail>(dest.next, "*next", db);
     {
     {
-        //std::shared_ptr<CollectionObject> prev;
-        //ReadFieldPtr<ErrorPolicy_Fail>(prev, "*prev", db);
-        //dest.prev = prev.get();
-
         std::shared_ptr<Object> ob;
         std::shared_ptr<Object> ob;
         ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
         ReadFieldPtr<ErrorPolicy_Igno>(ob, "*ob", db);
         dest.ob = ob.get();
         dest.ob = ob.get();
@@ -301,7 +297,7 @@ void Structure ::Convert<Base>(
         const FileDatabase &db) const {
         const FileDatabase &db) const {
     // note: as per https://github.com/assimp/assimp/issues/128,
     // note: as per https://github.com/assimp/assimp/issues/128,
     // reading the Object linked list recursively is prone to stack overflow.
     // reading the Object linked list recursively is prone to stack overflow.
-    // This structure converter is therefore an hand-written exception that
+    // This structure converter is therefore a hand-written exception that
     // does it iteratively.
     // does it iteratively.
 
 
     const int initial_pos = db.reader->GetCurrentPos();
     const int initial_pos = db.reader->GetCurrentPos();
@@ -569,7 +565,7 @@ void Structure ::Convert<MVert>(
         const FileDatabase &db) const {
         const FileDatabase &db) const {
 
 
     ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
     ReadFieldArray<ErrorPolicy_Fail>(dest.co, "co", db);
-    ReadFieldArray<ErrorPolicy_Fail>(dest.no, "no", db);
+    ReadFieldArray<ErrorPolicy_Warn>(dest.no, "no", db);
     ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
     ReadField<ErrorPolicy_Igno>(dest.flag, "flag", db);
     //ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
     //ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
     ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);
     ReadField<ErrorPolicy_Igno>(dest.bweight, "bweight", db);

+ 8 - 19
Engine/lib/assimp/code/AssetLib/Blender/BlenderScene.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -182,7 +182,7 @@ struct MVert : ElemBase {
     int bweight;
     int bweight;
 
 
     MVert() :
     MVert() :
-            ElemBase(), flag(0), mat_nr(0), bweight(0) {}
+            flag(0), mat_nr(0), bweight(0) {}
 };
 };
 
 
 // -------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------
@@ -417,7 +417,6 @@ struct CustomDataLayer : ElemBase {
     std::shared_ptr<ElemBase> data; // must be converted to real type according type member
     std::shared_ptr<ElemBase> data; // must be converted to real type according type member
 
 
     CustomDataLayer() :
     CustomDataLayer() :
-            ElemBase(),
             type(0),
             type(0),
             offset(0),
             offset(0),
             flag(0),
             flag(0),
@@ -729,7 +728,7 @@ struct Object : ElemBase {
     ListBase modifiers;
     ListBase modifiers;
 
 
     Object() :
     Object() :
-            ElemBase(), type(Type_EMPTY), parent(nullptr), track(), proxy(), proxy_from(), data() {
+            type(Type_EMPTY), parent(nullptr) {
         // empty
         // empty
     }
     }
 };
 };
@@ -741,8 +740,7 @@ struct Base : ElemBase {
     std::shared_ptr<Object> object WARN;
     std::shared_ptr<Object> object WARN;
 
 
     Base() :
     Base() :
-            ElemBase(), prev(nullptr), next(), object() {
-        // empty
+            prev(nullptr) {
         // empty
         // empty
     }
     }
 };
 };
@@ -758,10 +756,7 @@ struct Scene : ElemBase {
 
 
     ListBase base;
     ListBase base;
 
 
-    Scene() :
-            ElemBase(), camera(), world(), basact(), master_collection() {
-        // empty
-    }
+    Scene() = default;
 };
 };
 
 
 // -------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------
@@ -791,10 +786,7 @@ struct Image : ElemBase {
 
 
     short gen_x, gen_y, gen_type;
     short gen_x, gen_y, gen_type;
 
 
-    Image() :
-            ElemBase() {
-        // empty
-    }
+    Image() = default;
 };
 };
 
 
 // -------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------
@@ -884,7 +876,7 @@ struct Tex : ElemBase {
     //char use_nodes;
     //char use_nodes;
 
 
     Tex() :
     Tex() :
-            ElemBase(), imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS), ima() {
+            imaflag(ImageFlags_INTERPOL), type(Type_CLOUDS) {
         // empty
         // empty
     }
     }
 };
 };
@@ -976,10 +968,7 @@ struct MTex : ElemBase {
     //float shadowfac;
     //float shadowfac;
     //float zenupfac, zendownfac, blendfac;
     //float zenupfac, zendownfac, blendfac;
 
 
-    MTex() :
-            ElemBase() {
-        // empty
-    }
+    MTex() = default;
 };
 };
 
 
 } // namespace Blender
 } // namespace Blender

+ 6 - 13
Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.cpp

@@ -2,8 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -40,10 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 */
 */
 
 
-/** @file  BlenderTessellator.cpp
- *  @brief A simple tessellation wrapper
- */
-
+/// @file  BlenderTessellator.cpp
+/// @brief A simple tessellation wrapper
 
 
 #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 #ifndef ASSIMP_BUILD_NO_BLEND_IMPORTER
 
 
@@ -62,8 +59,7 @@ namspace Assimp
 {
 {
     template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
     template< > const char* LogFunctions< BlenderTessellatorGL >::Prefix()
     {
     {
-        static auto prefix = "BLEND_TESS_GL: ";
-        return prefix;
+        return "BLEND_TESS_GL: ";
     }
     }
 }
 }
 
 
@@ -81,9 +77,7 @@ BlenderTessellatorGL::BlenderTessellatorGL( BlenderBMeshConverter& converter ):
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-BlenderTessellatorGL::~BlenderTessellatorGL( )
-{
-}
+BlenderTessellatorGL::~BlenderTessellatorGL() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
 void BlenderTessellatorGL::Tessellate( const MLoop* polyLoop, int vertexCount, const std::vector< MVert >& vertices )
@@ -259,8 +253,7 @@ namespace Assimp
 {
 {
     template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
     template< > const char* LogFunctions< BlenderTessellatorP2T >::Prefix()
     {
     {
-        static auto prefix = "BLEND_TESS_P2T: ";
-        return prefix;
+        return "BLEND_TESS_P2T: ";
     }
     }
 }
 }
 
 

+ 2 - 7
Engine/lib/assimp/code/AssetLib/Blender/BlenderTessellator.h

@@ -2,8 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
-
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -144,11 +143,7 @@ namespace Assimp
 
 
 #if ASSIMP_BLEND_WITH_POLY_2_TRI
 #if ASSIMP_BLEND_WITH_POLY_2_TRI
 
 
-#ifdef ASSIMP_USE_HUNTER
-#  include <poly2tri/poly2tri.h>
-#else
-#  include "../contrib/poly2tri/poly2tri/poly2tri.h"
-#endif
+#include "contrib/poly2tri/poly2tri/poly2tri.h"
 
 
 namespace Assimp
 namespace Assimp
 {
 {

+ 11 - 21
Engine/lib/assimp/code/AssetLib/C4D/C4DImporter.cpp

@@ -46,10 +46,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // no #ifdefing here, Cinema4D support is carried out in a branch of assimp
 // no #ifdefing here, Cinema4D support is carried out in a branch of assimp
 // where it is turned on in the CMake settings.
 // where it is turned on in the CMake settings.
 
 
-#ifndef _MSC_VER
-#   error C4D support is currently MSVC only
-#endif
-
 #include "C4DImporter.h"
 #include "C4DImporter.h"
 #include <memory>
 #include <memory>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
@@ -86,8 +82,7 @@ void GetWriterInfo(int &id, String &appname) {
 
 
 namespace Assimp {
 namespace Assimp {
     template<> const char* LogFunctions<C4DImporter>::Prefix() {
     template<> const char* LogFunctions<C4DImporter>::Prefix() {
-        static auto prefix = "C4D: ";
-        return prefix;
+        return "C4D: ";
     }
     }
 }
 }
 
 
@@ -106,25 +101,20 @@ static const aiImporterDesc desc = {
 
 
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-C4DImporter::C4DImporter()
-: BaseImporter() {
-    // empty
-}
+C4DImporter::C4DImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-C4DImporter::~C4DImporter() {
-    // empty
-}
+C4DImporter::~C4DImporter() = default;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
+bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
     const std::string& extension = GetExtension(pFile);
     const std::string& extension = GetExtension(pFile);
     if (extension == "c4d") {
     if (extension == "c4d") {
         return true;
         return true;
     } else if ((!extension.length() || checkSig) && pIOHandler)   {
     } else if ((!extension.length() || checkSig) && pIOHandler)   {
         // TODO
         // TODO
     }
     }
-    
+
     return false;
     return false;
 }
 }
 
 
@@ -311,7 +301,7 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
 
 
     // based on Cineware sample code
     // based on Cineware sample code
     while (object) {
     while (object) {
-        const LONG type = object->GetType();
+        const Int32 type = object->GetType();
         const Matrix& ml = object->GetMl();
         const Matrix& ml = object->GetMl();
 
 
         aiNode* const nd = new aiNode();
         aiNode* const nd = new aiNode();
@@ -374,8 +364,8 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
     PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
     PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
     ai_assert(polyObject != nullptr);
     ai_assert(polyObject != nullptr);
 
 
-    const LONG pointCount = polyObject->GetPointCount();
-    const LONG polyCount = polyObject->GetPolygonCount();
+    const Int32 pointCount = polyObject->GetPointCount();
+    const Int32 polyCount = polyObject->GetPolygonCount();
     if(!polyObject || !pointCount) {
     if(!polyObject || !pointCount) {
         LogWarn("ignoring mesh with zero vertices or faces");
         LogWarn("ignoring mesh with zero vertices or faces");
         return nullptr;
         return nullptr;
@@ -397,7 +387,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
     unsigned int vcount = 0;
     unsigned int vcount = 0;
 
 
     // first count vertices
     // first count vertices
-    for (LONG i = 0; i < polyCount; i++)
+    for (Int32 i = 0; i < polyCount; i++)
     {
     {
         vcount += 3;
         vcount += 3;
 
 
@@ -440,7 +430,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
     }
     }
 
 
     // copy vertices and extra channels over and populate faces
     // copy vertices and extra channels over and populate faces
-    for (LONG i = 0; i < polyCount; ++i, ++face) {
+    for (Int32 i = 0; i < polyCount; ++i, ++face) {
         ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
         ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
         const Vector& pointA = points[polys[i].a];
         const Vector& pointA = points[polys[i].a];
         verts->x = pointA.x;
         verts->x = pointA.x;
@@ -517,7 +507,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
         if (tangents_src) {
         if (tangents_src) {
 
 
             for(unsigned int k = 0; k < face->mNumIndices; ++k) {
             for(unsigned int k = 0; k < face->mNumIndices; ++k) {
-                LONG l;
+                Int32 l;
                 switch(k) {
                 switch(k) {
                 case 0:
                 case 0:
                     l = polys[i].a;
                     l = polys[i].a;

+ 2 - 0
Engine/lib/assimp/code/AssetLib/C4D/C4DImporter.h

@@ -78,6 +78,8 @@ namespace Assimp  {
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
 class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
 class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
 public:
 public:
+    C4DImporter();
+    ~C4DImporter() override;
     bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override;
     bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override;
 
 
 protected:
 protected:

+ 39 - 39
Engine/lib/assimp/code/AssetLib/COB/COBLoader.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -61,11 +61,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include <memory>
 #include <memory>
 
 
-using namespace Assimp;
+namespace Assimp {
 using namespace Assimp::COB;
 using namespace Assimp::COB;
 using namespace Assimp::Formatter;
 using namespace Assimp::Formatter;
 
 
-static const float units[] = {
+static constexpr float units[] = {
     1000.f,
     1000.f,
     100.f,
     100.f,
     1.f,
     1.f,
@@ -76,7 +76,7 @@ static const float units[] = {
     1.f / 1609.344f
     1.f / 1609.344f
 };
 };
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "TrueSpace Object Importer",
     "TrueSpace Object Importer",
     "",
     "",
     "",
     "",
@@ -89,14 +89,6 @@ static const aiImporterDesc desc = {
     "cob scn"
     "cob scn"
 };
 };
 
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-COBImporter::COBImporter() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-COBImporter::~COBImporter() = default;
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
 bool COBImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@@ -158,7 +150,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     // sort faces by material indices
     // sort faces by material indices
     for (std::shared_ptr<Node> &n : scene.nodes) {
     for (std::shared_ptr<Node> &n : scene.nodes) {
         if (n->type == Node::TYPE_MESH) {
         if (n->type == Node::TYPE_MESH) {
-            Mesh &mesh = (Mesh &)(*n.get());
+            Mesh &mesh = (Mesh &)(*n);
             for (Face &f : mesh.faces) {
             for (Face &f : mesh.faces) {
                 mesh.temp_map[f.material].push_back(&f);
                 mesh.temp_map[f.material].push_back(&f);
             }
             }
@@ -168,7 +160,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
     // count meshes
     // count meshes
     for (std::shared_ptr<Node> &n : scene.nodes) {
     for (std::shared_ptr<Node> &n : scene.nodes) {
         if (n->type == Node::TYPE_MESH) {
         if (n->type == Node::TYPE_MESH) {
-            Mesh &mesh = (Mesh &)(*n.get());
+            Mesh &mesh = (Mesh &)(*n);
             if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
             if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
                 pScene->mNumMeshes += static_cast<unsigned int>(mesh.temp_map.size());
                 pScene->mNumMeshes += static_cast<unsigned int>(mesh.temp_map.size());
             }
             }
@@ -211,7 +203,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
         }
         }
     }
     }
 
 
-    pScene->mRootNode = BuildNodes(*root.get(), scene, pScene);
+    pScene->mRootNode = BuildNodes(*root, scene, pScene);
     //flip normals after import
     //flip normals after import
     FlipWindingOrderProcess flip;
     FlipWindingOrderProcess flip;
     flip.Execute(pScene);
     flip.Execute(pScene);
@@ -380,9 +372,11 @@ aiNode *COBImporter::BuildNodes(const Node &root, const Scene &scin, aiScene *fi
     }
     }
 
 
     // add children recursively
     // add children recursively
-    nd->mChildren = new aiNode *[root.temp_children.size()]();
-    for (const Node *n : root.temp_children) {
-        (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd;
+    if (!root.temp_children.empty()) {
+        nd->mChildren = new aiNode *[root.temp_children.size()]();
+        for (const Node *n : root.temp_children) {
+            (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n, scin, fill))->mParent = nd;
+        }
     }
     }
 
 
     return nd;
     return nd;
@@ -481,8 +475,9 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
         } else if (splitter.match_start("Transform")) {
         } else if (splitter.match_start("Transform")) {
             for (unsigned int y = 0; y < 4 && ++splitter; ++y) {
             for (unsigned int y = 0; y < 4 && ++splitter; ++y) {
                 const char *s = splitter->c_str();
                 const char *s = splitter->c_str();
+                const char *end = s + splitter->size();
                 for (unsigned int x = 0; x < 4; ++x) {
                 for (unsigned int x = 0; x < 4; ++x) {
-                    SkipSpaces(&s);
+                    SkipSpaces(&s, end);
                     msh.transform[y][x] = fast_atof(&s);
                     msh.transform[y][x] = fast_atof(&s);
                 }
                 }
             }
             }
@@ -494,12 +489,12 @@ void COBImporter::ReadBasicNodeInfo_Ascii(Node &msh, LineSplitter &splitter, con
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 template <typename T>
 template <typename T>
-void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in) {
+void COBImporter::ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end) {
     const char *rgb = *in;
     const char *rgb = *in;
     for (unsigned int i = 0; i < 3; ++i) {
     for (unsigned int i = 0; i < 3; ++i) {
-        SkipSpaces(&rgb);
+        SkipSpaces(&rgb, end);
         if (*rgb == ',') ++rgb;
         if (*rgb == ',') ++rgb;
-        SkipSpaces(&rgb);
+        SkipSpaces(&rgb, end);
 
 
         fill[i] = fast_atof(&rgb);
         fill[i] = fast_atof(&rgb);
     }
     }
@@ -546,7 +541,7 @@ void COBImporter::ReadMat1_Ascii(Scene &out, LineSplitter &splitter, const Chunk
     }
     }
 
 
     const char *rgb = splitter[1];
     const char *rgb = splitter[1];
-    ReadFloat3Tuple_Ascii(mat.rgb, &rgb);
+    ReadFloat3Tuple_Ascii(mat.rgb, &rgb, splitter.getEnd());
 
 
     ++splitter;
     ++splitter;
     if (!splitter.match_start("alpha ")) {
     if (!splitter.match_start("alpha ")) {
@@ -625,20 +620,21 @@ void COBImporter::ReadLght_Ascii(Scene &out, LineSplitter &splitter, const Chunk
     }
     }
 
 
     const char *rgb = splitter[1];
     const char *rgb = splitter[1];
-    ReadFloat3Tuple_Ascii(msh.color, &rgb);
+    const char *end = splitter.getEnd();
+    ReadFloat3Tuple_Ascii(msh.color, &rgb, end);
 
 
-    SkipSpaces(&rgb);
+    SkipSpaces(&rgb, end);
     if (strncmp(rgb, "cone angle", 10) != 0) {
     if (strncmp(rgb, "cone angle", 10) != 0) {
         ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
         ASSIMP_LOG_WARN("Expected `cone angle` entity in `color` line in `Lght` chunk ", nfo.id);
     }
     }
-    SkipSpaces(rgb + 10, &rgb);
+    SkipSpaces(rgb + 10, &rgb, end);
     msh.angle = fast_atof(&rgb);
     msh.angle = fast_atof(&rgb);
 
 
-    SkipSpaces(&rgb);
+    SkipSpaces(&rgb, end);
     if (strncmp(rgb, "inner angle", 11) != 0) {
     if (strncmp(rgb, "inner angle", 11) != 0) {
         ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
         ASSIMP_LOG_WARN("Expected `inner angle` entity in `color` line in `Lght` chunk ", nfo.id);
     }
     }
-    SkipSpaces(rgb + 11, &rgb);
+    SkipSpaces(rgb + 11, &rgb, end);
     msh.inner_angle = fast_atof(&rgb);
     msh.inner_angle = fast_atof(&rgb);
 
 
     // skip the rest for we can't handle this kind of physically-based lighting information.
     // skip the rest for we can't handle this kind of physically-based lighting information.
@@ -711,14 +707,14 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
 
 
             for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
             for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
                 const char *s = splitter->c_str();
                 const char *s = splitter->c_str();
-
+                const char *end = splitter.getEnd();
                 aiVector3D &v = msh.vertex_positions[cur];
                 aiVector3D &v = msh.vertex_positions[cur];
 
 
-                SkipSpaces(&s);
+                SkipSpaces(&s, end);
                 v.x = fast_atof(&s);
                 v.x = fast_atof(&s);
-                SkipSpaces(&s);
+                SkipSpaces(&s, end);
                 v.y = fast_atof(&s);
                 v.y = fast_atof(&s);
-                SkipSpaces(&s);
+                SkipSpaces(&s, end);
                 v.z = fast_atof(&s);
                 v.z = fast_atof(&s);
             }
             }
         } else if (splitter.match_start("Texture Vertices")) {
         } else if (splitter.match_start("Texture Vertices")) {
@@ -727,12 +723,13 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
 
 
             for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
             for (unsigned int cur = 0; cur < cnt && ++splitter; ++cur) {
                 const char *s = splitter->c_str();
                 const char *s = splitter->c_str();
+                const char *end = splitter.getEnd();
 
 
                 aiVector2D &v = msh.texture_coords[cur];
                 aiVector2D &v = msh.texture_coords[cur];
 
 
-                SkipSpaces(&s);
+                SkipSpaces(&s, end);
                 v.x = fast_atof(&s);
                 v.x = fast_atof(&s);
-                SkipSpaces(&s);
+                SkipSpaces(&s, end);
                 v.y = fast_atof(&s);
                 v.y = fast_atof(&s);
             }
             }
         } else if (splitter.match_start("Faces")) {
         } else if (splitter.match_start("Faces")) {
@@ -757,8 +754,9 @@ void COBImporter::ReadPolH_Ascii(Scene &out, LineSplitter &splitter, const Chunk
                 face.material = strtoul10(splitter[6]);
                 face.material = strtoul10(splitter[6]);
 
 
                 const char *s = (++splitter)->c_str();
                 const char *s = (++splitter)->c_str();
+                const char *end = splitter.getEnd();
                 for (size_t i = 0; i < face.indices.size(); ++i) {
                 for (size_t i = 0; i < face.indices.size(); ++i) {
-                    if (!SkipSpaces(&s)) {
+                    if (!SkipSpaces(&s, end)) {
                         ThrowException("Expected EOL token in Face entry");
                         ThrowException("Expected EOL token in Face entry");
                     }
                     }
                     if ('<' != *s++) {
                     if ('<' != *s++) {
@@ -868,7 +866,7 @@ void COBImporter::ReadBinaryFile(Scene &out, StreamReaderLE *reader) {
         return;
         return;
     }
     }
 
 
-    while (1) {
+    while (true) {
         std::string type;
         std::string type;
         type += reader->GetI1();
         type += reader->GetI1();
         type += reader->GetI1();
         type += reader->GetI1();
@@ -1054,7 +1052,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const
     id[0] = reader.GetI1(), id[1] = reader.GetI1();
     id[0] = reader.GetI1(), id[1] = reader.GetI1();
 
 
     if (id[0] == 'e' && id[1] == ':') {
     if (id[0] == 'e' && id[1] == ':') {
-        mat.tex_env.reset(new Texture());
+        mat.tex_env = std::make_shared<Texture>();
 
 
         reader.GetI1();
         reader.GetI1();
         ReadString_Binary(mat.tex_env->path, reader);
         ReadString_Binary(mat.tex_env->path, reader);
@@ -1064,7 +1062,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const
     }
     }
 
 
     if (id[0] == 't' && id[1] == ':') {
     if (id[0] == 't' && id[1] == ':') {
-        mat.tex_color.reset(new Texture());
+        mat.tex_color = std::make_shared<Texture>();
 
 
         reader.GetI1();
         reader.GetI1();
         ReadString_Binary(mat.tex_color->path, reader);
         ReadString_Binary(mat.tex_color->path, reader);
@@ -1080,7 +1078,7 @@ void COBImporter::ReadMat1_Binary(COB::Scene &out, StreamReaderLE &reader, const
     }
     }
 
 
     if (id[0] == 'b' && id[1] == ':') {
     if (id[0] == 'b' && id[1] == ':') {
-        mat.tex_bump.reset(new Texture());
+        mat.tex_bump = std::make_shared<Texture>();
 
 
         reader.GetI1();
         reader.GetI1();
         ReadString_Binary(mat.tex_bump->path, reader);
         ReadString_Binary(mat.tex_bump->path, reader);
@@ -1172,4 +1170,6 @@ void COBImporter::ReadUnit_Binary(COB::Scene &out, StreamReaderLE &reader, const
     ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
     ASSIMP_LOG_WARN("`Unit` chunk ", nfo.id, " is a child of ", nfo.parent_id, " which does not exist");
 }
 }
 
 
+}
+
 #endif // ASSIMP_BUILD_NO_COB_IMPORTER
 #endif // ASSIMP_BUILD_NO_COB_IMPORTER

+ 10 - 10
Engine/lib/assimp/code/AssetLib/COB/COBLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -56,16 +56,16 @@ class LineSplitter;
 
 
 // TinyFormatter.h
 // TinyFormatter.h
 namespace Formatter {
 namespace Formatter {
-template <typename T, typename TR, typename A>
-class basic_formatter;
-typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
+    template <typename T, typename TR, typename A>
+    class basic_formatter;
+    typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>> format;
 } // namespace Formatter
 } // namespace Formatter
 
 
 // COBScene.h
 // COBScene.h
 namespace COB {
 namespace COB {
-struct ChunkInfo;
-struct Node;
-struct Scene;
+    struct ChunkInfo;
+    struct Node;
+    struct Scene;
 } // namespace COB
 } // namespace COB
 
 
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
@@ -75,8 +75,8 @@ struct Scene;
 // -------------------------------------------------------------------------------------------
 // -------------------------------------------------------------------------------------------
 class COBImporter : public BaseImporter {
 class COBImporter : public BaseImporter {
 public:
 public:
-    COBImporter();
-    ~COBImporter() override;
+    COBImporter() = default;
+    ~COBImporter() override = default;
 
 
     // --------------------
     // --------------------
     bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
     bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
@@ -120,7 +120,7 @@ private:
     void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
     void ReadChunkInfo_Ascii(COB::ChunkInfo &out, const LineSplitter &splitter);
     void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
     void ReadBasicNodeInfo_Ascii(COB::Node &msh, LineSplitter &splitter, const COB::ChunkInfo &nfo);
     template <typename T>
     template <typename T>
-    void ReadFloat3Tuple_Ascii(T &fill, const char **in);
+    void ReadFloat3Tuple_Ascii(T &fill, const char **in, const char *end);
 
 
     void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
     void ReadPolH_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
     void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);
     void ReadBitM_Ascii(COB::Scene &out, LineSplitter &splitter, const COB::ChunkInfo &nfo);

+ 1 - 1
Engine/lib/assimp/code/AssetLib/COB/COBScene.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 48 - 54
Engine/lib/assimp/code/AssetLib/CSM/CSMLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 
 
@@ -44,9 +44,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 /** @file  CSMLoader.cpp
 /** @file  CSMLoader.cpp
  *  Implementation of the CSM importer class.
  *  Implementation of the CSM importer class.
  */
  */
-
-
-
 #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
 #ifndef ASSIMP_BUILD_NO_CSM_IMPORTER
 
 
 #include "CSMLoader.h"
 #include "CSMLoader.h"
@@ -63,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "CharacterStudio Motion Importer (MoCap)",
     "CharacterStudio Motion Importer (MoCap)",
     "",
     "",
     "",
     "",
@@ -79,33 +76,26 @@ static const aiImporterDesc desc = {
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 // Constructor to be privately used by Importer
-CSMImporter::CSMImporter()
-: noSkeletonMesh()
-{}
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-CSMImporter::~CSMImporter() = default;
+CSMImporter::CSMImporter() : noSkeletonMesh(){
+    // empty
+}
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
-bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const
-{
+bool CSMImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool /*checkSig*/) const {
     static const char* tokens[] = {"$Filename"};
     static const char* tokens[] = {"$Filename"};
     return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
     return SearchFileHeaderForToken(pIOHandler,pFile,tokens,AI_COUNT_OF(tokens));
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Build a string of all file extensions supported
 // Build a string of all file extensions supported
-const aiImporterDesc* CSMImporter::GetInfo () const
-{
+const aiImporterDesc* CSMImporter::GetInfo () const {
     return &desc;
     return &desc;
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Setup configuration properties for the loader
 // Setup configuration properties for the loader
-void CSMImporter::SetupProperties(const Importer* pImp)
-{
+void CSMImporter::SetupProperties(const Importer* pImp) {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES,0) != 0;
 }
 }
 
 
@@ -117,7 +107,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
     std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
     std::unique_ptr<IOStream> file( pIOHandler->Open( pFile, "rb"));
 
 
     // Check whether we can read from the file
     // Check whether we can read from the file
-    if( file.get() == nullptr) {
+    if (file == nullptr) {
         throw DeadlyImportError( "Failed to open CSM file ", pFile, ".");
         throw DeadlyImportError( "Failed to open CSM file ", pFile, ".");
     }
     }
 
 
@@ -125,38 +115,38 @@ void CSMImporter::InternReadFile( const std::string& pFile,
     std::vector<char> mBuffer2;
     std::vector<char> mBuffer2;
     TextFileToBuffer(file.get(),mBuffer2);
     TextFileToBuffer(file.get(),mBuffer2);
     const char* buffer = &mBuffer2[0];
     const char* buffer = &mBuffer2[0];
-
+    const char *end = &mBuffer2[mBuffer2.size() - 1] + 1;
     std::unique_ptr<aiAnimation> anim(new aiAnimation());
     std::unique_ptr<aiAnimation> anim(new aiAnimation());
     int first = 0, last = 0x00ffffff;
     int first = 0, last = 0x00ffffff;
 
 
     // now process the file and look out for '$' sections
     // now process the file and look out for '$' sections
-    while (1)   {
-        SkipSpaces(&buffer);
+    while (true) {
+        SkipSpaces(&buffer, end);
         if ('\0' == *buffer)
         if ('\0' == *buffer)
             break;
             break;
 
 
         if ('$'  == *buffer)    {
         if ('$'  == *buffer)    {
             ++buffer;
             ++buffer;
             if (TokenMatchI(buffer,"firstframe",10))    {
             if (TokenMatchI(buffer,"firstframe",10))    {
-                SkipSpaces(&buffer);
+                SkipSpaces(&buffer, end);
                 first = strtol10(buffer,&buffer);
                 first = strtol10(buffer,&buffer);
             }
             }
             else if (TokenMatchI(buffer,"lastframe",9))     {
             else if (TokenMatchI(buffer,"lastframe",9))     {
-                SkipSpaces(&buffer);
+                SkipSpaces(&buffer, end);
                 last = strtol10(buffer,&buffer);
                 last = strtol10(buffer,&buffer);
             }
             }
             else if (TokenMatchI(buffer,"rate",4))  {
             else if (TokenMatchI(buffer,"rate",4))  {
-                SkipSpaces(&buffer);
-                float d;
+                SkipSpaces(&buffer, end);
+                float d = { 0.0f };
                 buffer = fast_atoreal_move<float>(buffer,d);
                 buffer = fast_atoreal_move<float>(buffer,d);
                 anim->mTicksPerSecond = d;
                 anim->mTicksPerSecond = d;
             }
             }
             else if (TokenMatchI(buffer,"order",5)) {
             else if (TokenMatchI(buffer,"order",5)) {
                 std::vector< aiNodeAnim* > anims_temp;
                 std::vector< aiNodeAnim* > anims_temp;
                 anims_temp.reserve(30);
                 anims_temp.reserve(30);
-                while (1)   {
-                    SkipSpaces(&buffer);
-                    if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer) && *buffer == '$')
+                while (true) {
+                    SkipSpaces(&buffer, end);
+                    if (IsLineEnd(*buffer) && SkipSpacesAndLineEnd(&buffer, end) && *buffer == '$')
                         break; // next section
                         break; // next section
 
 
                     // Construct a new node animation channel and setup its name
                     // Construct a new node animation channel and setup its name
@@ -164,41 +154,43 @@ void CSMImporter::InternReadFile( const std::string& pFile,
                     aiNodeAnim* nda = anims_temp.back();
                     aiNodeAnim* nda = anims_temp.back();
 
 
                     char* ot = nda->mNodeName.data;
                     char* ot = nda->mNodeName.data;
-                    while (!IsSpaceOrNewLine(*buffer))
+                    while (!IsSpaceOrNewLine(*buffer)) {
                         *ot++ = *buffer++;
                         *ot++ = *buffer++;
+                    }
 
 
                     *ot = '\0';
                     *ot = '\0';
                     nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
                     nda->mNodeName.length = static_cast<ai_uint32>(ot-nda->mNodeName.data);
                 }
                 }
 
 
                 anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
                 anim->mNumChannels = static_cast<unsigned int>(anims_temp.size());
-                if (!anim->mNumChannels)
+                if (!anim->mNumChannels) {
                     throw DeadlyImportError("CSM: Empty $order section");
                     throw DeadlyImportError("CSM: Empty $order section");
+                }
 
 
                 // copy over to the output animation
                 // copy over to the output animation
                 anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
                 anim->mChannels = new aiNodeAnim*[anim->mNumChannels];
                 ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
                 ::memcpy(anim->mChannels,&anims_temp[0],sizeof(aiNodeAnim*)*anim->mNumChannels);
-            }
-            else if (TokenMatchI(buffer,"points",6))    {
-                if (!anim->mNumChannels)
+            } else if (TokenMatchI(buffer,"points",6)) {
+                if (!anim->mNumChannels) {
                     throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
                     throw DeadlyImportError("CSM: \'$order\' section is required to appear prior to \'$points\'");
+                }
 
 
                 // If we know how many frames we'll read, we can preallocate some storage
                 // If we know how many frames we'll read, we can preallocate some storage
                 unsigned int alloc = 100;
                 unsigned int alloc = 100;
-                if (last != 0x00ffffff)
-                {
+                if (last != 0x00ffffff) {
                     alloc = last-first;
                     alloc = last-first;
                     alloc += alloc>>2u; // + 25%
                     alloc += alloc>>2u; // + 25%
-                    for (unsigned int i = 0; i < anim->mNumChannels;++i)
+                    for (unsigned int i = 0; i < anim->mNumChannels; ++i) {
                         anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
                         anim->mChannels[i]->mPositionKeys = new aiVectorKey[alloc];
+                    }
                 }
                 }
 
 
                 unsigned int filled = 0;
                 unsigned int filled = 0;
 
 
                 // Now read all point data.
                 // Now read all point data.
-                while (1)   {
-                    SkipSpaces(&buffer);
-                    if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer) || *buffer == '$'))   {
+                while (true) {
+                    SkipSpaces(&buffer, end);
+                    if (IsLineEnd(*buffer) && (!SkipSpacesAndLineEnd(&buffer, end) || *buffer == '$'))   {
                         break; // next section
                         break; // next section
                     }
                     }
 
 
@@ -209,8 +201,8 @@ void CSMImporter::InternReadFile( const std::string& pFile,
                     for (unsigned int i = 0; i < anim->mNumChannels;++i)    {
                     for (unsigned int i = 0; i < anim->mNumChannels;++i)    {
 
 
                         aiNodeAnim* s = anim->mChannels[i];
                         aiNodeAnim* s = anim->mChannels[i];
-                        if (s->mNumPositionKeys == alloc)   { /* need to reallocate? */
-
+                        if (s->mNumPositionKeys == alloc)   {
+                            // need to reallocate?
                             aiVectorKey* old = s->mPositionKeys;
                             aiVectorKey* old = s->mPositionKeys;
                             s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
                             s->mPositionKeys = new aiVectorKey[s->mNumPositionKeys = alloc*2];
                             ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
                             ::memcpy(s->mPositionKeys,old,sizeof(aiVectorKey)*alloc);
@@ -218,24 +210,26 @@ void CSMImporter::InternReadFile( const std::string& pFile,
                         }
                         }
 
 
                         // read x,y,z
                         // read x,y,z
-                        if(!SkipSpacesAndLineEnd(&buffer))
+                        if (!SkipSpacesAndLineEnd(&buffer, end)) {
                             throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
                             throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample x coord");
+                        }
 
 
                         if (TokenMatchI(buffer, "DROPOUT", 7))  {
                         if (TokenMatchI(buffer, "DROPOUT", 7))  {
                             // seems this is invalid marker data; at least the doc says it's possible
                             // seems this is invalid marker data; at least the doc says it's possible
                             ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
                             ASSIMP_LOG_WARN("CSM: Encountered invalid marker data (DROPOUT)");
-                        }
-                        else    {
+                        } else {
                             aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
                             aiVectorKey* sub = s->mPositionKeys + s->mNumPositionKeys;
                             sub->mTime = (double)frame;
                             sub->mTime = (double)frame;
                             buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
                             buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.x);
 
 
-                            if(!SkipSpacesAndLineEnd(&buffer))
+                            if (!SkipSpacesAndLineEnd(&buffer, end)) {
                                 throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
                                 throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample y coord");
+                            }
                             buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
                             buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.y);
 
 
-                            if(!SkipSpacesAndLineEnd(&buffer))
+                            if (!SkipSpacesAndLineEnd(&buffer, end)) {
                                 throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
                                 throw DeadlyImportError("CSM: Unexpected EOF occurred reading sample z coord");
+                            }
                             buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
                             buffer = fast_atoreal_move<float>(buffer, (float&)sub->mValue.z);
 
 
                             ++s->mNumPositionKeys;
                             ++s->mNumPositionKeys;
@@ -243,22 +237,22 @@ void CSMImporter::InternReadFile( const std::string& pFile,
                     }
                     }
 
 
                     // update allocation granularity
                     // update allocation granularity
-                    if (filled == alloc)
+                    if (filled == alloc) {
                         alloc *= 2;
                         alloc *= 2;
+                    }
 
 
                     ++filled;
                     ++filled;
                 }
                 }
                 // all channels must be complete in order to continue safely.
                 // all channels must be complete in order to continue safely.
                 for (unsigned int i = 0; i < anim->mNumChannels;++i)    {
                 for (unsigned int i = 0; i < anim->mNumChannels;++i)    {
-
-                    if (!anim->mChannels[i]->mNumPositionKeys)
+                    if (!anim->mChannels[i]->mNumPositionKeys) {
                         throw DeadlyImportError("CSM: Invalid marker track");
                         throw DeadlyImportError("CSM: Invalid marker track");
+                    }
                 }
                 }
             }
             }
-        }
-        else    {
+        } else {
             // advance to the next line
             // advance to the next line
-            SkipLine(&buffer);
+            SkipLine(&buffer, end);
         }
         }
     }
     }
 
 
@@ -272,7 +266,7 @@ void CSMImporter::InternReadFile( const std::string& pFile,
     pScene->mRootNode->mNumChildren = anim->mNumChannels;
     pScene->mRootNode->mNumChildren = anim->mNumChannels;
     pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
     pScene->mRootNode->mChildren = new aiNode* [anim->mNumChannels];
 
 
-    for (unsigned int i = 0; i < anim->mNumChannels;++i)    {
+    for (unsigned int i = 0; i < anim->mNumChannels;++i) {
         aiNodeAnim* na = anim->mChannels[i];
         aiNodeAnim* na = anim->mChannels[i];
 
 
         aiNode* nd  = pScene->mRootNode->mChildren[i] = new aiNode();
         aiNode* nd  = pScene->mRootNode->mChildren[i] = new aiNode();

+ 4 - 5
Engine/lib/assimp/code/AssetLib/CSM/CSMLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -61,7 +61,7 @@ namespace Assimp {
 class CSMImporter : public BaseImporter {
 class CSMImporter : public BaseImporter {
 public:
 public:
     CSMImporter();
     CSMImporter();
-    ~CSMImporter() override;
+    ~CSMImporter() override = default;
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
     bool CanRead(const std::string &pFile, IOSystem *pIOHandler,
@@ -81,9 +81,8 @@ protected:
 private:
 private:
     bool noSkeletonMesh;
     bool noSkeletonMesh;
 
 
-}; // end of class CSMImporter
+};
 
 
-} // end of namespace Assimp
+} // namespace Assimp
 
 
 #endif // AI_AC3DIMPORTER_H_INC
 #endif // AI_AC3DIMPORTER_H_INC
-

+ 5 - 5
Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -91,7 +91,7 @@ void ExportSceneCollada(const char *pFile, IOSystem *pIOSystem, const aiScene *p
 // Encodes a string into a valid XML ID using the xsd:ID schema qualifications.
 // Encodes a string into a valid XML ID using the xsd:ID schema qualifications.
 static const std::string XMLIDEncode(const std::string &name) {
 static const std::string XMLIDEncode(const std::string &name) {
     const char XML_ID_CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.";
     const char XML_ID_CHARS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_-.";
-    const unsigned int XML_ID_CHARS_COUNT = sizeof(XML_ID_CHARS) / sizeof(char);
+    const unsigned int XML_ID_CHARS_COUNT = sizeof(XML_ID_CHARS) / sizeof(char) - 1;
 
 
     if (name.length() == 0) {
     if (name.length() == 0) {
         return name;
         return name;
@@ -246,7 +246,7 @@ void ColladaExporter::WriteHeader() {
     }
     }
 
 
     // Assimp root nodes can have meshes, Collada Scenes cannot
     // Assimp root nodes can have meshes, Collada Scenes cannot
-    if (mScene->mRootNode->mNumChildren == 0 || mScene->mRootNode->mMeshes != 0) {
+    if (mScene->mRootNode->mNumChildren == 0 || mScene->mRootNode->mMeshes != nullptr) {
         mAdd_root_node = true;
         mAdd_root_node = true;
     }
     }
 
 
@@ -448,7 +448,7 @@ void ColladaExporter::WriteLight(size_t pIndex) {
     PushTag();
     PushTag();
     switch (light->mType) {
     switch (light->mType) {
     case aiLightSource_AMBIENT:
     case aiLightSource_AMBIENT:
-        WriteAmbienttLight(light);
+        WriteAmbientLight(light);
         break;
         break;
     case aiLightSource_DIRECTIONAL:
     case aiLightSource_DIRECTIONAL:
         WriteDirectionalLight(light);
         WriteDirectionalLight(light);
@@ -543,7 +543,7 @@ void ColladaExporter::WriteSpotLight(const aiLight *const light) {
     mOutput << startstr << "</spot>" << endstr;
     mOutput << startstr << "</spot>" << endstr;
 }
 }
 
 
-void ColladaExporter::WriteAmbienttLight(const aiLight *const light) {
+void ColladaExporter::WriteAmbientLight(const aiLight *const light) {
 
 
     const aiColor3D &color = light->mColorAmbient;
     const aiColor3D &color = light->mColorAmbient;
     mOutput << startstr << "<ambient>" << endstr;
     mOutput << startstr << "<ambient>" << endstr;

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Collada/ColladaExporter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -101,7 +101,7 @@ protected:
     void WritePointLight(const aiLight *const light);
     void WritePointLight(const aiLight *const light);
     void WriteDirectionalLight(const aiLight *const light);
     void WriteDirectionalLight(const aiLight *const light);
     void WriteSpotLight(const aiLight *const light);
     void WriteSpotLight(const aiLight *const light);
-    void WriteAmbienttLight(const aiLight *const light);
+    void WriteAmbientLight(const aiLight *const light);
 
 
     /// Writes the controller library
     /// Writes the controller library
     void WriteControllerLibrary();
     void WriteControllerLibrary();

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 2 - 2
Engine/lib/assimp/code/AssetLib/Collada/ColladaHelper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -666,7 +666,7 @@ struct ChannelEntry {
     const Collada::Accessor *mTimeAccessor; ///> Collada accessor to the time values
     const Collada::Accessor *mTimeAccessor; ///> Collada accessor to the time values
     const Collada::Data *mTimeData; ///> Source data array for the time values
     const Collada::Data *mTimeData; ///> Source data array for the time values
     const Collada::Accessor *mValueAccessor; ///> Collada accessor to the key value values
     const Collada::Accessor *mValueAccessor; ///> Collada accessor to the key value values
-    const Collada::Data *mValueData; ///> Source datat array for the key value values
+    const Collada::Data *mValueData; ///> Source data array for the key value values
 
 
     ChannelEntry() :
     ChannelEntry() :
             mChannel(),
             mChannel(),

+ 24 - 32
Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -64,7 +64,7 @@ namespace Assimp {
 using namespace Assimp::Formatter;
 using namespace Assimp::Formatter;
 using namespace Assimp::Collada;
 using namespace Assimp::Collada;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "Collada Importer",
     "Collada Importer",
     "",
     "",
     "",
     "",
@@ -92,27 +92,15 @@ inline void AddNodeMetaData(aiNode *node, const std::string &key, const T &value
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 // Constructor to be privately used by Importer
 ColladaLoader::ColladaLoader() :
 ColladaLoader::ColladaLoader() :
-        mFileName(),
-        mMeshIndexByID(),
-        mMaterialIndexByName(),
-        mMeshes(),
-        newMats(),
-        mCameras(),
-        mLights(),
-        mTextures(),
-        mAnims(),
         noSkeletonMesh(false),
         noSkeletonMesh(false),
         removeEmptyBones(false),
         removeEmptyBones(false),
         ignoreUpDirection(false),
         ignoreUpDirection(false),
+        ignoreUnitSize(false),
         useColladaName(false),
         useColladaName(false),
         mNodeNameCounter(0) {
         mNodeNameCounter(0) {
     // empty
     // empty
 }
 }
 
 
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-ColladaLoader::~ColladaLoader() = default;
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
 bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool /*checkSig*/) const {
@@ -131,6 +119,7 @@ void ColladaLoader::SetupProperties(const Importer *pImp) {
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
     noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
     removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
     removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
     ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
+    ignoreUnitSize = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UNIT_SIZE, 0) != 0;
     useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
     useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
 }
 }
 
 
@@ -179,12 +168,15 @@ void ColladaLoader::InternReadFile(const std::string &pFile, aiScene *pScene, IO
     // ... then fill the materials with the now adjusted settings
     // ... then fill the materials with the now adjusted settings
     FillMaterials(parser, pScene);
     FillMaterials(parser, pScene);
 
 
-    // Apply unit-size scale calculation
-
-    pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
-            0, parser.mUnitSize, 0, 0,
-            0, 0, parser.mUnitSize, 0,
-            0, 0, 0, 1);
+    if (!ignoreUnitSize) {
+        // Apply unit-size scale calculation
+        pScene->mRootNode->mTransformation *= aiMatrix4x4(
+                parser.mUnitSize, 0, 0, 0,
+                0, parser.mUnitSize, 0, 0,
+                0, 0, parser.mUnitSize, 0,
+                0, 0, 0, 1);
+    }
+    
     if (!ignoreUpDirection) {
     if (!ignoreUpDirection) {
         // Convert to Y_UP, if different orientation
         // Convert to Y_UP, if different orientation
         if (parser.mUpDirection == ColladaParser::UP_X) {
         if (parser.mUpDirection == ColladaParser::UP_X) {
@@ -255,7 +247,9 @@ aiNode *ColladaLoader::BuildHierarchy(const ColladaParser &pParser, const Collad
 
 
     // add children. first the *real* ones
     // add children. first the *real* ones
     node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size() + instances.size());
     node->mNumChildren = static_cast<unsigned int>(pNode->mChildren.size() + instances.size());
-    node->mChildren = new aiNode *[node->mNumChildren];
+    if (node->mNumChildren != 0) {
+        node->mChildren = new aiNode * [node->mNumChildren];
+    }
 
 
     for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
     for (size_t a = 0; a < pNode->mChildren.size(); ++a) {
         node->mChildren[a] = BuildHierarchy(pParser, pNode->mChildren[a]);
         node->mChildren[a] = BuildHierarchy(pParser, pNode->mChildren[a]);
@@ -631,16 +625,14 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
     }
     }
 
 
     // same for texture coords, as many as we have
     // same for texture coords, as many as we have
-    // empty slots are not allowed, need to pack and adjust UV indexes accordingly
-    for (size_t a = 0, real = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
+    for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
         if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
         if (pSrcMesh->mTexCoords[a].size() >= pStartVertex + numVertices) {
-            dstMesh->mTextureCoords[real] = new aiVector3D[numVertices];
+            dstMesh->mTextureCoords[a] = new aiVector3D[numVertices];
             for (size_t b = 0; b < numVertices; ++b) {
             for (size_t b = 0; b < numVertices; ++b) {
-                dstMesh->mTextureCoords[real][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
+                dstMesh->mTextureCoords[a][b] = pSrcMesh->mTexCoords[a][pStartVertex + b];
             }
             }
 
 
-            dstMesh->mNumUVComponents[real] = pSrcMesh->mNumUVComponents[a];
-            ++real;
+            dstMesh->mNumUVComponents[a] = pSrcMesh->mNumUVComponents[a];
         }
         }
     }
     }
 
 
@@ -1264,12 +1256,12 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
             // now for every unique point in time, find or interpolate the key values for that time
             // now for every unique point in time, find or interpolate the key values for that time
             // and apply them to the transform chain. Then the node's present transformation can be calculated.
             // and apply them to the transform chain. Then the node's present transformation can be calculated.
             ai_real time = startTime;
             ai_real time = startTime;
-            while (1) {
+            while (true) {
                 for (ChannelEntry & e : entries) {
                 for (ChannelEntry & e : entries) {
                     // find the keyframe behind the current point in time
                     // find the keyframe behind the current point in time
                     size_t pos = 0;
                     size_t pos = 0;
                     ai_real postTime = 0.0;
                     ai_real postTime = 0.0;
-                    while (1) {
+                    while (true) {
                         if (pos >= e.mTimeAccessor->mCount) {
                         if (pos >= e.mTimeAccessor->mCount) {
                             break;
                             break;
                         }
                         }
@@ -1523,7 +1515,7 @@ void ColladaLoader::AddTexture(aiMaterial &mat,
         map = -1;
         map = -1;
         for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
         for (std::string::const_iterator it = sampler.mUVChannel.begin(); it != sampler.mUVChannel.end(); ++it) {
             if (IsNumeric(*it)) {
             if (IsNumeric(*it)) {
-                map = strtoul10(&(*it));        
+                map = strtoul10(&(*it));
                 break;
                 break;
             }
             }
         }
         }
@@ -1680,7 +1672,7 @@ aiString ColladaLoader::FindFilenameForEffectTexture(const ColladaParser &pParse
 
 
     // recurse through the param references until we end up at an image
     // recurse through the param references until we end up at an image
     std::string name = pName;
     std::string name = pName;
-    while (1) {
+    while (true) {
         // the given string is a param entry. Find it
         // the given string is a param entry. Find it
         Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
         Effect::ParamLibrary::const_iterator it = pEffect.mParams.find(name);
         // if not found, we're at the end of the recursion. The resulting string should be the image ID
         // if not found, we're at the end of the recursion. The resulting string should be the image ID

+ 3 - 2
Engine/lib/assimp/code/AssetLib/Collada/ColladaLoader.h

@@ -4,7 +4,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -86,7 +86,7 @@ public:
     ColladaLoader();
     ColladaLoader();
 
 
     /// The class destructor.
     /// The class destructor.
-    ~ColladaLoader() override;
+    ~ColladaLoader() override = default;
 
 
     /// Returns whether the class can handle the format of the given file.
     /// Returns whether the class can handle the format of the given file.
     /// @see BaseImporter::CanRead() for more details.
     /// @see BaseImporter::CanRead() for more details.
@@ -239,6 +239,7 @@ protected:
     bool noSkeletonMesh;
     bool noSkeletonMesh;
     bool removeEmptyBones;
     bool removeEmptyBones;
     bool ignoreUpDirection;
     bool ignoreUpDirection;
+    bool ignoreUnitSize;
     bool useColladaName;
     bool useColladaName;
 
 
     /** Used by FindNameForNode() to generate unique node names */
     /** Used by FindNameForNode() to generate unique node names */

+ 134 - 108
Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/IOSystem.hpp>
 #include <assimp/IOSystem.hpp>
 #include <memory>
 #include <memory>
+#include <utility>
 
 
 using namespace Assimp;
 using namespace Assimp;
 using namespace Assimp::Collada;
 using namespace Assimp::Collada;
@@ -67,7 +68,7 @@ static void ReportWarning(const char *msg, ...) {
     va_start(args, msg);
     va_start(args, msg);
 
 
     char szBuffer[3000];
     char szBuffer[3000];
-    const int iLen = vsprintf(szBuffer, msg, args);
+    const int iLen = vsnprintf(szBuffer, sizeof(szBuffer), msg, args);
     ai_assert(iLen > 0);
     ai_assert(iLen > 0);
 
 
     va_end(args);
     va_end(args);
@@ -144,7 +145,7 @@ ColladaParser::ColladaParser(IOSystem *pIOHandler, const std::string &pFile) :
     } else {
     } else {
         // attempt to open the file directly
         // attempt to open the file directly
         daefile.reset(pIOHandler->Open(pFile));
         daefile.reset(pIOHandler->Open(pFile));
-        if (daefile.get() == nullptr) {
+        if (daefile == nullptr) {
             throw DeadlyImportError("Failed to open file '", pFile, "'.");
             throw DeadlyImportError("Failed to open file '", pFile, "'.");
         }
         }
     }
     }
@@ -634,7 +635,8 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
         const std::string &currentName = currentNode.name();
         const std::string &currentName = currentNode.name();
         if (currentName == "morph") {
         if (currentName == "morph") {
             controller.mType = Morph;
             controller.mType = Morph;
-            controller.mMeshId = currentNode.attribute("source").as_string();
+            std::string id = currentNode.attribute("source").as_string();
+            controller.mMeshId = id.substr(1, id.size() - 1);
             int methodIndex = currentNode.attribute("method").as_int();
             int methodIndex = currentNode.attribute("method").as_int();
             if (methodIndex > 0) {
             if (methodIndex > 0) {
                 std::string method;
                 std::string method;
@@ -653,12 +655,13 @@ void ColladaParser::ReadController(XmlNode &node, Collada::Controller &controlle
             std::string v;
             std::string v;
             XmlParser::getValueAsString(currentNode, v);
             XmlParser::getValueAsString(currentNode, v);
             const char *content = v.c_str();
             const char *content = v.c_str();
+            const char *end = content + v.size();
             for (unsigned int a = 0; a < 16; a++) {
             for (unsigned int a = 0; a < 16; a++) {
-                SkipSpacesAndLineEnd(&content);
+                SkipSpacesAndLineEnd(&content, end);
                 // read a number
                 // read a number
                 content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
                 content = fast_atoreal_move<ai_real>(content, controller.mBindShapeMatrix[a]);
                 // skip whitespace after it
                 // skip whitespace after it
-                SkipSpacesAndLineEnd(&content);
+                SkipSpacesAndLineEnd(&content, end);
             }
             }
         } else if (currentName == "source") {
         } else if (currentName == "source") {
             ReadSource(currentNode);
             ReadSource(currentNode);
@@ -739,7 +742,9 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
                 throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
                 throw DeadlyImportError("Unknown semantic \"", attrSemantic, "\" in <vertex_weights> data <input> element");
             }
             }
         } else if (currentName == "vcount" && vertexCount > 0) {
         } else if (currentName == "vcount" && vertexCount > 0) {
-            const char *text = currentNode.text().as_string();
+            const std::string stdText = currentNode.text().as_string();
+            const char *text = stdText.c_str();
+            const char *end = text + stdText.size();
             size_t numWeights = 0;
             size_t numWeights = 0;
             for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
             for (std::vector<size_t>::iterator it = pController.mWeightCounts.begin(); it != pController.mWeightCounts.end(); ++it) {
                 if (*text == 0) {
                 if (*text == 0) {
@@ -748,7 +753,7 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
 
 
                 *it = strtoul10(text, &text);
                 *it = strtoul10(text, &text);
                 numWeights += *it;
                 numWeights += *it;
-                SkipSpacesAndLineEnd(&text);
+                SkipSpacesAndLineEnd(&text, end);
             }
             }
             // reserve weight count
             // reserve weight count
             pController.mWeights.resize(numWeights);
             pController.mWeights.resize(numWeights);
@@ -757,17 +762,19 @@ void ColladaParser::ReadControllerWeights(XmlNode &node, Collada::Controller &pC
             std::string stdText;
             std::string stdText;
             XmlParser::getValueAsString(currentNode, stdText);
             XmlParser::getValueAsString(currentNode, stdText);
             const char *text = stdText.c_str();
             const char *text = stdText.c_str();
+            const char *end = text + stdText.size();
             for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
             for (std::vector<std::pair<size_t, size_t>>::iterator it = pController.mWeights.begin(); it != pController.mWeights.end(); ++it) {
-                if (text == 0) {
+                if (text == nullptr) {
                     throw DeadlyImportError("Out of data while reading <vertex_weights>");
                     throw DeadlyImportError("Out of data while reading <vertex_weights>");
                 }
                 }
+                SkipSpacesAndLineEnd(&text, end);
                 it->first = strtoul10(text, &text);
                 it->first = strtoul10(text, &text);
-                SkipSpacesAndLineEnd(&text);
+                SkipSpacesAndLineEnd(&text, end);
                 if (*text == 0) {
                 if (*text == 0) {
                     throw DeadlyImportError("Out of data while reading <vertex_weights>");
                     throw DeadlyImportError("Out of data while reading <vertex_weights>");
                 }
                 }
                 it->second = strtoul10(text, &text);
                 it->second = strtoul10(text, &text);
-                SkipSpacesAndLineEnd(&text);
+                SkipSpacesAndLineEnd(&text, end);
             }
             }
         }
         }
     }
     }
@@ -812,38 +819,38 @@ void ColladaParser::ReadImage(XmlNode &node, Collada::Image &pImage) {
                 if (!pImage.mFileName.length()) {
                 if (!pImage.mFileName.length()) {
                     pImage.mFileName = "unknown_texture";
                     pImage.mFileName = "unknown_texture";
                 }
                 }
-            }
-        } else if (mFormat == FV_1_5_n) {
-            std::string value;
-            XmlNode refChild = currentNode.child("ref");
-            XmlNode hexChild = currentNode.child("hex");
-            if (refChild) {
-                // element content is filename - hopefully
-                if (XmlParser::getValueAsString(refChild, value)) {
-                    aiString filepath(value);
-                    UriDecodePath(filepath);
-                    pImage.mFileName = filepath.C_Str();
-                }
-            } else if (hexChild && !pImage.mFileName.length()) {
-                // embedded image. get format
-                pImage.mEmbeddedFormat = hexChild.attribute("format").as_string();
-                if (pImage.mEmbeddedFormat.empty()) {
-                    ASSIMP_LOG_WARN("Collada: Unknown image file format");
-                }
+            } else if (mFormat == FV_1_5_n) {
+                std::string value;
+                XmlNode refChild = currentNode.child("ref");
+                XmlNode hexChild = currentNode.child("hex");
+                if (refChild) {
+                    // element content is filename - hopefully
+                    if (XmlParser::getValueAsString(refChild, value)) {
+                        aiString filepath(value);
+                        UriDecodePath(filepath);
+                        pImage.mFileName = filepath.C_Str();
+                    }
+                } else if (hexChild && !pImage.mFileName.length()) {
+                    // embedded image. get format
+                    pImage.mEmbeddedFormat = hexChild.attribute("format").as_string();
+                    if (pImage.mEmbeddedFormat.empty()) {
+                        ASSIMP_LOG_WARN("Collada: Unknown image file format");
+                    }
 
 
-                XmlParser::getValueAsString(hexChild, value);
-                const char *data = value.c_str();
-                // hexadecimal-encoded binary octets. First of all, find the
-                // required buffer size to reserve enough storage.
-                const char *cur = data;
-                while (!IsSpaceOrNewLine(*cur)) {
-                    ++cur;
-                }
+                    XmlParser::getValueAsString(hexChild, value);
+                    const char *data = value.c_str();
+                    // hexadecimal-encoded binary octets. First of all, find the
+                    // required buffer size to reserve enough storage.
+                    const char *cur = data;
+                    while (!IsSpaceOrNewLine(*cur)) {
+                        ++cur;
+                    }
 
 
-                const unsigned int size = (unsigned int)(cur - data) * 2;
-                pImage.mImageData.resize(size);
-                for (unsigned int i = 0; i < size; ++i) {
-                    pImage.mImageData[i] = HexOctetToDecimal(data + (i << 1));
+                    const unsigned int size = (unsigned int)(cur - data) * 2;
+                    pImage.mImageData.resize(size);
+                    for (unsigned int i = 0; i < size; ++i) {
+                        pImage.mImageData[i] = HexOctetToDecimal(data + (i << 1));
+                    }
                 }
                 }
             }
             }
         }
         }
@@ -950,44 +957,45 @@ void ColladaParser::ReadLight(XmlNode &node, Collada::Light &pLight) {
             std::string v;
             std::string v;
             XmlParser::getValueAsString(currentNode, v);
             XmlParser::getValueAsString(currentNode, v);
             const char *content = v.c_str();
             const char *content = v.c_str();
+            const char *end = content + v.size();
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.r);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.g);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pLight.mColor.b);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
         } else if (currentName == "constant_attenuation") {
         } else if (currentName == "constant_attenuation") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mAttConstant);
+            XmlParser::getValueAsReal(currentNode, pLight.mAttConstant);
         } else if (currentName == "linear_attenuation") {
         } else if (currentName == "linear_attenuation") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mAttLinear);
+            XmlParser::getValueAsReal(currentNode, pLight.mAttLinear);
         } else if (currentName == "quadratic_attenuation") {
         } else if (currentName == "quadratic_attenuation") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mAttQuadratic);
+            XmlParser::getValueAsReal(currentNode, pLight.mAttQuadratic);
         } else if (currentName == "falloff_angle") {
         } else if (currentName == "falloff_angle") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
         } else if (currentName == "falloff_exponent") {
         } else if (currentName == "falloff_exponent") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mFalloffExponent);
+            XmlParser::getValueAsReal(currentNode, pLight.mFalloffExponent);
         }
         }
         // FCOLLADA extensions
         // FCOLLADA extensions
         // -------------------------------------------------------
         // -------------------------------------------------------
         else if (currentName == "outer_cone") {
         else if (currentName == "outer_cone") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
         } else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
         } else if (currentName == "penumbra_angle") { // this one is deprecated, now calculated using outer_cone
-            XmlParser::getValueAsFloat(currentNode, pLight.mPenumbraAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mPenumbraAngle);
         } else if (currentName == "intensity") {
         } else if (currentName == "intensity") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mIntensity);
+            XmlParser::getValueAsReal(currentNode, pLight.mIntensity);
         }
         }
         else if (currentName == "falloff") {
         else if (currentName == "falloff") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
         } else if (currentName == "hotspot_beam") {
         } else if (currentName == "hotspot_beam") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mFalloffAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mFalloffAngle);
         }
         }
         // OpenCOLLADA extensions
         // OpenCOLLADA extensions
         // -------------------------------------------------------
         // -------------------------------------------------------
         else if (currentName == "decay_falloff") {
         else if (currentName == "decay_falloff") {
-            XmlParser::getValueAsFloat(currentNode, pLight.mOuterAngle);
+            XmlParser::getValueAsReal(currentNode, pLight.mOuterAngle);
         }
         }
     }
     }
 }
 }
@@ -1002,15 +1010,15 @@ void ColladaParser::ReadCamera(XmlNode &node, Collada::Camera &camera) {
         if (currentName == "orthographic") {
         if (currentName == "orthographic") {
             camera.mOrtho = true;
             camera.mOrtho = true;
         } else if (currentName == "xfov" || currentName == "xmag") {
         } else if (currentName == "xfov" || currentName == "xmag") {
-            XmlParser::getValueAsFloat(currentNode, camera.mHorFov);
+            XmlParser::getValueAsReal(currentNode, camera.mHorFov);
         } else if (currentName == "yfov" || currentName == "ymag") {
         } else if (currentName == "yfov" || currentName == "ymag") {
-            XmlParser::getValueAsFloat(currentNode, camera.mVerFov);
+            XmlParser::getValueAsReal(currentNode, camera.mVerFov);
         } else if (currentName == "aspect_ratio") {
         } else if (currentName == "aspect_ratio") {
-            XmlParser::getValueAsFloat(currentNode, camera.mAspect);
+            XmlParser::getValueAsReal(currentNode, camera.mAspect);
         } else if (currentName == "znear") {
         } else if (currentName == "znear") {
-            XmlParser::getValueAsFloat(currentNode, camera.mZNear);
+            XmlParser::getValueAsReal(currentNode, camera.mZNear);
         } else if (currentName == "zfar") {
         } else if (currentName == "zfar") {
-            XmlParser::getValueAsFloat(currentNode, camera.mZFar);
+            XmlParser::getValueAsReal(currentNode, camera.mZFar);
         }
         }
     }
     }
 }
 }
@@ -1162,15 +1170,15 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
         } else if (currentName == "mirrorV") {
         } else if (currentName == "mirrorV") {
             XmlParser::getValueAsBool(currentNode, out.mMirrorV);
             XmlParser::getValueAsBool(currentNode, out.mMirrorV);
         } else if (currentName == "repeatU") {
         } else if (currentName == "repeatU") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.x);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.x);
         } else if (currentName == "repeatV") {
         } else if (currentName == "repeatV") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mScaling.y);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mScaling.y);
         } else if (currentName == "offsetU") {
         } else if (currentName == "offsetU") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.x);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.x);
         } else if (currentName == "offsetV") {
         } else if (currentName == "offsetV") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mTranslation.y);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mTranslation.y);
         } else if (currentName == "rotateUV") {
         } else if (currentName == "rotateUV") {
-            XmlParser::getValueAsFloat(currentNode, out.mTransform.mRotation);
+            XmlParser::getValueAsReal(currentNode, out.mTransform.mRotation);
         } else if (currentName == "blend_mode") {
         } else if (currentName == "blend_mode") {
             std::string v;
             std::string v;
             XmlParser::getValueAsString(currentNode, v);
             XmlParser::getValueAsString(currentNode, v);
@@ -1190,14 +1198,14 @@ void ColladaParser::ReadSamplerProperties(XmlNode &node, Sampler &out) {
         // OKINO extensions
         // OKINO extensions
         // -------------------------------------------------------
         // -------------------------------------------------------
         else if (currentName == "weighting") {
         else if (currentName == "weighting") {
-            XmlParser::getValueAsFloat(currentNode, out.mWeighting);
+            XmlParser::getValueAsReal(currentNode, out.mWeighting);
         } else if (currentName == "mix_with_previous_layer") {
         } else if (currentName == "mix_with_previous_layer") {
-            XmlParser::getValueAsFloat(currentNode, out.mMixWithPrevious);
+            XmlParser::getValueAsReal(currentNode, out.mMixWithPrevious);
         }
         }
         // MAX3D extensions
         // MAX3D extensions
         // -------------------------------------------------------
         // -------------------------------------------------------
         else if (currentName == "amount") {
         else if (currentName == "amount") {
-            XmlParser::getValueAsFloat(currentNode, out.mWeighting);
+            XmlParser::getValueAsReal(currentNode, out.mWeighting);
         }
         }
     }
     }
 }
 }
@@ -1218,18 +1226,19 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
             std::string v;
             std::string v;
             XmlParser::getValueAsString(currentNode, v);
             XmlParser::getValueAsString(currentNode, v);
             const char *content = v.c_str();
             const char *content = v.c_str();
+            const char *end = v.c_str() + v.size() + 1; 
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.r);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.g);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.b);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
 
 
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
             content = fast_atoreal_move<ai_real>(content, (ai_real &)pColor.a);
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
         } else if (currentName == "texture") {
         } else if (currentName == "texture") {
             // get name of source texture/sampler
             // get name of source texture/sampler
             XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
             XmlParser::getStdStrAttribute(currentNode, "texture", pSampler.mName);
@@ -1256,13 +1265,13 @@ void ColladaParser::ReadEffectColor(XmlNode &node, aiColor4D &pColor, Sampler &p
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Reads an effect entry containing a float
 // Reads an effect entry containing a float
-void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pFloat) {
-    pFloat = 0.f;
+void ColladaParser::ReadEffectFloat(XmlNode &node, ai_real &pReal) {
+    pReal = 0.f;
     XmlNode floatNode = node.child("float");
     XmlNode floatNode = node.child("float");
     if (floatNode.empty()) {
     if (floatNode.empty()) {
         return;
         return;
     }
     }
-    XmlParser::getValueAsFloat(floatNode, pFloat);
+    XmlParser::getValueAsReal(floatNode, pReal);
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -1272,9 +1281,7 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
         return;
         return;
     }
     }
 
 
-    XmlNodeIterator xmlIt(node, XmlNodeIterator::PreOrderMode);
-    XmlNode currentNode;
-    while (xmlIt.getNext(currentNode)) {
+    for (XmlNode &currentNode : node.children()) {
         const std::string &currentName = currentNode.name();
         const std::string &currentName = currentNode.name();
         if (currentName == "surface") {
         if (currentName == "surface") {
             // image ID given inside <init_from> tags
             // image ID given inside <init_from> tags
@@ -1287,22 +1294,24 @@ void ColladaParser::ReadEffectParam(XmlNode &node, Collada::EffectParam &pParam)
             }
             }
         } else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
         } else if (currentName == "sampler2D" && (FV_1_4_n == mFormat || FV_1_3_n == mFormat)) {
             // surface ID is given inside <source> tags
             // surface ID is given inside <source> tags
-            const char *content = currentNode.value();
-            pParam.mType = Param_Sampler;
-            pParam.mReference = content;
+            XmlNode source = currentNode.child("source");
+            if (source) {
+                std::string v;
+                XmlParser::getValueAsString(source, v);
+                pParam.mType = Param_Sampler;
+                pParam.mReference = v.c_str();
+            }
         } else if (currentName == "sampler2D") {
         } else if (currentName == "sampler2D") {
             // surface ID is given inside <instance_image> tags
             // surface ID is given inside <instance_image> tags
-            std::string url;
-            XmlParser::getStdStrAttribute(currentNode, "url", url);
-            if (url[0] != '#') {
-                throw DeadlyImportError("Unsupported URL format in instance_image");
-            }
-            pParam.mType = Param_Sampler;
-            pParam.mReference = url.c_str() + 1;
-        } else if (currentName == "source") {
-            const char *source = currentNode.child_value();
-            if (nullptr != source) {
-                pParam.mReference = source;
+            XmlNode instance_image = currentNode.child("instance_image");
+            if (instance_image) {
+                std::string url;
+                XmlParser::getStdStrAttribute(instance_image, "url", url);
+                if (url[0] != '#') {
+                    throw DeadlyImportError("Unsupported URL format in instance_image");
+                }
+                pParam.mType = Param_Sampler;
+                pParam.mReference = url.c_str() + 1;
             }
             }
         }
         }
     }
     }
@@ -1343,6 +1352,7 @@ void ColladaParser::ReadGeometry(XmlNode &node, Collada::Mesh &pMesh) {
     if (node.empty()) {
     if (node.empty()) {
         return;
         return;
     }
     }
+    
     for (XmlNode &currentNode : node.children()) {
     for (XmlNode &currentNode : node.children()) {
         const std::string &currentName = currentNode.name();
         const std::string &currentName = currentNode.name();
         if (currentName == "mesh") {
         if (currentName == "mesh") {
@@ -1413,6 +1423,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
     XmlParser::getValueAsString(node, v);
     XmlParser::getValueAsString(node, v);
     v = ai_trim(v);
     v = ai_trim(v);
     const char *content = v.c_str();
     const char *content = v.c_str();
+    const char *end = content + v.size();
 
 
     // read values and store inside an array in the data library
     // read values and store inside an array in the data library
     mDataLibrary[id] = Data();
     mDataLibrary[id] = Data();
@@ -1431,11 +1442,13 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
                 }
                 }
 
 
                 s.clear();
                 s.clear();
-                while (!IsSpaceOrNewLine(*content))
-                    s += *content++;
+                while (!IsSpaceOrNewLine(*content)) {
+                    s += *content;
+                    content++;
+                }
                 data.mStrings.push_back(s);
                 data.mStrings.push_back(s);
 
 
-                SkipSpacesAndLineEnd(&content);
+                SkipSpacesAndLineEnd(&content, end);
             }
             }
         } else {
         } else {
             data.mValues.reserve(count);
             data.mValues.reserve(count);
@@ -1450,7 +1463,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
                 content = fast_atoreal_move<ai_real>(content, value);
                 content = fast_atoreal_move<ai_real>(content, value);
                 data.mValues.push_back(value);
                 data.mValues.push_back(value);
                 // skip whitespace after it
                 // skip whitespace after it
-                SkipSpacesAndLineEnd(&content);
+                SkipSpacesAndLineEnd(&content, end);
             }
             }
         }
         }
     }
     }
@@ -1615,8 +1628,10 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
                     std::string v;
                     std::string v;
                     XmlParser::getValueAsString(currentNode, v);
                     XmlParser::getValueAsString(currentNode, v);
                     const char *content = v.c_str();
                     const char *content = v.c_str();
+                    const char *end = content + v.size();
+
                     vcount.reserve(numPrimitives);
                     vcount.reserve(numPrimitives);
-                    SkipSpacesAndLineEnd(&content);
+                    SkipSpacesAndLineEnd(&content, end);
                     for (unsigned int a = 0; a < numPrimitives; a++) {
                     for (unsigned int a = 0; a < numPrimitives; a++) {
                         if (*content == 0) {
                         if (*content == 0) {
                             throw DeadlyImportError("Expected more values while reading <vcount> contents.");
                             throw DeadlyImportError("Expected more values while reading <vcount> contents.");
@@ -1624,7 +1639,7 @@ void ColladaParser::ReadIndexData(XmlNode &node, Mesh &pMesh) {
                         // read a number
                         // read a number
                         vcount.push_back((size_t)strtoul10(content, &content));
                         vcount.push_back((size_t)strtoul10(content, &content));
                         // skip whitespace after it
                         // skip whitespace after it
-                        SkipSpacesAndLineEnd(&content);
+                        SkipSpacesAndLineEnd(&content, end);
                     }
                     }
                 }
                 }
             }
             }
@@ -1733,14 +1748,16 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
         std::string v;
         std::string v;
         XmlParser::getValueAsString(node, v);
         XmlParser::getValueAsString(node, v);
         const char *content = v.c_str();
         const char *content = v.c_str();
-        SkipSpacesAndLineEnd(&content);
+        const char *end = content + v.size();
+
+        SkipSpacesAndLineEnd(&content, end);
         while (*content != 0) {
         while (*content != 0) {
             // read a value.
             // read a value.
             // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
             // Hack: (thom) Some exporters put negative indices sometimes. We just try to carry on anyways.
             int value = std::max(0, strtol10(content, &content));
             int value = std::max(0, strtol10(content, &content));
             indices.push_back(size_t(value));
             indices.push_back(size_t(value));
             // skip whitespace after it
             // skip whitespace after it
-            SkipSpacesAndLineEnd(&content);
+            SkipSpacesAndLineEnd(&content, end);
         }
         }
     }
     }
 
 
@@ -1770,6 +1787,10 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
         const Accessor *acc = input.mResolved;
         const Accessor *acc = input.mResolved;
         if (!acc->mData) {
         if (!acc->mData) {
             acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
             acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
+            const size_t dataSize = acc->mOffset + acc->mCount * acc->mStride;
+            if (dataSize > acc->mData->mValues.size()) {
+                throw DeadlyImportError("Not enough data for accessor");
+            }
         }
         }
     }
     }
     // and the same for the per-index channels
     // and the same for the per-index channels
@@ -1794,13 +1815,19 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
         const Accessor *acc = input.mResolved;
         const Accessor *acc = input.mResolved;
         if (!acc->mData) {
         if (!acc->mData) {
             acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
             acc->mData = &ResolveLibraryReference(mDataLibrary, acc->mSource);
+            const size_t dataSize = acc->mOffset + acc->mCount * acc->mStride;
+            if (dataSize > acc->mData->mValues.size()) {
+                throw DeadlyImportError("Not enough data for accessor");
+            }
         }
         }
     }
     }
 
 
     // For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
     // For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
     size_t numPrimitives = pNumPrimitives;
     size_t numPrimitives = pNumPrimitives;
-    if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
+    if (pPrimType == Prim_TriFans || pPrimType == Prim_Polygon) {
         numPrimitives = 1;
         numPrimitives = 1;
+    }
+
     // For continued primitives, the given count is actually the number of <p>'s inside the parent tag
     // For continued primitives, the given count is actually the number of <p>'s inside the parent tag
     if (pPrimType == Prim_TriStrips) {
     if (pPrimType == Prim_TriStrips) {
         size_t numberOfVertices = indices.size() / numOffsets;
         size_t numberOfVertices = indices.size() / numOffsets;
@@ -1853,7 +1880,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
         default:
         default:
             // LineStrip is not supported due to expected index unmangling
             // LineStrip is not supported due to expected index unmangling
             throw DeadlyImportError("Unsupported primitive type.");
             throw DeadlyImportError("Unsupported primitive type.");
-            break;
         }
         }
 
 
         // store the face size to later reconstruct the face from
         // store the face size to later reconstruct the face from
@@ -1866,7 +1892,7 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
 
 
 ///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
 ///@note This function won't work correctly if both PerIndex and PerVertex channels have same channels.
 ///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
 ///For example if TEXCOORD present in both <vertices> and <polylist> tags this function will create wrong uv coordinates.
-///It's not clear from COLLADA documentation is this allowed or not. For now only exporter fixed to avoid such behavior
+///It's not clear from COLLADA documentation whether this is allowed or not. For now only exporter fixed to avoid such behavior
 void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
 void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh &pMesh,
         std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
         std::vector<InputChannel> &pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t> &indices) {
     // calculate the base offset of the vertex whose attributes we ant to copy
     // calculate the base offset of the vertex whose attributes we ant to copy
@@ -2165,15 +2191,15 @@ void ColladaParser::ReadNodeTransformation(XmlNode &node, Node *pNode, Transform
     }
     }
 
 
     // how many parameters to read per transformation type
     // how many parameters to read per transformation type
-    static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
+    static constexpr unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
     std::string value;
     std::string value;
     XmlParser::getValueAsString(node, value);
     XmlParser::getValueAsString(node, value);
     const char *content = value.c_str();
     const char *content = value.c_str();
-
+    const char *end = value.c_str() + value.size();
     // read as many parameters and store in the transformation
     // read as many parameters and store in the transformation
     for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
     for (unsigned int a = 0; a < sNumParameters[pType]; a++) {
         // skip whitespace before the number
         // skip whitespace before the number
-        SkipSpacesAndLineEnd(&content);
+        SkipSpacesAndLineEnd(&content, end);
         // read a number
         // read a number
         content = fast_atoreal_move<ai_real>(content, tf.f[a]);
         content = fast_atoreal_move<ai_real>(content, tf.f[a]);
     }
     }
@@ -2267,9 +2293,9 @@ void ColladaParser::ReadNodeGeometry(XmlNode &node, Node *pNode) {
                             urlMat++;
                             urlMat++;
 
 
                         s.mMatName = urlMat;
                         s.mMatName = urlMat;
+                        ReadMaterialVertexInputBinding(instanceMatNode, s);
                         // store the association
                         // store the association
                         instance.mMaterials[group] = s;
                         instance.mMaterials[group] = s;
-                        ReadMaterialVertexInputBinding(instanceMatNode, s);
                     }
                     }
                 }
                 }
             }
             }
@@ -2305,7 +2331,7 @@ void ColladaParser::ReadScene(XmlNode &node) {
             // find the referred scene, skip the leading #
             // find the referred scene, skip the leading #
             NodeLibrary::const_iterator sit = mNodeLibrary.find(url.c_str() + 1);
             NodeLibrary::const_iterator sit = mNodeLibrary.find(url.c_str() + 1);
             if (sit == mNodeLibrary.end()) {
             if (sit == mNodeLibrary.end()) {
-                throw DeadlyImportError("Unable to resolve visual_scene reference \"", std::string(url), "\" in <instance_visual_scene> element.");
+                throw DeadlyImportError("Unable to resolve visual_scene reference \"", std::string(std::move(url)), "\" in <instance_visual_scene> element.");
             }
             }
             mRootNode = sit->second;
             mRootNode = sit->second;
         }
         }

+ 1 - 1
Engine/lib/assimp/code/AssetLib/Collada/ColladaParser.h

@@ -2,7 +2,7 @@
  Open Asset Import Library (assimp)
  Open Asset Import Library (assimp)
  ----------------------------------------------------------------------
  ----------------------------------------------------------------------
 
 
- Copyright (c) 2006-2022, assimp team
+ Copyright (c) 2006-2024, assimp team
 
 
  All rights reserved.
  All rights reserved.
 
 

+ 2 - 4
Engine/lib/assimp/code/AssetLib/DXF/DXFHelper.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -65,7 +65,6 @@ public:
     LineReader(StreamReaderLE& reader)
     LineReader(StreamReaderLE& reader)
     : splitter(reader,false,true)
     : splitter(reader,false,true)
     , groupcode( 0 )
     , groupcode( 0 )
-    , value()
     , end() {
     , end() {
         // empty
         // empty
     }
     }
@@ -186,8 +185,7 @@ struct InsertBlock {
     InsertBlock()
     InsertBlock()
     : pos()
     : pos()
     , scale(1.f,1.f,1.f)
     , scale(1.f,1.f,1.f)
-    , angle()
-    , name() {
+    , angle() {
         // empty
         // empty
     }
     }
 
 

+ 292 - 54
Engine/lib/assimp/code/AssetLib/DXF/DXFLoader.cpp

@@ -3,7 +3,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ---------------------------------------------------------------------------
 ---------------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -43,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *  @brief Implementation of the DXF importer class
  *  @brief Implementation of the DXF importer class
  */
  */
 
 
-
 #ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
 #ifndef ASSIMP_BUILD_NO_DXF_IMPORTER
 
 
 #include "AssetLib/DXF/DXFLoader.h"
 #include "AssetLib/DXF/DXFLoader.h"
@@ -57,6 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/importerdesc.h>
 #include <assimp/importerdesc.h>
 
 
 #include <numeric>
 #include <numeric>
+#include <utility>
 
 
 using namespace Assimp;
 using namespace Assimp;
 
 
@@ -67,26 +67,269 @@ static constexpr size_t AI_DXF_BINARY_IDENT_LEN = sizeof AI_DXF_BINARY_IDENT;
 // default vertex color that all uncolored vertices will receive
 // default vertex color that all uncolored vertices will receive
 static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
 static const aiColor4D AI_DXF_DEFAULT_COLOR(aiColor4D(0.6f, 0.6f, 0.6f, 0.6f));
 
 
-// color indices for DXF - 16 are supported, the table is
-// taken directly from the DXF spec.
-static aiColor4D g_aclrDxfIndexColors[] = {
-    aiColor4D (0.6f, 0.6f, 0.6f, 1.0f),
-    aiColor4D (1.0f, 0.0f, 0.0f, 1.0f), // red
-    aiColor4D (0.0f, 1.0f, 0.0f, 1.0f), // green
-    aiColor4D (0.0f, 0.0f, 1.0f, 1.0f), // blue
-    aiColor4D (0.3f, 1.0f, 0.3f, 1.0f), // light green
-    aiColor4D (0.3f, 0.3f, 1.0f, 1.0f), // light blue
-    aiColor4D (1.0f, 0.3f, 0.3f, 1.0f), // light red
-    aiColor4D (1.0f, 0.0f, 1.0f, 1.0f), // pink
-    aiColor4D (1.0f, 0.6f, 0.0f, 1.0f), // orange
-    aiColor4D (0.6f, 0.3f, 0.0f, 1.0f), // dark orange
-    aiColor4D (1.0f, 1.0f, 0.0f, 1.0f), // yellow
-    aiColor4D (0.3f, 0.3f, 0.3f, 1.0f), // dark gray
-    aiColor4D (0.8f, 0.8f, 0.8f, 1.0f), // light gray
-    aiColor4D (0.0f, 00.f, 0.0f, 1.0f), // black
-    aiColor4D (1.0f, 1.0f, 1.0f, 1.0f), // white
-    aiColor4D (0.6f, 0.0f, 1.0f, 1.0f)  // violet
+// color indices for DXF - 256 are supported, the table is
+// taken directly from the AutoCad Index (ACI) table
+// https://gohtx.com/acadcolors.php
+//STH 2024-0126
+static const aiColor4D g_aclrDxfIndexColors[256] = {
+    aiColor4D (0.0f, 0.0f ,0.0f, 1.0f), //dxf color code 0
+    aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 1
+    aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 2
+    aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 3
+    aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 4
+    aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 5
+    aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 6
+    aiColor4D (1.0f, 1.0f ,1.0f, 1.0f), //dxf color code 7
+    aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 8
+    aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 9
+    aiColor4D (1.0f, 0.0f ,0.0f, 1.0f), //dxf color code 10
+    aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 11
+    aiColor4D (0.7f, 0.0f ,0.0f, 1.0f), //dxf color code 12
+    aiColor4D (0.7f, 0.5f ,0.5f, 1.0f), //dxf color code 13
+    aiColor4D (0.5f, 0.0f ,0.0f, 1.0f), //dxf color code 14
+    aiColor4D (0.5f, 0.3f ,0.3f, 1.0f), //dxf color code 15
+    aiColor4D (0.4f, 0.0f ,0.0f, 1.0f), //dxf color code 16
+    aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 17
+    aiColor4D (0.3f, 0.0f ,0.0f, 1.0f), //dxf color code 18
+    aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 19
+    aiColor4D (1.0f, 0.2f ,0.0f, 1.0f), //dxf color code 20
+    aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 21
+    aiColor4D (0.7f, 0.2f ,0.0f, 1.0f), //dxf color code 22
+    aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 23
+    aiColor4D (0.5f, 0.1f ,0.0f, 1.0f), //dxf color code 24
+    aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 25
+    aiColor4D (0.4f, 0.1f ,0.0f, 1.0f), //dxf color code 26
+    aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 27
+    aiColor4D (0.3f, 0.1f ,0.0f, 1.0f), //dxf color code 28
+    aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 29
+    aiColor4D (1.0f, 0.5f ,0.0f, 1.0f), //dxf color code 30
+    aiColor4D (1.0f, 0.8f ,0.7f, 1.0f), //dxf color code 31
+    aiColor4D (0.7f, 0.4f ,0.0f, 1.0f), //dxf color code 32
+    aiColor4D (0.7f, 0.6f ,0.5f, 1.0f), //dxf color code 33
+    aiColor4D (0.5f, 0.3f ,0.0f, 1.0f), //dxf color code 34
+    aiColor4D (0.5f, 0.4f ,0.3f, 1.0f), //dxf color code 35
+    aiColor4D (0.4f, 0.2f ,0.0f, 1.0f), //dxf color code 36
+    aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 37
+    aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 38
+    aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 39
+    aiColor4D (1.0f, 0.7f ,0.0f, 1.0f), //dxf color code 40
+    aiColor4D (1.0f, 0.9f ,0.7f, 1.0f), //dxf color code 41
+    aiColor4D (0.7f, 0.6f ,0.0f, 1.0f), //dxf color code 42
+    aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 43
+    aiColor4D (0.5f, 0.4f ,0.0f, 1.0f), //dxf color code 44
+    aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 45
+    aiColor4D (0.4f, 0.3f ,0.0f, 1.0f), //dxf color code 46
+    aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 47
+    aiColor4D (0.3f, 0.2f ,0.0f, 1.0f), //dxf color code 48
+    aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 49
+    aiColor4D (1.0f, 1.0f ,0.0f, 1.0f), //dxf color code 50
+    aiColor4D (1.0f, 1.0f ,0.7f, 1.0f), //dxf color code 51
+    aiColor4D (0.7f, 0.7f ,0.0f, 1.0f), //dxf color code 52
+    aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 53
+    aiColor4D (0.5f, 0.5f ,0.0f, 1.0f), //dxf color code 54
+    aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 55
+    aiColor4D (0.4f, 0.4f ,0.0f, 1.0f), //dxf color code 56
+    aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 57
+    aiColor4D (0.3f, 0.3f ,0.0f, 1.0f), //dxf color code 58
+    aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 59
+    aiColor4D (0.7f, 1.0f ,0.0f, 1.0f), //dxf color code 60
+    aiColor4D (0.9f, 1.0f ,0.7f, 1.0f), //dxf color code 61
+    aiColor4D (0.6f, 0.7f ,0.0f, 1.0f), //dxf color code 62
+    aiColor4D (0.7f, 0.7f ,0.5f, 1.0f), //dxf color code 63
+    aiColor4D (0.4f, 0.5f ,0.0f, 1.0f), //dxf color code 64
+    aiColor4D (0.5f, 0.5f ,0.3f, 1.0f), //dxf color code 65
+    aiColor4D (0.3f, 0.4f ,0.0f, 1.0f), //dxf color code 66
+    aiColor4D (0.4f, 0.4f ,0.3f, 1.0f), //dxf color code 67
+    aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 68
+    aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 69
+    aiColor4D (0.5f, 1.0f ,0.0f, 1.0f), //dxf color code 70
+    aiColor4D (0.8f, 1.0f ,0.7f, 1.0f), //dxf color code 71
+    aiColor4D (0.4f, 0.7f ,0.0f, 1.0f), //dxf color code 72
+    aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 73
+    aiColor4D (0.3f, 0.5f ,0.0f, 1.0f), //dxf color code 74
+    aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 75
+    aiColor4D (0.2f, 0.4f ,0.0f, 1.0f), //dxf color code 76
+    aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 77
+    aiColor4D (0.2f, 0.3f ,0.0f, 1.0f), //dxf color code 78
+    aiColor4D (0.3f, 0.3f ,0.2f, 1.0f), //dxf color code 79
+    aiColor4D (0.2f, 1.0f ,0.0f, 1.0f), //dxf color code 80
+    aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 81
+    aiColor4D (0.2f, 0.7f ,0.0f, 1.0f), //dxf color code 82
+    aiColor4D (0.6f, 0.7f ,0.5f, 1.0f), //dxf color code 83
+    aiColor4D (0.1f, 0.5f ,0.0f, 1.0f), //dxf color code 84
+    aiColor4D (0.4f, 0.5f ,0.3f, 1.0f), //dxf color code 85
+    aiColor4D (0.1f, 0.4f ,0.0f, 1.0f), //dxf color code 86
+    aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 87
+    aiColor4D (0.1f, 0.3f ,0.0f, 1.0f), //dxf color code 88
+    aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 89
+    aiColor4D (0.0f, 1.0f ,0.0f, 1.0f), //dxf color code 90
+    aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 91
+    aiColor4D (0.0f, 0.7f ,0.0f, 1.0f), //dxf color code 92
+    aiColor4D (0.5f, 0.7f ,0.5f, 1.0f), //dxf color code 93
+    aiColor4D (0.0f, 0.5f ,0.0f, 1.0f), //dxf color code 94
+    aiColor4D (0.3f, 0.5f ,0.3f, 1.0f), //dxf color code 95
+    aiColor4D (0.0f, 0.4f ,0.0f, 1.0f), //dxf color code 96
+    aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 97
+    aiColor4D (0.0f, 0.3f ,0.0f, 1.0f), //dxf color code 98
+    aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 99
+    aiColor4D (0.0f, 1.0f ,0.2f, 1.0f), //dxf color code 100
+    aiColor4D (0.7f, 1.0f ,0.7f, 1.0f), //dxf color code 101
+    aiColor4D (0.0f, 0.7f ,0.2f, 1.0f), //dxf color code 102
+    aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 103
+    aiColor4D (0.0f, 0.5f ,0.1f, 1.0f), //dxf color code 104
+    aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 105
+    aiColor4D (0.0f, 0.4f ,0.1f, 1.0f), //dxf color code 106
+    aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 107
+    aiColor4D (0.0f, 0.3f ,0.1f, 1.0f), //dxf color code 108
+    aiColor4D (0.2f, 0.3f ,0.2f, 1.0f), //dxf color code 109
+    aiColor4D (0.0f, 1.0f ,0.5f, 1.0f), //dxf color code 110
+    aiColor4D (0.7f, 1.0f ,0.8f, 1.0f), //dxf color code 111
+    aiColor4D (0.0f, 0.7f ,0.4f, 1.0f), //dxf color code 112
+    aiColor4D (0.5f, 0.7f ,0.6f, 1.0f), //dxf color code 113
+    aiColor4D (0.0f, 0.5f ,0.3f, 1.0f), //dxf color code 114
+    aiColor4D (0.3f, 0.5f ,0.4f, 1.0f), //dxf color code 115
+    aiColor4D (0.0f, 0.4f ,0.2f, 1.0f), //dxf color code 116
+    aiColor4D (0.3f, 0.4f ,0.3f, 1.0f), //dxf color code 117
+    aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 118
+    aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 119
+    aiColor4D (0.0f, 1.0f ,0.7f, 1.0f), //dxf color code 120
+    aiColor4D (0.7f, 1.0f ,0.9f, 1.0f), //dxf color code 121
+    aiColor4D (0.0f, 0.7f ,0.6f, 1.0f), //dxf color code 122
+    aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 123
+    aiColor4D (0.0f, 0.5f ,0.4f, 1.0f), //dxf color code 124
+    aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 125
+    aiColor4D (0.0f, 0.4f ,0.3f, 1.0f), //dxf color code 126
+    aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 127
+    aiColor4D (0.0f, 0.3f ,0.2f, 1.0f), //dxf color code 128
+    aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 129
+    aiColor4D (0.0f, 1.0f ,1.0f, 1.0f), //dxf color code 130
+    aiColor4D (0.7f, 1.0f ,1.0f, 1.0f), //dxf color code 131
+    aiColor4D (0.0f, 0.7f ,0.7f, 1.0f), //dxf color code 132
+    aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 133
+    aiColor4D (0.0f, 0.5f ,0.5f, 1.0f), //dxf color code 134
+    aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 135
+    aiColor4D (0.0f, 0.4f ,0.4f, 1.0f), //dxf color code 136
+    aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 137
+    aiColor4D (0.0f, 0.3f ,0.3f, 1.0f), //dxf color code 138
+    aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 139
+    aiColor4D (0.0f, 0.7f ,1.0f, 1.0f), //dxf color code 140
+    aiColor4D (0.7f, 0.9f ,1.0f, 1.0f), //dxf color code 141
+    aiColor4D (0.0f, 0.6f ,0.7f, 1.0f), //dxf color code 142
+    aiColor4D (0.5f, 0.7f ,0.7f, 1.0f), //dxf color code 143
+    aiColor4D (0.0f, 0.4f ,0.5f, 1.0f), //dxf color code 144
+    aiColor4D (0.3f, 0.5f ,0.5f, 1.0f), //dxf color code 145
+    aiColor4D (0.0f, 0.3f ,0.4f, 1.0f), //dxf color code 146
+    aiColor4D (0.3f, 0.4f ,0.4f, 1.0f), //dxf color code 147
+    aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 148
+    aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 149
+    aiColor4D (0.0f, 0.5f ,1.0f, 1.0f), //dxf color code 150
+    aiColor4D (0.7f, 0.8f ,1.0f, 1.0f), //dxf color code 151
+    aiColor4D (0.0f, 0.4f ,0.7f, 1.0f), //dxf color code 152
+    aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 153
+    aiColor4D (0.0f, 0.3f ,0.5f, 1.0f), //dxf color code 154
+    aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 155
+    aiColor4D (0.0f, 0.2f ,0.4f, 1.0f), //dxf color code 156
+    aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 157
+    aiColor4D (0.0f, 0.2f ,0.3f, 1.0f), //dxf color code 158
+    aiColor4D (0.2f, 0.3f ,0.3f, 1.0f), //dxf color code 159
+    aiColor4D (0.0f, 0.2f ,1.0f, 1.0f), //dxf color code 160
+    aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 161
+    aiColor4D (0.0f, 0.2f ,0.7f, 1.0f), //dxf color code 162
+    aiColor4D (0.5f, 0.6f ,0.7f, 1.0f), //dxf color code 163
+    aiColor4D (0.0f, 0.1f ,0.5f, 1.0f), //dxf color code 164
+    aiColor4D (0.3f, 0.4f ,0.5f, 1.0f), //dxf color code 165
+    aiColor4D (0.0f, 0.1f ,0.4f, 1.0f), //dxf color code 166
+    aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 167
+    aiColor4D (0.0f, 0.1f ,0.3f, 1.0f), //dxf color code 168
+    aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 169
+    aiColor4D (0.0f, 0.0f ,1.0f, 1.0f), //dxf color code 170
+    aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 171
+    aiColor4D (0.0f, 0.0f ,0.7f, 1.0f), //dxf color code 172
+    aiColor4D (0.5f, 0.5f ,0.7f, 1.0f), //dxf color code 173
+    aiColor4D (0.0f, 0.0f ,0.5f, 1.0f), //dxf color code 174
+    aiColor4D (0.3f, 0.3f ,0.5f, 1.0f), //dxf color code 175
+    aiColor4D (0.0f, 0.0f ,0.4f, 1.0f), //dxf color code 176
+    aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 177
+    aiColor4D (0.0f, 0.0f ,0.3f, 1.0f), //dxf color code 178
+    aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 179
+    aiColor4D (0.2f, 0.0f ,1.0f, 1.0f), //dxf color code 180
+    aiColor4D (0.7f, 0.7f ,1.0f, 1.0f), //dxf color code 181
+    aiColor4D (0.2f, 0.0f ,0.7f, 1.0f), //dxf color code 182
+    aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 183
+    aiColor4D (0.1f, 0.0f ,0.5f, 1.0f), //dxf color code 184
+    aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 185
+    aiColor4D (0.1f, 0.0f ,0.4f, 1.0f), //dxf color code 186
+    aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 187
+    aiColor4D (0.1f, 0.0f ,0.3f, 1.0f), //dxf color code 188
+    aiColor4D (0.2f, 0.2f ,0.3f, 1.0f), //dxf color code 189
+    aiColor4D (0.5f, 0.0f ,1.0f, 1.0f), //dxf color code 190
+    aiColor4D (0.8f, 0.7f ,1.0f, 1.0f), //dxf color code 191
+    aiColor4D (0.4f, 0.0f ,0.7f, 1.0f), //dxf color code 192
+    aiColor4D (0.6f, 0.5f ,0.7f, 1.0f), //dxf color code 193
+    aiColor4D (0.3f, 0.0f ,0.5f, 1.0f), //dxf color code 194
+    aiColor4D (0.4f, 0.3f ,0.5f, 1.0f), //dxf color code 195
+    aiColor4D (0.2f, 0.0f ,0.4f, 1.0f), //dxf color code 196
+    aiColor4D (0.3f, 0.3f ,0.4f, 1.0f), //dxf color code 197
+    aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 198
+    aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 199
+    aiColor4D (0.7f, 0.0f ,1.0f, 1.0f), //dxf color code 200
+    aiColor4D (0.9f, 0.7f ,1.0f, 1.0f), //dxf color code 201
+    aiColor4D (0.6f, 0.0f ,0.7f, 1.0f), //dxf color code 202
+    aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 203
+    aiColor4D (0.4f, 0.0f ,0.5f, 1.0f), //dxf color code 204
+    aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 205
+    aiColor4D (0.3f, 0.0f ,0.4f, 1.0f), //dxf color code 206
+    aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 207
+    aiColor4D (0.2f, 0.0f ,0.3f, 1.0f), //dxf color code 208
+    aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 209
+    aiColor4D (1.0f, 0.0f ,1.0f, 1.0f), //dxf color code 210
+    aiColor4D (1.0f, 0.7f ,1.0f, 1.0f), //dxf color code 211
+    aiColor4D (0.7f, 0.0f ,0.7f, 1.0f), //dxf color code 212
+    aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 213
+    aiColor4D (0.5f, 0.0f ,0.5f, 1.0f), //dxf color code 214
+    aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 215
+    aiColor4D (0.4f, 0.0f ,0.4f, 1.0f), //dxf color code 216
+    aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 217
+    aiColor4D (0.3f, 0.0f ,0.3f, 1.0f), //dxf color code 218
+    aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 219
+    aiColor4D (1.0f, 0.0f ,0.7f, 1.0f), //dxf color code 220
+    aiColor4D (1.0f, 0.7f ,0.9f, 1.0f), //dxf color code 221
+    aiColor4D (0.7f, 0.0f ,0.6f, 1.0f), //dxf color code 222
+    aiColor4D (0.7f, 0.5f ,0.7f, 1.0f), //dxf color code 223
+    aiColor4D (0.5f, 0.0f ,0.4f, 1.0f), //dxf color code 224
+    aiColor4D (0.5f, 0.3f ,0.5f, 1.0f), //dxf color code 225
+    aiColor4D (0.4f, 0.0f ,0.3f, 1.0f), //dxf color code 226
+    aiColor4D (0.4f, 0.3f ,0.4f, 1.0f), //dxf color code 227
+    aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 228
+    aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 229
+    aiColor4D (1.0f, 0.0f ,0.5f, 1.0f), //dxf color code 230
+    aiColor4D (1.0f, 0.7f ,0.8f, 1.0f), //dxf color code 231
+    aiColor4D (0.7f, 0.0f ,0.4f, 1.0f), //dxf color code 232
+    aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 233
+    aiColor4D (0.5f, 0.0f ,0.3f, 1.0f), //dxf color code 234
+    aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 235
+    aiColor4D (0.4f, 0.0f ,0.2f, 1.0f), //dxf color code 236
+    aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 237
+    aiColor4D (0.3f, 0.0f ,0.2f, 1.0f), //dxf color code 238
+    aiColor4D (0.3f, 0.2f ,0.3f, 1.0f), //dxf color code 239
+    aiColor4D (1.0f, 0.0f ,0.2f, 1.0f), //dxf color code 240
+    aiColor4D (1.0f, 0.7f ,0.7f, 1.0f), //dxf color code 241
+    aiColor4D (0.7f, 0.0f ,0.2f, 1.0f), //dxf color code 242
+    aiColor4D (0.7f, 0.5f ,0.6f, 1.0f), //dxf color code 243
+    aiColor4D (0.5f, 0.0f ,0.1f, 1.0f), //dxf color code 244
+    aiColor4D (0.5f, 0.3f ,0.4f, 1.0f), //dxf color code 245
+    aiColor4D (0.4f, 0.0f ,0.1f, 1.0f), //dxf color code 246
+    aiColor4D (0.4f, 0.3f ,0.3f, 1.0f), //dxf color code 247
+    aiColor4D (0.3f, 0.0f ,0.1f, 1.0f), //dxf color code 248
+    aiColor4D (0.3f, 0.2f ,0.2f, 1.0f), //dxf color code 249
+    aiColor4D (0.2f, 0.2f ,0.2f, 1.0f), //dxf color code 250
+    aiColor4D (0.3f, 0.3f ,0.3f, 1.0f), //dxf color code 251
+    aiColor4D (0.4f, 0.4f ,0.4f, 1.0f), //dxf color code 252
+    aiColor4D (0.5f, 0.5f ,0.5f, 1.0f), //dxf color code 253
+    aiColor4D (0.7f, 0.7f ,0.7f, 1.0f), //dxf color code 254
+    aiColor4D (1.0f, 1.0f ,1.0f, 1.0f) //dxf color code 255
 };
 };
+
 #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
 #define AI_DXF_NUM_INDEX_COLORS (sizeof(g_aclrDxfIndexColors)/sizeof(g_aclrDxfIndexColors[0]))
 #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
 #define AI_DXF_ENTITIES_MAGIC_BLOCK "$ASSIMP_ENTITIES_MAGIC"
 
 
@@ -95,7 +338,7 @@ static const int GroupCode_XComp = 10;
 static const int GroupCode_YComp = 20;
 static const int GroupCode_YComp = 20;
 static const int GroupCode_ZComp = 30;
 static const int GroupCode_ZComp = 30;
 
 
-static const aiImporterDesc desc = {
+static constexpr aiImporterDesc desc = {
     "Drawing Interchange Format (DXF) Importer",
     "Drawing Interchange Format (DXF) Importer",
     "",
     "",
     "",
     "",
@@ -108,14 +351,6 @@ static const aiImporterDesc desc = {
     "dxf"
     "dxf"
 };
 };
 
 
-// ------------------------------------------------------------------------------------------------
-// Constructor to be privately used by Importer
-DXFImporter::DXFImporter() = default;
-
-// ------------------------------------------------------------------------------------------------
-// Destructor, private as well
-DXFImporter::~DXFImporter() = default;
-
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
 // Returns whether the class can handle the format of the given file.
 bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
 bool DXFImporter::CanRead( const std::string& filename, IOSystem* pIOHandler, bool /*checkSig*/ ) const {
@@ -135,7 +370,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
     std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( filename) );
     std::shared_ptr<IOStream> file = std::shared_ptr<IOStream>( pIOHandler->Open( filename) );
 
 
     // Check whether we can read the file
     // Check whether we can read the file
-    if( file.get() == nullptr ) {
+    if (file == nullptr) {
         throw DeadlyImportError( "Failed to open DXF file ", filename, "");
         throw DeadlyImportError( "Failed to open DXF file ", filename, "");
     }
     }
 
 
@@ -150,7 +385,7 @@ void DXFImporter::InternReadFile( const std::string& filename, aiScene* pScene,
     // DXF files can grow very large, so read them via the StreamReader,
     // DXF files can grow very large, so read them via the StreamReader,
     // which will choose a suitable strategy.
     // which will choose a suitable strategy.
     file->Seek(0,aiOrigin_SET);
     file->Seek(0,aiOrigin_SET);
-    StreamReaderLE stream( file );
+    StreamReaderLE stream( std::move(file) );
 
 
     DXF::LineReader reader (stream);
     DXF::LineReader reader (stream);
     DXF::FileData output;
     DXF::FileData output;
@@ -228,7 +463,7 @@ void DXFImporter::ConvertMeshes(aiScene* pScene, DXF::FileData& output) {
         ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
         ASSIMP_LOG_VERBOSE_DEBUG("DXF: Unexpanded polycount is ", icount, ", vertex count is ", vcount);
     }
     }
 
 
-    if (! output.blocks.size()  ) {
+    if (output.blocks.empty()) {
         throw DeadlyImportError("DXF: no data blocks loaded");
         throw DeadlyImportError("DXF: no data blocks loaded");
     }
     }
 
 
@@ -370,7 +605,7 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
                 ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
                 ASSIMP_LOG_ERROR("DXF: PolyLine instance is nullptr, skipping.");
                 continue;
                 continue;
             }
             }
-            
+
             std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
             std::shared_ptr<DXF::PolyLine> pl_out = std::shared_ptr<DXF::PolyLine>(new DXF::PolyLine(*pl_in));
 
 
             if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
             if (bl_src.base.Length() || insert.scale.x!=1.f || insert.scale.y!=1.f || insert.scale.z!=1.f || insert.angle || insert.pos.Length()) {
@@ -378,8 +613,12 @@ void DXFImporter::ExpandBlockReferences(DXF::Block& bl,const DXF::BlockMap& bloc
                 // XXX order
                 // XXX order
                 aiMatrix4x4 trafo, tmp;
                 aiMatrix4x4 trafo, tmp;
                 aiMatrix4x4::Translation(-bl_src.base,trafo);
                 aiMatrix4x4::Translation(-bl_src.base,trafo);
-                trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
+                //Need to translate position before scaling the insert
+                //otherwise the position ends up being the position*scaling
+                //STH 2024.01.17
                 trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
                 trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
+                trafo *= aiMatrix4x4::Scaling(insert.scale,tmp);
+                //trafo *= aiMatrix4x4::Translation(insert.pos,tmp);
 
 
                 // XXX rotation currently ignored - I didn't find an appropriate sample model.
                 // XXX rotation currently ignored - I didn't find an appropriate sample model.
                 if (insert.angle != 0.f) {
                 if (insert.angle != 0.f) {
@@ -586,10 +825,11 @@ void DXFImporter::ParseInsertion(DXF::LineReader& reader, DXF::FileData& output)
     }
     }
 }
 }
 
 
-#define DXF_POLYLINE_FLAG_CLOSED        0x1
-#define DXF_POLYLINE_FLAG_3D_POLYLINE   0x8
-#define DXF_POLYLINE_FLAG_3D_POLYMESH   0x10
-#define DXF_POLYLINE_FLAG_POLYFACEMESH  0x40
+static constexpr unsigned int DXF_POLYLINE_FLAG_CLOSED = 0x1;
+// Currently unused
+//static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYLINE = 0x8;
+//static constexpr unsigned int DXF_POLYLINE_FLAG_3D_POLYMESH = 0x10;
+static constexpr unsigned int DXF_POLYLINE_FLAG_POLYFACEMESH = 0x40;
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) {
 void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output) {
@@ -638,12 +878,6 @@ void DXFImporter::ParsePolyLine(DXF::LineReader& reader, DXF::FileData& output)
         reader++;
         reader++;
     }
     }
 
 
-    //if (!(line.flags & DXF_POLYLINE_FLAG_POLYFACEMESH))   {
-    //  DefaultLogger::get()->warn((Formatter::format("DXF: polyline not currently supported: "),line.flags));
-    //  output.blocks.back().lines.pop_back();
-    //  return;
-    //}
-
     if (vguess && line.positions.size() != vguess) {
     if (vguess && line.positions.size() != vguess) {
         ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ",
         ASSIMP_LOG_WARN("DXF: unexpected vertex count in polymesh: ",
             line.positions.size(),", expected ", vguess );
             line.positions.size(),", expected ", vguess );
@@ -733,12 +967,18 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
         case 71:
         case 71:
         case 72:
         case 72:
         case 73:
         case 73:
-        case 74:
-            if (cnti == 4) {
-                ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring");
-                break;
+        case 74: {
+                if (cnti == 4) {
+                    ASSIMP_LOG_WARN("DXF: more than 4 indices per face not supported; ignoring");
+                    break;
+                }
+                const int index = reader.ValueAsSignedInt();
+                if (index >= 0) {
+                    indices[cnti++] = static_cast<unsigned int>(index);
+                } else {
+                    indices[cnti++] = static_cast<unsigned int>(-index);
+                }
             }
             }
-            indices[cnti++] = reader.ValueAsUnsignedInt();
             break;
             break;
 
 
         // color
         // color
@@ -776,8 +1016,7 @@ void DXFImporter::ParsePolyLineVertex(DXF::LineReader& reader, DXF::PolyLine& li
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
-{
+void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output) {
     // (note) this is also used for for parsing line entities, so we
     // (note) this is also used for for parsing line entities, so we
     // must handle the vertex_count == 2 case as well.
     // must handle the vertex_count == 2 case as well.
 
 
@@ -794,8 +1033,7 @@ void DXFImporter::Parse3DFace(DXF::LineReader& reader, DXF::FileData& output)
         if (reader.GroupCode() == 0) {
         if (reader.GroupCode() == 0) {
             break;
             break;
         }
         }
-        switch (reader.GroupCode())
-        {
+        switch (reader.GroupCode()) {
 
 
         // 8 specifies the layer
         // 8 specifies the layer
         case 8:
         case 8:

+ 3 - 3
Engine/lib/assimp/code/AssetLib/DXF/DXFLoader.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -68,8 +68,8 @@ namespace DXF {
  */
  */
 class DXFImporter : public BaseImporter {
 class DXFImporter : public BaseImporter {
 public:
 public:
-    DXFImporter();
-    ~DXFImporter() override;
+    DXFImporter() = default;
+    ~DXFImporter() override = default;
 
 
     // -------------------------------------------------------------------
     // -------------------------------------------------------------------
     /** Returns whether the class can handle the format of the given file.
     /** Returns whether the class can handle the format of the given file.

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXAnimation.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 7 - 7
Engine/lib/assimp/code/AssetLib/FBX/FBXBinaryTokenizer.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXUtil.h"
 #include "FBXUtil.h"
 #include <assimp/defs.h>
 #include <assimp/defs.h>
 #include <stdint.h>
 #include <stdint.h>
+#include <cstdint>
 #include <assimp/Exceptional.h>
 #include <assimp/Exceptional.h>
 #include <assimp/ByteSwapper.h>
 #include <assimp/ByteSwapper.h>
 #include <assimp/DefaultLogger.hpp>
 #include <assimp/DefaultLogger.hpp>
@@ -139,6 +140,7 @@ size_t Offset(const char* begin, const char* cursor) {
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
+AI_WONT_RETURN void TokenizeError(const std::string& message, const char* begin, const char* cursor) AI_WONT_RETURN_SUFFIX;
 void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
 void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
     TokenizeError(message, Offset(begin, cursor));
     TokenizeError(message, Offset(begin, cursor));
 }
 }
@@ -341,8 +343,7 @@ void ReadData(const char*& sbegin_out, const char*& send_out, const char* input,
 
 
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, const char* end, bool const is64bits)
-{
+bool ReadScope(TokenList &output_tokens, StackAllocator &token_allocator, const char *input, const char *&cursor, const char *end, bool const is64bits) {
     // the first word contains the offset at which this block ends
     // the first word contains the offset at which this block ends
 	const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
 	const uint64_t end_offset = is64bits ? ReadDoubleWord(input, cursor, end) : ReadWord(input, cursor, end);
 
 
@@ -408,7 +409,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
 
 
         // XXX this is vulnerable to stack overflowing ..
         // XXX this is vulnerable to stack overflowing ..
         while(Offset(input, cursor) < end_offset - sentinel_block_length) {
         while(Offset(input, cursor) < end_offset - sentinel_block_length) {
-			ReadScope(output_tokens, input, cursor, input + end_offset - sentinel_block_length, is64bits);
+            ReadScope(output_tokens, token_allocator, input, cursor, input + end_offset - sentinel_block_length, is64bits);
         }
         }
         output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
         output_tokens.push_back(new_Token(cursor, cursor + 1, TokenType_CLOSE_BRACKET, Offset(input, cursor) ));
 
 
@@ -431,8 +432,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
 // TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
 // TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent
-void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
-{
+void TokenizeBinary(TokenList &output_tokens, const char *input, size_t length, StackAllocator &token_allocator) {
 	ai_assert(input);
 	ai_assert(input);
 	ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
 	ASSIMP_LOG_DEBUG("Tokenizing binary FBX file");
 
 
@@ -465,7 +465,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
     try
     try
     {
     {
         while (cursor < end ) {
         while (cursor < end ) {
-		    if (!ReadScope(output_tokens, input, cursor, input + length, is64bits)) {
+            if (!ReadScope(output_tokens, token_allocator, input, cursor, input + length, is64bits)) {
                 break;
                 break;
             }
             }
         }
         }

+ 2 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXCommon.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -55,6 +55,7 @@ const char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 nul
     '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
     '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
     '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
     '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
 }; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
 }; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
+static std::string NULL_RECORD_STRING(NumNullRecords, '\0');
 const std::string SEPARATOR = { '\x00', '\x01' }; // for use inside strings
 const std::string SEPARATOR = { '\x00', '\x01' }; // for use inside strings
 const std::string MAGIC_NODE_TAG = "_$AssimpFbx$"; // from import
 const std::string MAGIC_NODE_TAG = "_$AssimpFbx$"; // from import
 const int64_t SECOND = 46186158000; // FBX's kTime unit
 const int64_t SECOND = 46186158000; // FBX's kTime unit

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXCompileConfig.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 142 - 57
Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -55,9 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 #include <assimp/MathFunctions.h>
 #include <assimp/MathFunctions.h>
 #include <assimp/StringComparison.h>
 #include <assimp/StringComparison.h>
-
 #include <assimp/scene.h>
 #include <assimp/scene.h>
-
 #include <assimp/CreateAnimMesh.h>
 #include <assimp/CreateAnimMesh.h>
 #include <assimp/StringUtils.h>
 #include <assimp/StringUtils.h>
 #include <assimp/commonMetaData.h>
 #include <assimp/commonMetaData.h>
@@ -78,6 +76,53 @@ using namespace Util;
 
 
 #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
 #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000LL
 
 
+static void correctRootTransform(const aiScene *scene) {
+    if (scene == nullptr) {
+        return;
+    }
+
+    if (scene->mMetaData == nullptr) {
+        return;
+    }
+
+    int32_t UpAxis = 1, UpAxisSign = 1, FrontAxis = 2, FrontAxisSign = 1, CoordAxis = 0, CoordAxisSign = 1;
+    double UnitScaleFactor = 1.0;
+    for (unsigned MetadataIndex = 0; MetadataIndex < scene->mMetaData->mNumProperties; ++MetadataIndex) {
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "UpAxis") == 0) {
+            scene->mMetaData->Get<int32_t>(MetadataIndex, UpAxis);
+        }
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "UpAxisSign") == 0) {
+            scene->mMetaData->Get<int32_t>(MetadataIndex, UpAxisSign);
+        }
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "FrontAxis") == 0) {
+            scene->mMetaData->Get<int32_t>(MetadataIndex, FrontAxis);
+        }
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "FrontAxisSign") == 0) {
+            scene->mMetaData->Get<int32_t>(MetadataIndex, FrontAxisSign);
+        }
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "CoordAxis") == 0) {
+            scene->mMetaData->Get<int32_t>(MetadataIndex, CoordAxis);
+        }
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "CoordAxisSign") == 0) {
+            scene->mMetaData->Get<int32_t>(MetadataIndex, CoordAxisSign);
+        }
+        if (strcmp(scene->mMetaData->mKeys[MetadataIndex].C_Str(), "UnitScaleFactor") == 0) {
+            scene->mMetaData->Get<double>(MetadataIndex, UnitScaleFactor);
+        }
+    }
+
+    aiVector3D upVec, forwardVec, rightVec;
+    upVec[UpAxis] = UpAxisSign * static_cast<float>(UnitScaleFactor);
+    forwardVec[FrontAxis] = FrontAxisSign * static_cast<float>(UnitScaleFactor);
+    rightVec[CoordAxis] = CoordAxisSign * (float)UnitScaleFactor;
+
+    aiMatrix4x4 mat(rightVec.x, rightVec.y, rightVec.z, 0.0f,
+                    upVec.x, upVec.y, upVec.z, 0.0f,
+                    forwardVec.x, forwardVec.y, forwardVec.z, 0.0f,
+                    0.0f, 0.0f, 0.0f, 1.0f);
+    scene->mRootNode->mTransformation *= mat;
+}
+
 FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) :
 FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) :
         defaultMaterialIndex(),
         defaultMaterialIndex(),
         mMeshes(),
         mMeshes(),
@@ -93,6 +138,8 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
         mSceneOut(out),
         mSceneOut(out),
         doc(doc),
         doc(doc),
         mRemoveEmptyBones(removeEmptyBones) {
         mRemoveEmptyBones(removeEmptyBones) {
+
+
     // animations need to be converted first since this will
     // animations need to be converted first since this will
     // populate the node_anim_chain_bits map, which is needed
     // populate the node_anim_chain_bits map, which is needed
     // to determine which nodes need to be generated.
     // to determine which nodes need to be generated.
@@ -119,7 +166,7 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
             if (mat) {
             if (mat) {
 
 
                 if (materials_converted.find(mat) == materials_converted.end()) {
                 if (materials_converted.find(mat) == materials_converted.end()) {
-                    ConvertMaterial(*mat, 0);
+                    ConvertMaterial(*mat, nullptr);
                 }
                 }
             }
             }
         }
         }
@@ -133,6 +180,10 @@ FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBo
     // need not contain geometry (i.e. camera animations, raw armatures).
     // need not contain geometry (i.e. camera animations, raw armatures).
     if (out->mNumMeshes == 0) {
     if (out->mNumMeshes == 0) {
         out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
         out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
+    } else {
+        // Apply the FBX axis metadata unless requested not to
+        if (!doc.Settings().ignoreUpDirection)
+            correctRootTransform(mSceneOut);
     }
     }
 }
 }
 
 
@@ -196,7 +247,7 @@ struct FBXConverter::PotentialNode {
 /// todo: get bone from stack
 /// todo: get bone from stack
 /// todo: make map of aiBone* to aiNode*
 /// todo: make map of aiBone* to aiNode*
 /// then update convert clusters to the new format
 /// then update convert clusters to the new format
-void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node) {
+void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4& parent_transform) {
     const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
     const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(id, "Model");
 
 
     std::vector<PotentialNode> nodes;
     std::vector<PotentialNode> nodes;
@@ -227,7 +278,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
         if (nullptr != model) {
         if (nullptr != model) {
             nodes_chain.clear();
             nodes_chain.clear();
             post_nodes_chain.clear();
             post_nodes_chain.clear();
-            aiMatrix4x4 new_abs_transform = parent->mTransformation;
+            aiMatrix4x4 new_abs_transform = parent_transform;
             std::string node_name = FixNodeName(model->Name());
             std::string node_name = FixNodeName(model->Name());
             // even though there is only a single input node, the design of
             // even though there is only a single input node, the design of
             // assimp (or rather: the complicated transformation chain that
             // assimp (or rather: the complicated transformation chain that
@@ -261,6 +312,8 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
 
 
                 child->mParent = last_parent;
                 child->mParent = last_parent;
                 last_parent = child.mNode;
                 last_parent = child.mNode;
+
+                new_abs_transform *= child->mTransformation;
             }
             }
 
 
             // attach geometry
             // attach geometry
@@ -283,6 +336,8 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
 
 
                     postnode->mParent = last_parent;
                     postnode->mParent = last_parent;
                     last_parent = postnode.mNode;
                     last_parent = postnode.mNode;
+
+                    new_abs_transform *= postnode->mTransformation;
                 }
                 }
             } else {
             } else {
                 // free the nodes we allocated as we don't need them
                 // free the nodes we allocated as we don't need them
@@ -290,7 +345,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
             }
             }
 
 
             // recursion call - child nodes
             // recursion call - child nodes
-            ConvertNodes(model->ID(), last_parent, root_node);
+            ConvertNodes(model->ID(), last_parent, root_node, new_abs_transform);
 
 
             if (doc.Settings().readLights) {
             if (doc.Settings().readLights) {
                 ConvertLights(*model, node_name);
                 ConvertLights(*model, node_name);
@@ -305,18 +360,15 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
         }
         }
     }
     }
 
 
-    if (nodes.size()) {
+    if (nodes.empty()) {
+        parent->mNumChildren = 0;
+        parent->mChildren = nullptr;
+    } else {
         parent->mChildren = new aiNode *[nodes.size()]();
         parent->mChildren = new aiNode *[nodes.size()]();
         parent->mNumChildren = static_cast<unsigned int>(nodes.size());
         parent->mNumChildren = static_cast<unsigned int>(nodes.size());
-
-        for (unsigned int i = 0; i < nodes.size(); ++i)
-        {
+        for (unsigned int i = 0; i < nodes.size(); ++i) {
             parent->mChildren[i] = nodes[i].mOwnership.release();
             parent->mChildren[i] = nodes[i].mOwnership.release();
         }
         }
-        nodes.clear();
-    } else {
-        parent->mNumChildren = 0;
-        parent->mChildren = nullptr;
     }
     }
 }
 }
 
 
@@ -424,16 +476,32 @@ void FBXConverter::ConvertCamera(const Camera &cam, const std::string &orig_name
 
 
     out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
     out_camera->mAspect = cam.AspectWidth() / cam.AspectHeight();
 
 
+    // NOTE: Camera mPosition, mLookAt and mUp must be set to default here.
+    // All transformations to the camera will be handled by its node in the scenegraph.
     out_camera->mPosition = aiVector3D(0.0f);
     out_camera->mPosition = aiVector3D(0.0f);
     out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
     out_camera->mLookAt = aiVector3D(1.0f, 0.0f, 0.0f);
     out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
     out_camera->mUp = aiVector3D(0.0f, 1.0f, 0.0f);
 
 
-    out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
-
-    out_camera->mClipPlaneNear = cam.NearPlane();
-    out_camera->mClipPlaneFar = cam.FarPlane();
+    // NOTE: Some software (maya) does not put FieldOfView in FBX, so we compute
+    // mHorizontalFOV from FocalLength and FilmWidth with unit conversion.
+
+    // TODO: This is not a complete solution for how FBX cameras can be stored.
+    // TODO: Incorporate non-square pixel aspect ratio.
+    // TODO: FBX aperture mode might be storing vertical FOV in need of conversion with aspect ratio.
+
+    float fov_deg = cam.FieldOfView();
+    // If FOV not specified in file, compute using FilmWidth and FocalLength.
+    if (fov_deg == kFovUnknown) {
+        float film_width_inches = cam.FilmWidth();
+        float focal_length_mm = cam.FocalLength();
+        ASSIMP_LOG_VERBOSE_DEBUG("FBX FOV unspecified. Computing from FilmWidth (", film_width_inches, "inches) and FocalLength (", focal_length_mm, "mm).");
+        double half_fov_rad = std::atan2(film_width_inches * 25.4 * 0.5, focal_length_mm);
+        out_camera->mHorizontalFOV = static_cast<float>(half_fov_rad);
+    } else {
+        // FBX fov is full-view degrees. We want half-view radians.
+        out_camera->mHorizontalFOV = AI_DEG_TO_RAD(fov_deg) * 0.5f;
+    }
 
 
-    out_camera->mHorizontalFOV = AI_DEG_TO_RAD(cam.FieldOfView());
     out_camera->mClipPlaneNear = cam.NearPlane();
     out_camera->mClipPlaneNear = cam.NearPlane();
     out_camera->mClipPlaneFar = cam.FarPlane();
     out_camera->mClipPlaneFar = cam.FarPlane();
 }
 }
@@ -562,16 +630,17 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
     bool is_id[3] = { true, true, true };
     bool is_id[3] = { true, true, true };
 
 
     aiMatrix4x4 temp[3];
     aiMatrix4x4 temp[3];
-    if (std::fabs(rotation.z) > angle_epsilon) {
-        aiMatrix4x4::RotationZ(AI_DEG_TO_RAD(rotation.z), temp[2]);
+    const auto rot = AI_DEG_TO_RAD(rotation);
+    if (std::fabs(rot.z) > angle_epsilon) {
+        aiMatrix4x4::RotationZ(rot.z, temp[2]);
         is_id[2] = false;
         is_id[2] = false;
     }
     }
-    if (std::fabs(rotation.y) > angle_epsilon) {
-        aiMatrix4x4::RotationY(AI_DEG_TO_RAD(rotation.y), temp[1]);
+    if (std::fabs(rot.y) > angle_epsilon) {
+        aiMatrix4x4::RotationY(rot.y, temp[1]);
         is_id[1] = false;
         is_id[1] = false;
     }
     }
-    if (std::fabs(rotation.x) > angle_epsilon) {
-        aiMatrix4x4::RotationX(AI_DEG_TO_RAD(rotation.x), temp[0]);
+    if (std::fabs(rot.x) > angle_epsilon) {
+        aiMatrix4x4::RotationX(rot.x, temp[0]);
         is_id[0] = false;
         is_id[0] = false;
     }
     }
 
 
@@ -643,13 +712,12 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
 bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
 bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
     const PropertyTable &props = model.Props();
     const PropertyTable &props = model.Props();
 
 
-    const auto zero_epsilon = ai_epsilon;
+    const auto zero_epsilon = Math::getEpsilon<ai_real>();
     const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
     const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
     for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
     for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
         const TransformationComp comp = static_cast<TransformationComp>(i);
         const TransformationComp comp = static_cast<TransformationComp>(i);
 
 
-        if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation ||
-            comp == TransformationComp_PreRotation || comp == TransformationComp_PostRotation) {
+        if (comp == TransformationComp_Rotation || comp == TransformationComp_Scaling || comp == TransformationComp_Translation) {
             continue;
             continue;
         }
         }
 
 
@@ -876,8 +944,12 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
             data->Set(index++, prop.first, interpretedBool->Value());
             data->Set(index++, prop.first, interpretedBool->Value());
         } else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
         } else if (const TypedProperty<int> *interpretedInt = prop.second->As<TypedProperty<int>>()) {
             data->Set(index++, prop.first, interpretedInt->Value());
             data->Set(index++, prop.first, interpretedInt->Value());
+        } else if (const TypedProperty<uint32_t> *interpretedUInt = prop.second->As<TypedProperty<uint32_t>>()) {
+            data->Set(index++, prop.first, interpretedUInt->Value());
         } else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
         } else if (const TypedProperty<uint64_t> *interpretedUint64 = prop.second->As<TypedProperty<uint64_t>>()) {
             data->Set(index++, prop.first, interpretedUint64->Value());
             data->Set(index++, prop.first, interpretedUint64->Value());
+        } else if (const TypedProperty<int64_t> *interpretedint64 = prop.second->As<TypedProperty<int64_t>>()) {
+            data->Set(index++, prop.first, interpretedint64->Value());
         } else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
         } else if (const TypedProperty<float> *interpretedFloat = prop.second->As<TypedProperty<float>>()) {
             data->Set(index++, prop.first, interpretedFloat->Value());
             data->Set(index++, prop.first, interpretedFloat->Value());
         } else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
         } else if (const TypedProperty<std::string> *interpretedString = prop.second->As<TypedProperty<std::string>>()) {
@@ -1179,19 +1251,27 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
     std::vector<aiAnimMesh *> animMeshes;
     std::vector<aiAnimMesh *> animMeshes;
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
-            const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
-            for (size_t i = 0; i < shapeGeometries.size(); i++) {
-                aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
-                const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
-                const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
-                const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
-                const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
+            const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+            for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
+                const auto &curNormals = shapeGeometry->GetNormals();
+                aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh, true, !curNormals.empty());
+                const auto &curVertices = shapeGeometry->GetVertices();
+                const auto &curIndices = shapeGeometry->GetIndices();
                 //losing channel name if using shapeGeometry->Name()
                 //losing channel name if using shapeGeometry->Name()
-                animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
+                // if blendShapeChannel Name is empty or doesn't have a ".", add geoMetryName;
+                auto aniName = FixAnimMeshName(blendShapeChannel->Name());
+                auto geoMetryName = FixAnimMeshName(shapeGeometry->Name());
+                if (aniName.empty()) {
+                    aniName = geoMetryName;
+                }
+                else if (aniName.find('.') == aniName.npos) {
+                    aniName += "." + geoMetryName;
+                }
+                animMesh->mName.Set(aniName);
                 for (size_t j = 0; j < curIndices.size(); j++) {
                 for (size_t j = 0; j < curIndices.size(); j++) {
                     const unsigned int curIndex = curIndices.at(j);
                     const unsigned int curIndex = curIndices.at(j);
                     aiVector3D vertex = curVertices.at(j);
                     aiVector3D vertex = curVertices.at(j);
-                    aiVector3D normal = curNormals.at(j);
+                    aiVector3D normal = curNormals.empty() ? aiVector3D() : curNormals.at(j);
                     unsigned int count = 0;
                     unsigned int count = 0;
                     const unsigned int *outIndices = mesh.ToOutputVertexIndex(curIndex, count);
                     const unsigned int *outIndices = mesh.ToOutputVertexIndex(curIndex, count);
                     for (unsigned int k = 0; k < count; k++) {
                     for (unsigned int k = 0; k < count; k++) {
@@ -1409,18 +1489,17 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
     std::vector<aiAnimMesh *> animMeshes;
     std::vector<aiAnimMesh *> animMeshes;
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
     for (const BlendShape *blendShape : mesh.GetBlendShapes()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
         for (const BlendShapeChannel *blendShapeChannel : blendShape->BlendShapeChannels()) {
-            const std::vector<const ShapeGeometry *> &shapeGeometries = blendShapeChannel->GetShapeGeometries();
-            for (size_t i = 0; i < shapeGeometries.size(); i++) {
-                aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh);
-                const ShapeGeometry *shapeGeometry = shapeGeometries.at(i);
-                const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
-                const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
-                const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
+            const auto& shapeGeometries = blendShapeChannel->GetShapeGeometries();
+            for (const ShapeGeometry *shapeGeometry : shapeGeometries) {
+                const auto& curNormals = shapeGeometry->GetNormals();
+                aiAnimMesh *animMesh = aiCreateAnimMesh(out_mesh, true, !curNormals.empty());
+                const auto& curVertices = shapeGeometry->GetVertices();
+                const auto& curIndices = shapeGeometry->GetIndices();
                 animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
                 animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
                 for (size_t j = 0; j < curIndices.size(); j++) {
                 for (size_t j = 0; j < curIndices.size(); j++) {
                     unsigned int curIndex = curIndices.at(j);
                     unsigned int curIndex = curIndices.at(j);
                     aiVector3D vertex = curVertices.at(j);
                     aiVector3D vertex = curVertices.at(j);
-                    aiVector3D normal = curNormals.at(j);
+                    aiVector3D normal = curNormals.empty() ? aiVector3D() : curNormals.at(j);
                     unsigned int count = 0;
                     unsigned int count = 0;
                     const unsigned int *outIndices = mesh.ToOutputVertexIndex(curIndex, count);
                     const unsigned int *outIndices = mesh.ToOutputVertexIndex(curIndex, count);
                     for (unsigned int k = 0; k < count; k++) {
                     for (unsigned int k = 0; k < count; k++) {
@@ -1458,7 +1537,9 @@ static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *s
     skeletonBone->mWeights = bone->mWeights;
     skeletonBone->mWeights = bone->mWeights;
     skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
     skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
     skeletonBone->mMeshId = mesh;
     skeletonBone->mMeshId = mesh;
+#ifndef ASSIMP_BUILD_NO_ARMATUREPOPULATE_PROCESS
     skeletonBone->mNode = bone->mNode;
     skeletonBone->mNode = bone->mNode;
+#endif
     skeletonBone->mParent = -1;
     skeletonBone->mParent = -1;
 }
 }
 
 
@@ -1566,7 +1647,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
         out->mBones = nullptr;
         out->mBones = nullptr;
         out->mNumBones = 0;
         out->mNumBones = 0;
         return;
         return;
-    } 
+    }
 
 
     out->mBones = new aiBone *[bones.size()]();
     out->mBones = new aiBone *[bones.size()]();
     out->mNumBones = static_cast<unsigned int>(bones.size());
     out->mNumBones = static_cast<unsigned int>(bones.size());
@@ -1575,7 +1656,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const ai
 
 
 void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
 void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
         std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
         std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
-        std::vector<size_t> &count_out_indices, const aiMatrix4x4 & /* absolute_transform*/,
+        std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform,
         aiNode *) {
         aiNode *) {
     ai_assert(cluster != nullptr); // make sure cluster valid
     ai_assert(cluster != nullptr); // make sure cluster valid
 
 
@@ -1592,16 +1673,16 @@ void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const
         bone = new aiBone();
         bone = new aiBone();
         bone->mName = bone_name;
         bone->mName = bone_name;
 
 
-        bone->mOffsetMatrix = cluster->Transform();
+        //bone->mOffsetMatrix = cluster->Transform();
         // store local transform link for post processing
         // store local transform link for post processing
-        /*
+
         bone->mOffsetMatrix = cluster->TransformLink();
         bone->mOffsetMatrix = cluster->TransformLink();
         bone->mOffsetMatrix.Inverse();
         bone->mOffsetMatrix.Inverse();
 
 
-        aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
+        const aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
 
 
         bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
         bone->mOffsetMatrix = bone->mOffsetMatrix * matrix; // * mesh_offset
-        */
+
         //
         //
         // Now calculate the aiVertexWeights
         // Now calculate the aiVertexWeights
         //
         //
@@ -1784,7 +1865,7 @@ aiString FBXConverter::GetTexturePath(const Texture *tex) {
                 // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
                 // We need to load all textures before referencing them, as FBX file format order may reference a texture before loading it
                 // This may occur on this case too, it has to be studied
                 // This may occur on this case too, it has to be studied
                 path.data[0] = '*';
                 path.data[0] = '*';
-                path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
+                path.length = 1 + ASSIMP_itoa10(path.data + 1, AI_MAXLEN - 1, index);
             }
             }
         }
         }
     }
     }
@@ -2052,6 +2133,10 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_
     TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
     TrySetTextureProperties(out_mat, _textures, "Maya|emissionColor", aiTextureType_EMISSION_COLOR, mesh);
     TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
     TrySetTextureProperties(out_mat, _textures, "Maya|metalness", aiTextureType_METALNESS, mesh);
     TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
     TrySetTextureProperties(out_mat, _textures, "Maya|diffuseRoughness", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+    TrySetTextureProperties(out_mat, _textures, "Maya|base", aiTextureType_MAYA_BASE, mesh);
+    TrySetTextureProperties(out_mat, _textures, "Maya|specular", aiTextureType_MAYA_SPECULAR, mesh);
+    TrySetTextureProperties(out_mat, _textures, "Maya|specularColor", aiTextureType_MAYA_SPECULAR_COLOR, mesh);
+    TrySetTextureProperties(out_mat, _textures, "Maya|specularRoughness", aiTextureType_MAYA_SPECULAR_ROUGHNESS, mesh);
 
 
     // Maya stingray
     // Maya stingray
     TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
     TrySetTextureProperties(out_mat, _textures, "Maya|TEX_color_map", aiTextureType_BASE_COLOR, mesh);
@@ -2364,7 +2449,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
 
 
                 // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
                 // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
                 path.data[0] = '*';
                 path.data[0] = '*';
-                path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
+                path.length = 1 + ASSIMP_itoa10(path.data + 1, AI_MAXLEN - 1, index);
             }
             }
 
 
             out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0);
             out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0);
@@ -2730,7 +2815,7 @@ void FBXConverter::ProcessMorphAnimDatas(std::map<std::string, morphAnimData *>
                                 auto geoIt = std::find(model->GetGeometry().begin(), model->GetGeometry().end(), geo);
                                 auto geoIt = std::find(model->GetGeometry().begin(), model->GetGeometry().end(), geo);
                                 auto geoIndex = static_cast<unsigned int>(std::distance(model->GetGeometry().begin(), geoIt));
                                 auto geoIndex = static_cast<unsigned int>(std::distance(model->GetGeometry().begin(), geoIt));
                                 auto name = aiString(FixNodeName(model->Name() + "*"));
                                 auto name = aiString(FixNodeName(model->Name() + "*"));
-                                name.length = 1 + ASSIMP_itoa10(name.data + name.length, MAXLEN - 1, geoIndex);
+                                name.length = 1 + ASSIMP_itoa10(name.data + name.length, AI_MAXLEN - 1, geoIndex);
                                 morphAnimData *animData;
                                 morphAnimData *animData;
                                 auto animIt = morphAnimDatas->find(name.C_Str());
                                 auto animIt = morphAnimDatas->find(name.C_Str());
                                 if (animIt == morphAnimDatas->end()) {
                                 if (animIt == morphAnimDatas->end()) {
@@ -3197,7 +3282,6 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
     aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
     aiVector3D defTranslate = PropertyGet(props, "Lcl Translation", aiVector3D(0.f, 0.f, 0.f));
     aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
     aiVector3D defRotation = PropertyGet(props, "Lcl Rotation", aiVector3D(0.f, 0.f, 0.f));
     aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
     aiVector3D defScale = PropertyGet(props, "Lcl Scaling", aiVector3D(1.f, 1.f, 1.f));
-    aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
 
 
     aiVectorKey* outTranslations = new aiVectorKey[keyCount];
     aiVectorKey* outTranslations = new aiVectorKey[keyCount];
     aiQuatKey* outRotations = new aiQuatKey[keyCount];
     aiQuatKey* outRotations = new aiQuatKey[keyCount];
@@ -3215,6 +3299,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
     if (keyframeLists[TransformationComp_Rotation].size() > 0) {
     if (keyframeLists[TransformationComp_Rotation].size() > 0) {
         InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
         InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder);
     } else {
     } else {
+        aiQuaternion defQuat = EulerToQuaternion(defRotation, rotOrder);
         for (size_t i = 0; i < keyCount; ++i) {
         for (size_t i = 0; i < keyCount; ++i) {
             outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
             outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps;
             outRotations[i].mValue = defQuat;
             outRotations[i].mValue = defQuat;
@@ -3231,7 +3316,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
     }
     }
 
 
     bool ok = false;
     bool ok = false;
-    
+
     const auto zero_epsilon = ai_epsilon;
     const auto zero_epsilon = ai_epsilon;
 
 
     const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
     const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);

+ 2 - 2
Engine/lib/assimp/code/AssetLib/FBX/FBXConverter.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.
@@ -134,7 +134,7 @@ private:
 
 
     // ------------------------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------------------------
     // collect and assign child nodes
     // collect and assign child nodes
-    void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node);
+    void ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node, const aiMatrix4x4& parent_transform = aiMatrix4x4());
 
 
     // ------------------------------------------------------------------------------------------------
     // ------------------------------------------------------------------------------------------------
     void ConvertLights(const Model& model, const std::string &orig_name );
     void ConvertLights(const Model& model, const std::string &orig_name );

+ 10 - 6
Engine/lib/assimp/code/AssetLib/FBX/FBXDeformer.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -84,7 +84,7 @@ Cluster::Cluster(uint64_t id, const Element& element, const Document& doc, const
     transform = ReadMatrix(Transform);
     transform = ReadMatrix(Transform);
     transformLink = ReadMatrix(TransformLink);
     transformLink = ReadMatrix(TransformLink);
 
 
-    // it is actually possible that there be Deformer's with no weights
+    // it is actually possible that there are Deformer's with no weights
     if (!!Indexes != !!Weights) {
     if (!!Indexes != !!Weights) {
         DOMError("either Indexes or Weights are missing from Cluster",&element);
         DOMError("either Indexes or Weights are missing from Cluster",&element);
     }
     }
@@ -154,8 +154,10 @@ BlendShape::BlendShape(uint64_t id, const Element& element, const Document& doc,
     for (const Connection* con : conns) {
     for (const Connection* con : conns) {
         const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
         const BlendShapeChannel* const bspc = ProcessSimpleConnection<BlendShapeChannel>(*con, false, "BlendShapeChannel -> BlendShape", element);
         if (bspc) {
         if (bspc) {
-            blendShapeChannels.push_back(bspc);
-            continue;
+            auto pr = blendShapeChannels.insert(bspc);
+            if (!pr.second) {
+                FBXImporter::LogWarn("there is the same blendShapeChannel id ", bspc->ID());
+            }
         }
         }
     }
     }
 }
 }
@@ -179,8 +181,10 @@ BlendShapeChannel::BlendShapeChannel(uint64_t id, const Element& element, const
     for (const Connection* con : conns) {
     for (const Connection* con : conns) {
         const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
         const ShapeGeometry* const sg = ProcessSimpleConnection<ShapeGeometry>(*con, false, "Shape -> BlendShapeChannel", element);
         if (sg) {
         if (sg) {
-            shapeGeometries.push_back(sg);
-            continue;
+            auto pr = shapeGeometries.insert(sg);
+            if (!pr.second) {
+                FBXImporter::LogWarn("there is the same shapeGeometrie id ", sg->ID());
+            }
         }
         }
     }
     }
 }
 }

+ 34 - 16
Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -78,7 +78,7 @@ const Object* LazyObject::Get(bool dieOnError) {
         return nullptr;
         return nullptr;
     }
     }
 
 
-    if (object.get()) {
+    if (object) {
         return object.get();
         return object.get();
     }
     }
 
 
@@ -199,6 +199,14 @@ const Object* LazyObject::Get(bool dieOnError) {
             object.reset(new AnimationCurveNode(id,element,name,doc));
             object.reset(new AnimationCurveNode(id,element,name,doc));
         }
         }
     }
     }
+    catch (std::bad_alloc&) {
+        // out-of-memory is unrecoverable and should always lead to a failure
+
+        flags &= ~BEING_CONSTRUCTED;
+        flags |= FAILED_TO_CONSTRUCT;
+
+        throw;
+    }
     catch(std::exception& ex) {
     catch(std::exception& ex) {
         flags &= ~BEING_CONSTRUCTED;
         flags &= ~BEING_CONSTRUCTED;
         flags |= FAILED_TO_CONSTRUCT;
         flags |= FAILED_TO_CONSTRUCT;
@@ -214,7 +222,7 @@ const Object* LazyObject::Get(bool dieOnError) {
         return nullptr;
         return nullptr;
     }
     }
 
 
-    if (!object.get()) {
+    if (!object) {
         //DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element);
         //DOMError("failed to convert element to DOM object, class: " + classtag + ", name: " + name,&element);
     }
     }
 
 
@@ -235,7 +243,7 @@ FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<cons
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-Document::Document(const Parser& parser, const ImportSettings& settings) :
+Document::Document(Parser& parser, const ImportSettings& settings) :
      settings(settings), parser(parser) {
      settings(settings), parser(parser) {
 	ASSIMP_LOG_DEBUG("Creating FBX Document");
 	ASSIMP_LOG_DEBUG("Creating FBX Document");
 
 
@@ -257,13 +265,17 @@ Document::Document(const Parser& parser, const ImportSettings& settings) :
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-Document::~Document() {
-    for(ObjectMap::value_type& v : objects) {
-        delete v.second;
+Document::~Document()
+{
+	// The document does not own the memory for the following objects, but we need to call their d'tor
+	// so they can properly free memory like string members:
+	
+    for (ObjectMap::value_type &v : objects) {
+        delete_LazyObject(v.second);
     }
     }
 
 
-    for(ConnectionMap::value_type& v : src_connections) {
-        delete v.second;
+    for (ConnectionMap::value_type &v : src_connections) {
+        delete_Connection(v.second);
     }
     }
     // |dest_connections| contain the same Connection objects as the |src_connections|
     // |dest_connections| contain the same Connection objects as the |src_connections|
 }
 }
@@ -336,7 +348,7 @@ void Document::ReadGlobalSettings() {
         DOMError("GlobalSettings dictionary contains no property table");
         DOMError("GlobalSettings dictionary contains no property table");
     }
     }
 
 
-    globals.reset(new FileGlobalSettings(*this, props));
+    globals.reset(new FileGlobalSettings(*this, std::move(props)));
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
@@ -348,9 +360,11 @@ void Document::ReadObjects() {
         DOMError("no Objects dictionary found");
         DOMError("no Objects dictionary found");
     }
     }
 
 
+    StackAllocator &allocator = parser.GetAllocator();
+
     // add a dummy entry to represent the Model::RootNode object (id 0),
     // add a dummy entry to represent the Model::RootNode object (id 0),
     // which is only indirectly defined in the input file
     // which is only indirectly defined in the input file
-    objects[0] = new LazyObject(0L, *eobjects, *this);
+    objects[0] = new_LazyObject(0L, *eobjects, *this);
 
 
     const Scope& sobjects = *eobjects->Compound();
     const Scope& sobjects = *eobjects->Compound();
     for(const ElementMap::value_type& el : sobjects.Elements()) {
     for(const ElementMap::value_type& el : sobjects.Elements()) {
@@ -373,11 +387,13 @@ void Document::ReadObjects() {
             DOMError("encountered object with implicitly defined id 0",el.second);
             DOMError("encountered object with implicitly defined id 0",el.second);
         }
         }
 
 
-        if(objects.find(id) != objects.end()) {
+        const auto foundObject = objects.find(id);
+        if(foundObject != objects.end()) {
             DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
             DOMWarning("encountered duplicate object id, ignoring first occurrence",el.second);
+            delete_LazyObject(foundObject->second);
         }
         }
 
 
-        objects[id] = new LazyObject(id, *el.second, *this);
+        objects[id] = new_LazyObject(id, *el.second, *this);
 
 
         // grab all animation stacks upfront since there is no listing of them
         // grab all animation stacks upfront since there is no listing of them
         if(!strcmp(el.first.c_str(),"AnimationStack")) {
         if(!strcmp(el.first.c_str(),"AnimationStack")) {
@@ -444,8 +460,10 @@ void Document::ReadPropertyTemplates() {
 }
 }
 
 
 // ------------------------------------------------------------------------------------------------
 // ------------------------------------------------------------------------------------------------
-void Document::ReadConnections() {
-    const Scope& sc = parser.GetRootScope();
+void Document::ReadConnections()
+{
+    StackAllocator &allocator = parser.GetAllocator();
+    const Scope &sc = parser.GetRootScope();
     // read property templates from "Definitions" section
     // read property templates from "Definitions" section
     const Element* const econns = sc["Connections"];
     const Element* const econns = sc["Connections"];
     if(!econns || !econns->Compound()) {
     if(!econns || !econns->Compound()) {
@@ -484,7 +502,7 @@ void Document::ReadConnections() {
         }
         }
 
 
         // add new connection
         // add new connection
-        const Connection* const c = new Connection(insertionOrder++,src,dest,prop,*this);
+        const Connection* const c = new_Connection(insertionOrder++,src,dest,prop,*this);
         src_connections.insert(ConnectionMap::value_type(src,c));
         src_connections.insert(ConnectionMap::value_type(src,c));
         dest_connections.insert(ConnectionMap::value_type(dest,c));
         dest_connections.insert(ConnectionMap::value_type(dest,c));
     }
     }

+ 30 - 20
Engine/lib/assimp/code/AssetLib/FBX/FBXDocument.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define INCLUDED_AI_FBX_DOCUMENT_H
 #define INCLUDED_AI_FBX_DOCUMENT_H
 
 
 #include <numeric>
 #include <numeric>
+#include <unordered_set>
 #include <stdint.h>
 #include <stdint.h>
 #include <assimp/mesh.h>
 #include <assimp/mesh.h>
 #include "FBXProperties.h"
 #include "FBXProperties.h"
@@ -54,9 +55,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define _AI_CONCAT(a,b)  a ## b
 #define _AI_CONCAT(a,b)  a ## b
 #define  AI_CONCAT(a,b)  _AI_CONCAT(a,b)
 #define  AI_CONCAT(a,b)  _AI_CONCAT(a,b)
 
 
+
 namespace Assimp {
 namespace Assimp {
 namespace FBX {
 namespace FBX {
 
 
+// Use an 'illegal' default FOV value to detect if the FBX camera has set the FOV.
+static const float kFovUnknown = -1.0f;
+
+
 class Parser;
 class Parser;
 class Object;
 class Object;
 struct ImportSettings;
 struct ImportSettings;
@@ -80,6 +86,10 @@ class BlendShape;
 class Skin;
 class Skin;
 class Cluster;
 class Cluster;
 
 
+#define new_LazyObject new (allocator.Allocate(sizeof(LazyObject))) LazyObject
+#define new_Connection new (allocator.Allocate(sizeof(Connection))) Connection
+#define delete_LazyObject(_p) (_p)->~LazyObject()
+#define delete_Connection(_p) (_p)->~Connection()
 
 
 /** Represents a delay-parsed FBX objects. Many objects in the scene
 /** Represents a delay-parsed FBX objects. Many objects in the scene
  *  are not needed by assimp, so it makes no sense to parse them
  *  are not needed by assimp, so it makes no sense to parse them
@@ -168,7 +178,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
 private:
 private:
@@ -242,7 +252,7 @@ public:
     fbx_simple_property(FilmAspectRatio, float, 1.0f)
     fbx_simple_property(FilmAspectRatio, float, 1.0f)
     fbx_simple_property(ApertureMode, int, 0)
     fbx_simple_property(ApertureMode, int, 0)
 
 
-    fbx_simple_property(FieldOfView, float, 1.0f)
+    fbx_simple_property(FieldOfView, float, kFovUnknown)
     fbx_simple_property(FocalLength, float, 1.0f)
     fbx_simple_property(FocalLength, float, 1.0f)
 };
 };
 
 
@@ -432,7 +442,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     /** Get material links */
     /** Get material links */
@@ -503,7 +513,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     // return a 4-tuple
     // return a 4-tuple
@@ -618,7 +628,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     const uint8_t* Content() const {
     const uint8_t* Content() const {
@@ -632,7 +642,7 @@ public:
 
 
     uint8_t* RelinquishContent() {
     uint8_t* RelinquishContent() {
         uint8_t* ptr = content;
         uint8_t* ptr = content;
-        content = 0;
+        content = nullptr;
         return ptr;
         return ptr;
     }
     }
 
 
@@ -663,7 +673,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     const TextureMap& Textures() const {
     const TextureMap& Textures() const {
@@ -735,7 +745,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
 
 
@@ -780,7 +790,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     /* the optional white list specifies a list of property names for which the caller
     /* the optional white list specifies a list of property names for which the caller
@@ -808,7 +818,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     const AnimationLayerList& Layers() const {
     const AnimationLayerList& Layers() const {
@@ -829,7 +839,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
 private:
 private:
@@ -855,14 +865,14 @@ public:
         return fullWeights;
         return fullWeights;
     }
     }
 
 
-    const std::vector<const ShapeGeometry*>& GetShapeGeometries() const {
+    const std::unordered_set<const ShapeGeometry*>& GetShapeGeometries() const {
         return shapeGeometries;
         return shapeGeometries;
     }
     }
 
 
 private:
 private:
     float percent;
     float percent;
     WeightArray fullWeights;
     WeightArray fullWeights;
-    std::vector<const ShapeGeometry*> shapeGeometries;
+    std::unordered_set<const ShapeGeometry*> shapeGeometries;
 };
 };
 
 
 /** DOM class for BlendShape deformers */
 /** DOM class for BlendShape deformers */
@@ -872,12 +882,12 @@ public:
 
 
     virtual ~BlendShape();
     virtual ~BlendShape();
 
 
-    const std::vector<const BlendShapeChannel*>& BlendShapeChannels() const {
+    const std::unordered_set<const BlendShapeChannel*>& BlendShapeChannels() const {
         return blendShapeChannels;
         return blendShapeChannels;
     }
     }
 
 
 private:
 private:
-    std::vector<const BlendShapeChannel*> blendShapeChannels;
+    std::unordered_set<const BlendShapeChannel*> blendShapeChannels;
 };
 };
 
 
 /** DOM class for skin deformer clusters (aka sub-deformers) */
 /** DOM class for skin deformer clusters (aka sub-deformers) */
@@ -1018,7 +1028,7 @@ public:
 
 
     const PropertyTable& Props() const {
     const PropertyTable& Props() const {
         ai_assert(props.get());
         ai_assert(props.get());
-        return *props.get();
+        return *props;
     }
     }
 
 
     const Document& GetDocument() const {
     const Document& GetDocument() const {
@@ -1072,7 +1082,7 @@ private:
 /** DOM root for a FBX file */
 /** DOM root for a FBX file */
 class Document {
 class Document {
 public:
 public:
-    Document(const Parser& parser, const ImportSettings& settings);
+    Document(Parser& parser, const ImportSettings& settings);
 
 
     ~Document();
     ~Document();
 
 
@@ -1097,7 +1107,7 @@ public:
 
 
     const FileGlobalSettings& GlobalSettings() const {
     const FileGlobalSettings& GlobalSettings() const {
         ai_assert(globals.get());
         ai_assert(globals.get());
-        return *globals.get();
+        return *globals;
     }
     }
 
 
     const PropertyTemplateMap& Templates() const {
     const PropertyTemplateMap& Templates() const {
@@ -1156,7 +1166,7 @@ private:
     const ImportSettings& settings;
     const ImportSettings& settings;
 
 
     ObjectMap objects;
     ObjectMap objects;
-    const Parser& parser;
+    Parser& parser;
 
 
     PropertyTemplateMap templates;
     PropertyTemplateMap templates;
     ConnectionMap src_connections;
     ConnectionMap src_connections;

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 
 
 All rights reserved.
 All rights reserved.

+ 2 - 3
Engine/lib/assimp/code/AssetLib/FBX/FBXDocumentUtil.h

@@ -58,12 +58,11 @@ namespace Util {
 
 
 /* DOM/Parse error reporting - does not return */
 /* DOM/Parse error reporting - does not return */
 AI_WONT_RETURN void DOMError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
 AI_WONT_RETURN void DOMError(const std::string& message, const Token& token) AI_WONT_RETURN_SUFFIX;
-AI_WONT_RETURN void DOMError(const std::string& message, const Element* element = NULL) AI_WONT_RETURN_SUFFIX;
+AI_WONT_RETURN void DOMError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX;
 
 
 // does return
 // does return
 void DOMWarning(const std::string& message, const Token& token);
 void DOMWarning(const std::string& message, const Token& token);
-void DOMWarning(const std::string& message, const Element* element = NULL);
-
+void DOMWarning(const std::string &message, const Element *element = nullptr);
 
 
 // fetch a property table and the corresponding property template
 // fetch a property table and the corresponding property template
 std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
 std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,

+ 2 - 2
Engine/lib/assimp/code/AssetLib/FBX/FBXExportNode.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -360,7 +360,7 @@ void FBX::Node::EndBinary(
     bool has_children
     bool has_children
 ) {
 ) {
     // if there were children, add a null record
     // if there were children, add a null record
-    if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD); }
+    if (has_children) { s.PutString(Assimp::FBX::NULL_RECORD_STRING); }
 
 
     // now go back and write initial pos
     // now go back and write initial pos
     this->end_pos = s.Tell();
     this->end_pos = s.Tell();

+ 15 - 18
Engine/lib/assimp/code/AssetLib/FBX/FBXExportNode.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 
@@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <assimp/StreamWriter.h> // StreamWriterLE
 #include <assimp/StreamWriter.h> // StreamWriterLE
 
 
 #include <string>
 #include <string>
+#include <utility>
 #include <vector>
 #include <vector>
 
 
 namespace Assimp {
 namespace Assimp {
@@ -76,34 +77,30 @@ public: // constructors
     /// The class constructor with the name.
     /// The class constructor with the name.
     Node(const std::string& n)
     Node(const std::string& n)
     : name(n)
     : name(n)
-    , properties()
-    , children()
     , force_has_children( false ) {
     , force_has_children( false ) {
         // empty
         // empty
     }
     }
 
 
     // convenience template to construct with properties directly
     // convenience template to construct with properties directly
     template <typename... More>
     template <typename... More>
-    Node(const std::string& n, const More... more)
+    Node(const std::string& n, More&&... more)
     : name(n)
     : name(n)
-    , properties()
-    , children()
     , force_has_children(false) {
     , force_has_children(false) {
-        AddProperties(more...);
+        AddProperties(std::forward<More>(more)...);
     }
     }
 
 
 public: // functions to add properties or children
 public: // functions to add properties or children
     // add a single property to the node
     // add a single property to the node
     template <typename T>
     template <typename T>
-    void AddProperty(T value) {
-        properties.emplace_back(value);
+    void AddProperty(T&& value) {
+        properties.emplace_back(std::forward<T>(value));
     }
     }
 
 
     // convenience function to add multiple properties at once
     // convenience function to add multiple properties at once
     template <typename T, typename... More>
     template <typename T, typename... More>
-    void AddProperties(T value, More... more) {
-        properties.emplace_back(value);
-        AddProperties(more...);
+    void AddProperties(T&& value, More&&... more) {
+        properties.emplace_back(std::forward<T>(value));
+        AddProperties(std::forward<More>(more)...);
     }
     }
     void AddProperties() {}
     void AddProperties() {}
 
 
@@ -114,11 +111,11 @@ public: // functions to add properties or children
     template <typename... More>
     template <typename... More>
     void AddChild(
     void AddChild(
         const std::string& name,
         const std::string& name,
-        More... more
+        More&&... more
     ) {
     ) {
         FBX::Node c(name);
         FBX::Node c(name);
-        c.AddProperties(more...);
-        children.push_back(c);
+        c.AddProperties(std::forward<More>(more)...);
+        children.push_back(std::move(c));
     }
     }
 
 
 public: // support specifically for dealing with Properties70 nodes
 public: // support specifically for dealing with Properties70 nodes
@@ -146,10 +143,10 @@ public: // support specifically for dealing with Properties70 nodes
         const std::string& type,
         const std::string& type,
         const std::string& type2,
         const std::string& type2,
         const std::string& flags,
         const std::string& flags,
-        More... more
+        More&&... more
     ) {
     ) {
         Node n("P");
         Node n("P");
-        n.AddProperties(name, type, type2, flags, more...);
+        n.AddProperties(name, type, type2, flags, std::forward<More>(more)...);
         AddChild(n);
         AddChild(n);
     }
     }
 
 
@@ -214,7 +211,7 @@ public: // static member functions
         bool binary, int indent
         bool binary, int indent
     ) {
     ) {
         FBX::FBXExportProperty p(value);
         FBX::FBXExportProperty p(value);
-        FBX::Node node(name, p);
+        FBX::Node node(name, std::move(p));
         node.Dump(s, binary, indent);
         node.Dump(s, binary, indent);
     }
     }
 
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXExportProperty.cpp

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

+ 1 - 1
Engine/lib/assimp/code/AssetLib/FBX/FBXExportProperty.h

@@ -2,7 +2,7 @@
 Open Asset Import Library (assimp)
 Open Asset Import Library (assimp)
 ----------------------------------------------------------------------
 ----------------------------------------------------------------------
 
 
-Copyright (c) 2006-2022, assimp team
+Copyright (c) 2006-2024, assimp team
 
 
 All rights reserved.
 All rights reserved.
 
 

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików