1#include <Core/Utils/Color.hpp>
2#include <Core/Utils/Log.hpp>
4#include <Eigen/Geometry>
6#include <IO/AssimpLoader/AssimpLightDataLoader.hpp>
7#include <IO/AssimpLoader/AssimpWrapper.hpp>
9#include <assimp/matrix4x4.inl>
10#include <assimp/scene.h>
11#include <assimp/vector3.inl>
17using namespace Core::Utils;
18using namespace Core::Asset;
20AssimpLightDataLoader::AssimpLightDataLoader(
const std::string& filepath,
21 const bool VERBOSE_MODE ) :
22 DataLoader<LightData>( VERBOSE_MODE ), m_filepath( filepath ) {}
24AssimpLightDataLoader::~AssimpLightDataLoader() =
default;
27void AssimpLightDataLoader::loadData(
const aiScene* scene,
31 if ( scene ==
nullptr ) {
32 LOG( logDEBUG ) <<
"AssimpLightDataLoader : scene is nullptr.";
36 if ( !sceneHasLight( scene ) ) {
37 LOG( logDEBUG ) <<
"AssimpLightDataLoader : scene has no lights.";
42 LOG( logINFO ) <<
"File contains light.";
43 LOG( logINFO ) <<
"Light Loading begin...";
46 uint lightSize = sceneLightSize( scene );
47 data.reserve( lightSize );
48 for ( uint lightId = 0; lightId < lightSize; ++lightId ) {
49 data.emplace_back( loadLightData( scene, *( scene->mLights[lightId] ) ) );
52 if ( m_verbose ) { LOG( logINFO ) <<
"Light Loading end.\n"; }
55bool AssimpLightDataLoader::sceneHasLight(
const aiScene* scene )
const {
56 return ( scene->HasLights() );
59uint AssimpLightDataLoader::sceneLightSize(
const aiScene* scene )
const {
60 return scene->mNumLights;
66 const aiLight& light ) {
68 auto builtLight = std::make_unique<LightData>( fetchName( light ), fetchType( light ) );
69 Core::Matrix4 rootMatrix;
70 rootMatrix = Core::Matrix4::Identity();
71 Core::Matrix4 frame = loadLightFrame( scene, rootMatrix, builtLight->getName() );
73 auto color = assimpToCore( light.mColorDiffuse );
75 switch ( builtLight->getType() ) {
76 case LightData::DIRECTIONAL_LIGHT: {
77 Core::Vector4 dir( light.mDirection[0], light.mDirection[1], light.mDirection[2], 0.0 );
78 builtLight->setLight( color, -( frame.transpose().inverse() * dir ).head<3>() );
81 case LightData::POINT_LIGHT: {
85 Core::Vector4 { light.mPosition[0], light.mPosition[1], light.mPosition[2], 1.0 } )
87 LightData::LightAttenuation( light.mAttenuationConstant,
88 light.mAttenuationLinear,
89 light.mAttenuationQuadratic ) );
92 case LightData::SPOT_LIGHT: {
93 Core::Vector4 dir( light.mDirection[0], light.mDirection[1], light.mDirection[2], 0.0 );
98 Core::Vector4 { light.mPosition[0], light.mPosition[1], light.mPosition[2], 1.0 } )
100 -( frame.transpose().inverse() * dir ).head<3>(),
101 light.mAngleInnerCone,
102 light.mAngleOuterCone,
103 LightData::LightAttenuation( light.mAttenuationConstant,
104 light.mAttenuationLinear,
105 light.mAttenuationQuadratic ) );
108 case LightData::AREA_LIGHT: {
109 LOG( logWARNING ) <<
"Light " << builtLight->getName()
110 <<
" : AREA light are not yet supported.";
113 LOG( logWARNING ) <<
"Light " << builtLight->getName() <<
" : unknown type.";
119Core::Matrix4 AssimpLightDataLoader::loadLightFrame(
const aiScene* scene,
120 const Core::Matrix4& parentFrame,
122 const aiNode* lightNode = scene->mRootNode->FindNode( lightName.
c_str() );
124 if ( lightNode !=
nullptr ) {
126 auto t0 = Core::Matrix4::NullaryExpr(
127 [&scene](
int i,
int j ) {
return scene->mRootNode->mTransformation[i][j]; } );
128 auto t1 = Core::Matrix4::NullaryExpr(
129 [&lightNode](
int i,
int j ) {
return lightNode->mTransformation[i][j]; } );
131 return parentFrame * t0 * t1;
136std::string AssimpLightDataLoader::fetchName(
const aiLight& light )
const {
137 return assimpToCore( light.mName );
140LightData::LightType AssimpLightDataLoader::fetchType(
const aiLight& light )
const {
141 switch ( light.mType ) {
142 case aiLightSource_DIRECTIONAL: {
143 return LightData::DIRECTIONAL_LIGHT;
146 case aiLightSource_POINT: {
147 return LightData::POINT_LIGHT;
150 case aiLightSource_SPOT: {
151 return LightData::SPOT_LIGHT;
154 case aiLightSource_AREA: {
155 return LightData::AREA_LIGHT;
158 case aiLightSource_UNDEFINED:
161 return LightData::UNKNOWN;
hepler function to manage enum as underlying types in VariableSet