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

Last change on this file was 466, checked in by Sanahuja Guillaume, 2 years ago

unlock memory in simulator to avoid mmap problems when running simulator as non root

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