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

Last change on this file was 466, checked in by Sanahuja Guillaume, 15 months 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.