Loading [MathJax]/extensions/TeX/AMSmath.js
Radium Engine  1.5.27
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AssimpLightDataLoader.cpp
1#include <Core/Utils/Color.hpp>
2#include <Core/Utils/Log.hpp>
3#include <Eigen/Core>
4#include <Eigen/Geometry>
5#include <Eigen/LU>
6#include <IO/AssimpLoader/AssimpLightDataLoader.hpp>
7#include <IO/AssimpLoader/AssimpWrapper.hpp>
8#include <algorithm>
9#include <assimp/matrix4x4.inl>
10#include <assimp/scene.h>
11#include <assimp/vector3.inl>
12#include <ostream>
13
14namespace Ra {
15namespace IO {
16
17using namespace Core::Utils; // log
18using namespace Core::Asset;
19
20AssimpLightDataLoader::AssimpLightDataLoader( const std::string& filepath,
21 const bool VERBOSE_MODE ) :
22 DataLoader<LightData>( VERBOSE_MODE ), m_filepath( filepath ) {}
23
24AssimpLightDataLoader::~AssimpLightDataLoader() = default;
25
27void AssimpLightDataLoader::loadData( const aiScene* scene,
29 data.clear();
30
31 if ( scene == nullptr ) {
32 LOG( logDEBUG ) << "AssimpLightDataLoader : scene is nullptr.";
33 return;
34 }
35
36 if ( !sceneHasLight( scene ) ) {
37 LOG( logDEBUG ) << "AssimpLightDataLoader : scene has no lights.";
38 return;
39 }
40
41 if ( m_verbose ) {
42 LOG( logINFO ) << "File contains light.";
43 LOG( logINFO ) << "Light Loading begin...";
44 }
45
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] ) ) );
50 }
51
52 if ( m_verbose ) { LOG( logINFO ) << "Light Loading end.\n"; }
53}
54
55bool AssimpLightDataLoader::sceneHasLight( const aiScene* scene ) const {
56 return ( scene->HasLights() );
57}
58
59uint AssimpLightDataLoader::sceneLightSize( const aiScene* scene ) const {
60 return scene->mNumLights;
61}
62
63// LightData * AssimpLightDataLoader::loadLightData(const aiScene *scene, const aiLight
64// &light)
65std::unique_ptr<LightData> AssimpLightDataLoader::loadLightData( const aiScene* scene,
66 const aiLight& light ) {
67 // auto builtLight = new LightData(fetchName( light ), fetchType( 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() );
72 setFrame( frame );
73 auto color = assimpToCore( light.mColorDiffuse );
74
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>() );
79 } break;
80
81 case LightData::POINT_LIGHT: {
82 builtLight->setLight(
83 color,
84 ( frame *
85 Core::Vector4 { light.mPosition[0], light.mPosition[1], light.mPosition[2], 1.0 } )
86 .hnormalized(),
87 LightData::LightAttenuation( light.mAttenuationConstant,
88 light.mAttenuationLinear,
89 light.mAttenuationQuadratic ) );
90 } break;
91
92 case LightData::SPOT_LIGHT: {
93 Core::Vector4 dir( light.mDirection[0], light.mDirection[1], light.mDirection[2], 0.0 );
94
95 builtLight->setLight(
96 color,
97 ( frame *
98 Core::Vector4 { light.mPosition[0], light.mPosition[1], light.mPosition[2], 1.0 } )
99 .hnormalized(),
100 -( frame.transpose().inverse() * dir ).head<3>(),
101 light.mAngleInnerCone,
102 light.mAngleOuterCone,
103 LightData::LightAttenuation( light.mAttenuationConstant,
104 light.mAttenuationLinear,
105 light.mAttenuationQuadratic ) );
106 } break;
107
108 case LightData::AREA_LIGHT: {
109 LOG( logWARNING ) << "Light " << builtLight->getName()
110 << " : AREA light are not yet supported.";
111 } break;
112 default: {
113 LOG( logWARNING ) << "Light " << builtLight->getName() << " : unknown type.";
114 } break;
115 }
116 return builtLight;
117}
118
119Core::Matrix4 AssimpLightDataLoader::loadLightFrame( const aiScene* scene,
120 const Core::Matrix4& parentFrame,
121 const std::string& lightName ) const {
122 const aiNode* lightNode = scene->mRootNode->FindNode( lightName.c_str() );
123
124 if ( lightNode != nullptr ) {
125
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]; } );
130
131 return parentFrame * t0 * t1;
132 }
133 return parentFrame;
134}
135
136std::string AssimpLightDataLoader::fetchName( const aiLight& light ) const {
137 return assimpToCore( light.mName );
138}
139
140LightData::LightType AssimpLightDataLoader::fetchType( const aiLight& light ) const {
141 switch ( light.mType ) {
142 case aiLightSource_DIRECTIONAL: {
143 return LightData::DIRECTIONAL_LIGHT;
144 }
145
146 case aiLightSource_POINT: {
147 return LightData::POINT_LIGHT;
148 }
149
150 case aiLightSource_SPOT: {
151 return LightData::SPOT_LIGHT;
152 }
153
154 case aiLightSource_AREA: {
155 return LightData::AREA_LIGHT;
156 }
157
158 case aiLightSource_UNDEFINED:
159 default: {
160 // LOG(ERROR) << "Light " << name.C_Str() << " has undefined type.";
161 return LightData::UNKNOWN;
162 }
163 }
164}
165
166} // namespace IO
167} // namespace Ra
T c_str(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:4