Radium Engine  1.5.0
AssimpFileLoader.cpp
1 #include <IO/AssimpLoader/AssimpFileLoader.hpp>
2 
3 #include <Core/Asset/FileData.hpp>
4 #include <Core/Utils/StringUtils.hpp>
5 
6 #include <assimp/postprocess.h>
7 #include <assimp/scene.h>
8 
9 #include <IO/AssimpLoader/AssimpAnimationDataLoader.hpp>
10 #include <IO/AssimpLoader/AssimpCameraDataLoader.hpp>
11 #include <IO/AssimpLoader/AssimpGeometryDataLoader.hpp>
12 #include <IO/AssimpLoader/AssimpHandleDataLoader.hpp>
13 #include <IO/AssimpLoader/AssimpLightDataLoader.hpp>
14 
15 #include <iostream>
16 
17 namespace Ra {
18 namespace IO {
19 
20 using namespace Core::Utils; // log
21 using namespace Core::Asset;
22 
23 AssimpFileLoader::AssimpFileLoader() = default;
24 
25 AssimpFileLoader::~AssimpFileLoader() = default;
26 
27 std::vector<std::string> AssimpFileLoader::getFileExtensions() const {
28  std::string extensionsList;
29 
30  m_importer.GetExtensionList( extensionsList );
31 
32  // source: https://www.fluentcpp.com/2017/04/21/how-to-split-a-string-in-c/
33  std::istringstream iss( extensionsList );
34  std::string ext;
35  std::vector<std::string> extensions;
36  while ( std::getline( iss, ext, ';' ) ) {
37  extensions.push_back( ext );
38  }
39  return extensions;
40 }
41 
42 bool AssimpFileLoader::handleFileExtension( const std::string& extension ) const {
43  return m_importer.IsExtensionSupported( extension );
44 }
45 
46 FileData* AssimpFileLoader::loadFile( const std::string& filename ) {
47 
48  auto fileData = new FileData( filename );
49  // fileData->setVerbose( true );
50 
51  if ( !fileData->isInitialized() ) { return nullptr; }
52 
53  /*
54  * TODO : allow user to parameterize assimp process on loaded meshes
55  */
56  const aiScene* scene =
57  m_importer.ReadFile( fileData->getFileName(),
58  aiProcess_GenSmoothNormals | aiProcess_SortByPType |
59  aiProcess_CalcTangentSpace | aiProcess_GenUVCoords );
60 
61  if ( scene == nullptr ) {
62  LOG( logINFO ) << "File \"" << fileData->getFileName()
63  << "\" assimp error : " << m_importer.GetErrorString() << ".";
64  return nullptr;
65  }
66 
67  if ( fileData->isVerbose() ) { LOG( logINFO ) << "File Loading begin..."; }
68 
69  std::clock_t startTime;
70  startTime = std::clock();
71 
72  // FIXME : this workaround is related to assimp issue
73  // #2260 Mesh created for a light only file (collada)
74  // https://github.com/assimp/assimp/issues/2260
75  if ( scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE ) {
76  LOG( logWARNING )
77  << " ai scene is incomplete, just try to load lights or skeletons (but not both).";
78 
79  AssimpLightDataLoader lightLoader( Core::Utils::getDirName( filename ),
80  fileData->isVerbose() );
81  lightLoader.loadData( scene, fileData->m_lightData );
82 
83  if ( !fileData->hasLight() ) {
84  AssimpHandleDataLoader handleLoader( fileData->isVerbose() );
85  handleLoader.loadData( scene, fileData->m_handleData );
86 
87  AssimpAnimationDataLoader animationLoader( fileData->isVerbose() );
88  animationLoader.loadData( scene, fileData->m_animationData );
89  }
90  }
91  else {
92  AssimpGeometryDataLoader geometryLoader( Core::Utils::getDirName( filename ),
93  fileData->isVerbose() );
94  geometryLoader.loadData( scene, fileData->m_geometryData );
95 
96  // check if that the scene contains at least one mesh
97  // Note that currently, Assimp is ALWAYS creating faces, even when
98  // loading point clouds
99  // (see 3rdPartyLibraries/Assimp/code/PlyLoader.cpp:260)
100  bool ok = std::any_of( fileData->m_geometryData.begin(),
101  fileData->m_geometryData.end(),
102  []( const auto& geom ) -> bool { return geom->hasFaces(); } );
103  if ( !ok ) {
104  if ( fileData->isVerbose() ) { LOG( logINFO ) << "Point-cloud found. Aborting"; }
105  delete fileData;
106  return nullptr;
107  }
108 
109  AssimpHandleDataLoader handleLoader( fileData->isVerbose() );
110  handleLoader.loadData( scene, fileData->m_handleData );
111 
112  AssimpAnimationDataLoader animationLoader( fileData->isVerbose() );
113  animationLoader.loadData( scene, fileData->m_animationData );
114 
115  AssimpLightDataLoader lightLoader( Core::Utils::getDirName( filename ),
116  fileData->isVerbose() );
117  lightLoader.loadData( scene, fileData->m_lightData );
118  AssimpCameraDataLoader cameraLoader( fileData->isVerbose() );
119  cameraLoader.loadData( scene, fileData->m_cameraData );
120  }
121 
122  fileData->m_loadingTime = ( std::clock() - startTime ) / Scalar( CLOCKS_PER_SEC );
123 
124  if ( fileData->isVerbose() ) {
125  LOG( logINFO ) << "File Loading end.";
126 
127  fileData->displayInfo();
128  }
129 
130  fileData->m_processed = true;
131 
132  return fileData;
133 }
134 
135 std::string AssimpFileLoader::name() const {
136  return "Assimp";
137 }
138 } // namespace IO
139 } // namespace Ra
Definition: Cage.cpp:3