Explorar o código

Merge branch 'master' into add_VS2013_VS2019

escherstair %!s(int64=6) %!d(string=hai) anos
pai
achega
19fddb0861
Modificáronse 63 ficheiros con 888 adicións e 3811 borrados
  1. 2 1
      .travis.sh
  2. 26 0
      BUILDBINARIES_EXAMPLE.bat
  3. 21 7
      Build.md
  4. 10 14
      CMakeLists.txt
  5. 1 1
      Readme.md
  6. 4 0
      appveyor.yml
  7. 2 0
      code/CMakeLists.txt
  8. 4 3
      code/Collada/ColladaExporter.cpp
  9. 1 1
      code/Common/BaseImporter.cpp
  10. 19 3
      code/FBX/FBXConverter.cpp
  11. 1 5
      code/FBX/FBXExportProperty.cpp
  12. 1 1
      code/FBX/FBXExporter.cpp
  13. 3 4
      code/Importer/IFC/IFCCurve.cpp
  14. 3 3
      code/Importer/IFC/IFCOpenings.cpp
  15. 1 1
      code/MD2/MD2Loader.cpp
  16. 2 1
      code/MD5/MD5Loader.cpp
  17. 1 1
      code/MD5/MD5Parser.cpp
  18. 16 25
      code/MDL/MDLLoader.cpp
  19. 1 17
      code/MDL/MDLLoader.h
  20. 1 17
      code/Material/MaterialSystem.cpp
  21. 1 4
      code/Obj/ObjFileImporter.cpp
  22. 3 3
      code/PostProcessing/ComputeUVMappingProcess.cpp
  23. 1 1
      code/PostProcessing/ValidateDataStructure.cpp
  24. 3 3
      code/X/XFileParser.cpp
  25. 1 1
      code/X3D/X3DImporter.cpp
  26. 23 23
      code/X3D/X3DImporter_Postprocess.cpp
  27. 8 61
      code/glTF/glTFAsset.h
  28. 10 192
      code/glTF/glTFAsset.inl
  29. 5 3
      code/glTF/glTFAssetWriter.inl
  30. 193 0
      code/glTF/glTFCommon.cpp
  31. 248 0
      code/glTF/glTFCommon.h
  32. 4 1
      code/glTF/glTFExporter.cpp
  33. 24 58
      code/glTF/glTFImporter.cpp
  34. 9 60
      code/glTF2/glTF2Asset.h
  35. 9 194
      code/glTF2/glTF2Asset.inl
  36. 1 1
      code/glTF2/glTF2AssetWriter.inl
  37. 36 16
      code/glTF2/glTF2Importer.cpp
  38. 2 2
      contrib/gtest/test/gtest-param-test_test.cc
  39. 1 1
      contrib/irrXML/irrXML.h
  40. 19 10
      include/assimp/MathFunctions.h
  41. 0 2
      include/assimp/camera.h
  42. 33 13
      include/assimp/material.h
  43. 4 5
      include/assimp/matrix4x4.inl
  44. 13 8
      include/assimp/types.h
  45. 2 2
      port/PyAssimp/pyassimp/helper.py
  46. 1 0
      samples/SimpleOpenGL/CMakeLists.txt
  47. 2 2
      samples/SimpleOpenGL/Sample_SimpleOpenGL.c
  48. 1 0
      test/models/FBX/transparentTest.fbx
  49. 98 0
      test/models/glTF2/cameras/Cameras.gltf
  50. BIN=BIN
      test/models/glTF2/cameras/simpleSquare.bin
  51. 6 0
      test/unit/utFBXImporterExporter.cpp
  52. 7 0
      test/unit/utglTF2ImportExport.cpp
  53. 0 76
      tools/assimp_qt_viewer/CMakeLists.txt
  54. BIN=BIN
      tools/assimp_qt_viewer/doc/Assimp_qt_viewer. Manual (en).odt
  55. BIN=BIN
      tools/assimp_qt_viewer/doc/Assimp_qt_viewer. Manual (ru).odt
  56. 0 1161
      tools/assimp_qt_viewer/glview.cpp
  57. 0 456
      tools/assimp_qt_viewer/glview.hpp
  58. 0 64
      tools/assimp_qt_viewer/loggerview.cpp
  59. 0 67
      tools/assimp_qt_viewer/loggerview.hpp
  60. 0 58
      tools/assimp_qt_viewer/main.cpp
  61. 0 466
      tools/assimp_qt_viewer/mainwindow.cpp
  62. 0 148
      tools/assimp_qt_viewer/mainwindow.hpp
  63. 0 544
      tools/assimp_qt_viewer/mainwindow.ui

+ 2 - 1
.travis.sh

@@ -7,7 +7,8 @@
 #
 function generate() {
     OPTIONS="-DASSIMP_WERROR=ON"
-
+    OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=NO"
+    
     if [ "$DISABLE_EXPORTERS" = "YES" ] ; then
         OPTIONS="$OPTIONS -DASSIMP_NO_EXPORT=YES"
     else

+ 26 - 0
BUILDBINARIES_EXAMPLE.bat

@@ -0,0 +1,26 @@
+:: This is an example file to generate binaries using Windows Operating System
+:: This script is configured to be executed from the source directory
+
+:: Compiled binaries will be placed in BINARIES_DIR\code\CONFIG
+
+:: NOTE
+:: The build process will generate a config.h file that is placed in BINARIES_DIR\include
+:: This file must be merged with SOURCE_DIR\include
+:: You should write yourself a script that copies the files where you want them.
+:: Also see: https://github.com/assimp/assimp/pull/2646
+
+SET SOURCE_DIR=.
+
+:: For generators see "cmake --help"
+SET GENERATOR=Visual Studio 15 2017
+
+SET BINARIES_DIR="./BINARIES/Win32"
+cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
+cmake --build %BINARIES_DIR% --config release
+
+SET BINARIES_DIR="./BINARIES/x64"
+cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
+cmake --build %BINARIES_DIR% --config debug
+cmake --build %BINARIES_DIR% --config release
+
+PAUSE

+ 21 - 7
Build.md

@@ -1,17 +1,31 @@
 # Build Instructions
-## Install CMake
+
+## Build 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.
+
+## 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
 ```
 
-## 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:
 ```bash
 git clone https://github.com/assimp/assimp.git
 ```
 
-## Build instructions for Windows with Visual-Studio
+### 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:
@@ -20,10 +34,10 @@ 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.
 
-## 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>
 
-## Build instructions for Linux / Unix
+### Build instructions for Linux / Unix
 Open a terminal and got to your repository. You can generate the makefiles and build the library via:
 
 ```bash
@@ -34,7 +48,7 @@ The option -j descripes the number of parallel processes for the build. In this
 
 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 
 required to compile some of assimp's files, especially for debug builds.
 Version 7.3.0 of g++-mingw-w64 & gcc-mingw-w64 appears to work.
@@ -50,7 +64,7 @@ The following toolchain may or may not be helpful for building assimp using MinG
 
 Besides the toolchain, compilation should be the same as for Linux / Unix.
 
-## CMake build options
+### CMake build options
 The cmake-build-environment provides options to configure the build. The following options can be used:
 - **BUILD_SHARED_LIBS ( default ON )**: Generation of shared libs ( dll for windows, so for Linux ). Set this to OFF to get a static lib.
 - **BUILD_FRAMEWORK ( default OFF, MacOnly)**: Build package as Mac OS X Framework bundle

+ 10 - 14
CMakeLists.txt

@@ -277,16 +277,14 @@ ELSEIF( CMAKE_COMPILER_IS_MINGW )
 ENDIF()
 
 IF ( IOS AND NOT HUNTER_ENABLED)
-
-IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
-ELSE()
-  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
-  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
-  # Experimental for pdb generation
-ENDIF()
-
+  IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -Og")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -Og")
+  ELSE()
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fembed-bitcode -O3")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fembed-bitcode -O3")
+    # Experimental for pdb generation
+  ENDIF()
 ENDIF( IOS AND NOT HUNTER_ENABLED)
 
 IF (ASSIMP_COVERALLS)
@@ -559,17 +557,15 @@ ENDIF(NOT HUNTER_ENABLED)
 
 ADD_SUBDIRECTORY( code/ )
 IF ( ASSIMP_BUILD_ASSIMP_TOOLS )
+  # The viewer for windows only
   IF ( WIN32 AND DirectX_D3DX9_LIBRARY )
     OPTION ( ASSIMP_BUILD_ASSIMP_VIEW "If the Assimp view tool is built. (requires DirectX)" ${DirectX_FOUND} )
     IF ( ASSIMP_BUILD_ASSIMP_VIEW )
       ADD_SUBDIRECTORY( tools/assimp_view/ )
     ENDIF ( ASSIMP_BUILD_ASSIMP_VIEW )
   ENDIF ( WIN32 AND DirectX_D3DX9_LIBRARY )
-
+  # Te command line tool
   ADD_SUBDIRECTORY( tools/assimp_cmd/ )
-IF (NOT IOS)
-  ADD_SUBDIRECTORY( tools/assimp_qt_viewer/ )
-ENDIF (NOT IOS)
 ENDIF ( ASSIMP_BUILD_ASSIMP_TOOLS )
 
 IF ( ASSIMP_BUILD_SAMPLES)

+ 1 - 1
Readme.md

@@ -120,7 +120,7 @@ __Exporters__:
 - FBX ( experimental )
 
 ### Building ###
-Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file. Our build system is CMake, if you used CMake before there is a good chance you know what to do.
+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.
 
 ### Ports ###
 * [Android](port/AndroidJNI/README.md)

+ 4 - 0
appveyor.yml

@@ -18,6 +18,7 @@ image:
   - Visual Studio 2015
   - Visual Studio 2017
   - Visual Studio 2019
+  - MinGW  
     
 platform:
   - Win32
@@ -28,10 +29,13 @@ configuration: Release
 install:
   - set PATH=C:\Ruby24-x64\bin;%PATH%
   - set CMAKE_DEFINES -DASSIMP_WERROR=ON
+  - if [%COMPILER%]==[MinGW] set PATH=C:\MinGW\bin;%PATH%
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
   - if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
   - if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
   - cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%" .
+  # Rename sh.exe as sh.exe in PATH interferes with MinGW
+  - rename "C:\Program Files\Git\usr\bin\sh.exe" "sh2.exe"
   - set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"
   - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/5/7/b/57b2947c-7221-4f33-b35e-2fc78cb10df4/vc_redist.x64.exe -OutFile .\packaging\windows-innosetup\vc_redist.x64.exe
   - ps: Invoke-WebRequest -Uri https://download.microsoft.com/download/1/d/8/1d8137db-b5bb-4925-8c5d-927424a2e4de/vc_redist.x86.exe -OutFile .\packaging\windows-innosetup\vc_redist.x86.exe

+ 2 - 0
code/CMakeLists.txt

@@ -766,6 +766,8 @@ ADD_ASSIMP_EXPORTER( X3D
 )
 
 ADD_ASSIMP_IMPORTER( GLTF
+  glTF/glTFCommon.h
+  glTF/glTFCommon.cpp
   glTF/glTFAsset.h
   glTF/glTFAsset.inl
   glTF/glTFAssetWriter.h

+ 4 - 3
code/Collada/ColladaExporter.cpp

@@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include "ColladaExporter.h"
 #include <assimp/Bitmap.h>
+#include <assimp/MathFunctions.h>
 #include <assimp/fast_atof.h>
 #include <assimp/SceneCombiner.h>
 #include <assimp/StringUtils.h>
@@ -155,7 +156,7 @@ void ColladaExporter::WriteFile() {
 // ------------------------------------------------------------------------------------------------
 // Writes the asset header
 void ColladaExporter::WriteHeader() {
-    static const ai_real epsilon = ai_real( 0.00001 );
+    static const ai_real epsilon = Math::getEpsilon<ai_real>();
     static const aiQuaternion x_rot(aiMatrix3x3(
         0, -1,  0,
         1,  0,  0,
@@ -317,7 +318,7 @@ void ColladaExporter::WriteTextures() {
 
             std::string name = mFile + "_texture_" + (i < 1000 ? "0" : "") + (i < 100 ? "0" : "") + (i < 10 ? "0" : "") + str + "." + ((const char*) texture->achFormatHint);
 
-            std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + name, "wb"));
+            std::unique_ptr<IOStream> outfile(mIOSystem->Open(mPath + mIOSystem->getOsSeparator() + name, "wb"));
             if(outfile == NULL) {
                 throw DeadlyExportError("could not open output texture file: " + mPath + name);
             }
@@ -1671,4 +1672,4 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
 }
 
 #endif
-#endif
+#endif

+ 1 - 1
code/Common/BaseImporter.cpp

@@ -85,7 +85,7 @@ void BaseImporter::UpdateImporterScale( Importer* pImp )
     double activeScale = importerScale * fileScale;
 
     // Set active scaling
-    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, activeScale);
+    pImp->SetPropertyFloat( AI_CONFIG_APP_SCALE_KEY, static_cast<float>( activeScale) );
 
     ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale );
 }

+ 19 - 3
code/FBX/FBXConverter.cpp

@@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "FBXImporter.h"
 
 #include <assimp/StringComparison.h>
+#include <assimp/MathFunctions.h>
 
 #include <assimp/scene.h>
 
@@ -553,7 +554,7 @@ namespace Assimp {
                 return;
             }
 
-            const float angle_epsilon = 1e-6f;
+            const float angle_epsilon = Math::getEpsilon<float>();
 
             out = aiMatrix4x4();
 
@@ -694,7 +695,7 @@ namespace Assimp {
             std::fill_n(chain, static_cast<unsigned int>(TransformationComp_MAXIMUM), aiMatrix4x4());
 
             // generate transformation matrices for all the different transformation components
-            const float zero_epsilon = 1e-6f;
+            const float zero_epsilon = Math::getEpsilon<float>();
             const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
 
             const aiVector3D& PreRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
@@ -2001,6 +2002,21 @@ namespace Assimp {
             TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
             TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
             TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
+            
+            // Maya PBR
+            TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+            
+            // Maya stingray
+            TrySetTextureProperties(out_mat, textures, "Maya|TEX_color_map|file", aiTextureType_BASE_COLOR, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|TEX_normal_map|file", aiTextureType_NORMAL_CAMERA, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|TEX_emissive_map|file", aiTextureType_EMISSION_COLOR, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|TEX_metallic_map|file", aiTextureType_METALNESS, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|TEX_roughness_map|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
+            TrySetTextureProperties(out_mat, textures, "Maya|TEX_ao_map|file", aiTextureType_AMBIENT_OCCLUSION, mesh);            
         }
 
         void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@@ -2952,7 +2968,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
                 TransformationCompDefaultValue(comp)
                 );
 
-            const float epsilon = 1e-6f;
+            const float epsilon = Math::getEpsilon<float>();
             return (dyn_val - static_val).SquareLength() < epsilon;
         }
 

+ 1 - 5
code/FBX/FBXExportProperty.cpp

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

+ 1 - 1
code/FBX/FBXExporter.cpp

@@ -1289,7 +1289,7 @@ void FBXExporter::WriteObjects ()
 
         for(unsigned int lr = 1; lr < m->GetNumUVChannels(); ++ lr)
         {
-            FBX::Node layerExtra("Layer", int32_t(1));
+            FBX::Node layerExtra("Layer", int32_t(lr));
             layerExtra.AddChild("Version", int32_t(100));
             FBX::Node leExtra("LayerElement");
             leExtra.AddChild("Type", "LayerElementUV");

+ 3 - 4
code/Importer/IFC/IFCCurve.cpp

@@ -311,10 +311,9 @@ class TrimmedCurve : public BoundedCurve {
 public:
     // --------------------------------------------------
     TrimmedCurve(const Schema_2x3::IfcTrimmedCurve& entity, ConversionData& conv)
-        : BoundedCurve(entity,conv)
+        : BoundedCurve(entity,conv),
+          base(std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv)))
     {
-        base = std::shared_ptr<const Curve>(Curve::Convert(entity.BasisCurve,conv));
-
         typedef std::shared_ptr<const STEP::EXPRESS::DataType> Entry;
 
         // for some reason, trimmed curves can either specify a parametric value
@@ -500,7 +499,7 @@ bool Curve::InRange(IfcFloat u) const {
     if (IsClosed()) {
         return true;
     }
-    const IfcFloat epsilon = 1e-5;
+    const IfcFloat epsilon = Math::getEpsilon<float>();
     return u - range.first > -epsilon && range.second - u > -epsilon;
 }
 #endif

+ 3 - 3
code/Importer/IFC/IFCOpenings.cpp

@@ -593,7 +593,7 @@ typedef std::vector<std::pair<
 bool BoundingBoxesAdjacent(const BoundingBox& bb, const BoundingBox& ibb)
 {
     // TODO: I'm pretty sure there is a much more compact way to check this
-    const IfcFloat epsilon = 1e-5f;
+    const IfcFloat epsilon = Math::getEpsilon<float>();
     return  (std::fabs(bb.second.x - ibb.first.x) < epsilon && bb.first.y <= ibb.second.y && bb.second.y >= ibb.first.y) ||
         (std::fabs(bb.first.x - ibb.second.x) < epsilon && ibb.first.y <= bb.second.y && ibb.second.y >= bb.first.y) ||
         (std::fabs(bb.second.y - ibb.first.y) < epsilon && bb.first.x <= ibb.second.x && bb.second.x >= ibb.first.x) ||
@@ -681,7 +681,7 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
 // ------------------------------------------------------------------------------------------------
 void FindAdjacentContours(ContourVector::iterator current, const ContourVector& contours)
 {
-    const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(1e-8);
+    const IfcFloat sqlen_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
     const BoundingBox& bb = (*current).bb;
 
     // What is to be done here is to populate the skip lists for the contour
@@ -758,7 +758,7 @@ void FindAdjacentContours(ContourVector::iterator current, const ContourVector&
 // ------------------------------------------------------------------------------------------------
 AI_FORCE_INLINE bool LikelyBorder(const IfcVector2& vdelta)
 {
-    const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(1e-5);
+    const IfcFloat dot_point_epsilon = static_cast<IfcFloat>(Math::getEpsilon<float>());
     return std::fabs(vdelta.x * vdelta.y) < dot_point_epsilon;
 }
 

+ 1 - 1
code/MD2/MD2Loader.cpp

@@ -344,7 +344,7 @@ void MD2Importer::InternReadFile( const std::string& pFile,
         if (pcSkins->name[0])
         {
             aiString szString;
-            const size_t iLen = ::strlen(pcSkins->name);
+            const ai_uint32 iLen = (ai_uint32) ::strlen(pcSkins->name);
             ::memcpy(szString.data,pcSkins->name,iLen);
             szString.data[iLen] = '\0';
             szString.length = iLen;

+ 2 - 1
code/MD5/MD5Loader.cpp

@@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "MD5Loader.h"
 #include <assimp/StringComparison.h>
 #include <assimp/fast_atof.h>
+#include <assimp/MathFunctions.h>
 #include <assimp/SkeletonMeshBuilder.h>
 #include <assimp/Importer.hpp>
 #include <assimp/scene.h>
@@ -64,7 +65,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 using namespace Assimp;
 
 // Minimum weight value. Weights inside [-n ... n] are ignored
-#define AI_MD5_WEIGHT_EPSILON 1e-5f
+#define AI_MD5_WEIGHT_EPSILON Math::getEpsilon<float>()
 
 
 static const aiImporterDesc desc = {

+ 1 - 1
code/MD5/MD5Parser.cpp

@@ -235,7 +235,7 @@ bool MD5Parser::ParseSection(Section& out)
     const char* szStart = ++sz; \
 	while('\"'!=*sz)++sz; \
     const char* szEnd = (sz++); \
-    out.length = (size_t)(szEnd - szStart); \
+    out.length = (ai_uint32) (szEnd - szStart); \
     ::memcpy(out.data,szStart,out.length); \
     out.data[out.length] = '\0';
 // ------------------------------------------------------------------------------------------------

+ 16 - 25
code/MDL/MDLLoader.cpp

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -94,23 +92,24 @@ static const aiImporterDesc desc = {
 // ------------------------------------------------------------------------------------------------
 // Constructor to be privately used by Importer
 MDLImporter::MDLImporter()
-    : configFrameID(),
-    mBuffer(),
-    iGSFileVersion(),
-    pIOHandler(),
-    pScene(),
-    iFileSize()
-{}
+: configFrameID()
+, mBuffer()
+, iGSFileVersion()
+, pIOHandler()
+, pScene()
+, iFileSize() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Destructor, private as well
-MDLImporter::~MDLImporter()
-{}
+MDLImporter::~MDLImporter() {
+    // empty
+}
 
 // ------------------------------------------------------------------------------------------------
 // Returns whether the class can handle the format of the given file.
-bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
-{
+bool MDLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
     const std::string extension = GetExtension(pFile);
 
     // if check for extension is not enough, check for the magic tokens
@@ -404,23 +403,15 @@ void MDLImporter::InternReadFile_Quake1() {
 
     // now get a pointer to the first frame in the file
     BE_NCONST MDL::Frame* pcFrames = (BE_NCONST MDL::Frame*)szCurrent;
-    BE_NCONST MDL::SimpleFrame* pcFirstFrame;
+    MDL::SimpleFrame* pcFirstFrame;
 
     if (0 == pcFrames->type) {
         // get address of single frame
-        pcFirstFrame = &pcFrames->frame;
+        pcFirstFrame =( MDL::SimpleFrame*) &pcFrames->frame;
     } else {
         // get the first frame in the group
-
-#if 1
-        // FIXME: the cast is wrong and cause a warning on clang 5.0
-        // disable this code for now, fix it later
-        ai_assert(false && "Bad pointer cast");
-        pcFirstFrame = nullptr; // Workaround: msvc++ C4703 error
-#else
-        BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*)pcFrames;
-        pcFirstFrame = (BE_NCONST MDL::SimpleFrame*)(&pcFrames2->time + pcFrames->type);
-#endif
+        BE_NCONST MDL::GroupFrame* pcFrames2 = (BE_NCONST MDL::GroupFrame*) pcFrames;
+        pcFirstFrame = &(pcFrames2->frames[0]);
     }
     BE_NCONST MDL::Vertex* pcVertices = (BE_NCONST MDL::Vertex*) ((pcFirstFrame->name) + sizeof(pcFirstFrame->name));
     VALIDATE_FILE_SIZE((const unsigned char*)(pcVertices + pcHeader->num_verts));

+ 1 - 17
code/MDL/MDLLoader.h

@@ -89,16 +89,12 @@ public:
     MDLImporter();
     ~MDLImporter();
 
-
-public:
-
     // -------------------------------------------------------------------
     /** Returns whether the class can handle the format of the given file.
     * See BaseImporter::CanRead() for details.  */
     bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
         bool checkSig) const;
 
-
     // -------------------------------------------------------------------
     /** Called prior to ReadFile().
     * The function is a request to the importer to update its configuration
@@ -107,8 +103,6 @@ public:
     void SetupProperties(const Importer* pImp);
 
 protected:
-
-
     // -------------------------------------------------------------------
     /** Return importer meta information.
      * See #BaseImporter::GetInfo for the details
@@ -122,8 +116,6 @@ protected:
     void InternReadFile( const std::string& pFile, aiScene* pScene,
         IOSystem* pIOHandler);
 
-protected:
-
     // -------------------------------------------------------------------
     /** Import a quake 1 MDL file (IDPO)
     */
@@ -154,7 +146,6 @@ protected:
     void SizeCheck(const void* szPos);
     void SizeCheck(const void* szPos, const char* szFile, unsigned int iLine);
 
-
     // -------------------------------------------------------------------
     /** Validate the header data structure of a game studio MDL7 file
      * \param pcHeader Input header to be validated
@@ -167,7 +158,6 @@ protected:
      */
     void ValidateHeader_Quake1(const MDL::Header* pcHeader);
 
-
     // -------------------------------------------------------------------
     /** Try to load a  palette from the current directory (colormap.lmp)
      *  If it is not found the default palette of Quake1 is returned
@@ -179,9 +169,8 @@ protected:
      */
     void FreePalette(const unsigned char* pszColorMap);
 
-
     // -------------------------------------------------------------------
-    /** Load a paletized texture from the file and convert it to 32bpp
+    /** Load a palletized texture from the file and convert it to 32bpp
     */
     void CreateTextureARGB8_3DGS_MDL3(const unsigned char* szData);
 
@@ -195,7 +184,6 @@ protected:
         unsigned int iType,
         unsigned int* piSkip);
 
-
     // -------------------------------------------------------------------
     /** Used to load textures from MDL5
      * \param szData Input data
@@ -206,7 +194,6 @@ protected:
         unsigned int iType,
         unsigned int* piSkip);
 
-
     // -------------------------------------------------------------------
     /** Checks whether a texture can be replaced with a single color
      * This is useful for all file formats before MDL7 (all those
@@ -218,14 +205,12 @@ protected:
     */
     aiColor4D ReplaceTextureWithColor(const aiTexture* pcTexture);
 
-
     // -------------------------------------------------------------------
     /** Converts the absolute texture coordinates in MDL5 files to
      *  relative in a range between 0 and 1
     */
     void CalculateUVCoordinates_MDL5();
 
-
     // -------------------------------------------------------------------
     /** Read an UV coordinate from the file. If the file format is not
      * MDL5, the function calculates relative texture coordinates
@@ -245,7 +230,6 @@ protected:
      */
     void SetupMaterialProperties_3DGS_MDL5_Quake1( );
 
-
     // -------------------------------------------------------------------
     /** Parse a skin lump in a MDL7/HMP7 file with all of its features
      *  variant 1: Current cursor position is the beginning of the skin header

+ 1 - 17
code/Material/MaterialSystem.cpp

@@ -545,23 +545,7 @@ aiReturn aiMaterial::AddProperty (const aiString* pInput,
     unsigned int type,
     unsigned int index)
 {
-    // We don't want to add the whole buffer .. write a 32 bit length
-    // prefix followed by the zero-terminated UTF8 string.
-    // (HACK) I don't want to break the ABI now, but we definitely
-    // ought to change aiString::mLength to uint32_t one day.
-    if (sizeof(size_t) == 8) {
-        aiString copy = *pInput;
-        uint32_t* s = reinterpret_cast<uint32_t*>(&copy.length);
-        s[1] = static_cast<uint32_t>(pInput->length);
-
-        return AddBinaryProperty(s+1,
-            static_cast<unsigned int>(pInput->length+1+4),
-            pKey,
-            type,
-            index,
-            aiPTI_String);
-    }
-    ai_assert(sizeof(size_t)==4);
+    ai_assert(sizeof(ai_uint32)==4);
     return AddBinaryProperty(pInput,
         static_cast<unsigned int>(pInput->length+1+4),
         pKey,

+ 1 - 4
code/Obj/ObjFileImporter.cpp

@@ -79,10 +79,7 @@ using namespace std;
 ObjFileImporter::ObjFileImporter()
 : m_Buffer()
 , m_pRootObject( nullptr )
-, m_strAbsPath( "" ) {
-    DefaultIOSystem io;
-    m_strAbsPath = io.getOsSeparator();
-}
+, m_strAbsPath( std::string(1, DefaultIOSystem().getOsSeparator()) ) {}
 
 // ------------------------------------------------------------------------------------------------
 //  Destructor.

+ 3 - 3
code/PostProcessing/ComputeUVMappingProcess.cpp

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

+ 1 - 1
code/PostProcessing/ValidateDataStructure.cpp

@@ -958,7 +958,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
 {
     if (pString->length > MAXLEN)
     {
-        ReportError("aiString::length is too large (%lu, maximum is %lu)",
+        ReportError("aiString::length is too large (%u, maximum is %lu)",
             pString->length,MAXLEN);
     }
     const char* sz = pString->data;

+ 3 - 3
code/X/XFileParser.cpp

@@ -596,11 +596,11 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
     // do not crah when no face definitions are there
     if (numFaces > 0) {
         // normal face creation
-        pMesh->mNormFaces.resize( pMesh->mNormFaces.size() + numFaces );
+        pMesh->mNormFaces.resize( numFaces );
         for( unsigned int a = 0; a < numFaces; ++a ) {
             unsigned int numIndices = ReadInt();
-            pMesh->mNormFaces.push_back( Face() );
-            Face& face = pMesh->mNormFaces.back();
+            pMesh->mNormFaces[a] = Face();
+            Face& face = pMesh->mNormFaces[a];
             for( unsigned int b = 0; b < numIndices; ++b ) {
                 face.mIndices.push_back( ReadInt());
             }

+ 1 - 1
code/X3D/X3DImporter.cpp

@@ -614,7 +614,7 @@ void X3DImporter::XML_ReadNode_GetAttrVal_AsArrCol3f(const int pAttrIdx, std::ve
 
 	XML_ReadNode_GetAttrVal_AsListCol3f(pAttrIdx, tlist);// read as list
 	// and copy to array
-	if(tlist.size() > 0)
+	if(!tlist.empty())
 	{
 		pValue.reserve(tlist.size());
 		for(std::list<aiColor3D>::iterator it = tlist.begin(); it != tlist.end(); ++it) pValue.push_back(*it);

+ 23 - 23
code/X3D/X3DImporter_Postprocess.cpp

@@ -289,7 +289,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		// at first create mesh from existing vertices.
 		*pMesh = GeometryHelper_MakeMesh(tnemesh.CoordIdx, tnemesh.Vertices);
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
 				MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
@@ -301,7 +301,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				MeshGeometry_AddTexCoord(**pMesh, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of ElevationGrid: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_ElevationGrid)
@@ -313,7 +313,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -322,7 +322,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		}
 
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
 				MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
@@ -338,7 +338,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedFaceSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedFaceSet)
@@ -348,7 +348,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -357,7 +357,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		}
 
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			ai_assert(*pMesh);
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@@ -369,7 +369,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				{} // skip because already read when mesh created.
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedLineSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedLineSet)
@@ -381,7 +381,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_IndexedSet& tnemesh = *((CX3DImporter_NodeElement_IndexedSet*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -390,7 +390,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		}
 
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			ai_assert(*pMesh);
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@@ -408,7 +408,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of IndexedTriangleSet or IndexedTriangleFanSet, or \
 																	IndexedTriangleStripSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if((pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleFanSet) || (pNodeElement.Type == CX3DImporter_NodeElement::ENET_IndexedTriangleStripSet))
@@ -430,7 +430,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -448,7 +448,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		}
 
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			ai_assert(*pMesh);
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@@ -459,7 +459,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				{} // skip because already read when mesh created.
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of PointSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_PointSet)
@@ -469,7 +469,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -478,7 +478,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		}
 
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			ai_assert(*pMesh);
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
@@ -489,7 +489,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				{} // skip because already read when mesh created.
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of LineSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_LineSet)
@@ -499,7 +499,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -508,7 +508,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		}
 
 		// copy additional information from children
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if ( nullptr == *pMesh ) {
 				break;
@@ -526,7 +526,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeFanSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleFanSet)
@@ -536,7 +536,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 		CX3DImporter_NodeElement_Set& tnemesh = *((CX3DImporter_NodeElement_Set*)&pNodeElement);// create alias for convenience
 
 		// at first search for <Coordinate> node and create mesh.
-		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 		{
 			if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Coordinate)
 			{
@@ -570,7 +570,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TrianlgeSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleSet)
@@ -605,7 +605,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
 				MeshGeometry_AddTexCoord(**pMesh, tnemesh.CoordIndex, tnemesh.TexCoordIndex, ((CX3DImporter_NodeElement_TextureCoordinate*)*ch_it)->Value);
 			else
 				throw DeadlyImportError("Postprocess_BuildMesh. Unknown child of TriangleStripSet: " + to_string((*ch_it)->Type) + ".");
-		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
+		}// for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ++ch_it)
 
 		return;// mesh is build, nothing to do anymore.
 	}// if(pNodeElement.Type == CX3DImporter_NodeElement::ENET_TriangleStripSet)

+ 8 - 61
code/glTF/glTFAsset.h

@@ -92,38 +92,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #   endif
 #endif
 
+#include "glTF/glTFCommon.h"
+
 namespace glTF
 {
-#ifdef ASSIMP_API
-    using Assimp::IOStream;
-    using Assimp::IOSystem;
-    using std::shared_ptr;
-#else
-    using std::shared_ptr;
-
-    typedef std::runtime_error DeadlyImportError;
-    typedef std::runtime_error DeadlyExportError;
-
-    enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
-    class IOSystem;
-    class IOStream
-    {
-        FILE* f;
-    public:
-        IOStream(FILE* file) : f(file) {}
-        ~IOStream() { fclose(f); f = 0; }
-
-        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
-        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
-        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
-        size_t Tell() const { return ftell(f); }
-
-        size_t FileSize() {
-            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
-            return size_t((Seek(p, aiOrigin_SET), len));
-        }
-    };
-#endif
+    using glTFCommon::shared_ptr;
+    using glTFCommon::IOSystem;
+    using glTFCommon::IOStream;
 
     using rapidjson::Value;
     using rapidjson::Document;
@@ -136,37 +111,9 @@ namespace glTF
     struct Light;
     struct Skin;
 
-
-    // Vec/matrix types, as raw float arrays
-    typedef float (vec3)[3];
-    typedef float (vec4)[4];
-    typedef float (mat4)[16];
-
-
-    namespace Util
-    {
-        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
-
-        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
-
-        inline size_t DecodeBase64(const char* in, uint8_t*& out)
-        {
-            return DecodeBase64(in, strlen(in), out);
-        }
-
-        struct DataURI
-        {
-            const char* mediaType;
-            const char* charset;
-            bool base64;
-            const char* data;
-            size_t dataLength;
-        };
-
-        //! Check if a uri is a data URI
-        inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
-    }
-
+    using glTFCommon::vec3;
+    using glTFCommon::vec4;
+    using glTFCommon::mat4;
 
     //! Magic number for GLB files
     #define AI_GLB_MAGIC_NUMBER "glTF"

+ 10 - 192
code/glTF/glTFAsset.inl

@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -52,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #endif
 
 using namespace Assimp;
+using namespace glTFCommon;
 
 namespace glTF {
 
@@ -301,7 +301,7 @@ inline void Buffer::Read(Value& obj, Asset& r)
 
     const char* uri = it->GetString();
 
-    Util::DataURI dataURI;
+    glTFCommon::Util::DataURI dataURI;
     if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
         if (dataURI.base64) {
             uint8_t* data = 0;
@@ -654,12 +654,12 @@ inline void Image::Read(Value& obj, Asset& r)
         if (Value* uri = FindString(obj, "uri")) {
             const char* uristr = uri->GetString();
 
-            Util::DataURI dataURI;
+            glTFCommon::Util::DataURI dataURI;
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
                 mimeType = dataURI.mediaType;
                 if (dataURI.base64) {
                     uint8_t *ptr = nullptr;
-                    mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
+                    mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
                     mData.reset(ptr);
                 }
             }
@@ -1180,8 +1180,12 @@ inline void Light::SetDefaults()
     falloffExponent = 0.f;
 }
 
-inline void Node::Read(Value& obj, Asset& r)
-{
+inline 
+void Node::Read(Value& obj, Asset& r) {
+    if (name.empty()) {
+        name = id;
+    }
+
     if (Value* children = FindArray(obj, "children")) {
         this->children.reserve(children->Size());
         for (unsigned int i = 0; i < children->Size(); ++i) {
@@ -1474,190 +1478,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
     return id;
 }
 
-namespace Util {
-
-    inline
-    bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
-        if ( NULL == const_uri ) {
-            return false;
-        }
-
-        if (const_uri[0] != 0x10) { // we already parsed this uri?
-            if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
-                return false;
-        }
-
-        // set defaults
-        out.mediaType = "text/plain";
-        out.charset = "US-ASCII";
-        out.base64 = false;
-
-        char* uri = const_cast<char*>(const_uri);
-        if (uri[0] != 0x10) {
-            uri[0] = 0x10;
-            uri[1] = uri[2] = uri[3] = uri[4] = 0;
-
-            size_t i = 5, j;
-            if (uri[i] != ';' && uri[i] != ',') { // has media type?
-                uri[1] = char(i);
-                for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-            }
-            while (uri[i] == ';' && i < uriLen) {
-                uri[i++] = '\0';
-                for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-
-                if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
-                    uri[2] = char(j + 8);
-                } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
-                    uri[3] = char(j);
-                }
-            }
-            if (i < uriLen) {
-                uri[i++] = '\0';
-                uri[4] = char(i);
-            } else {
-                uri[1] = uri[2] = uri[3] = 0;
-                uri[4] = 5;
-            }
-        }
-
-        if ( uri[ 1 ] != 0 ) {
-            out.mediaType = uri + uri[ 1 ];
-        }
-        if ( uri[ 2 ] != 0 ) {
-            out.charset = uri + uri[ 2 ];
-        }
-        if ( uri[ 3 ] != 0 ) {
-            out.base64 = true;
-        }
-        out.data = uri + uri[4];
-        out.dataLength = (uri + uriLen) - out.data;
-
-        return true;
-    }
-
-    template<bool B>
-    struct DATA
-    {
-        static const uint8_t tableDecodeBase64[128];
-    };
-
-    template<bool B>
-    const uint8_t DATA<B>::tableDecodeBase64[128] = {
-         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, 62,  0,  0,  0, 63,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
-         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
-         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
-    };
-
-    inline char EncodeCharBase64(uint8_t b)
-    {
-        return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
-    }
-
-    inline uint8_t DecodeCharBase64(char c)
-    {
-        return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
-        /*if (c >= 'A' && c <= 'Z') return c - 'A';
-        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
-        if (c >= '0' && c <= '9') return c - '0' + 52;
-        if (c == '+') return 62;
-        if (c == '/') return 63;
-        return 64; // '-' */
-    }
-
-    inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
-    {
-        ai_assert(inLength % 4 == 0);
-
-        if (inLength < 4) {
-            out = 0;
-            return 0;
-        }
-
-        int nEquals = int(in[inLength - 1] == '=') +
-                      int(in[inLength - 2] == '=');
-
-        size_t outLength = (inLength * 3) / 4 - nEquals;
-        out = new uint8_t[outLength];
-        memset(out, 0, outLength);
-
-        size_t i, j = 0;
-
-        for (i = 0; i + 4 < inLength; i += 4) {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        return outLength;
-    }
-
-
-
-    inline void EncodeBase64(
-        const uint8_t* in, size_t inLength,
-        std::string& out)
-    {
-        size_t outLength = ((inLength + 2) / 3) * 4;
-
-        size_t j = out.size();
-        out.resize(j + outLength);
-
-        for (size_t i = 0; i <  inLength; i += 3) {
-            uint8_t b = (in[i] & 0xFC) >> 2;
-            out[j++] = EncodeCharBase64(b);
-
-            b = (in[i] & 0x03) << 4;
-            if (i + 1 < inLength) {
-                b |= (in[i + 1] & 0xF0) >> 4;
-                out[j++] = EncodeCharBase64(b);
-
-                b = (in[i + 1] & 0x0F) << 2;
-                if (i + 2 < inLength) {
-                    b |= (in[i + 2] & 0xC0) >> 6;
-                    out[j++] = EncodeCharBase64(b);
-
-                    b = in[i + 2] & 0x3F;
-                    out[j++] = EncodeCharBase64(b);
-                }
-                else {
-                    out[j++] = EncodeCharBase64(b);
-                    out[j++] = '=';
-                }
-            }
-            else {
-                out[j++] = EncodeCharBase64(b);
-                out[j++] = '=';
-                out[j++] = '=';
-            }
-        }
-    }
-
-}
-
 } // ns glTF

+ 5 - 3
code/glTF/glTFAssetWriter.inl

@@ -55,7 +55,8 @@ namespace glTF {
     namespace {
 
         template<size_t N>
-        inline Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
+        inline 
+        Value& MakeValue(Value& val, float(&r)[N], MemoryPoolAllocator<>& al) {
             val.SetArray();
             val.Reserve(N, al);
             for (decltype(N) i = 0; i < N; ++i) {
@@ -64,7 +65,8 @@ namespace glTF {
             return val;
         }
 
-        inline Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
+        inline 
+        Value& MakeValue(Value& val, const std::vector<float> & r, MemoryPoolAllocator<>& al) {
             val.SetArray();
             val.Reserve(static_cast<rapidjson::SizeType>(r.size()), al);
             for (unsigned int i = 0; i < r.size(); ++i) {
@@ -213,7 +215,7 @@ namespace glTF {
         else if (img.HasData()) {
             uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
             uri += ";base64,";
-            Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
+            glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
         }
         else {
             uri = img.uri;

+ 193 - 0
code/glTF/glTFCommon.cpp

@@ -0,0 +1,193 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#include "glTF/glTFCommon.h"
+
+namespace glTFCommon {
+
+using namespace glTFCommon::Util;
+
+namespace Util {
+
+size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out) {
+    ai_assert(inLength % 4 == 0);
+
+    if (inLength < 4) {
+        out = 0;
+        return 0;
+    }
+
+    int nEquals = int(in[inLength - 1] == '=') +
+        int(in[inLength - 2] == '=');
+
+    size_t outLength = (inLength * 3) / 4 - nEquals;
+    out = new uint8_t[outLength];
+    memset(out, 0, outLength);
+
+    size_t i, j = 0;
+
+    for (i = 0; i + 4 < inLength; i += 4) {
+        uint8_t b0 = DecodeCharBase64(in[i]);
+        uint8_t b1 = DecodeCharBase64(in[i + 1]);
+        uint8_t b2 = DecodeCharBase64(in[i + 2]);
+        uint8_t b3 = DecodeCharBase64(in[i + 3]);
+
+        out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
+        out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
+        out[j++] = (uint8_t)((b2 << 6) | b3);
+    }
+
+    {
+        uint8_t b0 = DecodeCharBase64(in[i]);
+        uint8_t b1 = DecodeCharBase64(in[i + 1]);
+        uint8_t b2 = DecodeCharBase64(in[i + 2]);
+        uint8_t b3 = DecodeCharBase64(in[i + 3]);
+
+        out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
+        if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
+        if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
+    }
+
+    return outLength;
+}
+
+void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out) {
+    size_t outLength = ((inLength + 2) / 3) * 4;
+
+    size_t j = out.size();
+    out.resize(j + outLength);
+
+    for (size_t i = 0; i < inLength; i += 3) {
+        uint8_t b = (in[i] & 0xFC) >> 2;
+        out[j++] = EncodeCharBase64(b);
+
+        b = (in[i] & 0x03) << 4;
+        if (i + 1 < inLength) {
+            b |= (in[i + 1] & 0xF0) >> 4;
+            out[j++] = EncodeCharBase64(b);
+
+            b = (in[i + 1] & 0x0F) << 2;
+            if (i + 2 < inLength) {
+                b |= (in[i + 2] & 0xC0) >> 6;
+                out[j++] = EncodeCharBase64(b);
+
+                b = in[i + 2] & 0x3F;
+                out[j++] = EncodeCharBase64(b);
+            }
+            else {
+                out[j++] = EncodeCharBase64(b);
+                out[j++] = '=';
+            }
+        }
+        else {
+            out[j++] = EncodeCharBase64(b);
+            out[j++] = '=';
+            out[j++] = '=';
+        }
+    }
+}
+
+bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
+    if (nullptr == const_uri) {
+        return false;
+    }
+
+    if (const_uri[0] != 0x10) { // we already parsed this uri?
+        if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
+            return false;
+    }
+
+    // set defaults
+    out.mediaType = "text/plain";
+    out.charset = "US-ASCII";
+    out.base64 = false;
+
+    char* uri = const_cast<char*>(const_uri);
+    if (uri[0] != 0x10) {
+        uri[0] = 0x10;
+        uri[1] = uri[2] = uri[3] = uri[4] = 0;
+
+        size_t i = 5, j;
+        if (uri[i] != ';' && uri[i] != ',') { // has media type?
+            uri[1] = char(i);
+            for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
+                // nothing to do!
+            }
+        }
+        while (uri[i] == ';' && i < uriLen) {
+            uri[i++] = '\0';
+            for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
+                // nothing to do!
+            }
+
+            if (strncmp(uri + j, "charset=", 8) == 0) {
+                uri[2] = char(j + 8);
+            }
+            else if (strncmp(uri + j, "base64", 6) == 0) {
+                uri[3] = char(j);
+            }
+        }
+        if (i < uriLen) {
+            uri[i++] = '\0';
+            uri[4] = char(i);
+        }
+        else {
+            uri[1] = uri[2] = uri[3] = 0;
+            uri[4] = 5;
+        }
+    }
+
+    if (uri[1] != 0) {
+        out.mediaType = uri + uri[1];
+    }
+    if (uri[2] != 0) {
+        out.charset = uri + uri[2];
+    }
+    if (uri[3] != 0) {
+        out.base64 = true;
+    }
+    out.data = uri + uri[4];
+    out.dataLength = (uri + uriLen) - out.data;
+
+    return true;
+}
+
+}
+}

+ 248 - 0
code/glTF/glTFCommon.h

@@ -0,0 +1,248 @@
+/*
+Open Asset Import Library (assimp)
+----------------------------------------------------------------------
+
+Copyright (c) 2006-2019, assimp team
+
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+* Redistributions of source code must retain the above
+copyright notice, this list of conditions and the
+following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the
+following disclaimer in the documentation and/or other
+materials provided with the distribution.
+
+* Neither the name of the assimp team, nor the names of its
+contributors may be used to endorse or promote products
+derived from this software without specific prior
+written permission of the assimp team.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+----------------------------------------------------------------------
+*/
+#ifndef AI_GLFTCOMMON_H_INC
+#define AI_GLFTCOMMON_H_INC
+
+#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#include <assimp/Exceptional.h>
+
+#include <map>
+#include <string>
+#include <list>
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+
+#define RAPIDJSON_HAS_STDSTRING 1
+#include <rapidjson/rapidjson.h>
+#include <rapidjson/document.h>
+#include <rapidjson/error/en.h>
+
+#ifdef ASSIMP_API
+#   include <memory>
+#   include <assimp/DefaultIOSystem.h>
+#   include <assimp/ByteSwapper.h>
+#else
+#   include <memory>
+#   define AI_SWAP4(p)
+#   define ai_assert
+#endif
+
+
+#if _MSC_VER > 1500 || (defined __GNUC___)
+#       define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
+#   else
+#       define gltf_unordered_map map
+#endif
+
+#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
+#   include <unordered_map>
+#   if _MSC_VER > 1600
+#       define gltf_unordered_map unordered_map
+#   else
+#       define gltf_unordered_map tr1::unordered_map
+#   endif
+#endif
+
+namespace glTFCommon {
+
+#ifdef ASSIMP_API
+    using Assimp::IOStream;
+    using Assimp::IOSystem;
+    using std::shared_ptr;
+#else
+    using std::shared_ptr;
+
+    typedef std::runtime_error DeadlyImportError;
+    typedef std::runtime_error DeadlyExportError;
+
+    enum aiOrigin {
+        aiOrigin_SET = 0,
+        aiOrigin_CUR = 1,
+        aiOrigin_END = 2
+    };
+
+    class IOSystem;
+
+    class IOStream {
+    public:
+        IOStream(FILE* file) : f(file) {}
+        ~IOStream() { fclose(f); f = 0; }
+
+        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
+        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
+        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
+        size_t Tell() const { return ftell(f); }
+
+        size_t FileSize() {
+            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
+            return size_t((Seek(p, aiOrigin_SET), len));
+        }
+
+    private:
+        FILE* f;
+    };
+#endif
+
+    // Vec/matrix types, as raw float arrays
+    typedef float(vec3)[3];
+    typedef float(vec4)[4];
+    typedef float(mat4)[16];
+
+    inline
+    void CopyValue(const glTFCommon::vec3& v, aiColor4D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+        out.a = 1.0;
+    }
+
+    inline
+    void CopyValue(const glTFCommon::vec4& v, aiColor4D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+        out.a = v[3];
+    }
+
+    inline
+    void CopyValue(const glTFCommon::vec4& v, aiColor3D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+    }
+
+    inline
+    void CopyValue(const glTFCommon::vec3& v, aiColor3D& out) {
+        out.r = v[0];
+        out.g = v[1];
+        out.b = v[2];
+    }
+
+    inline
+    void CopyValue(const glTFCommon::vec3& v, aiVector3D& out) {
+        out.x = v[0];
+        out.y = v[1];
+        out.z = v[2];
+    }
+
+    inline
+    void CopyValue(const glTFCommon::vec4& v, aiQuaternion& out) {
+        out.x = v[0];
+        out.y = v[1];
+        out.z = v[2];
+        out.w = v[3];
+    }
+
+    inline
+    void CopyValue(const glTFCommon::mat4& v, aiMatrix4x4& o) {
+        o.a1 = v[0]; o.b1 = v[1]; o.c1 = v[2]; o.d1 = v[3];
+        o.a2 = v[4]; o.b2 = v[5]; o.c2 = v[6]; o.d2 = v[7];
+        o.a3 = v[8]; o.b3 = v[9]; o.c3 = v[10]; o.d3 = v[11];
+        o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
+    }
+
+    namespace Util {
+
+        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
+
+        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
+
+        inline
+            size_t DecodeBase64(const char* in, uint8_t*& out) {
+            return DecodeBase64(in, strlen(in), out);
+        }
+
+        struct DataURI {
+            const char* mediaType;
+            const char* charset;
+            bool base64;
+            const char* data;
+            size_t dataLength;
+        };
+
+        //! Check if a uri is a data URI
+        bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out);
+
+        template<bool B>
+        struct DATA {
+            static const uint8_t tableDecodeBase64[128];
+        };
+
+        template<bool B>
+        const uint8_t DATA<B>::tableDecodeBase64[128] = {
+                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, 62,  0,  0,  0, 63,
+            52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
+                0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+            15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
+                0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+            41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
+        };
+
+        inline
+            char EncodeCharBase64(uint8_t b) {
+            return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
+        }
+
+        inline
+            uint8_t DecodeCharBase64(char c) {
+            return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
+            /*if (c >= 'A' && c <= 'Z') return c - 'A';
+            if (c >= 'a' && c <= 'z') return c - 'a' + 26;
+            if (c >= '0' && c <= '9') return c - '0' + 52;
+            if (c == '+') return 62;
+            if (c == '/') return 63;
+            return 64; // '-' */
+        }
+
+        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
+
+        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
+    }
+
+}
+
+#endif  // ASSIMP_BUILD_NO_GLTF_IMPORTER
+
+#endif // AI_GLFTCOMMON_H_INC

+ 4 - 1
code/glTF/glTFExporter.cpp

@@ -242,7 +242,10 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
 
 namespace {
     void GetMatScalar(const aiMaterial* mat, float& val, const char* propName, int type, int idx) {
-        ai_assert(mat->Get(propName, type, idx, val) == AI_SUCCESS);
+        ai_assert( nullptr != mat );
+        if ( nullptr != mat ) {
+            mat->Get(propName, type, idx, val);
+        }
     }
 }
 

+ 24 - 58
code/glTF/glTFImporter.cpp

@@ -82,7 +82,7 @@ glTFImporter::glTFImporter()
 : BaseImporter()
 , meshOffsets()
 , embeddedTexIdxs()
-, mScene( NULL ) {
+, mScene( nullptr ) {
     // empty
 }
 
@@ -90,17 +90,16 @@ glTFImporter::~glTFImporter() {
     // empty
 }
 
-const aiImporterDesc* glTFImporter::GetInfo() const
-{
+const aiImporterDesc* glTFImporter::GetInfo() const {
     return &desc;
 }
 
-bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const
-{
+bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const {
     const std::string &extension = GetExtension(pFile);
 
-    if (extension != "gltf" && extension != "glb")
+    if (extension != "gltf" && extension != "glb") {
         return false;
+    }
 
     if (pIOHandler) {
         glTF::Asset asset(pIOHandler);
@@ -116,44 +115,9 @@ bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
     return false;
 }
 
-
-
-//static void CopyValue(const glTF::vec3& v, aiColor3D& out)
-//{
-//    out.r = v[0]; out.g = v[1]; out.b = v[2];
-//}
-
-static void CopyValue(const glTF::vec4& v, aiColor4D& out)
-{
-    out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
-}
-
-static void CopyValue(const glTF::vec4& v, aiColor3D& out)
-{
-    out.r = v[0]; out.g = v[1]; out.b = v[2];
-}
-
-static void CopyValue(const glTF::vec3& v, aiVector3D& out)
-{
-    out.x = v[0]; out.y = v[1]; out.z = v[2];
-}
-
-static void CopyValue(const glTF::vec4& v, aiQuaternion& out)
-{
-    out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
-}
-
-static void CopyValue(const glTF::mat4& v, aiMatrix4x4& o)
-{
-    o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
-    o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
-    o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
-    o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
-}
-
-inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
-    aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx)
-{
+inline
+void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /*r*/, glTF::TexProperty prop, aiMaterial* mat,
+        aiTextureType texType, const char* pKey, unsigned int type, unsigned int idx) {
     if (prop.texture) {
         if (prop.texture->source) {
             aiString uri(prop.texture->source->uri);
@@ -167,16 +131,14 @@ inline void SetMaterialColorProperty(std::vector<int>& embeddedTexIdxs, Asset& /
 
             mat->AddProperty(&uri, _AI_MATKEY_TEXTURE_BASE, texType, 0);
         }
-    }
-    else {
+    } else {
         aiColor4D col;
         CopyValue(prop.color, col);
         mat->AddProperty(&col, 1, pKey, type, idx);
     }
 }
 
-void glTFImporter::ImportMaterials(glTF::Asset& r)
-{
+void glTFImporter::ImportMaterials(glTF::Asset& r) {
     mScene->mNumMaterials = unsigned(r.materials.Size());
     mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials];
 
@@ -304,7 +266,7 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
 
             aim->mName = mesh.id;
             if (mesh.primitives.size() > 1) {
-                size_t& len = aim->mName.length;
+                ai_uint32& len = aim->mName.length;
                 aim->mName.data[len] = '-';
                 len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
             }
@@ -499,27 +461,31 @@ void glTFImporter::ImportMeshes(glTF::Asset& r)
     CopyVector(meshes, mScene->mMeshes, mScene->mNumMeshes);
 }
 
-void glTFImporter::ImportCameras(glTF::Asset& r)
-{
-    if (!r.cameras.Size()) return;
+void glTFImporter::ImportCameras(glTF::Asset& r) {
+    if (!r.cameras.Size()) {
+        return;
+    }
 
     mScene->mNumCameras = r.cameras.Size();
     mScene->mCameras = new aiCamera*[r.cameras.Size()];
-
     for (size_t i = 0; i < r.cameras.Size(); ++i) {
         Camera& cam = r.cameras[i];
 
         aiCamera* aicam = mScene->mCameras[i] = new aiCamera();
 
         if (cam.type == Camera::Perspective) {
-
             aicam->mAspect        = cam.perspective.aspectRatio;
-            aicam->mHorizontalFOV = cam.perspective.yfov * aicam->mAspect;
+            aicam->mHorizontalFOV = cam.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
             aicam->mClipPlaneFar  = cam.perspective.zfar;
             aicam->mClipPlaneNear = cam.perspective.znear;
-        }
-        else {
-            // assimp does not support orthographic cameras
+        } else {
+            aicam->mClipPlaneFar = cam.ortographic.zfar;
+            aicam->mClipPlaneNear = cam.ortographic.znear;
+            aicam->mHorizontalFOV = 0.0;
+            aicam->mAspect = 1.0f;
+            if (0.f != cam.ortographic.ymag) {
+                aicam->mAspect = cam.ortographic.xmag / cam.ortographic.ymag;
+            }
         }
     }
 }

+ 9 - 60
code/glTF2/glTF2Asset.h

@@ -95,38 +95,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 #include <assimp/StringUtils.h>
 
+#include "glTF/glTFCommon.h"
+
 namespace glTF2
 {
-#ifdef ASSIMP_API
-    using Assimp::IOStream;
-    using Assimp::IOSystem;
-    using std::shared_ptr;
-#else
-    using std::shared_ptr;
-
-    typedef std::runtime_error DeadlyImportError;
-    typedef std::runtime_error DeadlyExportError;
-
-    enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
-    class IOSystem;
-    class IOStream
-    {
-        FILE* f;
-    public:
-        IOStream(FILE* file) : f(file) {}
-        ~IOStream() { fclose(f); f = 0; }
-
-        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
-        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
-        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
-        size_t Tell() const { return ftell(f); }
-
-        size_t FileSize() {
-            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
-            return size_t((Seek(p, aiOrigin_SET), len));
-        }
-    };
-#endif
+    using glTFCommon::shared_ptr;
+    using glTFCommon::IOSystem;
+    using glTFCommon::IOStream;
 
     using rapidjson::Value;
     using rapidjson::Document;
@@ -138,35 +113,9 @@ namespace glTF2
     struct Texture;
     struct Skin;
 
-    // Vec/matrix types, as raw float arrays
-    typedef float (vec3)[3];
-    typedef float (vec4)[4];
-    typedef float (mat4)[16];
-
-    namespace Util
-    {
-        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);
-
-        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);
-
-        inline size_t DecodeBase64(const char* in, uint8_t*& out)
-        {
-            return DecodeBase64(in, strlen(in), out);
-        }
-
-        struct DataURI
-        {
-            const char* mediaType;
-            const char* charset;
-            bool base64;
-            const char* data;
-            size_t dataLength;
-        };
-
-        //! Check if a uri is a data URI
-        inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
-    }
-
+    using glTFCommon::vec3;
+    using glTFCommon::vec4;
+    using glTFCommon::mat4;
 
     //! Magic number for GLB files
 	#define AI_GLB_MAGIC_NUMBER "glTF"
@@ -552,7 +501,7 @@ namespace glTF2
 		/// but in real life you'll get:
 		/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
 		/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
-		/// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
+		/// And when before you start to read data of current mesh (with encoded data of course) you must decode region of "bufferView", after read finished
 		/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
 		///
 		/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in

+ 9 - 194
code/glTF2/glTF2Asset.inl

@@ -282,9 +282,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
 template<class T>
 Ref<T> LazyDict<T>::Get(unsigned int i)
 {
-
     return Ref<T>(mObjs, i);
-
 }
 
 template<class T>
@@ -361,11 +359,11 @@ inline void Buffer::Read(Value& obj, Asset& r)
 
     const char* uri = it->GetString();
 
-    Util::DataURI dataURI;
+    glTFCommon::Util::DataURI dataURI;
     if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
         if (dataURI.base64) {
             uint8_t* data = 0;
-            this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
+            this->byteLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
             this->mData.reset(data, std::default_delete<uint8_t[]>());
 
             if (statedLength > 0 && this->byteLength != statedLength) {
@@ -717,12 +715,12 @@ inline void Image::Read(Value& obj, Asset& r)
         if (Value* uri = FindString(obj, "uri")) {
             const char* uristr = uri->GetString();
 
-            Util::DataURI dataURI;
+            glTFCommon::Util::DataURI dataURI;
             if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
                 mimeType = dataURI.mediaType;
                 if (dataURI.base64) {
                     uint8_t *ptr = nullptr;
-                    mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
+                    mDataLength = glTFCommon::Util::DecodeBase64(dataURI.data, dataURI.dataLength, ptr);
                     mData.reset(ptr);
                 }
             }
@@ -1100,8 +1098,11 @@ inline void Light::Read(Value& obj, Asset& /*r*/)
     }
 }
 
-inline void Node::Read(Value& obj, Asset& r)
-{
+inline 
+void Node::Read(Value& obj, Asset& r) {
+    if (name.empty()) {
+        name = id;
+    }
 
     if (Value* children = FindArray(obj, "children")) {
         this->children.reserve(children->Size());
@@ -1515,190 +1516,4 @@ inline std::string Asset::FindUniqueID(const std::string& str, const char* suffi
     return id;
 }
 
-namespace Util {
-
-    inline
-    bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
-        if ( NULL == const_uri ) {
-            return false;
-        }
-
-        if (const_uri[0] != 0x10) { // we already parsed this uri?
-            if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
-                return false;
-        }
-
-        // set defaults
-        out.mediaType = "text/plain";
-        out.charset = "US-ASCII";
-        out.base64 = false;
-
-        char* uri = const_cast<char*>(const_uri);
-        if (uri[0] != 0x10) {
-            uri[0] = 0x10;
-            uri[1] = uri[2] = uri[3] = uri[4] = 0;
-
-            size_t i = 5, j;
-            if (uri[i] != ';' && uri[i] != ',') { // has media type?
-                uri[1] = char(i);
-                for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-            }
-            while (uri[i] == ';' && i < uriLen) {
-                uri[i++] = '\0';
-                for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
-                    // nothing to do!
-                }
-
-                if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
-                    uri[2] = char(j + 8);
-                } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
-                    uri[3] = char(j);
-                }
-            }
-            if (i < uriLen) {
-                uri[i++] = '\0';
-                uri[4] = char(i);
-            } else {
-                uri[1] = uri[2] = uri[3] = 0;
-                uri[4] = 5;
-            }
-        }
-
-        if ( uri[ 1 ] != 0 ) {
-            out.mediaType = uri + uri[ 1 ];
-        }
-        if ( uri[ 2 ] != 0 ) {
-            out.charset = uri + uri[ 2 ];
-        }
-        if ( uri[ 3 ] != 0 ) {
-            out.base64 = true;
-        }
-        out.data = uri + uri[4];
-        out.dataLength = (uri + uriLen) - out.data;
-
-        return true;
-    }
-
-    template<bool B>
-    struct DATA
-    {
-        static const uint8_t tableDecodeBase64[128];
-    };
-
-    template<bool B>
-    const uint8_t DATA<B>::tableDecodeBase64[128] = {
-         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, 62,  0,  0,  0, 63,
-        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
-         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
-        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
-         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
-        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
-    };
-
-    inline char EncodeCharBase64(uint8_t b)
-    {
-        return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
-    }
-
-    inline uint8_t DecodeCharBase64(char c)
-    {
-        return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
-        /*if (c >= 'A' && c <= 'Z') return c - 'A';
-        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
-        if (c >= '0' && c <= '9') return c - '0' + 52;
-        if (c == '+') return 62;
-        if (c == '/') return 63;
-        return 64; // '-' */
-    }
-
-    inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
-    {
-        ai_assert(inLength % 4 == 0);
-
-        if (inLength < 4) {
-            out = 0;
-            return 0;
-        }
-
-        int nEquals = int(in[inLength - 1] == '=') +
-                      int(in[inLength - 2] == '=');
-
-        size_t outLength = (inLength * 3) / 4 - nEquals;
-        out = new uint8_t[outLength];
-        memset(out, 0, outLength);
-
-        size_t i, j = 0;
-
-        for (i = 0; i + 4 < inLength; i += 4) {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        {
-            uint8_t b0 = DecodeCharBase64(in[i]);
-            uint8_t b1 = DecodeCharBase64(in[i + 1]);
-            uint8_t b2 = DecodeCharBase64(in[i + 2]);
-            uint8_t b3 = DecodeCharBase64(in[i + 3]);
-
-            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
-            if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
-            if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
-        }
-
-        return outLength;
-    }
-
-
-
-    inline void EncodeBase64(
-        const uint8_t* in, size_t inLength,
-        std::string& out)
-    {
-        size_t outLength = ((inLength + 2) / 3) * 4;
-
-        size_t j = out.size();
-        out.resize(j + outLength);
-
-        for (size_t i = 0; i <  inLength; i += 3) {
-            uint8_t b = (in[i] & 0xFC) >> 2;
-            out[j++] = EncodeCharBase64(b);
-
-            b = (in[i] & 0x03) << 4;
-            if (i + 1 < inLength) {
-                b |= (in[i + 1] & 0xF0) >> 4;
-                out[j++] = EncodeCharBase64(b);
-
-                b = (in[i + 1] & 0x0F) << 2;
-                if (i + 2 < inLength) {
-                    b |= (in[i + 2] & 0xC0) >> 6;
-                    out[j++] = EncodeCharBase64(b);
-
-                    b = in[i + 2] & 0x3F;
-                    out[j++] = EncodeCharBase64(b);
-                }
-                else {
-                    out[j++] = EncodeCharBase64(b);
-                    out[j++] = '=';
-                }
-            }
-            else {
-                out[j++] = EncodeCharBase64(b);
-                out[j++] = '=';
-                out[j++] = '=';
-            }
-        }
-    }
-
-}
-
 } // ns glTF

+ 1 - 1
code/glTF2/glTF2AssetWriter.inl

@@ -218,7 +218,7 @@ namespace glTF2 {
             if (img.HasData()) {
                 uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType);
                 uri += ";base64,";
-                Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
+                glTFCommon::Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri);
             }
             else {
                 uri = img.uri;

+ 36 - 16
code/glTF2/glTF2Importer.cpp

@@ -64,6 +64,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 using namespace Assimp;
 using namespace glTF2;
+using namespace glTFCommon;
 
 namespace {
     // generate bi-tangents from normals and tangents according to spec
@@ -140,22 +141,23 @@ static aiTextureMapMode ConvertWrappingMode(SamplerWrap gltfWrapMode)
     }
 }
 
-static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
+/*static void CopyValue(const glTF2::vec3& v, aiColor3D& out)
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2];
 }
 
+
 static void CopyValue(const glTF2::vec4& v, aiColor4D& out)
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = v[3];
-}
+}*/
 
 /*static void CopyValue(const glTF2::vec4& v, aiColor3D& out)
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2];
 }*/
 
-static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
+/*static void CopyValue(const glTF2::vec3& v, aiColor4D& out)
 {
     out.r = v[0]; out.g = v[1]; out.b = v[2]; out.a = 1.0;
 }
@@ -168,15 +170,15 @@ static void CopyValue(const glTF2::vec3& v, aiVector3D& out)
 static void CopyValue(const glTF2::vec4& v, aiQuaternion& out)
 {
     out.x = v[0]; out.y = v[1]; out.z = v[2]; out.w = v[3];
-}
+}*/
 
-static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
+/*static void CopyValue(const glTF2::mat4& v, aiMatrix4x4& o)
 {
     o.a1 = v[ 0]; o.b1 = v[ 1]; o.c1 = v[ 2]; o.d1 = v[ 3];
     o.a2 = v[ 4]; o.b2 = v[ 5]; o.c2 = v[ 6]; o.d2 = v[ 7];
     o.a3 = v[ 8]; o.b3 = v[ 9]; o.c3 = v[10]; o.d3 = v[11];
     o.a4 = v[12]; o.b4 = v[13]; o.c4 = v[14]; o.d4 = v[15];
-}
+}*/
 
 inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 {
@@ -188,7 +190,7 @@ inline void SetMaterialColorProperty(Asset& /*r*/, vec4& prop, aiMaterial* mat,
 inline void SetMaterialColorProperty(Asset& /*r*/, vec3& prop, aiMaterial* mat, const char* pKey, unsigned int type, unsigned int idx)
 {
     aiColor4D col;
-    CopyValue(prop, col);
+    glTFCommon::CopyValue(prop, col);
     mat->AddProperty(&col, 1, pKey, type, idx);
 }
 
@@ -383,7 +385,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
             aim->mName = mesh.name.empty() ? mesh.id : mesh.name;
 
             if (mesh.primitives.size() > 1) {
-                size_t& len = aim->mName.length;
+                ai_uint32& len = aim->mName.length;
                 aim->mName.data[len] = '-';
                 len += 1 + ASSIMP_itoa10(aim->mName.data + len + 1, unsigned(MAXLEN - len - 1), p);
             }
@@ -442,7 +444,6 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r)
                         "\" does not match the vertex count");
                     continue;
                 }
-                aim->mColors[c] = new aiColor4D[attr.color[c]->count];
                 attr.color[c]->ExtractData(aim->mColors[c]);
             }
             for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
@@ -700,12 +701,17 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r)
         if (cam.type == Camera::Perspective) {
 
             aicam->mAspect        = cam.cameraProperties.perspective.aspectRatio;
-            aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * aicam->mAspect;
+            aicam->mHorizontalFOV = cam.cameraProperties.perspective.yfov * ((aicam->mAspect == 0.f) ? 1.f : aicam->mAspect);
             aicam->mClipPlaneFar  = cam.cameraProperties.perspective.zfar;
             aicam->mClipPlaneNear = cam.cameraProperties.perspective.znear;
-        }
-        else {
-            // assimp does not support orthographic cameras
+        } else {
+            aicam->mClipPlaneFar = cam.cameraProperties.ortographic.zfar;
+            aicam->mClipPlaneNear = cam.cameraProperties.ortographic.znear;
+            aicam->mHorizontalFOV = 0.0;
+            aicam->mAspect = 1.0f;
+            if (0.f != cam.cameraProperties.ortographic.ymag ) {
+                aicam->mAspect = cam.cameraProperties.ortographic.xmag / cam.cameraProperties.ortographic.ymag;
+            }
         }
     }
 }
@@ -901,6 +907,9 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
                 std::vector<std::vector<aiVertexWeight>> weighting(mesh->mNumBones);
                 BuildVertexWeightMapping(node.meshes[0]->primitives[primitiveNo], weighting);
 
+                mat4* pbindMatrices = nullptr;
+                node.skin->inverseBindMatrices->ExtractData(pbindMatrices);
+
                 for (uint32_t i = 0; i < mesh->mNumBones; ++i) {
                     aiBone* bone = new aiBone();
 
@@ -916,6 +925,8 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
                     }
                     GetNodeTransform(bone->mOffsetMatrix, *joint);
 
+                    CopyValue(pbindMatrices[i], bone->mOffsetMatrix);
+
                     std::vector<aiVertexWeight>& weights = weighting[i];
 
                     bone->mNumWeights = static_cast<uint32_t>(weights.size());
@@ -931,6 +942,10 @@ aiNode* ImportNode(aiScene* pScene, glTF2::Asset& r, std::vector<unsigned int>&
                     }
                     mesh->mBones[i] = bone;
                 }
+
+                if (pbindMatrices) {
+                    delete[] pbindMatrices;
+                }
             }
         }
 
@@ -987,7 +1002,12 @@ void glTF2Importer::ImportNodes(glTF2::Asset& r)
 }
 
 struct AnimationSamplers {
-    AnimationSamplers() : translation(nullptr), rotation(nullptr), scale(nullptr) {}
+    AnimationSamplers()
+    : translation(nullptr)
+    , rotation(nullptr)
+    , scale(nullptr) {
+        // empty
+    }
 
     Animation::Sampler* translation;
     Animation::Sampler* rotation;
@@ -1016,7 +1036,7 @@ aiNodeAnim* CreateNodeAnim(glTF2::Asset& r, Node& node, AnimationSamplers& sampl
         delete[] values;
     } else if (node.translation.isPresent) {
         anim->mNumPositionKeys = 1;
-        anim->mPositionKeys = new aiVectorKey();
+        anim->mPositionKeys = new aiVectorKey[anim->mNumPositionKeys];
         anim->mPositionKeys->mTime = 0.f;
         anim->mPositionKeys->mValue.x = node.translation.value[0];
         anim->mPositionKeys->mValue.y = node.translation.value[1];
@@ -1156,7 +1176,7 @@ void glTF2Importer::ImportAnimations(glTF2::Asset& r)
             }
         }
         ai_anim->mDuration = maxDuration;
-        ai_anim->mTicksPerSecond = (maxNumberOfKeys > 0 && maxDuration > 0) ? (maxNumberOfKeys / (maxDuration/1000)) : 30;
+        ai_anim->mTicksPerSecond = 1000.0;
 
         mScene->mAnimations[i] = ai_anim;
     }

+ 2 - 2
contrib/gtest/test/gtest-param-test_test.cc

@@ -141,7 +141,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
         << ", expected_values[i] is " << PrintValue(expected_values[i])
         << ", *it is " << PrintValue(*it)
         << ", and 'it' is an iterator created with the copy constructor.\n";
-    it++;
+    ++it;
   }
   EXPECT_TRUE(it == generator.end())
         << "At the presumed end of sequence when accessing via an iterator "
@@ -161,7 +161,7 @@ void VerifyGenerator(const ParamGenerator<T>& generator,
         << ", expected_values[i] is " << PrintValue(expected_values[i])
         << ", *it is " << PrintValue(*it)
         << ", and 'it' is an iterator created with the copy constructor.\n";
-    it++;
+    ++it;
   }
   EXPECT_TRUE(it == generator.end())
         << "At the presumed end of sequence when accessing via an iterator "

+ 1 - 1
contrib/irrXML/irrXML.h

@@ -215,7 +215,7 @@ namespace io
 	two methods to read your data and give a pointer to an instance of
 	your implementation when calling createIrrXMLReader(), 
 	createIrrXMLReaderUTF16() or createIrrXMLReaderUTF32() */
-	class IFileReadCallBack
+	class IRRXML_API IFileReadCallBack
 	{
 	public:
 

+ 19 - 10
include/assimp/MathFunctions.h

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

+ 0 - 2
include/assimp/camera.h

@@ -113,7 +113,6 @@ struct aiCamera
      */
     C_STRUCT aiVector3D mPosition;
 
-
     /** 'Up' - vector of the camera coordinate system relative to
      *  the coordinate space defined by the corresponding node.
      *
@@ -134,7 +133,6 @@ struct aiCamera
      */
     C_STRUCT aiVector3D mLookAt;
 
-
     /** Half horizontal field of view angle, in radians.
      *
      *  The field of view angle is the angle between the center

+ 33 - 13
include/assimp/material.h

@@ -196,34 +196,40 @@ enum aiTextureType
      *  (#aiMaterialProperty::mSemantic) for all material properties
      *  *not* related to textures.
      */
-    aiTextureType_NONE = 0x0,
+    aiTextureType_NONE = 0,
+
+    /** LEGACY API MATERIALS 
+     * Legacy refers to materials which 
+     * Were originally implemented in the specifications around 2000.
+     * These must never be removed, as most engines support them.
+     */
 
     /** The texture is combined with the result of the diffuse
      *  lighting equation.
      */
-    aiTextureType_DIFFUSE = 0x1,
+    aiTextureType_DIFFUSE = 1,
 
     /** The texture is combined with the result of the specular
      *  lighting equation.
      */
-    aiTextureType_SPECULAR = 0x2,
+    aiTextureType_SPECULAR = 2,
 
     /** The texture is combined with the result of the ambient
      *  lighting equation.
      */
-    aiTextureType_AMBIENT = 0x3,
+    aiTextureType_AMBIENT = 3,
 
     /** The texture is added to the result of the lighting
      *  calculation. It isn't influenced by incoming light.
      */
-    aiTextureType_EMISSIVE = 0x4,
+    aiTextureType_EMISSIVE = 4,
 
     /** The texture is a height map.
      *
      *  By convention, higher gray-scale values stand for
      *  higher elevations from the base height.
      */
-    aiTextureType_HEIGHT = 0x5,
+    aiTextureType_HEIGHT = 5,
 
     /** The texture is a (tangent space) normal-map.
      *
@@ -231,7 +237,7 @@ enum aiTextureType
      *  normal maps. Assimp does (intentionally) not
      *  distinguish here.
      */
-    aiTextureType_NORMALS = 0x6,
+    aiTextureType_NORMALS = 6,
 
     /** The texture defines the glossiness of the material.
      *
@@ -240,21 +246,21 @@ enum aiTextureType
      *  function defined to map the linear color values in the
      *  texture to a suitable exponent. Have fun.
     */
-    aiTextureType_SHININESS = 0x7,
+    aiTextureType_SHININESS = 7,
 
     /** The texture defines per-pixel opacity.
      *
      *  Usually 'white' means opaque and 'black' means
      *  'transparency'. Or quite the opposite. Have fun.
     */
-    aiTextureType_OPACITY = 0x8,
+    aiTextureType_OPACITY = 8,
 
     /** Displacement texture
      *
      *  The exact purpose and format is application-dependent.
      *  Higher color values stand for higher vertex displacements.
     */
-    aiTextureType_DISPLACEMENT = 0x9,
+    aiTextureType_DISPLACEMENT = 9,
 
     /** Lightmap texture (aka Ambient Occlusion)
      *
@@ -263,14 +269,28 @@ enum aiTextureType
      *  scaling value for the final color value of a pixel. Its
      *  intensity is not affected by incoming light.
     */
-    aiTextureType_LIGHTMAP = 0xA,
+    aiTextureType_LIGHTMAP = 10,
 
     /** Reflection texture
      *
      * Contains the color of a perfect mirror reflection.
      * Rarely used, almost never for real-time applications.
     */
-    aiTextureType_REFLECTION = 0xB,
+    aiTextureType_REFLECTION = 11,
+
+    /** PBR Materials
+     * PBR definitions from maya and other modelling packages now use this standard.
+     * This was originally introduced around 2012.
+     * Support for this is in game engines like Godot, Unreal or Unity3D.
+     * Modelling packages which use this are very common now.
+     */
+
+    aiTextureType_BASE_COLOR = 12,
+    aiTextureType_NORMAL_CAMERA = 13,
+    aiTextureType_EMISSION_COLOR = 14,
+    aiTextureType_METALNESS = 15,
+    aiTextureType_DIFFUSE_ROUGHNESS = 16,
+    aiTextureType_AMBIENT_OCCLUSION = 17,
 
     /** Unknown texture
      *
@@ -278,7 +298,7 @@ enum aiTextureType
      *  above is considered to be 'unknown'. It is still imported,
      *  but is excluded from any further post-processing.
     */
-    aiTextureType_UNKNOWN = 0xC,
+    aiTextureType_UNKNOWN = 18,
 
 
 #ifndef SWIG

+ 4 - 5
include/assimp/matrix4x4.inl

@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
 
 Copyright (c) 2006-2019, assimp team
 
-
-
 All rights reserved.
 
 Redistribution and use of this software in source and binary forms,
@@ -53,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "matrix4x4.h"
 #include "matrix3x3.h"
 #include "quaternion.h"
+#include "MathFunctions.h"
 
 #include <algorithm>
 #include <limits>
@@ -420,8 +419,8 @@ inline void aiMatrix4x4t<TReal>::Decompose (aiVector3t<TReal>& pScaling, aiQuate
 }
 
 template <typename TReal>
-inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const
-{
+inline
+void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector3t<TReal>& pRotation, aiVector3t<TReal>& pPosition) const {
 	ASSIMP_MATRIX4_4_DECOMPOSE_PART;
 
     /*
@@ -442,7 +441,7 @@ inline void aiMatrix4x4t<TReal>::Decompose(aiVector3t<TReal>& pScaling, aiVector
 	*/
 
 	// Use a small epsilon to solve floating-point inaccuracies
-    const TReal epsilon = 10e-3f;
+    const TReal epsilon = Assimp::Math::getEpsilon<TReal>();
 
 	pRotation.y  = std::asin(-vCols[0].z);// D. Angle around oY.
 

+ 13 - 8
include/assimp/types.h

@@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include <stddef.h>
 #include <string.h>
 #include <limits.h>
+#include <stdint.h>
 
 // Our compile configuration
 #include "defs.h"
@@ -65,11 +66,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "matrix4x4.h"
 #include "quaternion.h"
 
+typedef int32_t ai_int32;
+typedef uint32_t ai_uint32 ;
+
 #ifdef __cplusplus
 #include <cstring>
 #include <new>      // for std::nothrow_t
 #include <string>   // for aiString::Set(const std::string&)
 
+
 namespace Assimp    {
     //! @cond never
 namespace Intern        {
@@ -269,8 +274,8 @@ struct aiString
     }
 
     /** Copy constructor */
-    aiString(const aiString& rOther) :
-        length(rOther.length)
+    aiString(const aiString& rOther)
+    : length(rOther.length)
     {
         // Crop the string to the maximum length
         length = length>=MAXLEN?MAXLEN-1:length;
@@ -280,7 +285,7 @@ struct aiString
 
     /** Constructor from std::string */
     explicit aiString(const std::string& pString) :
-        length(pString.length())
+        length( (ai_uint32) pString.length())
     {
         length = length>=MAXLEN?MAXLEN-1:length;
         memcpy( data, pString.c_str(), length);
@@ -292,15 +297,15 @@ struct aiString
         if( pString.length() > MAXLEN - 1) {
             return;
         }
-        length = pString.length();
+        length = (ai_uint32)pString.length();
         memcpy( data, pString.c_str(), length);
         data[length] = 0;
     }
 
     /** Copy a const char* to the aiString */
     void Set( const char* sz) {
-        const size_t len = ::strlen(sz);
-        if( len > MAXLEN - 1) {
+        const ai_int32 len = (ai_uint32) ::strlen(sz);
+        if( len > (ai_int32)MAXLEN - 1) {
             return;
         }
         length = len;
@@ -346,7 +351,7 @@ struct aiString
 
     /** Append a string to the string */
     void Append (const char* app)   {
-        const size_t len = ::strlen(app);
+        const ai_uint32 len = (ai_uint32) ::strlen(app);
         if (!len) {
             return;
         }
@@ -379,7 +384,7 @@ struct aiString
     /** Binary length of the string excluding the terminal 0. This is NOT the
      *  logical length of strings containing UTF-8 multi-byte sequences! It's
      *  the number of bytes from the beginning of the string to its end.*/
-    size_t length;
+    ai_uint32 length;
 
     /** String buffer. Size limit is MAXLEN */
     char data[MAXLEN];

+ 2 - 2
port/PyAssimp/pyassimp/helper.py

@@ -274,8 +274,8 @@ def hasattr_silent(object, name):
     """
 
     try:
-	    if not object:
-		    return False
+        if not object:
+            return False
         return hasattr(object, name)
     except AttributeError:
         return False

+ 1 - 0
samples/SimpleOpenGL/CMakeLists.txt

@@ -25,6 +25,7 @@ INCLUDE_DIRECTORIES(
   ${Assimp_SOURCE_DIR}/include
   ${Assimp_SOURCE_DIR}/code
   ${OPENGL_INCLUDE_DIR}
+  ${GLUT_INCLUDE_DIR}
   ${Assimp_SOURCE_DIR}/samples/freeglut/include
 )
 

+ 2 - 2
samples/SimpleOpenGL/Sample_SimpleOpenGL.c

@@ -49,7 +49,7 @@ void reshape(int width, int height)
 }
 
 /* ---------------------------------------------------------------------------- */
-void get_bounding_box_for_node (const a<C_STRUCT iNode* nd,
+void get_bounding_box_for_node (const C_STRUCT aiNode* nd,
 	C_STRUCT aiVector3D* min,
 	C_STRUCT aiVector3D* max,
 	C_STRUCT aiMatrix4x4* trafo
@@ -86,7 +86,7 @@ void get_bounding_box_for_node (const a<C_STRUCT iNode* nd,
 /* ---------------------------------------------------------------------------- */
 void get_bounding_box(C_STRUCT aiVector3D* min, C_STRUCT aiVector3D* max)
 {
-	aiMatrix4x4 trafo;
+	C_STRUCT aiMatrix4x4 trafo;
 	aiIdentityMatrix4(&trafo);
 
 	min->x = min->y = min->z =  1e10f;

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
test/models/FBX/transparentTest.fbx


+ 98 - 0
test/models/glTF2/cameras/Cameras.gltf

@@ -0,0 +1,98 @@
+{
+  "scenes" : [
+    {
+      "nodes" : [ 0, 1, 2 ]
+    }
+  ],
+  "nodes" : [
+    {
+      "rotation" : [ -0.383, 0.0, 0.0, 0.92375 ],
+      "mesh" : 0
+    },
+    {
+      "translation" : [ 0.5, 0.5, 3.0 ],
+      "camera" : 0
+    },
+    {
+      "translation" : [ 0.5, 0.5, 3.0 ],
+      "camera" : 1
+    }
+  ],
+  
+  "cameras" : [
+    {
+      "type": "perspective",
+      "perspective": {
+        "aspectRatio": 1.0,
+        "yfov": 0.7,
+        "zfar": 100,
+        "znear": 0.01
+      }
+    },
+    {
+      "type": "orthographic",
+      "orthographic": {
+        "xmag": 1.0,
+        "ymag": 1.0,
+        "zfar": 100,
+        "znear": 0.01
+      }
+    }
+  ],
+  
+  "meshes" : [
+    {
+      "primitives" : [ {
+        "attributes" : {
+          "POSITION" : 1
+        },
+        "indices" : 0
+      } ]
+    }
+  ],
+
+  "buffers" : [
+    {
+      "uri" : "simpleSquare.bin",
+      "byteLength" : 60
+    }
+  ],
+  "bufferViews" : [
+    {
+      "buffer" : 0,
+      "byteOffset" : 0,
+      "byteLength" : 12,
+      "target" : 34963
+    },
+    {
+      "buffer" : 0,
+      "byteOffset" : 12,
+      "byteLength" : 48,
+      "target" : 34962
+    }
+  ],
+  "accessors" : [
+    {
+      "bufferView" : 0,
+      "byteOffset" : 0,
+      "componentType" : 5123,
+      "count" : 6,
+      "type" : "SCALAR",
+      "max" : [ 3 ],
+      "min" : [ 0 ]
+    },
+    {
+      "bufferView" : 1,
+      "byteOffset" : 0,
+      "componentType" : 5126,
+      "count" : 4,
+      "type" : "VEC3",
+      "max" : [ 1.0, 1.0, 0.0 ],
+      "min" : [ 0.0, 0.0, 0.0 ]
+    }
+  ],
+  
+  "asset" : {
+    "version" : "2.0"
+  }
+}

BIN=BIN
test/models/glTF2/cameras/simpleSquare.bin


+ 6 - 0
test/unit/utFBXImporterExporter.cpp

@@ -276,3 +276,9 @@ TEST_F(utFBXImporterExporter, importEmbeddedFragmentedAsciiTest) {
     ASSERT_TRUE(scene->mTextures[0]->pcData);
     ASSERT_EQ(968029u, scene->mTextures[0]->mWidth) << "FBX ASCII base64 compression splits data by 512Kb, it should be two parts for this texture";
 }
+
+TEST_F(utFBXImporterExporter, fbxTokenizeTestTest) {
+    //Assimp::Importer importer;
+    //const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/transparentTest2.fbx", aiProcess_ValidateDataStructure);
+    //EXPECT_NE(nullptr, scene);
+}

+ 7 - 0
test/unit/utglTF2ImportExport.cpp

@@ -375,6 +375,13 @@ TEST_F( utglTF2ImportExport, bug_import_simple_skin ) {
     EXPECT_NE( nullptr, scene );
 }
 
+TEST_F(utglTF2ImportExport, import_cameras) {
+    Assimp::Importer importer;
+    const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/cameras/Cameras.gltf",
+        aiProcess_ValidateDataStructure);
+    EXPECT_NE(nullptr, scene);
+}
+
 #ifndef ASSIMP_BUILD_NO_EXPORT
 TEST_F( utglTF2ImportExport, exportglTF2FromFileTest ) {
     EXPECT_TRUE( exporterTest() );

+ 0 - 76
tools/assimp_qt_viewer/CMakeLists.txt

@@ -1,76 +0,0 @@
-set(PROJECT_VERSION "")
-project(assimp_qt_viewer)
-
-# Qt5 requires cmake 3.1 or newer
-cmake_minimum_required(VERSION 3.1)
-
-FIND_PACKAGE(OpenGL QUIET)
-
-# Qt5 version
-FIND_PACKAGE(Qt5 COMPONENTS Gui Widgets OpenGL QUIET)
-
-SET(VIEWER_BUILD:BOOL FALSE)
-
-IF(  Qt5Widgets_FOUND AND OPENGL_FOUND)
-	SET(VIEWER_BUILD TRUE)
-ELSE( Qt5Widgets_FOUND AND OPENGL_FOUND)
-	SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "")
-
-	IF (NOT Qt5_FOUND)
-		SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} Qt5")
-	ENDIF (NOT Qt5_FOUND)
-
-	IF (NOT OPENGL_FOUND)
-		SET ( ASSIMP_QT_VIEWER_DEPENDENCIES "${ASSIMP_QT_VIEWER_DEPENDENCIES} OpengGL")
-	ENDIF (NOT OPENGL_FOUND)
-
-	MESSAGE (WARNING "Build of assimp_qt_viewer is disabled. Unsatisfied dendencies: ${ASSIMP_QT_VIEWER_DEPENDENCIES}")
-ENDIF( Qt5Widgets_FOUND AND OPENGL_FOUND)
-
-IF(VIEWER_BUILD)
-	INCLUDE_DIRECTORIES(
-		${Assimp_SOURCE_DIR}/include
-		${Assimp_SOURCE_DIR}/code
-		${CMAKE_CURRENT_BINARY_DIR}
-		${CMAKE_SOURCE_DIR}
-		${OPENGL_INCLUDE_DIR}
-	)
-
-	LINK_DIRECTORIES(${Assimp_BINARY_DIR})
-	SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pedantic -Wall")
-
-	SET(assimp_qt_viewer_SRCS 
-        main.cpp 
-        loggerview.hpp
-        loggerview.cpp 
-        glview.hpp
-        glview.cpp 
-        mainwindow.hpp
-        mainwindow.cpp
-    )
-
-	MESSAGE("assimp_qt_viewer use Qt5")
-	INCLUDE_DIRECTORIES(${Qt5Widgets_INCLUDES})
-	qt5_wrap_ui(UISrcs mainwindow.ui)
-	qt5_wrap_cpp(MOCrcs mainwindow.hpp glview.hpp)
-
-	add_executable(${PROJECT_NAME} ${assimp_qt_viewer_SRCS} ${UISrcs} ${MOCrcs})
-	target_link_libraries(${PROJECT_NAME} Qt5::Gui Qt5::Widgets Qt5::OpenGL ${OPENGL_LIBRARIES} assimp)
-
-	IF(WIN32) # Check if we are on Windows
-		IF(MSVC) # Check if we are using the Visual Studio compiler
-			#set_target_properties(TestProject PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
-		ELSEIF(CMAKE_COMPILER_IS_GNUCXX)
-			# SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mwindows") # Not tested
-		ELSE()
-			MESSAGE(SEND_ERROR "You are using an unsupported Windows compiler! (Not MSVC or GCC)")
-		ENDIF()
-	ELSEIF(UNIX)
-		# Nothing special required
-	ELSE()
-		MESSAGE(SEND_ERROR "You are on an unsupported platform! (Not Win32 or Unix)")
-	ENDIF()
-
-	SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
-	INSTALL(TARGETS assimp_qt_viewer DESTINATION "${ASSIMP_BIN_INSTALL_DIR}")
-ENDIF(VIEWER_BUILD)

BIN=BIN
tools/assimp_qt_viewer/doc/Assimp_qt_viewer. Manual (en).odt


BIN=BIN
tools/assimp_qt_viewer/doc/Assimp_qt_viewer. Manual (ru).odt


+ 0 - 1161
tools/assimp_qt_viewer/glview.cpp

@@ -1,1161 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-#include "glview.hpp"
-
-// Header files, Qt.
-#include <QTime>
-
-// Header files, OpenGL.
-#if defined(__APPLE__)
-# include <OpenGL/glu.h>
-#else
-# include <GL/glu.h>
-#endif
-
-// Header files, DevIL.
-
-// Header files, Assimp.
-#include <assimp/DefaultLogger.hpp>
-
-#define STB_IMAGE_IMPLEMENTATION
-#include "contrib/stb_image/stb_image.h"
-
-CGLView::SHelper_Mesh::SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox)
-: Quantity_Point(pQuantity_Point)
-, Quantity_Line(pQuantity_Line)
-, Quantity_Triangle(pQuantity_Triangle)
-, BBox(pBBox) {
-	Index_Point = pQuantity_Point ? new GLuint[pQuantity_Point * 1] : nullptr;
-	Index_Line = pQuantity_Line ? new GLuint[pQuantity_Line * 2] : nullptr;
-	Index_Triangle = pQuantity_Triangle ? new GLuint[pQuantity_Triangle * 3] : nullptr;
-}
-
-CGLView::SHelper_Mesh::~SHelper_Mesh() {
-	delete [] Index_Point;
-	delete [] Index_Line;
-	delete [] Index_Triangle;
-}
-
-void CGLView::SHelper_Camera::SetDefault() {
-	Position.Set(0, 0, 0);
-	Target.Set(0, 0, -1);
-	Rotation_AroundCamera = aiMatrix4x4();
-	Rotation_Scene = aiMatrix4x4();
-	Translation_ToScene.Set(0, 0, 2);
-}
-
-static void set_float4(float f[4], float a, float b, float c, float d) {
-    f[0] = a;
-    f[1] = b;
-    f[2] = c;
-    f[3] = d;
-}
-
-static void color4_to_float4(const aiColor4D *c, float f[4]) {
-    f[0] = c->r;
-    f[1] = c->g;
-    f[2] = c->b;
-    f[3] = c->a;
-}
-
-void CGLView::Material_Apply(const aiMaterial* pMaterial) {
-    GLfloat tcol[4];
-    aiColor4D taicol;
-    unsigned int max;
-    int ret1, ret2;
-    int texture_index = 0;
-    aiString texture_path;
-
-	///TODO: cache materials
-	// Disable color material because glMaterial is used.
-	glDisable(GL_COLOR_MATERIAL);///TODO: cache
-	
-                                 // Set texture. If assigned.
-	if(AI_SUCCESS == pMaterial->GetTexture(aiTextureType_DIFFUSE, texture_index, &texture_path)) {
-		//bind texture
-		unsigned int texture_ID = mTexture_IDMap.value(texture_path.data, 0);
-
-		glBindTexture(GL_TEXTURE_2D, texture_ID);
-	}
-	//
-	// Set material parameters from scene or default values.
-	//
-	// Diffuse
-	set_float4(tcol, 0.8f, 0.8f, 0.8f, 1.0f);
-    if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_DIFFUSE, &taicol )) {
-        color4_to_float4( &taicol, tcol );
-    }
-
-	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, tcol);
-	
-    // Specular
-	set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f);
-    if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_SPECULAR, &taicol )) {
-        color4_to_float4( &taicol, tcol );
-    }
-
-	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol);
-	// Ambient
-	set_float4(tcol, 0.2f, 0.2f, 0.2f, 1.0f);
-    if ( AI_SUCCESS == aiGetMaterialColor( pMaterial, AI_MATKEY_COLOR_AMBIENT, &taicol )) {
-        color4_to_float4( &taicol, tcol );
-    }
-	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, tcol);
-	
-    // Emission
-	set_float4(tcol, 0.0f, 0.0f, 0.0f, 1.0f);
-	if(AI_SUCCESS == aiGetMaterialColor(pMaterial, AI_MATKEY_COLOR_EMISSIVE, &taicol)) color4_to_float4(&taicol, tcol);
-
-	glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, tcol);
-	// Shininess
-	ai_real shininess, strength;
-
-	max = 1;
-	ret1 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS, &shininess, &max);
-	// Shininess strength
-	max = 1;
-	ret2 = aiGetMaterialFloatArray(pMaterial, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
-	if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS)) {
-		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);///TODO: cache
-	} else {
-		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);///TODO: cache
-		set_float4(tcol, 0.0f, 0.0f, 0.0f, 0.0f);
-		glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, tcol);
-	}
-
-	// Fill mode
-	GLenum fill_mode;
-	int wireframe;
-
-	max = 1;
-	if(AI_SUCCESS == aiGetMaterialIntegerArray(pMaterial, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
-		fill_mode = wireframe ? GL_LINE : GL_FILL;
-	else
-		fill_mode = GL_FILL;
-
-	glPolygonMode(GL_FRONT_AND_BACK, fill_mode);///TODO: cache
-	// Fill side
-	int two_sided;
-
-	max = 1;
-	if((AI_SUCCESS == aiGetMaterialIntegerArray(pMaterial, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)///TODO: cache
-		glDisable(GL_CULL_FACE);
-	else
-		glEnable(GL_CULL_FACE);
-}
-
-void CGLView::Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
-{
-    const aiNode* node_cur;
-    std::list<aiMatrix4x4> mat_list;
-
-	pOutMatrix = aiMatrix4x4();
-	// starting walk from current element to root
-	node_cur = pNode;
-	if(node_cur != nullptr)
-	{
-		do
-		{
-			// if cur_node is group then store group transformation matrix in list.
-			mat_list.push_back(node_cur->mTransformation);
-			node_cur = node_cur->mParent;
-		} while(node_cur != nullptr);
-	}
-
-	// multiply all matrices in reverse order
-    for ( std::list<aiMatrix4x4>::reverse_iterator rit = mat_list.rbegin(); rit != mat_list.rend(); ++rit)
-    {
-        pOutMatrix = pOutMatrix * (*rit);
-    }
-}
-
-void CGLView::ImportTextures(const QString& scenePath) {
-    auto LoadTexture = [&](const QString& pFileName) -> bool ///TODO: IME texture mode, operation.
-    {
-        GLuint id_ogl_texture;// OpenGL texture ID.
-
-	    if(!pFileName.startsWith(AI_EMBEDDED_TEXNAME_PREFIX))
-	    {
-		    QString basepath = scenePath.left(scenePath.lastIndexOf('/') + 1);// path with '/' at the end.
-		    QString fileloc = (basepath + pFileName);
-
-		    fileloc.replace('\\', "/");
-            int x, y, n;
-            unsigned char *data = stbi_load(fileloc.toLocal8Bit(), &x, &y, &n, STBI_rgb_alpha );
-            if ( nullptr == data ) {
-			    LogError(QString("Couldn't load Image: %1").arg(fileloc));
-
-			    return false;
-		    }
-
-		    // Convert every colour component into unsigned byte. If your image contains alpha channel you can replace IL_RGB with IL_RGBA.
-
-		    glGenTextures(1, &id_ogl_texture);// Texture ID generation.
-		    mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
-		    glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
-		    // Redefine standard texture values
-		    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
-		    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
-            glTexImage2D(GL_TEXTURE_2D, 0, n, x, y, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, data );// Texture specification.
-            stbi_image_free(data);
-            // Cleanup
-	    }
-	    else
-	    {
-		    struct SPixel_Description
-		    {
-			    const char* FormatHint;
-			    const GLint Image_InternalFormat;
-			    const GLint Pixel_Format;
-		    };
-
-		    constexpr SPixel_Description Pixel_Description[] = {
-			    {"rgba8880", GL_RGB, GL_RGB},
-			    {"rgba8888", GL_RGBA, GL_RGBA}
-		    };
-
-		    constexpr size_t Pixel_Description_Count = sizeof(Pixel_Description) / sizeof(SPixel_Description);
-
-		    size_t idx_description;
-		    // Get texture index.
-		    bool ok;
-		    size_t idx_texture = pFileName.right(strlen(AI_EMBEDDED_TEXNAME_PREFIX)).toULong(&ok);
-
-		    if(!ok)
-		    {
-			    LogError("Can not get index of the embedded texture from path in material.");
-
-			    return false;
-		    }
-
-		    // Create alias for conveniance.
-		    const aiTexture& als = *mScene->mTextures[idx_texture];
-
-		    if(als.mHeight == 0)// Compressed texture.
-		    {
-			    LogError("IME: compressed embedded textures are not implemented.");
-		    }
-		    else
-		    {
-			    ok = false;
-			    for(size_t idx = 0; idx < Pixel_Description_Count; idx++)
-			    {
-				    if(als.CheckFormat(Pixel_Description[idx].FormatHint))
-				    {
-					    idx_description = idx;
-					    ok = true;
-					    break;
-				    }
-			    }
-
-			    if(!ok)
-			    {
-				    LogError(QString("Unsupported format hint for embedded texture: [%1]").arg(als.achFormatHint));
-
-				    return false;
-			    }
-
-			    glGenTextures(1, &id_ogl_texture);// Texture ID generation.
-			    mTexture_IDMap[pFileName] = id_ogl_texture;// save texture ID for filename in map
-			    glBindTexture(GL_TEXTURE_2D, id_ogl_texture);// Binding of texture ID.
-			    // Redefine standard texture values
-			    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);// We will use linear interpolation for magnification filter.
-			    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);// We will use linear interpolation for minifying filter.
-			    // Texture specification.
-			    glTexImage2D(GL_TEXTURE_2D, 0, Pixel_Description[idx_description].Image_InternalFormat, als.mWidth, als.mHeight, 0,
-							    Pixel_Description[idx_description].Pixel_Format, GL_UNSIGNED_BYTE, (uint8_t*)als.pcData);
-		    }// if(als.mHeight == 0) else
-	    }// if(!filename.startsWith(AI_EMBEDDED_TEXNAME_PREFIX)) else
-
-	    return true;
-    };// auto LoadTexture = [&](const aiString& pPath)
-
-	if(mScene == nullptr)
-	{
-		LogError("Trying to load textures for empty scene.");
-
-		return;
-	}
-
-	//
-	// Load textures.
-	//
-	// Get textures file names and number of textures.
-	for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++) {
-		int idx_texture = 0;
-		aiString path;
-
-		do {
-            if (mScene->mMaterials[ idx_material ]->GetTexture( aiTextureType_DIFFUSE, idx_texture, &path ) != AI_SUCCESS) {
-                break;
-            }
-
-			LoadTexture(QString(path.C_Str()));
-			idx_texture++;
-		} while(true);
-	}// for(size_t idx_material = 0; idx_material < mScene->mNumMaterials; idx_material++)
-
-	// Textures list is empty, exit.
-	if(mTexture_IDMap.empty()) {
-		LogInfo("No textures for import.");
-	}
-}
-
-void CGLView::BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParent_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign)
-{
-    aiMatrix4x4 mat_trans = pParent_TransformationMatrix * pNode.mTransformation;
-
-	// Check if node has meshes
-	for(size_t idx_idx_mesh = 0; idx_idx_mesh < pNode.mNumMeshes; idx_idx_mesh++)
-	{
-		size_t idx_mesh;
-		SBBox bbox_local;
-		aiVector3D bbox_vertices[8];
-
-		idx_mesh = pNode.mMeshes[idx_idx_mesh];
-		// Get vertices of mesh BBox
-		BBox_GetVertices(mHelper_Mesh[idx_mesh]->BBox, bbox_vertices);
-		// Transform vertices
-		for(size_t idx_vert = 0; idx_vert < 8; idx_vert++) bbox_vertices[idx_vert] *= mat_trans;
-
-		// And create BBox for transformed mesh
-		BBox_GetFromVertices(bbox_vertices, 8, bbox_local);
-
-		if(!pFirstAssign)
-		{
-			BBox_Extend(bbox_local, pNodeBBox);
-		}
-		else
-		{
-			pFirstAssign = false;
-			pNodeBBox = bbox_local;
-		}
-	}// for(size_t idx_idx_mesh = 0; idx_idx_mesh < pNode.mNumMeshes; idx_idx_mesh++)
-
-	for(size_t idx_node = 0; idx_node < pNode.mNumChildren; idx_node++)
-	{
-		BBox_GetForNode(*pNode.mChildren[idx_node], mat_trans, pNodeBBox, pFirstAssign);
-	}
-}
-
-void CGLView::BBox_Extend(const SBBox& pChild, SBBox& pParent)
-{
-	// search minimal...
-	AssignIfLesser(&pParent.Minimum.x, pChild.Minimum.x);
-	AssignIfLesser(&pParent.Minimum.y, pChild.Minimum.y);
-	AssignIfLesser(&pParent.Minimum.z, pChild.Minimum.z);
-	// and maximal values
-	AssignIfGreater(&pParent.Maximum.x, pChild.Maximum.x);
-	AssignIfGreater(&pParent.Maximum.y, pChild.Maximum.y);
-	AssignIfGreater(&pParent.Maximum.z, pChild.Maximum.z);
-}
-
-void CGLView::BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertex[8])
-{
-	pVertex[0] = pBBox.Minimum;
-	pVertex[1].Set(pBBox.Minimum.x, pBBox.Minimum.y, pBBox.Maximum.z);
-	pVertex[2].Set(pBBox.Minimum.x, pBBox.Maximum.y, pBBox.Maximum.z);
-	pVertex[3].Set(pBBox.Minimum.x, pBBox.Maximum.y, pBBox.Minimum.z);
-
-	pVertex[4].Set(pBBox.Maximum.x, pBBox.Minimum.y, pBBox.Minimum.z);
-	pVertex[5].Set(pBBox.Maximum.x, pBBox.Minimum.y, pBBox.Maximum.z);
-	pVertex[6] = pBBox.Maximum;
-	pVertex[7].Set(pBBox.Maximum.x, pBBox.Maximum.y, pBBox.Minimum.z);
-
-}
-
-void CGLView::BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox)
-{
-	if(pVerticesQuantity == 0)
-	{
-		pBBox.Maximum.Set(0, 0, 0);
-		pBBox.Minimum.Set(0, 0, 0);
-
-		return;
-	}
-
-	// Assign first values.
-	pBBox.Minimum = pVertices[0];
-	pBBox.Maximum = pVertices[0];
-
-	for(size_t idx_vert = 1; idx_vert < pVerticesQuantity; idx_vert++)
-	{
-		const ai_real x = pVertices[idx_vert].x;
-		const ai_real y = pVertices[idx_vert].y;
-		const ai_real z = pVertices[idx_vert].z;
-
-		// search minimal...
-		AssignIfLesser(&pBBox.Minimum.x, x);
-		AssignIfLesser(&pBBox.Minimum.y, y);
-		AssignIfLesser(&pBBox.Minimum.z, z);
-		// and maximal values
-		AssignIfGreater(&pBBox.Maximum.x, x);
-		AssignIfGreater(&pBBox.Maximum.y, y);
-		AssignIfGreater(&pBBox.Maximum.z, z);
-	}
-}
-
-void CGLView::LogInfo(const QString& pMessage) {
-	Assimp::DefaultLogger::get()->info(pMessage.toStdString());
-}
-
-void CGLView::LogError(const QString& pMessage) {
-	Assimp::DefaultLogger::get()->error(pMessage.toStdString());
-}
-
-void CGLView::Draw_Node(const aiNode* pNode) {
-    aiMatrix4x4 mat_node = pNode->mTransformation;
-
-	// Apply node transformation matrix.
-	mat_node.Transpose();
-	glPushMatrix();
-#ifdef ASSIMP_DOUBLE_PRECISION
-	glMultMatrixd((GLdouble*)mat_node[0]);
-#else
-	glMultMatrixf((GLfloat*)&mat_node);
-#endif // ASSIMP_DOUBLE_PRECISION
-
-	// Draw all meshes assigned to this node
-	for(size_t idx_mesh_arr = 0; idx_mesh_arr < pNode->mNumMeshes; idx_mesh_arr++) Draw_Mesh(pNode->mMeshes[idx_mesh_arr]);
-
-	// Draw all children nodes
-	for(size_t idx_node = 0; idx_node < pNode->mNumChildren; idx_node++) Draw_Node(pNode->mChildren[idx_node]);
-
-	// Restore transformation matrix.
-	glPopMatrix();
-}
-
-void CGLView::Draw_Mesh(const size_t pMesh_Index)
-{
-	// Check argument
-	if(pMesh_Index >= mHelper_Mesh_Quantity) return;
-
-	aiMesh& mesh_cur = *mScene->mMeshes[pMesh_Index];
-
-	if(!mesh_cur.HasPositions()) return;// Nothing to draw.
-
-	// If mesh use material then apply it
-	if(mScene->HasMaterials()) Material_Apply(mScene->mMaterials[mesh_cur.mMaterialIndex]);
-
-	//
-	// Vertices array
-	//
-	glEnableClientState(GL_VERTEX_ARRAY);
-#if ASSIMP_DOUBLE_PRECISION
-	glVertexPointer(3, GL_DOUBLE, 0, mesh_cur.mVertices);
-#else
-	glVertexPointer(3, GL_FLOAT, 0, mesh_cur.mVertices);
-#endif // ASSIMP_DOUBLE_PRECISION
-
-	if(mesh_cur.HasVertexColors(0))
-	{
-		glEnable(GL_COLOR_MATERIAL);///TODO: cache
-		glEnableClientState(GL_COLOR_ARRAY);
-#ifdef ASSIMP_DOUBLE_PRECISION
-		glColorPointer(4, GL_DOUBLE, 0, mesh_cur.mColors[0]);
-#else
-		glColorPointer(4, GL_FLOAT, 0, mesh_cur.mColors[0]);
-#endif // ASSIMP_DOUBLE_PRECISION
-	}
-
-	//
-	// Texture coordinates array
-	//
-	if(mesh_cur.HasTextureCoords(0))
-	{
-		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-#ifdef ASSIMP_DOUBLE_PRECISION
-		glTexCoordPointer(2, GL_DOUBLE, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
-#else
-		glTexCoordPointer(2, GL_FLOAT, sizeof(aiVector3D), mesh_cur.mTextureCoords[0]);
-#endif // ASSIMP_DOUBLE_PRECISION
-	}
-
-	//
-	// Normals array
-	//
-	if(mesh_cur.HasNormals())
-	{
-		glEnableClientState(GL_NORMAL_ARRAY);
-#ifdef ASSIMP_DOUBLE_PRECISION
-		glNormalPointer(GL_DOUBLE, 0, mesh_cur.mNormals);
-#else
-		glNormalPointer(GL_FLOAT, 0, mesh_cur.mNormals);
-#endif // ASSIMP_DOUBLE_PRECISION
-	}
-
-	//
-	// Draw arrays
-	//
-	SHelper_Mesh& helper_cur = *mHelper_Mesh[pMesh_Index];
-
-	if(helper_cur.Quantity_Triangle > 0) glDrawElements(GL_TRIANGLES, helper_cur.Quantity_Triangle * 3, GL_UNSIGNED_INT, helper_cur.Index_Triangle);
-	if(helper_cur.Quantity_Line > 0) glDrawElements(GL_LINES,helper_cur.Quantity_Line * 2, GL_UNSIGNED_INT, helper_cur.Index_Line);
-	if(helper_cur.Quantity_Point > 0) glDrawElements(GL_POINTS, helper_cur.Quantity_Point, GL_UNSIGNED_INT, helper_cur.Index_Point);
-
-	//
-	// Clean up
-	//
-	glDisableClientState(GL_VERTEX_ARRAY);
-	glDisableClientState(GL_COLOR_ARRAY);
-	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-	glDisableClientState(GL_NORMAL_ARRAY);
-}
-
-void CGLView::Draw_BBox(const SBBox& pBBox)
-{
-    aiVector3D vertex[8];
-
-	BBox_GetVertices(pBBox, vertex);
-	// Draw
-	if(mLightingEnabled) glDisable(GL_LIGHTING);///TODO: display list
-
-	glEnable(GL_COLOR_MATERIAL);
-	glBindTexture(GL_TEXTURE_1D, 0);
-	glBindTexture(GL_TEXTURE_2D, 0);
-	glBindTexture(GL_TEXTURE_3D, 0);
-	const QColor c_w(Qt::white);
-
-	glColor3f(c_w.redF(), c_w.greenF(), c_w.blueF());
-
-	glBegin(GL_LINE_STRIP);
-#	ifdef ASSIMP_DOUBLE_PRECISION
-		glVertex3dv(&vertex[0][0]), glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[0][0]);// "Minimum" side.
-		glVertex3dv(&vertex[4][0]), glVertex3dv(&vertex[5][0]), glVertex3dv(&vertex[6][0]), glVertex3dv(&vertex[7][0]), glVertex3dv(&vertex[4][0]);// Edge and "maximum" side.
-#	else
-		glVertex3fv(&vertex[0][0]), glVertex3fv(&vertex[1][0]), glVertex3fv(&vertex[2][0]), glVertex3fv(&vertex[3][0]), glVertex3fv(&vertex[0][0]);// "Minimum" side.
-		glVertex3fv(&vertex[4][0]), glVertex3fv(&vertex[5][0]), glVertex3fv(&vertex[6][0]), glVertex3fv(&vertex[7][0]), glVertex3fv(&vertex[4][0]);// Edge and "maximum" side.
-#	endif // ASSIMP_DOUBLE_PRECISION
-	glEnd();
-
-	glBegin(GL_LINES);
-#	ifdef ASSIMP_DOUBLE_PRECISION
-		glVertex3dv(&vertex[1][0]), glVertex3dv(&vertex[5][0]);
-		glVertex3dv(&vertex[2][0]), glVertex3dv(&vertex[6][0]);
-		glVertex3dv(&vertex[3][0]), glVertex3dv(&vertex[7][0]);
-#	else
-		glVertex3fv(&vertex[1][0]), glVertex3fv(&vertex[5][0]);
-		glVertex3fv(&vertex[2][0]), glVertex3fv(&vertex[6][0]);
-		glVertex3fv(&vertex[3][0]), glVertex3fv(&vertex[7][0]);
-#	endif // ASSIMP_DOUBLE_PRECISION
-	glEnd();
-	glDisable(GL_COLOR_MATERIAL);
-	if(mLightingEnabled) glEnable(GL_LIGHTING);
-
-}
-
-void CGLView::Enable_Textures(const bool pEnable) {
-	if(pEnable) {
-		glEnable(GL_TEXTURE_1D);
-		glEnable(GL_TEXTURE_2D);
-		glEnable(GL_TEXTURE_3D);
-	} else {
-		glDisable(GL_TEXTURE_1D);
-		glDisable(GL_TEXTURE_2D);
-		glDisable(GL_TEXTURE_3D);
-	}
-}
-
-void CGLView::initializeGL() {
-	mGLContext_Current = true;
-	initializeOpenGLFunctions();
-	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
-	glShadeModel(GL_SMOOTH);
-
-	glEnable(GL_DEPTH_TEST);
-	glEnable(GL_NORMALIZE);
-	glEnable(GL_TEXTURE_2D);
-    glEnable( GL_MULTISAMPLE );
-
-	glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
-	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
-	glDisable(GL_COLOR_MATERIAL);
-
-	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
-
-	glEnable(GL_CULL_FACE);
-	glCullFace(GL_BACK);
-
-	glFrontFace(GL_CCW);
-}
-
-void CGLView::resizeGL(int width, int height) {
-	mCamera_Viewport_AspectRatio = (GLdouble)width / height;
-	glViewport(0, 0, width, height);
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	gluPerspective(mCamera_FOVY, mCamera_Viewport_AspectRatio, 1.0, 100000.0);///TODO: znear/zfar depend on scene size.
-}
-
-void CGLView::drawCoordSystem() {
-	// Disable lighting. Colors must be bright and colorful)
-	if ( mLightingEnabled ) glDisable( GL_LIGHTING );///TODO: display list
-
-	// For same reason - disable textures.
-	glBindTexture(GL_TEXTURE_1D, 0);
-    glBindTexture(GL_TEXTURE_2D, 0);
-    glBindTexture(GL_TEXTURE_3D, 0);
-    glEnable(GL_COLOR_MATERIAL);
-    glBegin(GL_LINES);
-
-    // X, -X
-	glColor3f(1.0f, 0.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(100000.0, 0.0, 0.0);
-	glColor3f(0.5f, 0.5f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(-100000.0, 0.0, 0.0);
-	// Y, -Y
-	glColor3f(0.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 100000.0, 0.0);
-	glColor3f(1.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, -100000.0, 0.0);
-	// Z, -Z
-	glColor3f(0.0f, 0.0f, 1.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, 100000.0);
-	glColor3f(1.0f, 1.0f, 0.0f), glVertex3f(0.0, 0.0, 0.0), glVertex3f(0.0, 0.0, -100000.0);
-	glColor3f(1.0f, 1.0f, 1.0f);
-
-    glEnd();
-	// Restore previous state of lighting.
-    if (mLightingEnabled) {
-        glEnable( GL_LIGHTING );
-    }
-}
-
-void CGLView::paintGL() {
-	QTime time_paintbegin;
-
-	time_paintbegin = QTime::currentTime();
-
-	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
-
-	// Apply current camera transformations.
-#if ASSIMP_DOUBLE_PRECISION
-	glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_AroundCamera);
-	glTranslated(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z);
-	glMultMatrixd((GLdouble*)&mHelper_Camera.Rotation_Scene);
-#else
-	glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_AroundCamera);
-	glTranslatef(-mHelper_Camera.Translation_ToScene.x, -mHelper_Camera.Translation_ToScene.y, -mHelper_Camera.Translation_ToScene.z);
-	glMultMatrixf((GLfloat*)&mHelper_Camera.Rotation_Scene);
-#endif // ASSIMP_DOUBLE_PRECISION
-
-	// Coordinate system
-	if ( mScene_AxesEnabled ) {
-        drawCoordSystem();
-    }
-
-	glDisable(GL_COLOR_MATERIAL);
-	
-    // Scene
-	if(mScene != nullptr) {
-		Draw_Node(mScene->mRootNode);
-		// Scene BBox
-        if (mScene_DrawBBox) {
-            Draw_BBox( mScene_BBox );
-        }
-	}
-
-	emit Paint_Finished((size_t) time_paintbegin.msecsTo(QTime::currentTime()), mHelper_Camera.Translation_ToScene.Length());
-}
-
-
-CGLView::CGLView( QWidget *pParent )
-: QOpenGLWidget( pParent )
-, mGLContext_Current( false ) {
-    // set initial view
-    mHelper_CameraDefault.SetDefault();
-    Camera_Set( 0 );
-}
-
-CGLView::~CGLView() {
-	FreeScene();
-}
-
-void CGLView::FreeScene() {
-	// Set scene to null and after that \ref paintGL will not try to render it.
-	mScene = nullptr;
-	// Clean helper objects.
-	if(mHelper_Mesh != nullptr)
-	{
-		for(size_t idx_mesh = 0; idx_mesh < mHelper_Mesh_Quantity; idx_mesh++) delete mHelper_Mesh[idx_mesh];
-
-		delete [] mHelper_Mesh;
-		mHelper_Mesh = nullptr;
-	}
-
-	mHelper_Mesh_Quantity = 0;
-	// Delete textures
-	const int id_tex_size = mTexture_IDMap.size();
-
-	if(id_tex_size)
-	{
-		GLuint* id_tex = new GLuint[id_tex_size];
-		QMap<QString, GLuint>::iterator it = mTexture_IDMap.begin();
-
-		for(int idx = 0; idx < id_tex_size; idx++, ++it)
-		{
-			id_tex[idx] = it.value();
-		}
-
-		glDeleteTextures(id_tex_size, id_tex);
-		mTexture_IDMap.clear();
-		delete [] id_tex;
-	}
-}
-
-void CGLView::SetScene(const aiScene *pScene, const QString& pScenePath) {
-    FreeScene();// Clear old data
-	// Why checking here, not at begin of function. Because old scene may not exist at know. So, need cleanup.
-    if (pScene == nullptr) {
-        return;
-    }
-
-	mScene = pScene;// Copy pointer of new scene.
-
-	//
-	// Meshes
-	//
-	// Create helper objects for meshes. This allow to render meshes as OpenGL arrays.
-	if(mScene->HasMeshes())
-	{
-		// Create mesh helpers array.
-		mHelper_Mesh_Quantity = mScene->mNumMeshes;
-		mHelper_Mesh = new SHelper_Mesh*[mScene->mNumMeshes];
-
-		// Walk through the meshes and extract needed data and, also calculate BBox.
-		for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++)
-		{
-			aiMesh& mesh_cur = *mScene->mMeshes[idx_mesh];
-
-			//
-			// Calculate BBox
-			//
-			SBBox mesh_bbox;
-
-			BBox_GetFromVertices(mesh_cur.mVertices, mesh_cur.mNumVertices, mesh_bbox);
-			//
-			// Create vertices indices arrays splitted by primitive type.
-			//
-			size_t indcnt_p = 0;// points quantity
-			size_t indcnt_l = 0;// lines quantity
-			size_t indcnt_t = 0;// triangles quantity
-
-			if(mesh_cur.HasFaces())
-			{
-				// Usual way: all faces are triangles
-				if(mesh_cur.mPrimitiveTypes == aiPrimitiveType_TRIANGLE)
-				{
-					indcnt_t = mesh_cur.mNumFaces;
-				}
-				else
-				{
-					// Calculate count of primitives by types.
-					for(size_t idx_face = 0; idx_face < mesh_cur.mNumFaces; idx_face++)
-					{
-						if(mesh_cur.mFaces[idx_face].mNumIndices == 3)
-							indcnt_t++;
-						else if(mesh_cur.mFaces[idx_face].mNumIndices == 2)
-							indcnt_l++;
-						else if(mesh_cur.mFaces[idx_face].mNumIndices == 1)
-							indcnt_p++;
-					}
-				}// if(mesh_cur.mPrimitiveTypes == aiPrimitiveType_TRIANGLE) else
-
-				// Create helper
-				mHelper_Mesh[idx_mesh] = new SHelper_Mesh(indcnt_p, indcnt_l, indcnt_t, mesh_bbox);
-				// Fill indices arrays
-				indcnt_p = 0, indcnt_l = 0, indcnt_t = 0;// Reuse variables as indices
-				for(size_t idx_face = 0; idx_face < mesh_cur.mNumFaces; idx_face++)
-				{
-					if(mesh_cur.mFaces[idx_face].mNumIndices == 3)
-					{
-						mHelper_Mesh[idx_mesh]->Index_Triangle[indcnt_t++] = mesh_cur.mFaces[idx_face].mIndices[0];
-						mHelper_Mesh[idx_mesh]->Index_Triangle[indcnt_t++] = mesh_cur.mFaces[idx_face].mIndices[1];
-						mHelper_Mesh[idx_mesh]->Index_Triangle[indcnt_t++] = mesh_cur.mFaces[idx_face].mIndices[2];
-					}
-					else if(mesh_cur.mFaces[idx_face].mNumIndices == 2)
-					{
-						mHelper_Mesh[idx_mesh]->Index_Line[indcnt_l++] = mesh_cur.mFaces[idx_face].mIndices[0];
-						mHelper_Mesh[idx_mesh]->Index_Line[indcnt_l++] = mesh_cur.mFaces[idx_face].mIndices[1];
-					}
-					else if(mesh_cur.mFaces[idx_face].mNumIndices == 1)
-					{
-						mHelper_Mesh[idx_mesh]->Index_Point[indcnt_p++] = mesh_cur.mFaces[idx_face].mIndices[0];
-					}
-				}// for(size_t idx_face = 0; idx_face < mesh_cur.mNumFaces; idx_face++)
-			}// if(mesh_cur.HasFaces())
-			else
-			{
-				// If mesh has no faces then vertices can be just points set.
-				indcnt_p = mesh_cur.mNumVertices;
-				// Create helper
-				mHelper_Mesh[idx_mesh] = new SHelper_Mesh(indcnt_p, 0, 0, mesh_bbox);
-				// Fill indices arrays
-				for(size_t idx = 0; idx < indcnt_p; idx++) mHelper_Mesh[idx_mesh]->Index_Point[idx] = idx;
-
-			}// if(mesh_cur.HasFaces()) else
-		}// for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++)
-	}// if(mScene->HasMeshes())
-
-	//
-	// Scene BBox
-	//
-	// For calculating right BBox we must walk through all nodes and apply transformation to meshes BBoxes
-	if(mHelper_Mesh_Quantity > 0)
-	{
-		bool first_assign = true;
-		aiMatrix4x4 mat_root;
-
-		BBox_GetForNode(*mScene->mRootNode, mat_root, mScene_BBox, first_assign);
-		mScene_Center = mScene_BBox.Maximum + mScene_BBox.Minimum;
-		mScene_Center /= 2;
-	}
-	else
-	{
-		mScene_BBox = {{0, 0, 0}, {0, 0, 0}};
-		mScene_Center = {0, 0, 0};
-	}// if(mHelper_Mesh_Count > 0) else
-
-	//
-	// Textures
-	//
-	ImportTextures(pScenePath);
-
-	//
-	// Light sources
-	//
-	Lighting_Enable();
-	// If scene has no lights then enable default
-	if(!mScene->HasLights())
-	{
-		const GLfloat col_amb[4] = { 0.2, 0.2, 0.2, 1.0 };
-		SLightParameters lp;
-
-		lp.Type = aiLightSource_POINT;
-		lp.Ambient.r = col_amb[0], lp.Ambient.g = col_amb[1], lp.Ambient.b = col_amb[2], lp.Ambient.a = col_amb[3];
-		lp.Diffuse = { 1.0, 1.0, 1.0, 1.0 };
-		lp.Specular = lp.Diffuse;
-		lp.For.Point.Position = mScene_Center;
-		lp.For.Point.Attenuation_Constant = 1;
-		lp.For.Point.Attenuation_Linear = 0;
-		lp.For.Point.Attenuation_Quadratic = 0;
-		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col_amb);
-		Lighting_EditSource(0, lp);
-		emit SceneObject_LightSource("_default");// Light source will be enabled in signal handler.
-	}
-	else
-	{
-		for(size_t idx_light = 0; idx_light < mScene->mNumLights; idx_light++)
-		{
-			SLightParameters lp;
-			QString name;
-			const aiLight& light_cur = *mScene->mLights[idx_light];
-
-			auto col3_to_col4 = [](const aiColor3D& pCol3) -> aiColor4D { return aiColor4D(pCol3.r, pCol3.g, pCol3.b, 1.0); };
-
-			///TODO: find light source node and apply all transformations
-			// General properties
-			name = light_cur.mName.C_Str();
-			lp.Ambient = col3_to_col4(light_cur.mColorAmbient);
-			lp.Diffuse = col3_to_col4(light_cur.mColorDiffuse);
-			lp.Specular = col3_to_col4(light_cur.mColorSpecular);
-			lp.Type = light_cur.mType;
-			// Depend on type properties
-			switch(light_cur.mType)
-			{
-				case aiLightSource_DIRECTIONAL:
-					lp.For.Directional.Direction = light_cur.mDirection;
-					break;
-				case aiLightSource_POINT:
-					lp.For.Point.Position = light_cur.mPosition;
-					lp.For.Point.Attenuation_Constant = light_cur.mAttenuationConstant;
-					lp.For.Point.Attenuation_Linear = light_cur.mAttenuationLinear;
-					lp.For.Point.Attenuation_Quadratic = light_cur.mAttenuationQuadratic;
-					break;
-				case aiLightSource_SPOT:
-					lp.For.Spot.Position = light_cur.mPosition;
-					lp.For.Spot.Direction = light_cur.mDirection;
-					lp.For.Spot.Attenuation_Constant = light_cur.mAttenuationConstant;
-					lp.For.Spot.Attenuation_Linear = light_cur.mAttenuationLinear;
-					lp.For.Spot.Attenuation_Quadratic = light_cur.mAttenuationQuadratic;
-					lp.For.Spot.CutOff = light_cur.mAngleOuterCone;
-					break;
-				case aiLightSource_AMBIENT:
-					lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0;
-					name.append("_unsup_ambient");
-					break;
-				case aiLightSource_AREA:
-					lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0;
-					name.append("_unsup_area");
-					break;
-				case aiLightSource_UNDEFINED:
-					lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0;
-					name.append("_unsup_undefined");
-					break;
-				default:
-					lp.For.Point.Position = light_cur.mPosition, lp.For.Point.Attenuation_Constant = 1, lp.For.Point.Attenuation_Linear = 0, lp.For.Point.Attenuation_Quadratic = 0;
-					name.append("_unsupported_invalid");
-					break;
-			}// switch(light_cur.mType)
-
-			// Add light source
-            // Use index if name is empty.
-            if (name.isEmpty()) {
-                name += QString( "%1" ).arg( idx_light );
-            }
-
-			Lighting_EditSource(idx_light, lp);
-			emit SceneObject_LightSource(name);// Light source will be enabled in signal handler.
-		}// for(size_t idx_light = 0; idx_light < mScene->mNumLights; idx_light++)
-	}// if(!mScene->HasLights()) else
-
-	//
-	// Cameras
-	//
-	if(!mScene->HasCameras())
-	{
-		mCamera_DefaultAdded = true;
-		mHelper_CameraDefault.SetDefault();
-		// Calculate distance from camera to scene. Distance must be enoguh for that viewport contain whole scene.
-		const GLfloat tg_angle = tan(mCamera_FOVY / 2);
-
-		GLfloat val_x = ((mScene_BBox.Maximum.x - mScene_BBox.Minimum.x) / 2) / (mCamera_Viewport_AspectRatio * tg_angle);
-		GLfloat val_y = ((mScene_BBox.Maximum.y - mScene_BBox.Minimum.y) / 2) / tg_angle;
-		GLfloat val_step = val_x;
-
-		AssignIfGreater(val_step, val_y);
-		mHelper_CameraDefault.Translation_ToScene.Set(mScene_Center.x, mScene_Center.y, val_step + mScene_BBox.Maximum.z);
-		emit SceneObject_Camera("_default");
-	}
-	else
-	{
-		mCamera_DefaultAdded = false;
-		for(size_t idx_cam = 0; idx_cam < mScene->mNumCameras; idx_cam++)
-		{
-			emit SceneObject_Camera(mScene->mCameras[idx_cam]->mName.C_Str());
-		}
-	}// if(!mScene->HasCameras()) else
-}
-
-void CGLView::Lighting_Enable() {
-	mLightingEnabled = true;
-	glEnable(GL_LIGHTING);
-}
-
-void CGLView::Lighting_Disable() {
-    glDisable( GL_LIGHTING );
-	mLightingEnabled = false;
-}
-
-void CGLView::Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
-{
-    const size_t light_num = GL_LIGHT0 + pLightNumber;
-
-    GLfloat farr[4];
-
-	if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
-
-	// Ambient color
-    farr[0] = pLightParameters.Ambient.r;
-    farr[1] = pLightParameters.Ambient.g;
-    farr[2] = pLightParameters.Ambient.b;
-    farr[3] = pLightParameters.Ambient.a;
-	glLightfv(light_num, GL_AMBIENT, farr);
-
-    // Diffuse color
-    farr[0] = pLightParameters.Diffuse.r;
-    farr[1] = pLightParameters.Diffuse.g;
-    farr[2] = pLightParameters.Diffuse.b;
-    farr[3] = pLightParameters.Diffuse.a;
-	glLightfv(light_num, GL_DIFFUSE, farr);
-
-    // Specular color
-    farr[0] = pLightParameters.Specular.r;
-    farr[1] = pLightParameters.Specular.g;
-    farr[2] = pLightParameters.Specular.b;
-    farr[3] = pLightParameters.Specular.a;
-	glLightfv(light_num, GL_SPECULAR, farr);
-
-    // Other parameters
-	switch(pLightParameters.Type)
-	{
-		case aiLightSource_DIRECTIONAL:
-			// Direction
-			farr[0] = pLightParameters.For.Directional.Direction.x, farr[1] = pLightParameters.For.Directional.Direction.y;
-			farr[2] = pLightParameters.For.Directional.Direction.z; farr[3] = 0;
-			glLightfv(light_num, GL_POSITION, farr);
-			break;
-		case aiLightSource_POINT:
-			// Position
-			farr[0] = pLightParameters.For.Point.Position.x, farr[1] = pLightParameters.For.Point.Position.y;
-			farr[2] = pLightParameters.For.Point.Position.z; farr[3] = 1;
-			glLightfv(light_num, GL_POSITION, farr);
-			// Attenuation
-			glLightf(light_num, GL_CONSTANT_ATTENUATION, pLightParameters.For.Point.Attenuation_Constant);
-			glLightf(light_num, GL_LINEAR_ATTENUATION, pLightParameters.For.Point.Attenuation_Linear);
-			glLightf(light_num, GL_QUADRATIC_ATTENUATION, pLightParameters.For.Point.Attenuation_Quadratic);
-			glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
-			break;
-		case aiLightSource_SPOT:
-			// Position
-			farr[0] = pLightParameters.For.Spot.Position.x, farr[1] = pLightParameters.For.Spot.Position.y, farr[2] = pLightParameters.For.Spot.Position.z; farr[3] = 1;
-			glLightfv(light_num, GL_POSITION, farr);
-			// Attenuation
-			glLightf(light_num, GL_CONSTANT_ATTENUATION, pLightParameters.For.Spot.Attenuation_Constant);
-			glLightf(light_num, GL_LINEAR_ATTENUATION, pLightParameters.For.Spot.Attenuation_Linear);
-			glLightf(light_num, GL_QUADRATIC_ATTENUATION, pLightParameters.For.Spot.Attenuation_Quadratic);
-			// Spot specific
-			farr[0] = pLightParameters.For.Spot.Direction.x, farr[1] = pLightParameters.For.Spot.Direction.y, farr[2] = pLightParameters.For.Spot.Direction.z; farr[3] = 0;
-			glLightfv(light_num, GL_SPOT_DIRECTION, farr);
-			glLightf(light_num, GL_SPOT_CUTOFF, pLightParameters.For.Spot.CutOff);
-			break;
-		default:// For unknown light source types use point source.
-			// Position
-			farr[0] = pLightParameters.For.Point.Position.x, farr[1] = pLightParameters.For.Point.Position.y;
-			farr[2] = pLightParameters.For.Point.Position.z; farr[3] = 1;
-			glLightfv(light_num, GL_POSITION, farr);
-			// Attenuation
-			glLightf(light_num, GL_CONSTANT_ATTENUATION, 1);
-			glLightf(light_num, GL_LINEAR_ATTENUATION, 0);
-			glLightf(light_num, GL_QUADRATIC_ATTENUATION, 0);
-			glLightf(light_num, GL_SPOT_CUTOFF, 180.0);
-			break;
-	}// switch(pLightParameters.Type)
-}
-
-void CGLView::Lighting_EnableSource(const size_t pLightNumber) {
-	if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
-
-	glEnable(GL_LIGHT0 + pLightNumber);
-}
-
-void CGLView::Lighting_DisableSource(const size_t pLightNumber)
-{
-	if(pLightNumber >= GL_MAX_LIGHTS) return;///TODO: return value;
-
-	glDisable(GL_LIGHT0 + pLightNumber);
-}
-
-void CGLView::Camera_Set(const size_t pCameraNumber)
-{
-    SHelper_Camera& hcam = mHelper_Camera;// reference with short name for conveniance.
-    aiVector3D up;
-
-	if(mCamera_DefaultAdded || (pCameraNumber >= mScene->mNumCameras))// If default camera used then 'pCameraNumber' doesn't matter.
-	{
-		// Transformation parameters
-		hcam = mHelper_CameraDefault;
-		up.Set(0, 1, 0);
-	}
-	else
-	{
-		const aiCamera& camera_cur = *mScene->mCameras[pCameraNumber];
-		const aiNode* camera_node;
-
-		aiMatrix4x4 camera_mat;
-		aiQuaternion camera_quat_rot;
-		aiVector3D camera_tr;
-
-		up = camera_cur.mUp;
-		//
-		// Try to get real coordinates of the camera.
-		//
-		// Find node
-		camera_node = mScene->mRootNode->FindNode(camera_cur.mName);
-		if(camera_node != nullptr) Matrix_NodeToRoot(camera_node, camera_mat);
-
-		hcam.Position = camera_cur.mLookAt;
-		hcam.Target = camera_cur.mPosition;
-		hcam.Rotation_AroundCamera = aiMatrix4x4(camera_quat_rot.GetMatrix());
-		hcam.Rotation_AroundCamera.Transpose();
-		// get components of transformation matrix.
-		camera_mat.DecomposeNoScaling(camera_quat_rot, camera_tr);
-		hcam.Rotation_Scene = aiMatrix4x4();
-		hcam.Translation_ToScene = camera_tr;
-	}
-
-	// Load identity matrix - travel to world begin.
-	glMatrixMode(GL_MODELVIEW);
-	glLoadIdentity();
-	// Set camera and update picture
-	gluLookAt(hcam.Position.x, hcam.Position.y, hcam.Position.z, hcam.Target.x, hcam.Target.y, hcam.Target.z, up.x, up.y, up.z);
-}
-
-void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) {
-    auto deg2rad = [](const GLfloat pDegree) -> GLfloat { 
-        return pDegree * AI_MATH_PI / 180.0f;
-    };
-
-	aiMatrix4x4 mat_rot;
-
-	mat_rot.FromEulerAnglesXYZ(deg2rad(pAngle_X), deg2rad(pAngle_Y), deg2rad(pAngle_Z));
-	if(pMatrix_Rotation_Initial != nullptr)
-		mHelper_Camera.Rotation_Scene = *pMatrix_Rotation_Initial * mat_rot;
-	else
-		mHelper_Camera.Rotation_Scene *= mat_rot;
-}
-
-void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
-{
-    auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * AI_MATH_PI / 180.0; };
-
-	aiMatrix4x4 mat_rot;
-
-	mat_rot.FromEulerAnglesXYZ(deg2rad(pAngle_X), deg2rad(pAngle_Y), deg2rad(pAngle_Z));
-	if(pMatrix_Rotation_Initial != nullptr)
-		mHelper_Camera.Rotation_AroundCamera = *pMatrix_Rotation_Initial * mat_rot;
-	else
-		mHelper_Camera.Rotation_AroundCamera *= mat_rot;
-}
-
-void CGLView::Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z)
-{
-    aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z);
-
-	vect_tr *= mHelper_Camera.Rotation_AroundCamera;
-	mHelper_Camera.Translation_ToScene += vect_tr;
-}
-
-void CGLView::Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera)
-{
-	pRotation_Camera = mHelper_Camera.Rotation_AroundCamera;
-	pRotation_Scene = mHelper_Camera.Rotation_Scene;
-	pTranslation_Camera = mHelper_Camera.Translation_ToScene;
-}

+ 0 - 456
tools/assimp_qt_viewer/glview.hpp

@@ -1,456 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#pragma once
-
-// Header files, Qt.
-#include <QMap>
-#if ASSIMP_QT4_VIEWER
-#	include <QtOpenGL>
-#else
-#	include <QOpenGLWidget>
-#	include <QOpenGLFunctions>
-#endif // ASSIMP_QT4_VIEWER
-
-// Header files Assimp
-#include <assimp/scene.h>
-
-/// \class CGLView
-/// Class which hold and render scene.
-#if ASSIMP_QT4_VIEWER
-class CGLView : public QGLWidget
-#else
-class CGLView : public QOpenGLWidget, protected QOpenGLFunctions
-#endif // ASSIMP_QT4_VIEWER
-{
-	Q_OBJECT
-
-	/**********************************/
-	/************* Types **************/
-	/**********************************/
-
-private:
-
-	/// \struct SBBox
-	/// Bounding box for object.
-	struct SBBox
-	{
-		aiVector3D Minimum;///< Minimum values of coordinates.
-		aiVector3D Maximum;///< Maximum values of coordinates.
-	};
-
-	/// \struct SHelper_Mesh
-	/// Helper object for fast rendering of mesh (\ref aiMesh).
-	struct SHelper_Mesh
-	{
-		const size_t Quantity_Point;///< Quantity of points.
-		const size_t Quantity_Line;///< Quantity of lines.
-		const size_t Quantity_Triangle;///< Quantity of triangles.
-		GLuint* Index_Point;///< Array of indices for drawing points.
-		GLuint* Index_Line;///< Array of indices for drawing lines.
-		GLuint* Index_Triangle;///< Array of indices for drawing triangles.
-
-		const SBBox BBox;///< BBox of mesh.
-
-		/// \fn explicit SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox = {{0, 0, 0}, {0, 0, 0}})
-		/// Constructor.
-		/// \param [in] pQuantity_Point - quantity of points.
-		/// \param [in] pQuantity_Line - quantity of lines.
-		/// \param [in] pQuantity_Triangle - quantity of triangles.
-		/// \param [in] pBBox - BBox of mesh.
-		explicit SHelper_Mesh(const size_t pQuantity_Point, const size_t pQuantity_Line, const size_t pQuantity_Triangle, const SBBox& pBBox = {{0, 0, 0}, {0, 0, 0}});
-
-		/// \fn ~SHelper_Mesh()
-		/// Destructor.
-		~SHelper_Mesh();
-	};
-
-	/// \struct SHelper_Camera
-	/// Information about position of the camera in space.
-	struct SHelper_Camera
-	{
-		aiVector3D Position;///< Coordinates of the camera.
-		aiVector3D Target;///< Target point of the camera.
-		// Transformation path:
-		// set Camera -> Rotation_AroundCamera -> Translation_ToScene -> Rotation_Scene -> draw Scene
-		aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
-		aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
-		aiVector3D Translation_ToScene;///< Translation vector from camera to the scene.
-
-		/// \fn void SetDefault()
-		/// Set default parameters of camera.
-		void SetDefault();
-	};
-
-public:
-
-	/// \enum ELightType
-	/// Type of light source.
-	enum class ELightType { Directional, Point, Spot };
-
-	/// \struct SLightParameters
-	/// Parameters of light source.
-	struct SLightParameters
-	{
-		aiLightSourceType Type;///< Type of light source.
-
-		aiColor4D Ambient;///< Ambient RGBA intensity of the light.
-		aiColor4D Diffuse;///< Diffuse RGBA intensity of the light.
-		aiColor4D Specular;///< Specular RGBA intensity of the light.
-
-		union UFor
-		{
-			/// \struct SDirectional
-			/// Parameters of directional light source.
-			struct SDirectional
-			{
-				aiVector3D Direction;
-
-				SDirectional() {}
-			} Directional;
-
-			/// \struct SPoint
-			/// Parameters of point light source.
-			struct SPoint
-			{
-				aiVector3D Position;
-				GLfloat Attenuation_Constant;
-				GLfloat Attenuation_Linear;
-				GLfloat Attenuation_Quadratic;
-
-				SPoint() {}
-			} Point;
-
-			/// \struct SSpot
-			/// Parameters of spot light source.
-			struct SSpot
-			{
-				aiVector3D Position;
-				GLfloat Attenuation_Constant;
-				GLfloat Attenuation_Linear;
-				GLfloat Attenuation_Quadratic;
-				aiVector3D Direction;
-				GLfloat CutOff;
-
-				SSpot() {}
-			} Spot;
-
-			UFor() {}
-		} For;
-
-		SLightParameters() {}
-	};
-
-	/**********************************/
-	/************ Variables ***********/
-	/**********************************/
-
-private:
-
-#if !ASSIMP_QT4_VIEWER
-	// Qt5 widget has another behavior, so you must to know that you already made context are current. Yes, its a dirty hack. Better decision are welcome.
-	bool mGLContext_Current;///< Widget's GL-context made current.
-#endif // ASSIMP_QT4_VIEWER
-	// Scene
-	const aiScene* mScene = nullptr;///< Copy of pointer to scene (\ref aiScene).
-	SBBox mScene_BBox;///< Bounding box of scene.
-	aiVector3D mScene_Center;///< Coordinates of center of the scene.
-	bool mScene_DrawBBox = false;///< Flag which control drawing scene BBox.
-	bool mScene_AxesEnabled = true;///< Flag which control drawing axes of the coordinate system.
-	// Meshes
-	size_t mHelper_Mesh_Quantity = 0;///< Quantity of meshes in scene.
-	SHelper_Mesh** mHelper_Mesh = nullptr;///< Array of pointers to helper objects for drawing mesh. Sequence of meshes are equivalent to \ref aiScene::mMeshes.
-	// Cameras
-	SHelper_Camera mHelper_Camera;///< Information about current camera placing in space.
-	SHelper_Camera mHelper_CameraDefault;///< Information about default camera initial placing in space.
-	bool mCamera_DefaultAdded = true;///< If true then scene has no defined cameras and default was added, if false - scene has defined cameras.
-	GLdouble mCamera_FOVY = 45.0;///< Specifies the field of view angle, in degrees, in the y direction.
-	GLdouble mCamera_Viewport_AspectRatio;///< Specifies the aspect ratio that determines the field of view in the x direction. The aspect ratio is the ratio of x (width) to y (height).
-	// Lighting
-	bool mLightingEnabled = false;///< If true then OpenGL lighting is enabled (glEnable(GL_LIGHTING)), if false - disabled.
-	///TODO: map is goooood, but not for case when one image can be used in different materials with difference in: texture transformation, targeting of the
-	/// texture (ambient or emission, or even height map), texture properties.
-	QMap<QString, GLuint> mTexture_IDMap;///< Map image filenames to textures ID's.
-
-	/**********************************/
-	/************ Functions ***********/
-	/**********************************/
-
-private:
-
-	// Why in some cases pointers are used? Because: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
-	template<typename TArg> void AssignIfLesser(TArg* pBaseValue, const TArg pTestValue) { if(pTestValue < *pBaseValue) *pBaseValue = pTestValue; }
-	template<typename TArg> void AssignIfGreater(TArg* pBaseValue, const TArg pTestValue) { if(pTestValue > *pBaseValue) *pBaseValue = pTestValue; }
-
-	template<typename TArg> void AssignIfLesser(TArg& pBaseValue, const TArg pTestValue) { if(pTestValue < pBaseValue) pBaseValue = pTestValue; }
-	template<typename TArg> void AssignIfGreater(TArg& pBaseValue, const TArg pTestValue) { if(pTestValue > pBaseValue) pBaseValue = pTestValue; }
-
-	/// \fn void Material_Apply(const aiMaterial* pMaterial)
-	/// Enable pointed material.
-	/// \param [in] pMaterial - pointer to material which must be used.
-	void Material_Apply(const aiMaterial* pMaterial);
-
-	/// \fn void Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix)
-	/// Calculate matrix for transforming coordinates from pointed node to root node (read as "global coordinate system").
-	/// \param [in] pNode - pointer initial node from which relative coordintaes will be taken,
-	/// \param [out] pOutMatrix - matrix for transform relative coordinates in \ref pNode to coordinates in root node (\ref aiScene::mRootNode).
-	void Matrix_NodeToRoot(const aiNode* pNode, aiMatrix4x4& pOutMatrix);
-
-	/// \fn void ImportTextures()
-	/// Import textures.
-	/// \param [in] pScenePath - path to the file of the scene.
-	void ImportTextures(const QString& pScenePath);
-
-	/// \fn void BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParentNode_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign)
-	/// Calculate BBox for pointed node. Function walk thru child nodes and apply all transformations.
-	/// \param [in] pNode - reference to node for which needed BBox.
-	/// \param [in] pParent_TransformationMatrix - reference to parent (parent for pNode) transformation matrix.
-	/// \param [in,out] pNodeBBox - reference to where pNode BBox will be placed. It will expanded by child nodes BBoxes.
-	/// \param [in] pFirstAssign - means that pNodeBBox not contain valid BBox at now and assign ('=') will used for setting new value, If
-	/// false then \ref BBox_Extend will be used for setting new BBox.
-	void BBox_GetForNode(const aiNode& pNode, const aiMatrix4x4& pParent_TransformationMatrix, SBBox& pNodeBBox, bool& pFirstAssign);
-
-	/// \fn void BBox_Extend(const SBBox& pChild, SBBox& pParent)
-	/// Check and if need - extend current node BBox with BBox of child node.
-	/// \param [in] pChild - reference to BBox which used for extend parent BBox.
-	/// \param [in.out] pParent - BBox which will be extended using child BBox.
-	void BBox_Extend(const SBBox& pChild, SBBox& pParent);
-
-	/// \fn void BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertices[8])
-	/// Get vertices of a parallelepiped which is described by BBox.
-	/// \param [in] pBBox - input BBox.
-	/// \param [out] pVertices - array of vertices.
-	void BBox_GetVertices(const SBBox& pBBox, aiVector3D pVertices[8]);
-
-	/// \fn void BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox)
-	/// Calculate BBox for vertices array.
-	/// \param [in] pVertices - vertices array.
-	/// \param [in] pVerticesQuantity - quantity of vertices in array. If 0 then pBBox will be assigned with {{0, 0, 0}, {0, 0, 0}}.
-	/// \param [out] pBBox - calculated BBox.
-	void BBox_GetFromVertices(const aiVector3D* pVertices, const size_t pVerticesQuantity, SBBox& pBBox);
-
-	/********************************************************************/
-	/************************ Logging functions *************************/
-	/********************************************************************/
-
-	/// \fn void LogInfo(const QString& pMessage)
-	/// Add message with severity "Warning" to log.
-	void LogInfo(const QString& pMessage);
-
-	/// \fn void LogError(const QString& pMessage)
-	/// Add message with severity "Error" to log.
-	void LogError(const QString& pMessage);
-
-	/********************************************************************/
-	/************************** Draw functions **************************/
-	/********************************************************************/
-
-	/// \fn void Draw_Node(const aiNode* pNode)
-	/// Apply node transformation and draw meshes assigned to this node.
-	/// \param [in] pNode - pointer to node for drawing (\ref aiNode).
-	void Draw_Node(const aiNode* pNode);
-
-	/// \fn void Draw_Mesh(const size_t pMesh_Index)
-	/// Draw mesh.
-	/// \param [in] pMesh_Index - index of mesh which must be drawn. Index point to mesh in \ref mHelper_Mesh.
-	void Draw_Mesh(const size_t pMesh_Index);
-
-	/// \fn void Draw_BBox(const SBBox& pBBox)
-	/// Draw bounding box using lines.
-	/// \param [in] pBBox - bounding box for drawing.
-	void Draw_BBox(const SBBox& pBBox);
-
-	/********************************************************************/
-	/*********************** Override functions ************************/
-	/********************************************************************/
-
-protected:
-
-	/// \fn void drawCoordSystem()
-	/// Draw axes of the coordinate system.
-    void drawCoordSystem();
-
-	/// \fn void initializeGL() override
-	/// Override function to initialise OpenGL.
-	void initializeGL() override;
-
-	/// \fn void resizeGL(int pWidth, int pHeight) override
-	/// \param [in] pWidth - new width of viewport.
-	/// \param [in] pHeight - new height of viewport.
-	void resizeGL(int pWidth, int pHeight) override;
-
-	/// \fn void paintGL() override
-	/// Override function for rendering.
-	void paintGL() override;
-
-public:
-
-	/********************************************************************/
-	/********************** Constructor/Destructor **********************/
-	/********************************************************************/
-
-	/// \fn explicit CGLView(QWidget* pParent)
-	/// Constructor.
-	/// \param [in] pParent - parent widget.
-	explicit CGLView(QWidget* pParent);
-
-	/// \fn virtual ~CGLView()
-	/// Destructor.
-	virtual ~CGLView();
-
-	/********************************************************************/
-	/********************* Scene control functions **********************/
-	/********************************************************************/
-
-	/// \fn void FreeScene()
-	/// Free all helper objects data.
-	void FreeScene();
-
-	/// \fn void SetScene(const aiScene* pScene)
-	/// Set scene for rendering.
-	/// \param [in] pScene - pointer to scene.
-	/// \param [in] pScenePath - path to the file of the scene.
-	void SetScene(const aiScene* pScene, const QString& pScenePath);
-
-	/// \fn void Enable_SceneBBox(const bool pEnable)
-	/// Enable drawing scene bounding box.
-	/// \param [in] pEnable - if true then bbox will be drawing, if false - will not be drawing.
-	void Enable_SceneBBox(const bool pEnable) { mScene_DrawBBox = pEnable; }
-
-	/// \fn void Enable_Textures(const bool pEnable)
-	/// Control textures drawing.
-	/// \param [in] pEnable - if true then enable textures, false - disable textures.
-	void Enable_Textures(const bool pEnable);
-
-	/// \fn void Enable_Axes(const bool pEnable)
-	/// Control axes drawing.
-	/// \param [in] pEnable - if true then enable axes, false - disable axes.
-	void Enable_Axes(const bool pEnable) { this->mScene_AxesEnabled = pEnable; }
-
-	/********************************************************************/
-	/******************** Lighting control functions ********************/
-	/********************************************************************/
-
-	/// \fn void Lighting_Enable()
-	/// Enable OpenGL lighting.
-	void Lighting_Enable();
-
-	/// \fn void Lighting_Disable()
-	/// Disable OpenGL lighting.
-	void Lighting_Disable();
-
-	/// \fn void Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters)
-	/// Edit light source properties.
-	/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
-	/// \param [in] pLightParameters - light source parameters.
-	void Lighting_EditSource(const size_t pLightNumber, const SLightParameters& pLightParameters);///TODO: function set
-
-	/// \fn void Lighting_EnableSource(const size_t pLightNumber)
-	/// Enable light source.
-	/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
-	void Lighting_EnableSource(const size_t pLightNumber);
-
-	///void Lighting_DisableSource(const size_t pLightNumber)
-	/// Disable light source,
-	/// \param [in] pLightNumber - light source number. \ref aiScene::mLights.
-	void Lighting_DisableSource(const size_t pLightNumber);
-
-	/********************************************************************/
-	/******************** Cameras control functions *********************/
-	/********************************************************************/
-
-	/// \fn void Camera_Set(const size_t pCameraNumber)
-	/// Set view from pointed camera.
-	/// \param [in] pCamera_Index - index of the camera (\ref aiScene::mCameras).
-	void Camera_Set(const size_t pCameraNumber);
-
-	/// \fn void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
-	/// Rotate scene around axisees.
-	/// \param [in] pAngle_X - specifies the angle of rotation around axis oX, in degrees.
-	/// \param [in] pAngle_Y - specifies the angle of rotation around axis oY, in degrees.
-	/// \param [in] pAngle_Z - specifies the angle of rotation around axis oZ, in degrees.
-	/// \param [in] pMatrix_Rotation_Initial - matrix from which calculates new transformation matrix. If not set (equal to nullptr) then current transformation matrix
-	/// will be used.
-	void Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr);
-
-	/// \fn void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr)
-	/// Rotate camera around axisees.
-	/// \param [in] pAngle_X - specifies the angle of rotation around axis oX, in degrees.
-	/// \param [in] pAngle_Y - specifies the angle of rotation around axis oY, in degrees.
-	/// \param [in] pAngle_Z - specifies the angle of rotation around axis oZ, in degrees.
-	/// \param [in] pMatrix_Rotation_Initial - matrix from which calculates new transformation matrix. If not set (equal to nullptr) then current transformation matrix
-	/// will be used.
-	void Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial = nullptr);
-
-	/// \fn void Camera_Translate(const size_t pTranslate_X, const size_t pTranslate_Y, const size_t pTranslate_Z)
-	/// Translate camera along axises. In local coordinates.
-	/// \param [in] pTranslate_X - specifies the X coordinate of translation vector.
-	/// \param [in] pTranslate_Y - specifies the Y coordinate of translation vector.
-	/// \param [in] pTranslate_Z - specifies the Z coordinate of translation vector.
-	void Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z);
-
-	/// \fn void Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera)
-	/// Return data about camera position in world.
-	/// \param [out] pRotation_Camera - rotation matrix which set rotation angles of the scene around camera.
-	/// \param [out] pRotation_Scene - rotation matrix which set rotation angles of the scene around own center.
-	/// \param [out] pTranslation_Camera - translation vector from camera to the scene.
-	void Camera_Matrix(aiMatrix4x4& pRotation_Camera, aiMatrix4x4& pRotation_Scene, aiVector3D& pTranslation_Camera);
-
-signals:
-
-	/// \fn void Paint_Finished(const size_t pPaintTime, const GLfloat pDistance)
-	///< Signal. Emits when execution of \ref paintGL is end.
-	/// \param [out] pPaintTime_ms - time spent for rendering, in milliseconds.
-	/// \param [out] pDistance - distance between current camera and center of the scene. \sa SHelper_Camera::Translation_ToScene.
-	void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
-
-	/// \fn void SceneObject_Camera(const QString& pName)
-	/// Signal. Emit for every camera found in scene. Also for default camera.
-	/// \param [out] pName - name of the camera.
-	void SceneObject_Camera(const QString& pName);
-
-	/// \fn void SceneObject_LightSource(const QString& pName)
-	/// Signal. Emit for every light source found in scene. Also for default light source.
-	/// \param [out] pName - name of the light source.
-	void SceneObject_LightSource(const QString& pName);
-};// class CGLView

+ 0 - 64
tools/assimp_qt_viewer/loggerview.cpp

@@ -1,64 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-#include "loggerview.hpp"
-
-// Header files, Qt.
-#include <QTime>
-#include <QTextBrowser>
-
-CLoggerView::CLoggerView(QTextBrowser* pOutputWidget)
-: mOutputWidget(pOutputWidget) {
-    // empty
-}
-
-CLoggerView::~CLoggerView() {
-    mOutputWidget = nullptr;
-}
-
-void CLoggerView::write(const char *pMessage) {
-    if (nullptr == mOutputWidget) {
-        return;
-    }
-
-	mOutputWidget->insertPlainText(QString("[%1] %2").arg(QTime::currentTime().toString()).arg(pMessage));
-}

+ 0 - 67
tools/assimp_qt_viewer/loggerview.hpp

@@ -1,67 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-#pragma once
-
-// Header files, Assimp.
-#include <assimp/DefaultLogger.hpp>
-
-class QTextBrowser;
-
-/// @class  CLoggerView
-/// @brief  GUI-stream for Assimp logging sub-sytem. Get data for logging and write it to output widget.
-class CLoggerView final : public ::Assimp::LogStream {
-public:
-	/// @brief  The class constructor.
-	/// @param [in] pOutputWidget - pointer to output widget.
-	explicit CLoggerView( QTextBrowser* pOutputWidget );
-
-    /// @brief  The class destructor.
-    virtual ~CLoggerView();
-
-	/// Write message to output widget. Used by Assimp.
-	/// \param [in] pMessage - message for displaying.
-	virtual void write(const char *pMessage);
-
-private:
-    QTextBrowser * mOutputWidget; ///< Widget for displaying messages.
-};

+ 0 - 58
tools/assimp_qt_viewer/main.cpp

@@ -1,58 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-// Thanks to acorn89 for support.
-
-// Header files, project.
-#include "mainwindow.hpp"
-
-// Header files, Qt.
-#include <QApplication>
-
-int main(int argc, char *argv[]) {
-    QApplication app(argc, argv);
-    MainWindow win;
-    win.show();
-
-    return app.exec();
-}

+ 0 - 466
tools/assimp_qt_viewer/mainwindow.cpp

@@ -1,466 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#include "mainwindow.hpp"
-#include "ui_mainwindow.h"
-
-// Header files, Assimp.
-#include <assimp/Exporter.hpp>
-#include <assimp/postprocess.h>
-
-#ifndef __unused
-	#define __unused	__attribute__((unused))
-#endif // __unused
-
-using namespace Assimp;
-
-
-void MainWindow::ImportFile(const QString &pFileName) {
-    QTime time_begin = QTime::currentTime();
-
-	if ( mScene != nullptr ) {
-		mImporter.FreeScene();
-		mGLView->FreeScene();
-	}
-
-	// Try to import scene.
-	mScene = mImporter.ReadFile(pFileName.toStdString(), aiProcess_Triangulate | aiProcess_GenNormals | aiProcess_ValidateDataStructure | \
-															aiProcess_GenUVCoords | aiProcess_TransformUVCoords | aiProcess_FlipUVs);
-	if ( mScene != nullptr ) {
-		ui->lblLoadTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
-		LogInfo("Import done: " + pFileName);
-		// Prepare widgets for new scene.
-		ui->leFileName->setText(pFileName.right(pFileName.length() - pFileName.lastIndexOf('/') - 1));
-		ui->lstLight->clear();
-		ui->lstCamera->clear();
-		ui->cbxLighting->setChecked(true);	mGLView->Lighting_Enable();
-		ui->cbxBBox->setChecked(false);		mGLView->Enable_SceneBBox(false);
-		ui->cbxTextures->setChecked(true);	mGLView->Enable_Textures(true);
-
-		//
-		// Fill info labels
-		//
-		// Cameras
-		ui->lblCameraCount->setText(QString::number(mScene->mNumCameras));
-		// Lights
-		ui->lblLightCount->setText(QString::number(mScene->mNumLights));
-		// Meshes, faces, vertices.
-		size_t qty_face = 0;
-		size_t qty_vert = 0;
-
-		for(size_t idx_mesh = 0; idx_mesh < mScene->mNumMeshes; idx_mesh++) {
-			qty_face += mScene->mMeshes[idx_mesh]->mNumFaces;
-			qty_vert += mScene->mMeshes[idx_mesh]->mNumVertices;
-		}
-
-		ui->lblMeshCount->setText(QString::number(mScene->mNumMeshes));
-		ui->lblFaceCount->setText(QString::number(qty_face));
-		ui->lblVertexCount->setText(QString::number(qty_vert));
-		// Animation
-		if(mScene->mNumAnimations)
-			ui->lblHasAnimation->setText("yes");
-		else
-			ui->lblHasAnimation->setText("no");
-
-		//
-		// Set scene for GL viewer.
-		//
-		mGLView->SetScene(mScene, pFileName);
-		// Select first camera
-		ui->lstCamera->setCurrentRow(0);
-		mGLView->Camera_Set(0);
-		// Scene is loaded, do first rendering.
-		LogInfo("Scene is ready for rendering.");
-#if ASSIMP_QT4_VIEWER
-		mGLView->updateGL();
-#else
-		mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
-	}
-	else
-	{
-		ResetSceneInfos();
-
-		QString errorMessage = QString("Error parsing \'%1\' : \'%2\'").arg(pFileName).arg(mImporter.GetErrorString());
-		QMessageBox::critical(this, "Import error", errorMessage);
-		LogError(errorMessage);
-	}// if(mScene != nullptr)
-}
-
-void MainWindow::ResetSceneInfos()
-{
-	ui->lblLoadTime->clear();
-	ui->leFileName->clear();
-	ui->lblMeshCount->setText("0");
-	ui->lblFaceCount->setText("0");
-	ui->lblVertexCount->setText("0");
-	ui->lblCameraCount->setText("0");
-	ui->lblLightCount->setText("0");
-	ui->lblHasAnimation->setText("no");
-}
-
-/********************************************************************/
-/************************ Logging functions *************************/
-/********************************************************************/
-
-void MainWindow::LogInfo(const QString& pMessage)
-{
-	Assimp::DefaultLogger::get()->info(pMessage.toStdString());
-}
-
-void MainWindow::LogError(const QString& pMessage)
-{
-	Assimp::DefaultLogger::get()->error(pMessage.toStdString());
-}
-
-/********************************************************************/
-/*********************** Override functions ************************/
-/********************************************************************/
-
-void MainWindow::mousePressEvent(QMouseEvent* pEvent)
-{
-    const QPoint ms_pt = pEvent->pos();
-    aiVector3D temp_v3;
-
-	// Check if GLView is pointed.
-	if(childAt(ms_pt) == mGLView)
-	{
-		if(!mMouse_Transformation.Position_Pressed_Valid)
-		{
-			mMouse_Transformation.Position_Pressed_Valid = true;// set flag
-			// Store current transformation matrices.
-			mGLView->Camera_Matrix(mMouse_Transformation.Rotation_AroundCamera, mMouse_Transformation.Rotation_Scene, temp_v3);
-		}
-
-		if(pEvent->button() & Qt::LeftButton)
-			mMouse_Transformation.Position_Pressed_LMB = ms_pt;
-		else if(pEvent->button() & Qt::RightButton)
-			mMouse_Transformation.Position_Pressed_RMB = ms_pt;
-	}
-	else
-	{
-		mMouse_Transformation.Position_Pressed_Valid = false;
-	}
-}
-
-void MainWindow::mouseReleaseEvent(QMouseEvent *pEvent)
-{
-	if(pEvent->buttons() == 0) mMouse_Transformation.Position_Pressed_Valid = false;
-
-}
-
-void MainWindow::mouseMoveEvent(QMouseEvent* pEvent)
-{
-	if(mMouse_Transformation.Position_Pressed_Valid)
-	{
-		if(pEvent->buttons() & Qt::LeftButton)
-		{
-			GLfloat dx = 180 * GLfloat(pEvent->x() - mMouse_Transformation.Position_Pressed_LMB.x()) / mGLView->width();
-			GLfloat dy = 180 * GLfloat(pEvent->y() - mMouse_Transformation.Position_Pressed_LMB.y()) / mGLView->height();
-
-			if(pEvent->modifiers() & Qt::ShiftModifier)
-				mGLView->Camera_RotateScene(dy, 0, dx, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oZ axises.
-			else
-				mGLView->Camera_RotateScene(dy, dx, 0, &mMouse_Transformation.Rotation_Scene);// Rotate around oX and oY axises.
-
-	#if ASSIMP_QT4_VIEWER
-			mGLView->updateGL();
-	#else
-			mGLView->update();
-	#endif // ASSIMP_QT4_VIEWER
-		}
-
-		if(pEvent->buttons() & Qt::RightButton)
-		{
-			GLfloat dx = 180 * GLfloat(pEvent->x() - mMouse_Transformation.Position_Pressed_RMB.x()) / mGLView->width();
-			GLfloat dy = 180 * GLfloat(pEvent->y() - mMouse_Transformation.Position_Pressed_RMB.y()) / mGLView->height();
-
-			if(pEvent->modifiers() & Qt::ShiftModifier)
-				mGLView->Camera_Rotate(dy, 0, dx, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oZ axises.
-			else
-				mGLView->Camera_Rotate(dy, dx, 0, &mMouse_Transformation.Rotation_AroundCamera);// Rotate around oX and oY axises.
-
-	#if ASSIMP_QT4_VIEWER
-			mGLView->updateGL();
-	#else
-			mGLView->update();
-	#endif // ASSIMP_QT4_VIEWER
-		}
-	}
-}
-
-void MainWindow::keyPressEvent(QKeyEvent* pEvent)
-{
-GLfloat step;
-
-	if(pEvent->modifiers() & Qt::ControlModifier)
-		step = 10;
-	else if(pEvent->modifiers() & Qt::AltModifier)
-		step = 100;
-	else
-		step = 1;
-
-	if(pEvent->key() == Qt::Key_A)
-		mGLView->Camera_Translate(-step, 0, 0);
-	else if(pEvent->key() == Qt::Key_D)
-		mGLView->Camera_Translate(step, 0, 0);
-	else if(pEvent->key() == Qt::Key_W)
-		mGLView->Camera_Translate(0, step, 0);
-	else if(pEvent->key() == Qt::Key_S)
-		mGLView->Camera_Translate(0, -step, 0);
-	else if(pEvent->key() == Qt::Key_Up)
-		mGLView->Camera_Translate(0, 0, -step);
-	else if(pEvent->key() == Qt::Key_Down)
-		mGLView->Camera_Translate(0, 0, step);
-
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
-	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
-}
-
-/********************************************************************/
-/********************** Constructor/Destructor **********************/
-/********************************************************************/
-
-MainWindow::MainWindow(QWidget *parent)
-	: QMainWindow(parent), ui(new Ui::MainWindow),
-		mScene(nullptr)
-{
-
-	// other variables
-	mMouse_Transformation.Position_Pressed_Valid = false;
-
-	ui->setupUi(this);
-	// Create OpenGL widget
-	mGLView = new CGLView(this);
-	mGLView->setMinimumSize(800, 600);
-	mGLView->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
-	mGLView->setFocusPolicy(Qt::StrongFocus);
-	// Connect to GLView signals.
-	connect(mGLView, SIGNAL(Paint_Finished(size_t, GLfloat)), SLOT(Paint_Finished(size_t, GLfloat)));
-	connect(mGLView, SIGNAL(SceneObject_Camera(QString)), SLOT(SceneObject_Camera(QString)));
-	connect(mGLView, SIGNAL(SceneObject_LightSource(QString)), SLOT(SceneObject_LightSource(QString)));
-	// and add it to layout
-	ui->hlMainView->insertWidget(0, mGLView, 4);
-	// Create logger
-	mLoggerView = new CLoggerView(ui->tbLog);
-	DefaultLogger::create("", Logger::VERBOSE);
-	DefaultLogger::get()->attachStream(mLoggerView, DefaultLogger::Debugging | DefaultLogger::Info | DefaultLogger::Err | DefaultLogger::Warn);
-
-	ResetSceneInfos();
-}
-
-MainWindow::~MainWindow()
-{
-using namespace Assimp;
-
-	DefaultLogger::get()->detatchStream(mLoggerView, DefaultLogger::Debugging | DefaultLogger::Info | DefaultLogger::Err | DefaultLogger::Warn);
-	DefaultLogger::kill();
-
-	if(mScene != nullptr) mImporter.FreeScene();
-	if(mLoggerView != nullptr) delete mLoggerView;
-	if(mGLView != nullptr) delete mGLView;
-	delete ui;
-}
-
-/********************************************************************/
-/****************************** Slots *******************************/
-/********************************************************************/
-
-void MainWindow::Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance)
-{
-	ui->lblRenderTime->setText(QString::number(pPaintTime_ms));
-	ui->lblDistance->setText(QString::number(pDistance));
-}
-
-void MainWindow::SceneObject_Camera(const QString& pName)
-{
-	ui->lstCamera->addItem(pName);
-}
-
-void MainWindow::SceneObject_LightSource(const QString& pName)
-{
-	ui->lstLight->addItem(pName);
-	// After item added "currentRow" is still contain old value (even '-1' if first item added). Because "currentRow"/"currentItem" is changed by user interaction,
-	// not by "addItem". So, "currentRow" must be set manually.
-	ui->lstLight->setCurrentRow(ui->lstLight->count() - 1);
-	// And after "selectAll" handler of "signal itemSelectionChanged" will get right "currentItem" and "currentRow" values.
-	ui->lstLight->selectAll();
-}
-
-void MainWindow::on_butOpenFile_clicked() {
-    aiString filter_temp;
-    mImporter.GetExtensionList( filter_temp );
-
-    QString filename, filter;
-    filter = filter_temp.C_Str();
-	filter.replace(';', ' ');
-	filter.append(" ;; All (*.*)");
-	filename = QFileDialog::getOpenFileName(this, "Choose the file", "", filter);
-
-    if (!filename.isEmpty()) {
-        ImportFile( filename );
-    }
-}
-
-void MainWindow::on_butExport_clicked()
-{
-    using namespace Assimp;
-
-#ifndef ASSIMP_BUILD_NO_EXPORT
-    QString filename, filter, format_id;
-    Exporter exporter;
-    QTime time_begin;
-    aiReturn rv;
-    QStringList exportersList;
-    QMap<QString, const aiExportFormatDesc*> exportersMap;
-
-
-	if(mScene == nullptr)
-	{
-		QMessageBox::critical(this, "Export error", "Scene is empty");
-
-		return;
-	}
-
-	for (size_t i = 0; i < exporter.GetExportFormatCount(); ++i)
-	{
-		const aiExportFormatDesc* desc = exporter.GetExportFormatDescription(i);
-		exportersList.push_back(desc->id + QString(": ") + desc->description);
-		exportersMap.insert(desc->id, desc);
-	}
-
-	// get an exporter
-	bool dialogSelectExporterOk;
-	QString selectedExporter = QInputDialog::getItem(this, "Export format", "Select the exporter : ", exportersList, 0, false, &dialogSelectExporterOk);
-	if (!dialogSelectExporterOk)
-		return;
-
-	// build the filter
-	QString selectedId = selectedExporter.left(selectedExporter.indexOf(':'));
-	filter = QString("*.") + exportersMap[selectedId]->fileExtension;
-
-	// get file path
-	filename = QFileDialog::getSaveFileName(this, "Set file name", "", filter);
-	// if it's canceled
-	if (filename == "")
-		return;
-
-	// begin export
-	time_begin = QTime::currentTime();
-	rv = exporter.Export(mScene, selectedId.toLocal8Bit(), filename.toLocal8Bit(), aiProcess_FlipUVs);
-	ui->lblExportTime->setText(QString::number(time_begin.secsTo(QTime::currentTime())));
-	if(rv == aiReturn_SUCCESS)
-		LogInfo("Export done: " + filename);
-	else
-	{
-		QString errorMessage = QString("Export failed: ") + filename;
-		LogError(errorMessage);
-		QMessageBox::critical(this, "Export error", errorMessage);
-	}
-#endif
-}
-
-void MainWindow::on_cbxLighting_clicked(bool pChecked)
-{
-	if(pChecked)
-		mGLView->Lighting_Enable();
-	else
-		mGLView->Lighting_Disable();
-
-	mGLView->update();
-}
-
-void MainWindow::on_lstLight_itemSelectionChanged()
-{
-bool selected = ui->lstLight->isItemSelected(ui->lstLight->currentItem());
-
-	if(selected)
-		mGLView->Lighting_EnableSource(ui->lstLight->currentRow());
-	else
-		mGLView->Lighting_DisableSource(ui->lstLight->currentRow());
-
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
-	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
-}
-
-void MainWindow::on_lstCamera_clicked( const QModelIndex &)
-{
-	mGLView->Camera_Set(ui->lstLight->currentRow());
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
-	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
-}
-
-void MainWindow::on_cbxBBox_clicked(bool checked)
-{
-	mGLView->Enable_SceneBBox(checked);
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
-	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
-}
-
-void MainWindow::on_cbxDrawAxes_clicked(bool checked)
-{
-	mGLView->Enable_Axes(checked);
-#if ASSIMP_QT4_VIEWER
-	mGLView->updateGL();
-#else
-	mGLView->update();
-#endif // ASSIMP_QT4_VIEWER
-}
-
-void MainWindow::on_cbxTextures_clicked(bool checked)
-{
-	mGLView->Enable_Textures(checked);
-	mGLView->update();
-}

+ 0 - 148
tools/assimp_qt_viewer/mainwindow.hpp

@@ -1,148 +0,0 @@
-/*
----------------------------------------------------------------------------
-Open Asset Import Library (assimp)
----------------------------------------------------------------------------
-
-Copyright (c) 2006-2018, assimp team
-
-
-
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the following
-conditions are met:
-
-* Redistributions of source code must retain the above
-copyright notice, this list of conditions and the
-following disclaimer.
-
-* Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the
-following disclaimer in the documentation and/or other
-materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
-contributors may be used to endorse or promote products
-derived from this software without specific prior
-written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------------
-*/
-
-#pragma once
-
-// Header files, Qt.
-#if defined ASSIMP_QT4_VIEWER
-#	include <QMainWindow>
-#else
-#	include <QtWidgets>
-#endif
-
-// Header files, project.
-#include "glview.hpp"
-#include "loggerview.hpp"
-
-// Header files, Assimp.
-#include <assimp/Importer.hpp>
-#include <assimp/scene.h>
-
-namespace Ui { 
-    class MainWindow; 
-}
-
-/// \class MainWindow
-/// Main window and algorithms.
-class MainWindow : public QMainWindow {
-    Q_OBJECT
-
-    struct SMouse_Transformation;
-
-public:
-    /// @brief  The class constructor.
-    /// \param [in] pParent - pointer to parent widget.
-    explicit MainWindow( QWidget* pParent = 0 );
-
-    /// @brief  The class destructor.
-    ~MainWindow();
-    
-    /// Import scene from file.
-	/// \param [in] pFileName - path and name of the file.
-	void ImportFile(const QString& pFileName);
-
-	/// Reset informations about the scene
-	void ResetSceneInfos();
-
-	/// Add message with severity "Warning" to log.
-	void LogInfo(const QString& pMessage);
-
-	/// Add message with severity "Error" to log.
-	void LogError(const QString& pMessage);
-
-protected:
-	/// Override function which handles mouse event "button pressed".
-	/// \param [in] pEvent - pointer to event data.
-	void mousePressEvent(QMouseEvent* pEvent) override;
-
-	/// Override function which handles mouse event "button released".
-	/// \param [in] pEvent - pointer to event data.
-	void mouseReleaseEvent(QMouseEvent *pEvent) override;
-
-	/// Override function which handles mouse event "move".
-	/// \param [in] pEvent - pointer to event data.
-	void mouseMoveEvent(QMouseEvent* pEvent) override;
-
-	/// Override function which handles key event "key pressed".
-	/// \param [in] pEvent - pointer to event data.
-	void keyPressEvent(QKeyEvent* pEvent) override;
-
-private slots:
-	/// Show paint/render time and distance between camera and center of the scene.
-	/// \param [in] pPaintTime_ms - paint time in milliseconds.
-	void Paint_Finished(const size_t pPaintTime_ms, const GLfloat pDistance);
-
-	/// Add camera name to list.
-	/// \param [in] pName - name of the camera.
-	void SceneObject_Camera(const QString& pName);
-
-	/// Add lighting source name to list.
-	/// \param [in] pName - name of the light source,
-	void SceneObject_LightSource(const QString& pName);
-
-	void on_butOpenFile_clicked();
-	void on_butExport_clicked();
-	void on_cbxLighting_clicked(bool pChecked);
-	void on_lstLight_itemSelectionChanged();
-	void on_lstCamera_clicked(const QModelIndex &index);
-	void on_cbxBBox_clicked(bool checked);
-	void on_cbxTextures_clicked(bool checked);
-	void on_cbxDrawAxes_clicked(bool checked);
-
-private:
-    Ui::MainWindow *ui;
-    CGLView *mGLView;///< Pointer to OpenGL render.
-    CLoggerView *mLoggerView;///< Pointer to logging object.
-    Assimp::Importer mImporter;///< Assimp importer.
-    const aiScene* mScene;///< Pointer to loaded scene (\ref aiScene).
-
-    /// \struct SMouse_Transformation
-    /// Holds data about transformation of the scene/camera when mouse us used.
-    struct SMouse_Transformation {
-        bool Position_Pressed_Valid;///< Mouse button pressed on GLView.
-        QPoint Position_Pressed_LMB;///< Position where was pressed left mouse button.
-        QPoint Position_Pressed_RMB;///< Position where was pressed right mouse button.
-        aiMatrix4x4 Rotation_AroundCamera;///< Rotation matrix which set rotation angles of the scene around camera.
-        aiMatrix4x4 Rotation_Scene;///< Rotation matrix which set rotation angles of the scene around own center.
-    } mMouse_Transformation;
-};

+ 0 - 544
tools/assimp_qt_viewer/mainwindow.ui

@@ -1,544 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
-  <property name="geometry">
-   <rect>
-    <x>0</x>
-    <y>0</y>
-    <width>641</width>
-    <height>778</height>
-   </rect>
-  </property>
-  <property name="windowTitle">
-   <string>MainWindow</string>
-  </property>
-  <widget class="QWidget" name="centralWidget">
-   <layout class="QVBoxLayout" name="verticalLayout_2">
-    <item>
-     <layout class="QVBoxLayout" name="verticalLayout" stretch="5,1">
-      <item>
-       <layout class="QHBoxLayout" name="hlMainView" stretch="0">
-        <property name="sizeConstraint">
-         <enum>QLayout::SetDefaultConstraint</enum>
-        </property>
-        <item>
-         <layout class="QVBoxLayout" name="verticalLayout_3">
-          <item>
-           <widget class="QGroupBox" name="grpFile">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="focusPolicy">
-             <enum>Qt::NoFocus</enum>
-            </property>
-            <property name="title">
-             <string>File</string>
-            </property>
-            <layout class="QFormLayout" name="formLayout_2">
-             <item row="0" column="0" colspan="2">
-              <widget class="QPushButton" name="butOpenFile">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Open file</string>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="0">
-              <widget class="QLabel" name="lblFileName_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>File name</string>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="1">
-              <widget class="QLineEdit" name="leFileName">
-               <property name="maximumSize">
-                <size>
-                 <width>160</width>
-                 <height>16777215</height>
-                </size>
-               </property>
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="frame">
-                <bool>false</bool>
-               </property>
-               <property name="readOnly">
-                <bool>true</bool>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="0">
-              <widget class="QLabel" name="lblLoadTime_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Load time, s</string>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="1">
-              <widget class="QLabel" name="lblLoadTime">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="4" column="0" colspan="2">
-              <widget class="Line" name="line">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="orientation">
-                <enum>Qt::Horizontal</enum>
-               </property>
-              </widget>
-             </item>
-             <item row="5" column="0" colspan="2">
-              <widget class="QPushButton" name="butExport">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Export</string>
-               </property>
-              </widget>
-             </item>
-             <item row="6" column="0">
-              <widget class="QLabel" name="lblExportTime_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Export time, s</string>
-               </property>
-              </widget>
-             </item>
-             <item row="6" column="1">
-              <widget class="QLabel" name="lblExportTime">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-              </widget>
-             </item>
-            </layout>
-           </widget>
-          </item>
-          <item>
-           <widget class="QGroupBox" name="grpInfo">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="focusPolicy">
-             <enum>Qt::NoFocus</enum>
-            </property>
-            <property name="title">
-             <string>Info</string>
-            </property>
-            <layout class="QFormLayout" name="formLayout_4">
-             <item row="0" column="0">
-              <widget class="QLabel" name="lblRenderTime_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Render time, ms</string>
-               </property>
-              </widget>
-             </item>
-             <item row="0" column="1">
-              <widget class="QLabel" name="lblRenderTime">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="0">
-              <widget class="QLabel" name="lblMeshCount_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Meshes</string>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="0">
-              <widget class="QLabel" name="lblFaceCount_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Faces</string>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="1">
-              <widget class="QLabel" name="lblMeshCount">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="2" column="1">
-              <widget class="QLabel" name="lblFaceCount">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="3" column="0">
-              <widget class="QLabel" name="lblVertexCount_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Vertices</string>
-               </property>
-              </widget>
-             </item>
-             <item row="3" column="1">
-              <widget class="QLabel" name="lblVertexCount">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="4" column="0">
-              <widget class="QLabel" name="lblLightCount_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Lights</string>
-               </property>
-              </widget>
-             </item>
-             <item row="5" column="0">
-              <widget class="QLabel" name="lblCameraCount_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Cameras</string>
-               </property>
-              </widget>
-             </item>
-             <item row="7" column="0">
-              <widget class="QLabel" name="lblHasAnimation_Label">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Animation</string>
-               </property>
-              </widget>
-             </item>
-             <item row="6" column="0">
-              <widget class="QLabel" name="lblShaderCount_Label">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Shaders</string>
-               </property>
-              </widget>
-             </item>
-             <item row="4" column="1">
-              <widget class="QLabel" name="lblLightCount">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="5" column="1">
-              <widget class="QLabel" name="lblCameraCount">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="6" column="1">
-              <widget class="QLabel" name="lblShaderCount">
-               <property name="enabled">
-                <bool>false</bool>
-               </property>
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="7" column="1">
-              <widget class="QLabel" name="lblHasAnimation">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-             <item row="8" column="0">
-              <widget class="QLabel" name="lblDistance_Label">
-               <property name="text">
-                <string>Distance</string>
-               </property>
-              </widget>
-             </item>
-             <item row="8" column="1">
-              <widget class="QLabel" name="lblDistance">
-               <property name="text">
-                <string/>
-               </property>
-               <property name="alignment">
-                <set>Qt::AlignCenter</set>
-               </property>
-              </widget>
-             </item>
-            </layout>
-           </widget>
-          </item>
-          <item>
-           <widget class="QGroupBox" name="grpDynamics">
-            <property name="enabled">
-             <bool>false</bool>
-            </property>
-            <property name="focusPolicy">
-             <enum>Qt::NoFocus</enum>
-            </property>
-            <property name="title">
-             <string>Dynamics</string>
-            </property>
-            <layout class="QGridLayout" name="gridLayout">
-             <item row="0" column="0">
-              <widget class="QPushButton" name="butAnimationStart">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Animation start</string>
-               </property>
-              </widget>
-             </item>
-             <item row="1" column="0">
-              <widget class="QPushButton" name="butAnimationStop">
-               <property name="focusPolicy">
-                <enum>Qt::NoFocus</enum>
-               </property>
-               <property name="text">
-                <string>Animation stop</string>
-               </property>
-              </widget>
-             </item>
-            </layout>
-           </widget>
-          </item>
-         </layout>
-        </item>
-       </layout>
-      </item>
-      <item>
-       <widget class="QTabWidget" name="tabInfoAndControl">
-        <property name="focusPolicy">
-         <enum>Qt::NoFocus</enum>
-        </property>
-        <property name="currentIndex">
-         <number>2</number>
-        </property>
-        <widget class="QWidget" name="tab">
-         <attribute name="title">
-          <string>Log</string>
-         </attribute>
-         <layout class="QGridLayout" name="gridLayout_2">
-          <item row="0" column="0">
-           <widget class="QTextBrowser" name="tbLog">
-            <property name="sizePolicy">
-             <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-              <horstretch>0</horstretch>
-              <verstretch>0</verstretch>
-             </sizepolicy>
-            </property>
-            <property name="minimumSize">
-             <size>
-              <width>0</width>
-              <height>0</height>
-             </size>
-            </property>
-            <property name="focusPolicy">
-             <enum>Qt::NoFocus</enum>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-        <widget class="QWidget" name="tab_2">
-         <attribute name="title">
-          <string>Lights and cameras</string>
-         </attribute>
-         <layout class="QHBoxLayout" name="horizontalLayout">
-          <item>
-           <widget class="QListWidget" name="lstLight">
-            <property name="focusPolicy">
-             <enum>Qt::NoFocus</enum>
-            </property>
-            <property name="toolTip">
-             <string>Light sources of the scene</string>
-            </property>
-            <property name="editTriggers">
-             <set>QAbstractItemView::SelectedClicked</set>
-            </property>
-            <property name="showDropIndicator" stdset="0">
-             <bool>false</bool>
-            </property>
-            <property name="selectionMode">
-             <enum>QAbstractItemView::MultiSelection</enum>
-            </property>
-           </widget>
-          </item>
-          <item>
-           <widget class="QListWidget" name="lstCamera">
-            <property name="focusPolicy">
-             <enum>Qt::NoFocus</enum>
-            </property>
-            <property name="toolTip">
-             <string>Cameras of the scene</string>
-            </property>
-            <property name="editTriggers">
-             <set>QAbstractItemView::NoEditTriggers</set>
-            </property>
-            <property name="showDropIndicator" stdset="0">
-             <bool>false</bool>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-        <widget class="QWidget" name="tab_3">
-         <attribute name="title">
-          <string>Control</string>
-         </attribute>
-         <layout class="QGridLayout" name="gridLayout_3">
-          <item row="0" column="0">
-           <widget class="QCheckBox" name="cbxLighting">
-            <property name="toolTip">
-             <string>Enable/Disable OpenGL lighting</string>
-            </property>
-            <property name="text">
-             <string>Lighting</string>
-            </property>
-            <property name="checked">
-             <bool>true</bool>
-            </property>
-           </widget>
-          </item>
-          <item row="1" column="0">
-           <widget class="QCheckBox" name="cbxBBox">
-            <property name="text">
-             <string>Scene BBox</string>
-            </property>
-           </widget>
-          </item>
-          <item row="2" column="0">
-           <widget class="QCheckBox" name="cbxTextures">
-            <property name="text">
-             <string>Textures</string>
-            </property>
-           </widget>
-          </item>
-          <item row="3" column="0">
-           <widget class="QCheckBox" name="cbxDrawAxes">
-            <property name="text">
-             <string>Show Axes</string>
-            </property>
-            <property name="checked">
-             <bool>true</bool>
-            </property>
-           </widget>
-          </item>
-         </layout>
-        </widget>
-       </widget>
-      </item>
-     </layout>
-    </item>
-   </layout>
-  </widget>
- </widget>
- <layoutdefault spacing="6" margin="11"/>
- <resources/>
- <connections/>
- <slots>
-  <signal>installEventFilter()</signal>
- </slots>
-</ui>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio