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

Last change on this file since 450 was 365, checked in by Sanahuja Guillaume, 4 years 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.