00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <mvsim/World.h>
00010
00011
00012 #include <mrpt/version.h>
00013 #if MRPT_VERSION<0x199
00014 #include <mrpt/utils/utils_defs.h>
00015 #else
00016 #include <mrpt/core/format.h>
00017 #endif
00018
00019 #include <mrpt/opengl/COpenGLScene.h>
00020 #include <mrpt/opengl/CGridPlaneXY.h>
00021
00022 #include <rapidxml.hpp>
00023 #include "xml_utils.h"
00024
00025 using namespace mvsim;
00026 using namespace std;
00027
00028
00029 World::TGUI_Options::TGUI_Options()
00030 : win_w(800),
00031 win_h(600),
00032 ortho(false),
00033 show_forces(false),
00034 force_scale(0.01),
00035 camera_distance(80),
00036 fov_deg(60)
00037 {
00038 }
00039
00040 void World::TGUI_Options::parse_from(const rapidxml::xml_node<char>& node)
00041 {
00042 std::map<std::string, TParamEntry> gui_params;
00043 gui_params["win_w"] = TParamEntry("%u", &win_w);
00044 gui_params["win_h"] = TParamEntry("%u", &win_h);
00045 gui_params["ortho"] = TParamEntry("%bool", &ortho);
00046 gui_params["show_forces"] = TParamEntry("%bool", &show_forces);
00047 gui_params["force_scale"] = TParamEntry("%lf", &force_scale);
00048 gui_params["cam_distance"] = TParamEntry("%lf", &camera_distance);
00049 gui_params["fov_deg"] = TParamEntry("%lf", &fov_deg);
00050 gui_params["follow_vehicle"] = TParamEntry("%s", &follow_vehicle);
00051
00052 parse_xmlnode_children_as_param(node, gui_params, "[World::TGUI_Options]");
00053 }
00054
00055 World::TUpdateGUIParams::TUpdateGUIParams() {}
00056
00057 size_t ID_GLTEXT_CLOCK = 0;
00058
00061 bool World::is_GUI_open() const { return !!m_gui_win; }
00063 void World::close_GUI() { m_gui_win.reset(); }
00068 void World::update_GUI(TUpdateGUIParams* guiparams)
00069 {
00070
00071
00072 if (!m_gui_win)
00073 {
00074 m_timlogger.enter("update_GUI_init");
00075
00076 m_gui_win = mrpt::gui::CDisplayWindow3D::Create(
00077 "mvsim", m_gui_options.win_w, m_gui_options.win_h);
00078 m_gui_win->setCameraZoom(m_gui_options.camera_distance);
00079 m_gui_win->setCameraProjective(!m_gui_options.ortho);
00080 m_gui_win->setFOV(m_gui_options.fov_deg);
00081
00082
00083 if (m_world_elements.empty())
00084 {
00085 WorldElementBase* we =
00086 WorldElementBase::factory(this, NULL, "groundgrid");
00087 this->m_world_elements.push_back(we);
00088 }
00089
00090 m_timlogger.leave("update_GUI_init");
00091 }
00092
00093 m_timlogger.enter("update_GUI");
00094
00095
00096 m_timlogger.enter("update_GUI.1.get-lock");
00097 mrpt::opengl::COpenGLScene::Ptr gl_scene =
00098 m_gui_win->get3DSceneAndLock();
00099 m_timlogger.leave("update_GUI.1.get-lock");
00100
00101
00102
00103
00104
00105 if (!gl_scene->getByName("level_0"))
00106 {
00107 for (unsigned int i = 0; i < 5; i++)
00108 {
00109 auto gl_obj = mrpt::opengl::CSetOfObjects::Create();
00110 gl_obj->setName(mrpt::format("level_%u", i));
00111 gl_scene->insert(gl_obj);
00112 }
00113 }
00114
00115
00116
00117 m_timlogger.enter("update_GUI.2.map-elements");
00118
00119 for (std::list<WorldElementBase*>::iterator it = m_world_elements.begin();
00120 it != m_world_elements.end(); ++it)
00121 (*it)->gui_update(*gl_scene);
00122
00123 m_timlogger.leave("update_GUI.2.map-elements");
00124
00125
00126
00127 m_timlogger.enter("update_GUI.3.vehicles");
00128
00129 for (TListVehicles::iterator it = m_vehicles.begin();
00130 it != m_vehicles.end(); ++it)
00131 it->second->gui_update(*gl_scene);
00132
00133 m_timlogger.leave("update_GUI.3.vehicles");
00134
00135
00136
00137 m_timlogger.enter("update_GUI.4.blocks");
00138
00139 for (TListBlocks::iterator it = m_blocks.begin(); it != m_blocks.end();
00140 ++it)
00141 it->second->gui_update(*gl_scene);
00142
00143 m_timlogger.leave("update_GUI.4.blocks");
00144
00145
00146
00147 m_timlogger.enter("update_GUI.5.text-msgs");
00148 {
00149 const int txt_h = 12, space_h = 2;
00150 int txt_y = 4;
00151
00152
00153 m_gui_win->addTextMessage(
00154 2, 2,
00155 mrpt::format(
00156 "Time: %s",
00157 mrpt::system::formatTimeInterval(this->m_simul_time).c_str()),
00158 TColorf(1, 1, 1, 0.5), "serif", txt_h,
00159 mrpt::opengl::NICE, ID_GLTEXT_CLOCK);
00160 txt_y += txt_h + space_h;
00161
00162
00163 if (guiparams)
00164 {
00165 const size_t nLines = std::count(
00166 guiparams->msg_lines.begin(), guiparams->msg_lines.end(), '\n');
00167 txt_y += nLines * (txt_h + space_h);
00168 m_gui_win->addTextMessage(
00169 2, txt_y, guiparams->msg_lines,
00170 TColorf(1, 1, 1, 0.5), "serif", txt_h,
00171 mrpt::opengl::NICE, ID_GLTEXT_CLOCK + 1);
00172 }
00173 }
00174
00175 m_timlogger.leave("update_GUI.5.text-msgs");
00176
00177
00178
00179 if (!m_gui_options.follow_vehicle.empty())
00180 {
00181 TListVehicles::const_iterator it =
00182 m_vehicles.find(m_gui_options.follow_vehicle);
00183 if (it == m_vehicles.end())
00184 {
00185 static bool warn1st = true;
00186 if (warn1st)
00187 {
00188 std::cerr << mrpt::format(
00189 "GUI: Camera set to follow vehicle named '%s' which can't "
00190 "be found!\n",
00191 m_gui_options.follow_vehicle.c_str());
00192 warn1st = true;
00193 }
00194 }
00195 else
00196 {
00197 const mrpt::poses::CPose2D pose = it->second->getCPose2D();
00198 m_gui_win->setCameraPointingToPoint(pose.x(), pose.y(), 0.0f);
00199 }
00200 }
00201
00202
00203
00204 m_gui_win->unlockAccess3DScene();
00205 m_gui_win->repaint();
00206
00207 m_timlogger.leave("update_GUI");
00208
00209
00210
00211 if (guiparams && m_gui_win->keyHit())
00212 guiparams->keyevent.keycode =
00213 m_gui_win->getPushedKey(&guiparams->keyevent.key_modifier);
00214 }