Radium Engine  1.5.20
Loading...
Searching...
No Matches
CLIViewer.cpp
1#include <Headless/CLIViewer.hpp>
2
3#include <Core/Asset/Camera.hpp>
4#include <Core/Asset/FileLoaderInterface.hpp>
5#include <Core/Tasks/TaskQueue.hpp>
6#include <Core/Utils/Log.hpp>
7
8#include <Engine/Data/ViewingParameters.hpp>
9#include <Engine/RadiumEngine.hpp>
10#include <Engine/Rendering/Renderer.hpp>
11#include <Engine/Scene/DefaultCameraManager.hpp>
12#include <Engine/Scene/DirLight.hpp>
13#include <Engine/Scene/EntityManager.hpp>
14#include <Engine/Scene/GeometrySystem.hpp>
15#include <Engine/Scene/SkeletonBasedAnimationSystem.hpp>
17
18namespace Ra {
19namespace Headless {
20using namespace Ra::Core::Utils;
21
22constexpr int defaultSystemPriority = 1000;
23
26
28 if ( m_engineInitialized ) {
29 m_glContext->makeCurrent();
31 Ra::Engine::RadiumEngine::destroyInstance();
32 m_glContext->doneCurrent();
33 }
34}
35
36int CLIRadiumEngineApp::init( int argc, const char* argv[] ) {
37 int parseResult = CLIBaseApplication::init( argc, argv );
38 if ( parseResult != 0 ) {
39 if ( parseResult != 1 ) {
40 LOG( logERROR ) << "Invalid command line argument, the application can't run";
41 return parseResult;
42 }
43 return 1;
44 };
45 // Do the Viewer init
46 if ( !m_glContext->isValid() ) {
47 LOG( logERROR ) << "Invalid openglContext, the application can't run";
48 return 1;
49 }
50
51 // Create engine
52 m_engine = Ra::Engine::RadiumEngine::createInstance();
55
56 // initialize OpenGL part of the Engine
57 m_glContext->makeCurrent();
59 m_glContext->doneCurrent();
60
61 // Init is OK
62 return 0;
63}
64
66 m_glContext->makeCurrent();
67 f();
68 m_glContext->doneCurrent();
69}
70
72 if ( on ) { m_glContext->makeCurrent(); }
73 else { m_glContext->doneCurrent(); }
74}
75
76CLIViewer::CLIViewer( std::unique_ptr<OpenGLContext> context ) :
77 CLIRadiumEngineApp( std::move( context ) ) {
78 // add ->required() to force user to give a filename;
79 addOption( "-f,--file", m_parameters.m_dataFile, "Data file to process." )
80 ->check( CLI::ExistingFile );
81 addOption( "-s,--size", m_parameters.m_size, "Size of the computed image." )->delimiter( 'x' );
82 addFlag( "-a,--animation", m_parameters.m_animationEnable, "Enable Radium Animation system." );
83}
84
85CLIViewer::~CLIViewer() {
86 if ( m_engineInitialized ) {
87 m_glContext->makeCurrent();
88 m_renderer.reset();
89 m_glContext->doneCurrent();
90 }
91}
92
93const CLIViewer::ViewerParameters& CLIViewer::getCommandLineParameters() const {
94 return m_parameters;
95}
96
97int CLIViewer::init( int argc, const char* argv[] ) {
98
99 int parseResult = CLIRadiumEngineApp::init( argc, argv );
100 if ( parseResult != 0 ) { return parseResult; };
101
102 m_glContext->resize( m_parameters.m_size );
103 LOG( logINFO ) << "CLIViewer :\n" << m_glContext->getInfo();
104
105 // Initialize the Radium engine environment
106
107 // Register the GeometrySystem converting loaded assets to meshes
109 "GeometrySystem", new Ra::Engine::Scene::GeometrySystem, defaultSystemPriority );
110
111 if ( m_parameters.m_animationEnable ) {
112 // Register the SkeletonBasedAnimationSystem converting loaded assets to
113 // skeletons and skinning data
114 m_engine->registerSystem( "SkeletonBasedAnimationSystem",
116 defaultSystemPriority );
117 }
118
119 // register listeners on the OpenGL Context
120 m_glContext->resizeListener().attach(
121 [this]( int width, int height ) { resize( width, height ); } );
122 // Init is OK
123 return 0;
124}
125
126int CLIViewer::oneFrame( float timeStep ) {
127 if ( m_parameters.m_animationEnable ) {
128 auto animationSystem = dynamic_cast<Ra::Engine::Scene::SkeletonBasedAnimationSystem*>(
129 m_engine->getSystem( "SkeletonBasedAnimationSystem" ) );
130 if ( animationSystem ) { animationSystem->toggleSkeleton( false ); }
131 m_engine->setConstantTimeStep( timeStep );
132 m_engine->step();
133 }
134
136
137 m_engine->getTasks( &tasks, Scalar( timeStep ) );
138 tasks.startTasks();
139 tasks.waitForTasks();
140 tasks.flushTaskQueue();
141
143
145 m_camera->getViewMatrix(), m_camera->getProjMatrix(), timeStep };
146 if ( m_renderer ) m_renderer->render( data );
147 return 0;
148}
149
150std::unique_ptr<unsigned char[]> CLIViewer::grabFrame( size_t& w, size_t& h ) const {
151 return m_renderer->grabFrame( w, h );
152}
153
154void CLIViewer::setRenderer( Ra::Engine::Rendering::Renderer* renderer ) {
155 m_glContext->makeCurrent();
156
157 m_renderer.reset( renderer );
158 m_renderer->initialize( m_parameters.m_size[0], m_parameters.m_size[1] );
159
160 m_glContext->doneCurrent();
161}
162
163void CLIViewer::addDataFileLoader( Ra::Core::Asset::FileLoaderInterface* loader ) {
165}
166
167void CLIViewer::loadScene() {
168 m_engine->loadFile( m_parameters.m_dataFile );
169}
170
171void CLIViewer::compileScene() {
172 if ( m_renderer ) {
173 m_renderer->buildAllRenderTechniques();
174 if ( !m_renderer->hasLight() ) {
175 auto headlight = new Ra::Engine::Scene::DirectionalLight(
176 Ra::Engine::Scene::SystemEntity::getInstance(), "headlight" );
177 headlight->setColor( Ra::Core::Utils::Color::Grey( 2.0_ra ) );
178 headlight->setDirection( m_camera->getDirection() );
179 m_renderer->addLight( headlight );
180 }
181 }
182}
183Ra::Core::Utils::Index CLIViewer::setCamera( Ra::Core::Utils::Index camIdx ) {
184 auto cameraManager = static_cast<Ra::Engine::Scene::CameraManager*>(
185 Ra::Engine::RadiumEngine::getInstance()->getSystem( "DefaultCameraManager" ) );
186
187 if ( camIdx.isInvalid() || cameraManager->count() <= size_t( camIdx ) ) {
188 LOG( logDEBUG ) << "CLIViewer::setCamera : invalid camera index, using camera at index 0.";
189 camIdx = 0;
190 }
191
192 if ( cameraManager->count() == 0 ) {
193 LOG( logDEBUG )
194 << "CLIViewer::setCamera : no camera in the manager, creating default camera.";
195 // add camera to the manager
196 auto e = m_engine->getEntityManager()->createEntity( "Default Camera" );
197 auto camera = new Ra::Engine::Scene::CameraComponent( e, "Camera" );
198 camera->initialize();
199 cameraManager->addCamera( camera );
200
201 // set camera properties
202 auto cam = camera->getCamera();
203 cam->setFOV( 60.0_ra * Ra::Core::Math::toRad );
204 cam->setZNear( 0.1_ra );
205 cam->setZFar( 100_ra );
206 auto aabb = Ra::Engine::RadiumEngine::getInstance()->computeSceneAabb();
207 Scalar f = cam->getFOV();
208 Scalar a = cam->getAspect();
209 const Scalar r = ( aabb.max() - aabb.min() ).norm() / 2_ra;
210 const Scalar x = r / std::sin( f / 2_ra );
211 const Scalar y = r / std::sin( f * a / 2_ra );
212 Scalar d = std::max( std::max( x, y ), 0.001_ra );
213 cam->setPosition(
214 Ra::Core::Vector3( aabb.center().x(), aabb.center().y(), aabb.center().z() + d ) );
215 cam->setDirection( Ra::Core::Vector3( 0_ra, 0_ra, -1_ra ) );
216 Scalar zfar = std::max( d + ( aabb.max().z() - aabb.min().z() ) * 2_ra, cam->getZFar() );
217 cam->setZFar( zfar );
218 }
219
220 cameraManager->activate( camIdx );
221 m_camera = cameraManager->getActiveCamera();
222
223 return camIdx;
224}
225
226void CLIViewer::setImageNamePrefix( std::string s ) {
227 m_parameters.m_imgPrefix = std::move( s );
228}
229
230void CLIViewer::showWindow( bool on, OpenGLContext::EventMode mode, float delay ) {
231 m_exposedWindow = on;
232 if ( m_exposedWindow ) {
233 m_glContext->resize( m_parameters.m_size );
234 m_glContext->show( mode, delay );
235 }
236 else { m_glContext->hide(); }
237}
238
239void CLIViewer::renderLoop( std::function<void( float )> render ) {
240 m_glContext->renderLoop( render );
241}
242
243void CLIViewer::resize( int width, int height ) {
244 if ( m_renderer ) {
245 m_renderer->resize( width, height );
246 m_camera->setViewport( width, height );
247 }
248}
249
250} // namespace Headless
251} // namespace Ra
void setViewport(Scalar width, Scalar height)
Change the viewport size. Also compute aspectRatio.
Definition Camera.cpp:50
Core::Matrix4 getProjMatrix() const
Return the projection matrix.
Definition Camera.hpp:335
Core::Vector3 getDirection() const
Return the direction the camera is looking at.
Definition Camera.hpp:254
This class allows tasks to be registered and then executed in parallel on separate threads.
Definition TaskQueue.hpp:48
Scene::System * getSystem(const std::string &system) const
bool loadFile(const std::string &file)
Scene::EntityManager * getEntityManager() const
void getTasks(Core::TaskQueue *taskQueue, Scalar dt)
void registerFileLoader(std::shared_ptr< Core::Asset::FileLoaderInterface > fileLoader)
bool setConstantTimeStep(Scalar dt, bool forceConstantTime=false)
Sets the time delta between two frames for Constant-time time flow.
bool registerSystem(const std::string &name, Scene::System *system, int priority=1)
void render(const Data::ViewingParameters &renderData)
Tell the renderer it needs to render. This method does the following steps :
Definition Renderer.cpp:315
void initialize(uint width, uint height)
Initialize renderer.
Definition Renderer.cpp:56
void resize(uint width, uint height)
Resize the viewport and all the screen textures, fbos. This function must be overrided as soon as som...
Definition Renderer.cpp:671
bool hasLight() const
Tell if the renderer has an usable light.
Definition Renderer.cpp:756
virtual void addLight(const Scene::Light *light)
Definition Renderer.cpp:751
virtual std::unique_ptr< uchar[]> grabFrame(size_t &w, size_t &h) const
Definition Renderer.cpp:717
void activate(Core::Utils::Index index)
virtual int init(int argc, const char *argv[])
CLI::Option * addFlag(Args &&... args)
CLI::Option * addOption(Args &&... args)
Ra::Engine::RadiumEngine * m_engine
Instance of the radium engine.
Definition CLIViewer.hpp:85
virtual ~CLIRadiumEngineApp()
Base destructor.
Definition CLIViewer.cpp:27
bool m_engineInitialized
is the engine initialized ?
Definition CLIViewer.hpp:82
std::unique_ptr< OpenGLContext > m_glContext
Headless OpenGLContext.
Definition CLIViewer.hpp:79
int init(int argc, const char *argv[]) override
Application initialization method.
Definition CLIViewer.cpp:36
void openGlAddOns(std::function< void()> f)
Definition CLIViewer.cpp:65
void bindOpenGLContext(bool on=true)
Definition CLIViewer.cpp:71
CLIRadiumEngineApp(std::unique_ptr< OpenGLContext > context)
Construct the viewer using an OpenGL context of the given version.
Definition CLIViewer.cpp:24
EventMode
Identify the event processing method when the window is exposed.
T hardware_concurrency(T... args)
T max(T... args)
T move(T... args)
hepler function to manage enum as underlying types in VariableSet
Definition Cage.cpp:3
STL namespace.
T reset(T... args)
T sin(T... args)
the set of viewing parameters extracted from the camera and given to the renderer