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