source: flair-src/trunk/lib/FlairSimulator/src/Gui_impl.cpp@ 365

Last change on this file since 365 was 365, checked in by Sanahuja Guillaume, 16 months ago

change simu apps compilation to avoid problem with mixing host and toolchain libs
(log2@glibc_2.29 error when compiling on ubuntu 20.05 or mint 20)
now compile with host g++ and libs (except filelib, irrlicht, quat, udt and vrpn) for simu apps using the macro: FLAIR_DEMO_HOST_CXX

File size: 12.8 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5// created: 2013/03/27
6// filename: Gui.cpp
7//
8// author: Guillaume Sanahuja
9// Copyright Heudiasyc UMR UTC/CNRS 7253
10//
11// version: $Id: $
12//
13// purpose: classe definissant une Gui
14//
15/*********************************************************************/
16#ifdef GL
17
18#include "Gui_impl.h"
19#include "Gui.h"
20#include "Simulator.h"
21#include "GenericObject.h"
22#include "Model.h"
23#include "Model_impl.h"
24#include "VisualizationCamera.h"
25#include "FollowMeCamera.h"
26#include <Object.h>
27#include <Euler.h>
28#include <irrlicht.h>
29#include <unistd.h>
30#include <sstream>
31
32using namespace irr;
33using namespace irr::video;
34using namespace irr::core;
35using namespace irr::scene;
36using namespace irr::gui;
37using namespace flair::core;
38using namespace flair::simulator;
39
40class MyEventReceiver : public IEventReceiver {
41public:
42 // This is the one method that we have to implement
43 bool OnEvent(const SEvent &event) {
44 // Remember whether each key is down or up
45 if (event.EventType == EET_KEY_INPUT_EVENT)
46 KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
47
48 if (model)
49 return model->OnEvent(event);
50
51 return false;
52 }
53
54 // This is used to check whether a key is being held down
55 bool IsKeyDown(EKEY_CODE keyCode) {
56 if (KeyIsDown[keyCode] == true) {
57 KeyIsDown[keyCode] = false;
58 return true;
59 } else {
60 return false;
61 }
62 }
63
64 MyEventReceiver(void) {
65 model = NULL;
66 for (u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i)
67 KeyIsDown[i] = false;
68 }
69 void SetModel(Model *model) { this->model = model; }
70
71private:
72 // We use this array to store the current state of each key
73 bool KeyIsDown[KEY_KEY_CODES_COUNT];
74 Model *model;
75};
76
77Gui_impl::Gui_impl(Gui *self, int app_width, int app_height, int scene_width,
78 int scene_height, std::string media_path,
79 E_DRIVER_TYPE driver_type) {
80 this->self = self;
81 dbtFile_w = NULL;
82 dbtFile_r = NULL;
83 this->media_path = media_path;
84 this->scene_width = scene_width;
85 this->scene_height = scene_height;
86
87 device = createDevice(driver_type, dimension2d<u32>(app_width, app_height),16, false, false, false);
88 if(device==NULL) self->Err("Irrlicht failed to create video device\n");
89 receiver = new MyEventReceiver();
90 device->setEventReceiver(receiver);
91 device->getLogger()->setLogLevel(ELL_NONE);
92
93 device->getCursorControl()->setVisible(false);
94 device->setResizable(false);
95
96 driver = device->getVideoDriver();
97 smgr = device->getSceneManager();
98
99 smgr->setAmbientLight(video::SColorf(1, 1, 1));
100
101 /*
102env = device->getGUIEnvironment();
103IGUISkin* skin = env->getSkin();
104 font = env->getFont("./fonthaettenschweiler.bmp");
105
106 if (font)
107 skin->setFont(font);
108
109 // create menu
110
111 IGUIContextMenu* menu = env->addMenu();
112 menu->setMinSize(core::dimension2du(640,20));
113 menu->addItem(L"File", -1, true, true);
114 menu->addItem(L"View", -1, true, true);
115 menu->addItem(L"Camera", -1, true, true);
116 menu->addItem(L"Help", -1, true, true);
117
118 // disable alpha
119
120 for (s32 i=0; i<gui::EGDC_COUNT ; ++i)
121 {
122 video::SColor col =
123env->getSkin()->getColor((gui::EGUI_DEFAULT_COLOR)i);
124 col.setAlpha(255);
125 env->getSkin()->setColor((gui::EGUI_DEFAULT_COLOR)i, col);
126 }
127 */
128}
129
130Gui_impl::~Gui_impl() {
131 // printf("del Gui_impl\n");
132 //device->drop();
133
134 delete receiver;
135 // printf("del Gui_impl ok\n");
136}
137
138void Gui_impl::AddVisualizationCamera(VisualizationCamera* camera) {
139 cameras.push_back(camera);
140}
141
142void Gui_impl::setMesh(std::string file, vector3df position, vector3df rotation,
143 vector3df scale) {
144 IAnimatedMesh *mesh = smgr->getMesh(file.c_str());
145
146 if (!mesh) {
147 // model could not be loaded
148 self->Err("Model %s could not be loaded\n", file.c_str());
149 return;
150 }
151
152 node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
153 node->setPosition(position);
154 rotation +=
155 irr::core::vector3df(90, 0, Euler::ToDegree(getSimulator()->Yaw()));
156 node->setRotation(rotation);
157 for (int i = 0; i < node->getMaterialCount(); i++) {
158 node->getMaterial(i).TextureLayer->TextureWrapU = video::ETC_REPEAT;
159 node->getMaterial(i).TextureLayer->TextureWrapV = video::ETC_REPEAT;
160 }
161 // Ceillig
162 // node->getMaterial(0).getTextureMatrix(0).setTextureScale(scale.X/2.0,scale.Z/2.0);
163 // Walls
164 node->getMaterial(1).getTextureMatrix(0).setTextureScale(1 / (scale.Y / 2.5),
165 1 / (scale.Z / 2.5));
166 // Floor
167 node->getMaterial(2).getTextureMatrix(0).setTextureScale(
168 1 / (scale.X / 20.0), 1 / (scale.Z / 20.0));
169
170 node->setScale(scale);
171 // selector
172 selector = smgr->createOctreeTriangleSelector(node->getMesh(), node, 128);
173 node->setTriangleSelector(selector);
174}
175
176void Gui_impl::RunGui(std::vector<Model *> models,
177 std::vector<GenericObject *> objects) {
178 int lastFPS = -1;
179 int cam_id = 0;
180 ITexture* texture=0;
181 IGUIFont* font =0;
182 VisualizationCamera::AxisType axisType=VisualizationCamera::AxisType::vrpn;
183
184 if (!driver->queryFeature(video::EVDF_RENDER_TO_TARGET)) {
185 self->Warn("rendering to texture is not possible, axis will not be displayed\n");
186 } else {
187 texture= getGui()->getSceneManager()->getVideoDriver()->addRenderTargetTexture(dimension2d<u32>(128,128));
188 device->getGUIEnvironment()->addImage(texture,position2d<s32>(0,scene_height-texture->getSize().Height));
189 font = getGui()->getDevice()->getGUIEnvironment()->getFont((media_path+"/font/simu_axis_font.xml").c_str());
190 }
191
192 receiver->SetModel(models.at(0));
193
194 for (size_t i = 0; i < models.size(); i++) {
195 models.at(i)->Draw();
196 }
197
198 for (size_t i = 0; i < models.size(); i++) {
199 models.at(i)->pimpl_->MetaTriangleSelector()->addTriangleSelector(selector);
200 for (size_t j = 0; j < objects.size(); j++) {
201 models.at(i)->pimpl_->MetaTriangleSelector()->addTriangleSelector(
202 objects.at(j)->TriangleSelector());
203 }
204 for (size_t j = 0; j < models.size(); j++) {
205 if (i == j) continue;
206 models.at(i)->pimpl_->MetaTriangleSelector()->addTriangleSelector(
207 models.at(j)->pimpl_->TriangleSelector());
208 }
209 }
210
211 selector->drop(); // As soon as we're done with the selector, drop it.*/
212
213 // wait all models to be started
214 for (size_t i = 0; i < models.size(); i++) {
215 models.at(i)->pimpl_->SynchronizationPoint();
216 }
217
218 setWindowCaption(0, 0);
219
220 Printf("\nUsefull keys:\n");
221 Printf(" page up/down: circle between cameras\n");
222 Printf(" a: change axis display (VRPN, earth or none)\n");
223
224 while (device->run()) {
225 if (dbtFile_r != NULL) {// rejeu
226 takeScreenshot(); // on enregistre l'image precedente
227 road_time_t time;
228 road_timerange_t tr = 0;
229 if (read_hdfile(dbtFile_r, (void *)dbtbuf, &time, &tr) != 0) {
230 vector3df vect;
231 char *buf = dbtbuf;
232 for (size_t i = 0; i < models.size(); i++) {
233 models.at(i)->ReaddbtBuf(buf);
234 buf += models.at(i)->dbtSize();
235 }
236 } else {
237 // Printf("fin play\n");
238 close_hdfile(dbtFile_r);
239 dbtFile_r = NULL;
240 free(dbtbuf);
241 for (size_t i = 0; i < models.size(); i++) {
242 models.at(i)->pimpl_->Resume();
243 }
244 }
245 } else { // mode normal
246 for (size_t i = 0; i < models.size(); i++) {
247 models.at(i)->pimpl_->UpdatePos();
248 }
249 }
250
251 driver->beginScene(true, true, video::SColor(255, 200, 200, 200));
252
253 // vue poursuite
254 //smgr->setActiveCamera(models.at(cam_id)->getFollowMeCamera()->getCameraSceneNode());
255 smgr->setActiveCamera(cameras.at(cam_id)->getCameraSceneNode());
256 driver->setViewPort(core::rect<s32>(0, 0, scene_width, scene_height));
257 smgr->drawAll(); // commente voir plus bas
258
259 if (dbtFile_r == NULL) {// mode normal
260 for (size_t i = 0; i < models.size(); i++) {
261 models.at(i)->pimpl_->CheckCollision();
262 }
263 }
264
265 //render to texture for axis if possible
266 if (texture) {
267 cameras.at(cam_id)->renderAxisToTexture(texture,font,axisType);
268 }
269
270 //process update for sensors (cam, us...)
271 //also draws embedded cameras (see SimuCameraGL::UpdateFrom)
272 for (size_t i = 0; i < models.size(); i++) {
273 models.at(i)->ProcessUpdate(NULL);
274 }
275
276 // on fait ca ici, devrait etre un peu plus haut
277 // mais a priori souci avec models.at(i)->pimpl_->CheckCollision();
278 // (setelipsoid?)
279 //smgr->setActiveCamera(models.at(cam_id)->getFollowMeCamera()->getCameraSceneNode());
280 smgr->setActiveCamera(cameras.at(cam_id)->getCameraSceneNode());
281 driver->setViewPort(core::rect<s32>(0, 0, scene_width, scene_height));
282 smgr->drawAll();
283
284 driver->setViewPort(core::rect<s32>(0, 0, smgr->getVideoDriver()->getScreenSize().Width, smgr->getVideoDriver()->getScreenSize().Height));
285 device->getGUIEnvironment()->drawAll();
286 driver->endScene();
287
288 int fps = driver->getFPS();
289
290 if (lastFPS != fps) {
291 setWindowCaption(cam_id, fps);
292 lastFPS = fps;
293 }
294
295 if (receiver->IsKeyDown(KEY_PRIOR)) {
296 cam_id++;
297 if (cam_id >= (int)cameras.size()) cam_id = 0;
298 receiver->SetModel(getModelFromVisualizationCamera(models,cameras.at(cam_id)));
299 setWindowCaption(cam_id, fps);
300 }
301 if (receiver->IsKeyDown(KEY_NEXT)) {
302 cam_id--;
303 if (cam_id < 0) cam_id = cameras.size() - 1;
304 receiver->SetModel(getModelFromVisualizationCamera(models,cameras.at(cam_id)));
305 setWindowCaption(cam_id, fps);
306 }
307 if (receiver->IsKeyDown(KEY_KEY_A)) {
308 switch(axisType) {
309 case VisualizationCamera::AxisType::vrpn:
310 axisType=VisualizationCamera::AxisType::earth;
311 break;
312 case VisualizationCamera::AxisType::earth:
313 axisType=VisualizationCamera::AxisType::none;
314 break;
315 case VisualizationCamera::AxisType::none:
316 axisType=VisualizationCamera::AxisType::vrpn;
317 break;
318 }
319 }
320
321 // enregistrement DBT
322 if (receiver->IsKeyDown(KEY_KEY_R) && dbtFile_w == NULL) {
323 dbtFile_w = inithdFile((char *)"./record.dbt", UAV, dbtSize(models));
324 dbtbuf = (char *)malloc(dbtSize(models));
325 }
326 if (receiver->IsKeyDown(KEY_KEY_S) && dbtFile_w != NULL) {
327 close_hdfile(dbtFile_w);
328 dbtFile_w = NULL;
329 free(dbtbuf);
330 // rt_printf("stop rec\n");
331 }
332 if (dbtFile_w != NULL) {
333 Time time = GetTime();
334 vector3df vect;
335 char *buf = dbtbuf;
336
337 for (size_t i = 0; i < models.size(); i++) {
338 models.at(i)->WritedbtBuf(buf);
339 buf += models.at(i)->dbtSize();
340 }
341
342 write_hdfile(dbtFile_w, dbtbuf, (road_time_t)(time / 1000),
343 (road_timerange_t)(time % 1000), dbtSize(models));
344 }
345
346 // lecture dbt
347 if (receiver->IsKeyDown(KEY_KEY_P) && dbtFile_r == NULL) {
348 dbtFile_r = open_hdfile((char *)"./record.dbt", READ_MODE);
349 dbtbuf = (char *)malloc(dbtSize(models));
350 // on suspend les models pour ne pas interferer
351 for (size_t i = 0; i < models.size(); i++) {
352 models.at(i)->pimpl_->Suspend();
353 }
354 }
355 if (receiver->IsKeyDown(KEY_KEY_S) && dbtFile_r != NULL) {
356 // rt_printf("stop play\n");
357 close_hdfile(dbtFile_r);
358 dbtFile_r = NULL;
359 free(dbtbuf);
360 // on resume les models
361 for (size_t i = 0; i < models.size(); i++) {
362 models.at(i)->pimpl_->Resume();
363 }
364 }
365 }
366
367 receiver->SetModel(NULL);
368}
369
370Model *Gui_impl::getModelFromVisualizationCamera(std::vector<Model *> models,VisualizationCamera *camera) {
371 for (size_t i = 0; i < models.size(); i++) {
372 if(models.at(i)->getFollowMeCamera()==camera) return models.at(i);
373 }
374 return NULL;
375}
376
377void Gui_impl::setWindowCaption(int cam_id, int fps) {
378 std::ostringstream text;
379
380 text << getSimulator()->ObjectName().c_str() << ", active cam: " << cameras.at(cam_id)->getName().c_str()
381 << ", FPS: " << fps;
382
383 device->setWindowCaption(stringw(text.str().c_str()).c_str());
384}
385
386void Gui_impl::takeScreenshot(void) {
387 static int cpt = 0;
388 // get image from the last rendered frame
389 IImage *const image = driver->createScreenShot();
390 if (image) // should always be true, but you never know. ;)
391 {
392 // construct a filename, consisting of local time and file extension
393 c8 filename[64];
394 // snprintf(filename, 64, "screenshot_%u.png",
395 // device->getTimer()->getRealTime());
396 snprintf(filename, 64, "screenshot_%u.png", cpt);
397 cpt++;
398 // write screenshot to file
399 if (!driver->writeImageToFile(image, filename))
400 device->getLogger()->log(L"Failed to take screenshot.", ELL_WARNING);
401
402 // Don't forget to drop image since we don't need it anymore.
403 image->drop();
404 }
405}
406
407size_t Gui_impl::dbtSize(std::vector<Model *> models) {
408 size_t size = 0;
409 for (size_t i = 0; i < models.size(); i++) {
410 size += models.at(i)->dbtSize();
411 }
412
413 return size;
414}
415#endif // GL
Note: See TracBrowser for help on using the repository browser.