1#include <Core/Asset/BlinnPhongMaterialData.hpp>
2#include <Core/Asset/GeometryData.hpp>
3#include <Core/Utils/Color.hpp>
4#include <Core/Utils/ContainerIntrospectionInterface.hpp>
5#include <Core/Utils/Log.hpp>
6#include <IO/AssimpLoader/AssimpGeometryDataLoader.hpp>
8#include <assimp/scene.h>
17using namespace Core::Utils;
18using namespace Core::Asset;
20AssimpGeometryDataLoader::AssimpGeometryDataLoader(
const std::string& filepath,
21 const bool VERBOSE_MODE ) :
22 DataLoader<GeometryData>( VERBOSE_MODE ), m_filepath( filepath ) {}
24AssimpGeometryDataLoader::~AssimpGeometryDataLoader() =
default;
26void AssimpGeometryDataLoader::loadData(
const aiScene* scene,
30 if ( scene ==
nullptr ) {
31 LOG( logINFO ) <<
"AssimpGeometryDataLoader : scene is nullptr.";
35 if ( !sceneHasGeometry( scene ) ) {
36 LOG( logINFO ) <<
"AssimpGeometryDataLoader : scene has no mesh.";
41 LOG( logINFO ) <<
"File contains geometry.";
42 LOG( logINFO ) <<
"Geometry Loading begin...";
45 loadGeometryData( scene, data );
47 if ( m_verbose ) { LOG( logINFO ) <<
"Geometry Loading end.\n"; }
26void AssimpGeometryDataLoader::loadData(
const aiScene* scene, {
…}
50bool AssimpGeometryDataLoader::sceneHasGeometry(
const aiScene* scene )
const {
51 return ( sceneGeometrySize( scene ) != 0 );
50bool AssimpGeometryDataLoader::sceneHasGeometry(
const aiScene* scene )
const {
…}
54uint AssimpGeometryDataLoader::sceneGeometrySize(
const aiScene* scene )
const {
56 if ( scene->HasMeshes() ) {
57 const uint size = scene->mNumMeshes;
58 for ( uint i = 0; i < size; ++i ) {
59 aiMesh* mesh = scene->mMeshes[i];
60 if ( mesh->HasPositions() ) { ++mesh_size; }
54uint AssimpGeometryDataLoader::sceneGeometrySize(
const aiScene* scene )
const {
…}
66void AssimpGeometryDataLoader::loadMeshAttrib(
const aiMesh& mesh,
70 fetchName( mesh, data, usedNames );
71 fetchType( mesh, data );
78 mesh.mVertices, mesh.mNumVertices, geo, Core::Geometry::MeshAttrib::VERTEX_POSITION );
79 if ( mesh.HasNormals() ) {
80 fetchAttribute( mesh.mNormals,
83 Core::Geometry::MeshAttrib::VERTEX_NORMAL );
85 if ( mesh.HasTangentsAndBitangents() ) {
86 fetchAttribute( mesh.mTangents,
89 Core::Geometry::MeshAttrib::VERTEX_TANGENT );
90 fetchAttribute( mesh.mBitangents,
93 Core::Geometry::MeshAttrib::VERTEX_BITANGENT );
97 if ( mesh.GetNumUVChannels() > 1 ) {
99 <<
"Assimp loader : several UV channels are set, Radium will use only the 1st";
101 if ( mesh.HasTextureCoords( 0 ) ) {
102 fetchAttribute( mesh.mTextureCoords[0],
105 Core::Geometry::MeshAttrib::VERTEX_TEXCOORD );
108 if ( mesh.HasVertexColors( 0 ) ) {
109 fetchAttribute( mesh.mColors[0],
112 Core::Geometry::MeshAttrib::VERTEX_COLOR );
118 case GeometryData::GeometryType::LINE_MESH:
119 fetchIndexLayer<Core::Geometry::LineIndexLayer>( mesh.mFaces, mesh.mNumFaces, geo );
121 case GeometryData::GeometryType::TRI_MESH:
122 fetchIndexLayer<Core::Geometry::TriangleIndexLayer>( mesh.mFaces, mesh.mNumFaces, geo );
124 case GeometryData::GeometryType::QUAD_MESH:
125 fetchIndexLayer<Core::Geometry::QuadIndexLayer>( mesh.mFaces, mesh.mNumFaces, geo );
127 case GeometryData::GeometryType::POLY_MESH:
128 fetchIndexLayer<Core::Geometry::PolyIndexLayer>( mesh.mFaces, mesh.mNumFaces, geo );
130 case GeometryData::GeometryType::POINT_CLOUD:
133 std::make_unique<Core::Geometry::PointCloudIndexLayer>(
size_t( mesh.mNumVertices ) );
142void AssimpGeometryDataLoader::loadMeshFrame(
144 const Core::Transform& parentFrame,
147 const uint child_size = node->mNumChildren;
148 const uint mesh_size = node->mNumMeshes;
149 if ( ( child_size == 0 ) && ( mesh_size == 0 ) ) {
return; }
151 Core::Transform frame = parentFrame * assimpToCore( node->mTransformation );
152 for ( uint i = 0; i < mesh_size; ++i ) {
153 const uint ID = node->mMeshes[i];
154 auto it = indexTable.
find( ID );
155 if ( it != indexTable.
end() ) { data[it->second]->
setFrame( frame ); }
158 for ( uint i = 0; i < child_size; ++i ) {
159 loadMeshFrame( node->mChildren[i], frame, indexTable, data );
142void AssimpGeometryDataLoader::loadMeshFrame( {
…}
163void AssimpGeometryDataLoader::fetchName(
const aiMesh& mesh,
167 while ( usedNames.
find( name ) != usedNames.
end() ) {
174void AssimpGeometryDataLoader::fetchType(
const aiMesh& mesh, GeometryData& data )
const {
175 data.setType( GeometryData::UNKNOWN );
179 for ( uint i = 0; i < mesh.mNumFaces; ++i ) {
180 face_max =
std::max( face_max, mesh.mFaces[i].mNumIndices );
181 face_min =
std::min( face_min, mesh.mFaces[i].mNumIndices );
183 switch ( face_max ) {
186 data.setType( GeometryData::POINT_CLOUD );
189 data.setType( GeometryData::LINE_MESH );
192 data.setType( GeometryData::TRI_MESH );
195 if ( face_max - face_min == 0 ) { data.setType( GeometryData::QUAD_MESH ); }
196 else { data.setType( GeometryData::POLY_MESH ); }
199 data.setType( GeometryData::POLY_MESH );
204void AssimpGeometryDataLoader::fetchPolyhedron(
const aiMesh& mesh, GeometryData& data )
const {
210void AssimpGeometryDataLoader::loadMaterial(
const aiMaterial& material,
215 if ( AI_SUCCESS == material.Get( AI_MATKEY_NAME, assimpName ) ) {
216 matName = assimpName.C_Str();
220 auto blinnPhongMaterial =
new BlinnPhongMaterialData( matName );
221 if ( AI_DEFAULT_MATERIAL_NAME != matName ) {
227 if ( AI_SUCCESS == material.Get( AI_MATKEY_COLOR_DIFFUSE, color ) ) {
228 blinnPhongMaterial->m_hasDiffuse =
true;
229 blinnPhongMaterial->m_diffuse = assimpToCore( color );
232 if ( AI_SUCCESS == material.Get( AI_MATKEY_COLOR_SPECULAR, color ) ) {
233 blinnPhongMaterial->m_hasSpecular =
true;
234 blinnPhongMaterial->m_specular = assimpToCore( color );
237 if ( AI_SUCCESS == material.Get( AI_MATKEY_SHININESS, shininess ) ) {
238 blinnPhongMaterial->m_hasShininess =
true;
240 blinnPhongMaterial->m_shininess = shininess * 4;
243 if ( AI_SUCCESS == material.Get( AI_MATKEY_OPACITY, opacity ) ) {
244 blinnPhongMaterial->m_hasOpacity =
true;
248 blinnPhongMaterial->m_opacity = opacity < 1e-5 ? 1 : opacity;
251 if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_DIFFUSE, 0 ), name ) ) {
252 blinnPhongMaterial->m_texDiffuse = m_filepath +
"/" + assimpToCore( name );
253 blinnPhongMaterial->m_hasTexDiffuse =
true;
256 if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_SPECULAR, 0 ), name ) ) {
257 blinnPhongMaterial->m_texSpecular = m_filepath +
"/" + assimpToCore( name );
258 blinnPhongMaterial->m_hasTexSpecular =
true;
261 if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_SHININESS, 0 ), name ) ) {
262 blinnPhongMaterial->m_texShininess = m_filepath +
"/" + assimpToCore( name );
263 blinnPhongMaterial->m_hasTexShininess =
true;
266 if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_NORMALS, 0 ), name ) ) {
267 blinnPhongMaterial->m_texNormal = m_filepath +
"/" + assimpToCore( name );
268 blinnPhongMaterial->m_hasTexNormal =
true;
272 if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_HEIGHT, 0 ), name ) ) {
273 blinnPhongMaterial->m_texNormal = m_filepath +
"/" + assimpToCore( name );
274 blinnPhongMaterial->m_hasTexNormal =
true;
277 if ( AI_SUCCESS == material.Get( AI_MATKEY_TEXTURE( aiTextureType_OPACITY, 0 ), name ) ) {
278 blinnPhongMaterial->m_texOpacity = m_filepath +
"/" + assimpToCore( name );
279 blinnPhongMaterial->m_hasTexOpacity =
true;
282 else { LOG( logINFO ) <<
"Found assimp default material " << matName; }
210void AssimpGeometryDataLoader::loadMaterial(
const aiMaterial& material, {
…}
286void AssimpGeometryDataLoader::loadGeometryData(
287 const aiScene* scene,
289 const uint size = scene->mNumMeshes;
292 for ( uint i = 0; i < size; ++i ) {
293 aiMesh* mesh = scene->mMeshes[i];
294 if ( mesh->HasPositions() ) {
295 if ( m_verbose ) { LOG( logINFO ) <<
"Loading mesh attribs..."; }
297 loadMeshAttrib( *mesh, *geometry, usedNames );
298 if ( m_verbose ) { LOG( logINFO ) <<
"Mesh attribs loaded."; }
300 if ( scene->HasMaterials() ) {
301 const uint matID = mesh->mMaterialIndex;
302 if ( matID < scene->mNumMaterials ) {
303 aiMaterial* material = scene->mMaterials[matID];
304 loadMaterial( *material, *geometry );
308 indexTable[i] = data.
size() - 1;
310 if ( m_verbose ) { geometry->displayInfo(); }
313 loadMeshFrame( scene->mRootNode, Core::Transform::Identity(), indexTable, data );
286void AssimpGeometryDataLoader::loadGeometryData( {
…}
bool isTetraMesh() const
Return true if the object is a Tetrahedron Mesh.
bool isHexMesh() const
Return true if the object is a Hexahedron Mesh.
void setMaterial(MaterialData *material)
Set the MaterialData for the object.
void setPrimitiveCount(int n)
Used to track easily the number of primitives in the geometry data.
GeometryType getType() const
Return the type of geometry.
Geometry::MultiIndexedGeometry & getGeometry()
Read/write access to the multiIndexedGeometry;.
void setFrame(const Transform &frame)
Set the Transform of the object.
void setName(const std::string &name)
Return the name of the object.
hepler function to manage enum as underlying types in VariableSet