viewer.cpp 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356
  1. /*
  2. * esmini - Environment Simulator Minimalistic
  3. * https://github.com/esmini/esmini
  4. *
  5. * This Source Code Form is subject to the terms of the Mozilla Public
  6. * License, v. 2.0. If a copy of the MPL was not distributed with this
  7. * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  8. *
  9. * Copyright (c) partners of Simulation Scenarios
  10. * https://sites.google.com/view/simulationscenarios
  11. */
  12. #include "viewer.hpp"
  13. #include <osgDB/ReadFile>
  14. #include <osg/ComputeBoundsVisitor>
  15. #include <osg/LineWidth>
  16. #include <osg/Point>
  17. #include <osg/BlendFunc>
  18. #include <osg/BlendColor>
  19. #include <osg/Geode>
  20. #include <osg/Group>
  21. #include <osg/ShapeDrawable>
  22. #include <osg/CullFace>
  23. #include <osgGA/StateSetManipulator>
  24. #include <osgGA/TrackballManipulator>
  25. #include <osgGA/KeySwitchMatrixManipulator>
  26. #include <osgGA/FlightManipulator>
  27. #include <osgGA/DriveManipulator>
  28. #include <osgGA/TerrainManipulator>
  29. #include <osgGA/SphericalManipulator>
  30. #include <osgViewer/ViewerEventHandlers>
  31. #include <osgDB/Registry>
  32. #include <osgShadow/StandardShadowMap>
  33. #include <osgShadow/ShadowMap>
  34. #include <osgShadow/ShadowedScene>
  35. #include <osgUtil/SmoothingVisitor>
  36. #include <osgUtil/Tessellator> // to tessellate multiple contours
  37. #include "CommonMini.hpp"
  38. #define SHADOW_SCALE 1.20
  39. #define SHADOW_MODEL_FILEPATH "shadow_face.osgb"
  40. #define ARROW_MODEL_FILEPATH "arrow.osgb"
  41. #define LOD_DIST 3000
  42. #define LOD_SCALE_DEFAULT 1.0
  43. #define DEFAULT_AA_MULTISAMPLES 4
  44. #define OSI_LINE_WIDTH 2.0f
  45. double color_green[3] = { 0.25, 0.6, 0.3 };
  46. double color_gray[3] = { 0.7, 0.7, 0.7 };
  47. double color_dark_gray[3] = { 0.5, 0.5, 0.5 };
  48. double color_red[3] = { 0.73, 0.26, 0.26 };
  49. double color_blue[3] = { 0.25, 0.38, 0.7 };
  50. double color_yellow[3] = { 0.75, 0.7, 0.4 };
  51. double color_white[3] = { 0.80, 0.80, 0.79 };
  52. //USE_OSGPLUGIN(fbx)
  53. //USE_OSGPLUGIN(obj)
  54. USE_OSGPLUGIN(osg2)
  55. USE_OSGPLUGIN(jpeg)
  56. USE_SERIALIZER_WRAPPER_LIBRARY(osg)
  57. USE_SERIALIZER_WRAPPER_LIBRARY(osgSim)
  58. USE_COMPRESSOR_WRAPPER(ZLibCompressor)
  59. USE_GRAPHICSWINDOW()
  60. using namespace viewer;
  61. static osg::ref_ptr<osgShadow::ShadowedScene> shadowedScene;
  62. // Derive a class from NodeVisitor to find a node with a specific name.
  63. class FindNamedNode : public osg::NodeVisitor
  64. {
  65. public:
  66. FindNamedNode(const std::string& name)
  67. : osg::NodeVisitor( // Traverse all children.
  68. osg::NodeVisitor::TRAVERSE_ALL_CHILDREN),
  69. _name(name) {}
  70. // This method gets called for every node in the scene graph. Check each node
  71. // to see if its name matches out target. If so, save the node's address.
  72. virtual void apply(osg::Group& node)
  73. {
  74. if (node.getName() == _name )
  75. {
  76. _node = &node;
  77. }
  78. else
  79. {
  80. // Keep traversing the rest of the scene graph.
  81. traverse(node);
  82. }
  83. }
  84. osg::Node* getNode() { return _node.get(); }
  85. protected:
  86. std::string _name;
  87. osg::ref_ptr<osg::Group> _node;
  88. };
  89. Line::Line(double x0, double y0, double z0, double x1, double y1, double z1, double r, double g, double b)
  90. {
  91. line_vertex_data_ = new osg::Vec3Array;
  92. line_vertex_data_->push_back(osg::Vec3d(x0, y0, z0));
  93. line_vertex_data_->push_back(osg::Vec3d(x1, y1, z1));
  94. osg::ref_ptr<osg::Group> group = new osg::Group;
  95. line_ = new osg::Geometry();
  96. line_->setVertexArray(line_vertex_data_.get());
  97. line_->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, 2));
  98. line_->getOrCreateStateSet()->setAttributeAndModes(new osg::LineWidth(2), osg::StateAttribute::ON);
  99. line_->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  100. osg::ref_ptr<osg::Vec4Array> color_ = new osg::Vec4Array;
  101. color_->push_back(osg::Vec4(r, g, b, 1.0));
  102. line_->setColorArray(color_.get());
  103. line_->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
  104. }
  105. void Line::SetPoints(double x0, double y0, double z0, double x1, double y1, double z1)
  106. {
  107. line_vertex_data_->clear();
  108. line_vertex_data_->push_back(osg::Vec3d(x0, y0, z0));
  109. line_vertex_data_->push_back(osg::Vec3d(x1, y1, z1));
  110. line_->dirtyGLObjects();
  111. line_->dirtyBound();
  112. line_vertex_data_->dirty();
  113. }
  114. SensorViewFrustum::SensorViewFrustum(ObjectSensor *sensor, osg::Group *parent)
  115. {
  116. sensor_ = sensor;
  117. txNode_ = new osg::PositionAttitudeTransform;
  118. txNode_->setNodeMask(NodeMask::NODE_MASK_OBJECT_SENSORS);
  119. parent->addChild(txNode_);
  120. // Create geometry
  121. int numSegments = 16 * sensor_->fovH_ / M_PI;
  122. double angleDelta = sensor_->fovH_ / numSegments;
  123. double angle = -sensor_->fovH_ / 2.0;
  124. double fovV_rate = 0.2;
  125. line_group_ = new osg::Group;
  126. for (size_t i = 0; i < sensor_->maxObj_; i++)
  127. {
  128. Line *line = new Line(0, 0, 0, 1, 0, 0, 0.8, 0.8, 0.8);
  129. line_group_->addChild(line->line_);
  130. lines_.push_back(line);
  131. }
  132. txNode_->addChild(line_group_);
  133. osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(4 * (numSegments+1));
  134. osg::ref_ptr<osg::DrawElementsUInt> indices = new osg::DrawElementsUInt(GL_QUADS, 2 * 4 + 4 * 4 * numSegments);
  135. osg::ref_ptr<osg::DrawElementsUInt> indicesC0 = new osg::DrawElementsUInt(GL_LINE_STRIP, numSegments+1);
  136. osg::ref_ptr<osg::DrawElementsUInt> indicesC1 = new osg::DrawElementsUInt(GL_LINE_STRIP, numSegments+1);
  137. osg::ref_ptr<osg::DrawElementsUInt> indicesC2 = new osg::DrawElementsUInt(GL_LINE_STRIP, numSegments+1);
  138. osg::ref_ptr<osg::DrawElementsUInt> indicesC3 = new osg::DrawElementsUInt(GL_LINE_STRIP, numSegments+1);
  139. osg::ref_ptr<osg::DrawElementsUInt> indicesC4 = new osg::DrawElementsUInt(GL_LINE_LOOP, 4);
  140. osg::ref_ptr<osg::DrawElementsUInt> indicesC5 = new osg::DrawElementsUInt(GL_LINE_LOOP, 4);
  141. size_t i;
  142. unsigned int idx = 0;
  143. unsigned int idxC = 0;
  144. for (i = 0; i < numSegments+1; ++i, angle += angleDelta)
  145. {
  146. float x = cosf(angle);
  147. float y = sinf(angle);
  148. (*vertices)[i * 4 + 0].set(sensor_->near_ * x, sensor_->near_ * y, -sensor_->near_ * fovV_rate);
  149. (*vertices)[i * 4 + 3].set(sensor_->far_ * x, sensor_->far_ * y, -sensor_->far_ * fovV_rate);
  150. (*vertices)[i * 4 + 2].set(sensor_->far_ * x, sensor_->far_ * y, sensor_->far_ * fovV_rate);
  151. (*vertices)[i * 4 + 1].set(sensor_->near_ * x, sensor_->near_ * y, sensor_->near_ * fovV_rate);
  152. if (i > 0)
  153. {
  154. // Bottom face
  155. (*indices)[idx++] = (i - 1) * 4 + 0;
  156. (*indices)[idx++] = (i - 1) * 4 + 1;
  157. (*indices)[idx++] = (i - 0) * 4 + 1;
  158. (*indices)[idx++] = (i - 0) * 4 + 0;
  159. // Top face
  160. (*indices)[idx++] = (i - 1) * 4 + 3;
  161. (*indices)[idx++] = (i - 0) * 4 + 3;
  162. (*indices)[idx++] = (i - 0) * 4 + 2;
  163. (*indices)[idx++] = (i - 1) * 4 + 2;
  164. // Side facing host entity
  165. (*indices)[idx++] = (i - 1) * 4 + 0;
  166. (*indices)[idx++] = (i - 0) * 4 + 0;
  167. (*indices)[idx++] = (i - 0) * 4 + 3;
  168. (*indices)[idx++] = (i - 1) * 4 + 3;
  169. // Side facing away from host entity
  170. (*indices)[idx++] = (i - 1) * 4 + 1;
  171. (*indices)[idx++] = (i - 1) * 4 + 2;
  172. (*indices)[idx++] = (i - 0) * 4 + 2;
  173. (*indices)[idx++] = (i - 0) * 4 + 1;
  174. }
  175. // Countour
  176. (*indicesC0)[idxC] = i * 4 + 0;
  177. (*indicesC1)[idxC] = i * 4 + 1;
  178. (*indicesC2)[idxC] = i * 4 + 2;
  179. (*indicesC3)[idxC++] = i * 4 + 3;
  180. }
  181. (*indicesC4)[0] = (*indices)[idx++] = 0;
  182. (*indicesC4)[1] = (*indices)[idx++] = 3;
  183. (*indicesC4)[2] = (*indices)[idx++] = 2;
  184. (*indicesC4)[3] = (*indices)[idx++] = 1;
  185. (*indicesC5)[0] = (*indices)[idx++] = (i - 1) * 4 + 0;
  186. (*indicesC5)[1] = (*indices)[idx++] = (i - 1) * 4 + 1;
  187. (*indicesC5)[2] = (*indices)[idx++] = (i - 1) * 4 + 2;
  188. (*indicesC5)[3] = (*indices)[idx++] = (i - 1) * 4 + 3;
  189. const osg::Vec4 normalColor(0.8f, 0.7f, 0.6f, 1.0f);
  190. osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array(1);
  191. (*colors)[0] = normalColor;
  192. osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
  193. osg::ref_ptr<osg::Geometry> geom2 = new osg::Geometry;
  194. geom->setDataVariance(osg::Object::STATIC);
  195. geom->setUseDisplayList(true);
  196. geom->setUseVertexBufferObjects(true);
  197. geom->setVertexArray(vertices.get());
  198. geom2->setUseDisplayList(true);
  199. geom2->setUseVertexBufferObjects(true);
  200. geom2->setVertexArray(vertices.get());
  201. geom->addPrimitiveSet(indices.get());
  202. geom2->addPrimitiveSet(indicesC0.get());
  203. geom2->addPrimitiveSet(indicesC1.get());
  204. geom2->addPrimitiveSet(indicesC2.get());
  205. geom2->addPrimitiveSet(indicesC3.get());
  206. geom2->addPrimitiveSet(indicesC4.get());
  207. geom2->addPrimitiveSet(indicesC5.get());
  208. geom2->setColorArray(colors.get());
  209. geom2->setColorBinding(osg::Geometry::BIND_OVERALL);
  210. osgUtil::SmoothingVisitor::smooth(*geom, 0.5);
  211. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  212. geode->addDrawable(geom.release());
  213. osg::ref_ptr<osg::Material> material = new osg::Material;
  214. material->setDiffuse(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 1.0, 0.2));
  215. material->setAmbient(osg::Material::FRONT, osg::Vec4(1.0, 1.0, 1.0, 0.2));
  216. osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet(); // Get the StateSet of the group
  217. stateset->setAttribute(material.get()); // Set Material
  218. stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
  219. stateset->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
  220. stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
  221. osg::ref_ptr<osg::CullFace> cull = new osg::CullFace();
  222. cull->setMode(osg::CullFace::BACK);
  223. stateset->setAttributeAndModes(cull, osg::StateAttribute::ON);
  224. // Draw only wireframe to
  225. osg::ref_ptr<osg::PolygonMode> polygonMode = new osg::PolygonMode;
  226. polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
  227. stateset->setAttributeAndModes(polygonMode, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
  228. osg::ref_ptr<osg::Geode> geode2 = new osg::Geode;
  229. geom2->getOrCreateStateSet()->setAttribute(new osg::LineWidth(1.0f));
  230. geom2->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  231. geode2->addDrawable(geom2.release());
  232. txNode_->addChild(geode);
  233. txNode_->addChild(geode2);
  234. txNode_->setPosition(osg::Vec3(sensor_->pos_.x, sensor_->pos_.y, sensor_->pos_.z));
  235. txNode_->setAttitude(osg::Quat(sensor_->pos_.h, osg::Vec3(0, 0, 1)));
  236. }
  237. SensorViewFrustum::~SensorViewFrustum()
  238. {
  239. for (size_t i = 0; i < lines_.size(); i++)
  240. {
  241. delete lines_[i];
  242. }
  243. lines_.clear();
  244. }
  245. void SensorViewFrustum::Update()
  246. {
  247. // Visualize hits by a "line of sight"
  248. for (size_t i = 0; i < sensor_->nObj_; i++)
  249. {
  250. lines_[i]->SetPoints(0, 0, 0, sensor_->hitList_[i].x_, sensor_->hitList_[i].y_, sensor_->hitList_[i].z_);
  251. }
  252. // Reset additional lines possibly previously in use
  253. for (size_t i = sensor_->nObj_; i < sensor_->maxObj_; i++)
  254. {
  255. lines_[i]->SetPoints(0, 0, 0, 0, 0, 0);
  256. }
  257. }
  258. void VisibilityCallback::operator()(osg::Node* sa, osg::NodeVisitor* nv)
  259. {
  260. if (object_->CheckDirtyBits(scenarioengine::Object::DirtyBit::VISIBILITY))
  261. {
  262. if (object_->visibilityMask_ & scenarioengine::Object::Visibility::GRAPHICS)
  263. {
  264. entity_->txNode_->getChild(0)->setNodeMask(NodeMask::NODE_MASK_ENTITY_MODEL);
  265. if (object_->visibilityMask_ & scenarioengine::Object::Visibility::SENSORS)
  266. {
  267. entity_->SetTransparency(0.0);
  268. }
  269. else
  270. {
  271. entity_->SetTransparency(0.6);
  272. }
  273. }
  274. else
  275. {
  276. // Must set 0-mask on child node, otherwise it will not be traversed...
  277. entity_->txNode_->getChild(0)->setNodeMask(NodeMask::NODE_MASK_NONE);
  278. }
  279. }
  280. object_->ClearDirtyBits(scenarioengine::Object::DirtyBit::VISIBILITY);
  281. }
  282. void AlphaFadingCallback::operator()(osg::StateAttribute* sa, osg::NodeVisitor*)
  283. {
  284. osg::Material* material = static_cast<osg::Material*>(sa);
  285. if (material)
  286. {
  287. double age = viewer_->elapsedTime() - born_time_stamp_;
  288. double dt = viewer_->elapsedTime() - time_stamp_;
  289. time_stamp_ = viewer_->elapsedTime();
  290. if (age > TRAIL_DOT_LIFE_SPAN)
  291. {
  292. _motion->update(dt);
  293. }
  294. color_[3] = 1 - _motion->getValue();
  295. material->setDiffuse(osg::Material::FRONT_AND_BACK, color_);
  296. material->setAmbient(osg::Material::FRONT_AND_BACK, color_);
  297. }
  298. }
  299. TrailDot::TrailDot(double x, double y, double z, double heading,
  300. osgViewer::Viewer *viewer, osg::Group *parent, osg::ref_ptr<osg::Node> dot_node, osg::Vec4 trail_color)
  301. {
  302. double dot_radius = 0.8;
  303. osg::ref_ptr<osg::Node> new_node;
  304. dot_ = new osg::PositionAttitudeTransform;
  305. dot_->setPosition(osg::Vec3(x, y, z));
  306. dot_->setScale(osg::Vec3(dot_radius, dot_radius, dot_radius));
  307. dot_->setAttitude(osg::Quat(heading, osg::Vec3(0, 0, 1)));
  308. if (dot_node == 0)
  309. {
  310. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  311. geode->addDrawable(new osg::ShapeDrawable(new osg::Box()));
  312. new_node = geode;
  313. }
  314. else
  315. {
  316. // Clone into a unique object for unique material and alpha fading
  317. new_node = dynamic_cast<osg::Node*>(dot_node->clone(osg::CopyOp()));
  318. }
  319. dot_->addChild(new_node);
  320. material_ = new osg::Material;
  321. material_->setDiffuse(osg::Material::FRONT_AND_BACK, trail_color);
  322. material_->setAmbient(osg::Material::FRONT_AND_BACK, trail_color);
  323. fade_callback_ = new AlphaFadingCallback(viewer, trail_color);
  324. material_->setUpdateCallback(fade_callback_);
  325. new_node->getOrCreateStateSet()->setAttributeAndModes(material_.get());
  326. osg::ref_ptr<osg::StateSet> stateset = new_node->getOrCreateStateSet(); // Get the StateSet of the group
  327. stateset->setAttribute(material_.get()); // Set Material
  328. stateset->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
  329. stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
  330. dot_->setNodeMask(NodeMask::NODE_MASK_TRAILS);
  331. parent->addChild(dot_);
  332. }
  333. static osg::ref_ptr<osg::Node> CreateDotGeometry()
  334. {
  335. double height = 0.17;
  336. osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array(6);
  337. osg::ref_ptr<osg::DrawElementsUInt> indices1 = new osg::DrawElementsUInt(GL_QUADS, 3 * 4);
  338. osg::ref_ptr<osg::DrawElementsUInt> indices2 = new osg::DrawElementsUInt(GL_TRIANGLES, 3);
  339. int idx = 0;
  340. (*vertices)[idx++].set(0.0, -0.5, 0.0);
  341. (*vertices)[idx++].set(0.87, 0.0, 0.0);
  342. (*vertices)[idx++].set(0.0, 0.5, 0.0);
  343. (*vertices)[idx++].set(0.0, -0.5, height);
  344. (*vertices)[idx++].set(0.87, 0.0, height);
  345. (*vertices)[idx++].set(0.0, 0.5, height);
  346. // sides
  347. idx = 0;
  348. (*indices1)[idx++] = 0;
  349. (*indices1)[idx++] = 1;
  350. (*indices1)[idx++] = 4;
  351. (*indices1)[idx++] = 3;
  352. (*indices1)[idx++] = 2;
  353. (*indices1)[idx++] = 5;
  354. (*indices1)[idx++] = 4;
  355. (*indices1)[idx++] = 1;
  356. (*indices1)[idx++] = 0;
  357. (*indices1)[idx++] = 3;
  358. (*indices1)[idx++] = 5;
  359. (*indices1)[idx++] = 2;
  360. // Top face
  361. idx = 0;
  362. (*indices2)[idx++] = 3;
  363. (*indices2)[idx++] = 4;
  364. (*indices2)[idx++] = 5;
  365. osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
  366. geom->setDataVariance(osg::Object::DYNAMIC);
  367. geom->setUseDisplayList(false);
  368. geom->setUseVertexBufferObjects(true);
  369. geom->setVertexArray(vertices.get());
  370. geom->addPrimitiveSet(indices1.get());
  371. geom->addPrimitiveSet(indices2.get());
  372. osgUtil::SmoothingVisitor::smooth(*geom, 0.5);
  373. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  374. geode->addDrawable(geom.release());
  375. return geode;
  376. }
  377. void TrailDot::Reset(double x, double y, double z, double heading)
  378. {
  379. dot_->setPosition(osg::Vec3(x, y, z));
  380. dot_->setAttitude(osg::Quat(
  381. 0, osg::Vec3(1, 0, 0), // Roll
  382. 0, osg::Vec3(0, 1, 0), // Pitch
  383. heading, osg::Vec3(0, 0, 1)) // Heading
  384. );
  385. fade_callback_->Reset();
  386. }
  387. void Trail::AddDot(double x, double y, double z, double heading)
  388. {
  389. if (n_dots_ < TRAIL_MAX_DOTS)
  390. {
  391. dot_[current_] = new TrailDot(x, y, z, heading, viewer_, parent_, dot_node_, color_);
  392. n_dots_++;
  393. }
  394. else
  395. {
  396. dot_[current_]->Reset(x, y, z, heading);
  397. }
  398. if (++current_ >= TRAIL_MAX_DOTS)
  399. {
  400. current_ = 0;
  401. }
  402. }
  403. Trail::~Trail()
  404. {
  405. for (size_t i = 0; i < n_dots_; i++)
  406. {
  407. delete (dot_[i]);
  408. }
  409. }
  410. osg::ref_ptr<osg::PositionAttitudeTransform> CarModel::AddWheel(osg::ref_ptr<osg::Node> carNode, const char *wheelName)
  411. {
  412. osg::ref_ptr<osg::PositionAttitudeTransform> tx_node = 0;
  413. // Find wheel node
  414. FindNamedNode fnn(wheelName);
  415. carNode->accept(fnn);
  416. // Assume wheel is a tranformation node
  417. osg::MatrixTransform *node = dynamic_cast<osg::MatrixTransform*>(fnn.getNode());
  418. if (node != NULL)
  419. {
  420. tx_node = new osg::PositionAttitudeTransform;
  421. // We found the wheel. Put it under a useful transform node
  422. tx_node->addChild(node);
  423. // reset pivot point
  424. osg::Vec3d pos = node->getMatrix().getTrans();
  425. tx_node->setPivotPoint(pos);
  426. tx_node->setPosition(pos);
  427. osg::ref_ptr<osg::Group> parent = node->getParent(0); // assume the wheel node only belongs to one vehicle
  428. parent->removeChild(node);
  429. parent->addChild(tx_node);
  430. wheel_.push_back(tx_node);
  431. }
  432. return tx_node;
  433. }
  434. EntityModel::~EntityModel()
  435. {
  436. delete trail_;
  437. mparent->removeChild(txNode_);
  438. txNode_->removeChild(lod_);
  439. // delete lod_;
  440. }
  441. void EntityModel::ChangeScale(int length, int width, int height)
  442. {
  443. mtx->setScale(osg::Vec3(length,width,height));
  444. }
  445. EntityModel::EntityModel(osgViewer::Viewer *viewer, osg::ref_ptr<osg::Group> group, osg::ref_ptr<osg::Group> parent,
  446. osg::ref_ptr<osg::Group> trail_parent, osg::ref_ptr<osg::Node> dot_node, osg::Vec3 trail_color,std::string name)
  447. {
  448. if (!group)
  449. {
  450. return;
  451. }
  452. mparent = parent;
  453. name_ = name;
  454. group_ = group;
  455. // Add LevelOfDetail node
  456. lod_ = new osg::LOD();
  457. lod_->addChild(group_);
  458. lod_->setRange(0, 0, LOD_DIST);
  459. lod_->setName(name);
  460. // Add transform node
  461. txNode_ = new osg::PositionAttitudeTransform();
  462. txNode_->addChild(lod_);
  463. txNode_->setName(name);
  464. parent->addChild(txNode_);
  465. // Find boundingbox
  466. bb_ = 0;
  467. for (int i = 0; i < (int)group->getNumChildren(); i++)
  468. {
  469. if (group->getChild(i)->getName() == "BoundingBox")
  470. {
  471. bb_ = (osg::Group*)group->getChild(i);
  472. if(bb_ != 0)
  473. {
  474. mtx = (osg::PositionAttitudeTransform *)bb_->getChild(0);
  475. }
  476. break;
  477. }
  478. }
  479. viewer_ = viewer;
  480. state_set_ = 0;
  481. blend_color_ = 0;
  482. // Extract boundingbox of car to calculate size and center
  483. osg::ComputeBoundsVisitor cbv;
  484. txNode_->accept(cbv);
  485. osg::BoundingBox boundingBox = cbv.getBoundingBox();
  486. const osg::MatrixList& m = txNode_->getWorldMatrices();
  487. osg::Vec3 minV = boundingBox._min * m.front();
  488. osg::Vec3 maxV = boundingBox._max * m.front();
  489. size_x = maxV.x() - minV.x();
  490. size_y = maxV.y() - minV.y();
  491. center_x = (maxV.x() + minV.x()) / 2;
  492. center_y = (maxV.y() + minV.y()) / 2;
  493. // Prepare trail of dots
  494. trail_ = new Trail(trail_parent, viewer, dot_node, trail_color);
  495. }
  496. CarModel::CarModel(osgViewer::Viewer* viewer, osg::ref_ptr<osg::Group> group, osg::ref_ptr<osg::Group> parent,
  497. osg::ref_ptr<osg::Group> trail_parent, osg::ref_ptr<osg::Node> dot_node, osg::Vec3 trail_color, std::string name):
  498. EntityModel(viewer, group, parent, trail_parent, dot_node, trail_color, name)
  499. {
  500. steering_sensor_ = 0;
  501. road_sensor_ = 0;
  502. lane_sensor_ = 0;
  503. trail_sensor_ = 0;
  504. wheel_angle_ = 0;
  505. wheel_rot_ = 0;
  506. osg::ref_ptr<osg::Group> retval[4];
  507. osg::ref_ptr<osg::Node> car_node = txNode_->getChild(0);
  508. retval[0] = AddWheel(car_node, "wheel_fl");
  509. retval[1] = AddWheel(car_node, "wheel_fr");
  510. retval[2] = AddWheel(car_node, "wheel_rr");
  511. retval[3] = AddWheel(car_node, "wheel_rl");
  512. if (!(retval[0] || retval[1] || retval[2] || retval[3]))
  513. {
  514. LOG("No wheel nodes in model %s. No problem, wheels will just not appear to roll or steer", car_node->getName().c_str());
  515. }
  516. else
  517. {
  518. if (!retval[0])
  519. {
  520. LOG("Missing wheel node %s in vehicle model %s - ignoring", "wheel_fl", car_node->getName().c_str());
  521. }
  522. if (!retval[1])
  523. {
  524. LOG("Missing wheel node %s in vehicle model %s - ignoring", "wheel_fr", car_node->getName().c_str());
  525. }
  526. if (!retval[2])
  527. {
  528. LOG("Missing wheel node %s in vehicle model %s - ignoring", "wheel_rr", car_node->getName().c_str());
  529. }
  530. if (!retval[3])
  531. {
  532. LOG("Missing wheel node %s in vehicle model %s - ignoring", "wheel_rl", car_node->getName().c_str());
  533. }
  534. }
  535. }
  536. CarModel ::~CarModel()
  537. {
  538. wheel_.clear();
  539. delete trail_;
  540. }
  541. void EntityModel::SetPosition(double x, double y, double z)
  542. {
  543. txNode_->setPosition(osg::Vec3(x, y, z));
  544. }
  545. void EntityModel::SetRotation(double h, double p, double r)
  546. {
  547. quat_.makeRotate(
  548. r, osg::Vec3(1, 0, 0), // Roll
  549. p, osg::Vec3(0, 1, 0), // Pitch
  550. h, osg::Vec3(0, 0, 1)); // Heading
  551. txNode_->setAttitude(quat_);
  552. }
  553. void CarModel::UpdateWheels(double wheel_angle, double wheel_rotation)
  554. {
  555. // Update wheel angles and rotation for front wheels
  556. wheel_angle_ = wheel_angle;
  557. wheel_rot_ = wheel_rotation;
  558. osg::Quat quat;
  559. quat.makeRotate(
  560. 0, osg::Vec3(1, 0, 0), // Roll
  561. wheel_rotation, osg::Vec3(0, 1, 0), // Pitch
  562. wheel_angle, osg::Vec3(0, 0, 1)); // Heading
  563. if (wheel_.size() < 4)
  564. {
  565. // Wheels not available
  566. return;
  567. }
  568. wheel_[0]->setAttitude(quat);
  569. wheel_[1]->setAttitude(quat);
  570. // Update rotation for rear wheels
  571. quat.makeRotate(
  572. 0, osg::Vec3(1, 0, 0), // Roll
  573. wheel_rotation, osg::Vec3(0, 1, 0), // Pitch
  574. 0, osg::Vec3(0, 0, 1)); // Heading
  575. wheel_[2]->setAttitude(quat);
  576. wheel_[3]->setAttitude(quat);
  577. }
  578. void CarModel::UpdateWheelsDelta(double wheel_angle, double wheel_rotation_delta)
  579. {
  580. UpdateWheels(wheel_angle, wheel_rot_ + wheel_rotation_delta);
  581. }
  582. void EntityModel::SetTransparency(double factor)
  583. {
  584. if (factor < 0 || factor > 1)
  585. {
  586. LOG("Clamping transparency factor %.2f to [0:1]", factor);
  587. factor = CLAMP(factor, 0, 1);
  588. }
  589. blend_color_->setConstantColor(osg::Vec4(1, 1, 1, 1-factor));
  590. }
  591. Viewer::Viewer(roadmanager::OpenDrive* odrManager, const char* modelFilename, const char* scenarioFilename, const char* exe_path, osg::ArgumentParser arguments, SE_Options* opt)
  592. {
  593. odrManager_ = odrManager;
  594. bool clear_color;
  595. std::string arg_str;
  596. osgViewer_ = 0;
  597. if(scenarioFilename != NULL)
  598. {
  599. SE_Env::Inst().AddPath(DirNameOf(scenarioFilename));
  600. }
  601. if (odrManager != NULL)
  602. {
  603. SE_Env::Inst().AddPath(DirNameOf(odrManager->GetOpenDriveFilename()));
  604. }
  605. if (modelFilename != NULL)
  606. {
  607. SE_Env::Inst().AddPath(DirNameOf(modelFilename));
  608. }
  609. lodScale_ = LOD_SCALE_DEFAULT;
  610. currentCarInFocus_ = 0;
  611. keyUp_ = false;
  612. keyDown_ = false;
  613. keyLeft_ = false;
  614. keyRight_ = false;
  615. quit_request_ = false;
  616. showInfoText = true; // show info text HUD per default
  617. camMode_ = osgGA::RubberbandManipulator::RB_MODE_ORBIT;
  618. shadow_node_ = NULL;
  619. environment_ = NULL;
  620. roadGeom = NULL;
  621. int aa_mode = DEFAULT_AA_MULTISAMPLES;
  622. if (opt && (arg_str = opt->GetOptionArg("aa_mode")) != "")
  623. {
  624. aa_mode = atoi(arg_str.c_str());
  625. }
  626. LOG("Anti-Aliasing number of subsamples: %d", aa_mode);
  627. osg::DisplaySettings::instance()->setNumMultiSamples(aa_mode);
  628. arguments.getApplicationUsage()->addCommandLineOption("--lodScale <number>", "LOD Scale");
  629. arguments.read("--lodScale", lodScale_);
  630. clear_color = (arguments.find("--clear-color") != -1);
  631. // Store arguments in case we need to create a second viewer if the first fails
  632. int argc = arguments.argc() + 2; // make room for screen argument
  633. char **argv = (char**)malloc(argc * sizeof(char*));
  634. for (int i = 0; i < argc; i++)
  635. {
  636. argv[i] = (char*)malloc(strlen(arguments.argv()[i]) + 1); // +1 to include null termination
  637. strncpy(argv[i], arguments.argv()[i], strlen(arguments.argv()[i]) + 1);
  638. }
  639. osgViewer_ = new osgViewer::Viewer(arguments);
  640. // Check if the viewer has been created correctly - window created is a indication
  641. osgViewer::ViewerBase::Windows wins;
  642. osgViewer_->getWindows(wins);
  643. if (wins.size() == 0)
  644. {
  645. // Viewer failed to create window. Probably Anti Aliasing is not supported on executing platform.
  646. // Make another attempt without AA
  647. LOG("Viewer failure. Probably requested level of Anti Aliasing (%d multisamples) is not supported - try a lower number. Making another attempt without Anti-Alias and single screen.", aa_mode);
  648. osg::DisplaySettings::instance()->setNumMultiSamples(0);
  649. delete osgViewer_;
  650. osg::ArgumentParser args2(&argc, argv);
  651. // force single screen
  652. strncpy(argv[argc - 2], "--screen", strlen("--screen") + 1);
  653. strncpy(argv[argc - 1], "0", strlen("0") + 1);
  654. osgViewer_ = new osgViewer::Viewer(args2);
  655. osgViewer_->getWindows(wins);
  656. if (wins.size() == 0)
  657. {
  658. LOG("Failed second attempt opening a viewer window. Give up.");
  659. delete osgViewer_;
  660. for (int i = 0; i < argc; i++)
  661. {
  662. free(argv[i]);
  663. }
  664. return;
  665. }
  666. }
  667. else
  668. {
  669. for (int i = 0; i < argc; i++)
  670. {
  671. free(argv[i]);
  672. }
  673. free(argv);
  674. }
  675. // Create 3D geometry for trail dots
  676. dot_node_ = CreateDotGeometry();
  677. // set the scene to render
  678. rootnode_ = new osg::MatrixTransform;
  679. #if 0
  680. // Setup shadows
  681. const int CastsShadowTraversalMask = 0x2;
  682. LOG("1");
  683. shadowedScene = new osgShadow::ShadowedScene;
  684. osgShadow::ShadowSettings* settings = shadowedScene->getShadowSettings();
  685. LOG("2");
  686. settings->setReceivesShadowTraversalMask(CastsShadowTraversalMask);
  687. // shadowedScene->setCastsShadowTraversalMask(CastsShadowTraversalMask);
  688. osg::ref_ptr<osgShadow::ShadowMap> st = new osgShadow::ShadowMap;
  689. // osg::ref_ptr<osgShadow::StandardShadowMap> st = new osgShadow::StandardShadowMap;
  690. int mapres = 1024;
  691. LOG("3");
  692. st->setTextureSize(osg::Vec2s(mapres, mapres));
  693. shadowedScene->setShadowTechnique(st.get());
  694. shadowedScene->addChild(rootnode_);
  695. LOG("4");
  696. #endif
  697. envTx_ = new osg::PositionAttitudeTransform;
  698. envTx_->setPosition(osg::Vec3(0, 0, 0));
  699. envTx_->setScale(osg::Vec3(1, 1, 1));
  700. envTx_->setAttitude(osg::Quat(0, 0, 0, 1));
  701. envTx_->setNodeMask(NodeMask::NODE_MASK_ENV_MODEL);
  702. rootnode_->addChild(envTx_);
  703. ClearNodeMaskBits(NodeMask::NODE_MASK_TRAILS); // hide trails per default
  704. ClearNodeMaskBits(NodeMask::NODE_MASK_OSI_LINES);
  705. ClearNodeMaskBits(NodeMask::NODE_MASK_OSI_POINTS);
  706. ClearNodeMaskBits(NodeMask::NODE_MASK_OBJECT_SENSORS);
  707. ClearNodeMaskBits(NodeMask::NODE_MASK_ODR_FEATURES);
  708. ClearNodeMaskBits(NodeMask::NODE_MASK_TRAILS);
  709. ClearNodeMaskBits(NodeMask::NODE_MASK_ENTITY_BB);
  710. SetNodeMaskBits(NodeMask::NODE_MASK_ENTITY_MODEL);
  711. roadSensors_ = new osg::Group;
  712. roadSensors_->setNodeMask(NodeMask::NODE_MASK_ODR_FEATURES);
  713. rootnode_->addChild(roadSensors_);
  714. trails_ = new osg::Group;
  715. trails_->setNodeMask(NodeMask::NODE_MASK_TRAILS);
  716. rootnode_->addChild(trails_);
  717. odrLines_ = new osg::Group;
  718. odrLines_->setNodeMask(NodeMask::NODE_MASK_ODR_FEATURES);
  719. rootnode_->addChild(odrLines_);
  720. osiLines_ = new osg::Group;
  721. osiLines_->setNodeMask(NodeMask::NODE_MASK_OSI_LINES);
  722. rootnode_->addChild(osiLines_);
  723. osiPoints_ = new osg::Group;
  724. osiPoints_->setNodeMask(NodeMask::NODE_MASK_OSI_POINTS);
  725. rootnode_->addChild(osiPoints_);
  726. exe_path_ = exe_path;
  727. // add environment
  728. if (modelFilename != 0 && strcmp(modelFilename, ""))
  729. {
  730. std::vector<std::string> file_name_candidates;
  731. // absolute path or relative to current directory
  732. file_name_candidates.push_back(modelFilename);
  733. // Remove all directories from path and look in current directory
  734. file_name_candidates.push_back(FileNameOf(modelFilename));
  735. // Finally check registered paths
  736. for (size_t i = 0; i < SE_Env::Inst().GetPaths().size(); i++)
  737. {
  738. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], modelFilename));
  739. }
  740. size_t i;
  741. for (i = 0; i < file_name_candidates.size(); i++)
  742. {
  743. if (FileExists(file_name_candidates[i].c_str()))
  744. {
  745. if (AddEnvironment(file_name_candidates[i].c_str()) == 0)
  746. {
  747. break;
  748. }
  749. }
  750. }
  751. if (i == file_name_candidates.size())
  752. {
  753. LOG("Failed to read environment model %s!", modelFilename);
  754. }
  755. }
  756. if (environment_ == 0)
  757. {
  758. if (odrManager->GetNumOfRoads() > 0)
  759. {
  760. // No visual model of the road network loaded
  761. // Generate a simplistic 3D model based on OpenDRIVE content
  762. LOG("No scenegraph 3D model loaded. Generating a simplistic one...");
  763. roadGeom = new RoadGeom(odrManager);
  764. environment_ = roadGeom->root_;
  765. envTx_->addChild(environment_);
  766. // Since the generated 3D model is based on OSI features, let's hide those
  767. ClearNodeMaskBits(NodeMask::NODE_MASK_ODR_FEATURES);
  768. ClearNodeMaskBits(NodeMask::NODE_MASK_OSI_LINES);
  769. }
  770. }
  771. if (odrManager->GetNumOfRoads() > 0 && !CreateRoadLines(odrManager))
  772. {
  773. LOG("Viewer::Viewer Failed to create road lines!\n");
  774. }
  775. if (odrManager->GetNumOfRoads() > 0 && !CreateRoadMarkLines(odrManager))
  776. {
  777. LOG("Viewer::Viewer Failed to create road mark lines!\n");
  778. }
  779. if (odrManager->GetNumOfRoads() > 0 && CreateRoadSignsAndObjects(odrManager) != 0)
  780. {
  781. LOG("Viewer::Viewer Failed to create road signs!\n");
  782. }
  783. #if 0
  784. osgViewer_->setSceneData(shadowedScene);
  785. #else
  786. osgViewer_->setSceneData(rootnode_);
  787. #endif
  788. // Setup the camera models
  789. nodeTrackerManipulator_ = new osgGA::NodeTrackerManipulator;
  790. nodeTrackerManipulator_->setTrackerMode(osgGA::NodeTrackerManipulator::NODE_CENTER);
  791. nodeTrackerManipulator_->setRotationMode(osgGA::NodeTrackerManipulator::ELEVATION_AZIM);
  792. nodeTrackerManipulator_->setVerticalAxisFixed(true);
  793. osg::ref_ptr<osgGA::TrackballManipulator> trackBallManipulator;
  794. trackBallManipulator = new osgGA::TrackballManipulator;
  795. trackBallManipulator->setVerticalAxisFixed(true);
  796. osg::ref_ptr<osgGA::OrbitManipulator> orbitManipulator;
  797. orbitManipulator = new osgGA::OrbitManipulator;
  798. orbitManipulator->setVerticalAxisFixed(true);
  799. rubberbandManipulator_ = new osgGA::RubberbandManipulator(camMode_);
  800. rubberbandManipulator_->setTrackNode(envTx_);
  801. rubberbandManipulator_->calculateCameraDistance();
  802. {
  803. osg::ref_ptr<osgGA::KeySwitchMatrixManipulator> keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
  804. keyswitchManipulator->addMatrixManipulator('1', "Rubberband", rubberbandManipulator_.get());
  805. keyswitchManipulator->addMatrixManipulator('2', "Flight", new osgGA::FlightManipulator());
  806. keyswitchManipulator->addMatrixManipulator('3', "Drive", new osgGA::DriveManipulator());
  807. keyswitchManipulator->addMatrixManipulator('4', "Terrain", new osgGA::TerrainManipulator());
  808. keyswitchManipulator->addMatrixManipulator('5', "Orbit", new osgGA::OrbitManipulator());
  809. keyswitchManipulator->addMatrixManipulator('6', "FirstPerson", new osgGA::FirstPersonManipulator());
  810. keyswitchManipulator->addMatrixManipulator('7', "Spherical", new osgGA::SphericalManipulator());
  811. keyswitchManipulator->addMatrixManipulator('8', "NodeTracker", nodeTrackerManipulator_.get());
  812. keyswitchManipulator->addMatrixManipulator('9', "Trackball", trackBallManipulator.get());
  813. osgViewer_->setCameraManipulator(keyswitchManipulator.get());
  814. }
  815. osgViewer_->addEventHandler(new ViewerEventHandler(this));
  816. osgViewer_->getCamera()->setLODScale(lodScale_);
  817. osgViewer_->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
  818. if (!clear_color)
  819. {
  820. // Default background color
  821. osgViewer_->getCamera()->setClearColor(osg::Vec4(0.5f, 0.75f, 1.0f, 0.0f));
  822. }
  823. // add the window size toggle handler
  824. osgViewer_->addEventHandler(new osgViewer::WindowSizeHandler);
  825. // add the stats handler
  826. osgViewer_->addEventHandler(new osgViewer::StatsHandler);
  827. // add the state manipulator
  828. osgViewer_->addEventHandler(new osgGA::StateSetManipulator(osgViewer_->getCamera()->getOrCreateStateSet()));
  829. #if 1
  830. // add the thread model handler
  831. osgViewer_->addEventHandler(new osgViewer::ThreadingHandler);
  832. #else
  833. // If we see problem with chrashes when manipulating graphic nodes or states, in spite of
  834. // trying to use callback mechanisms, then locking to single thread might be a solution.
  835. // Hard code single thread model. Can't get setDataVariance(DYNAMIC)
  836. // to work with some state changes. And callbacks for all possible
  837. // nodes would be too much overhead. Solve when needed.
  838. osgViewer_->setThreadingModel(osgViewer::ViewerBase::SingleThreaded);
  839. #endif
  840. // add the help handler
  841. osgViewer_->addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));
  842. // add the record camera path handler
  843. osgViewer_->addEventHandler(new osgViewer::RecordCameraPathHandler);
  844. // add the LOD Scale handler
  845. osgViewer_->addEventHandler(new osgViewer::LODScaleHandler);
  846. // add the screen capture handler
  847. osgViewer_->addEventHandler(new osgViewer::ScreenCaptureHandler);
  848. osgViewer_->setReleaseContextAtEndOfFrameHint(false);
  849. // Light
  850. osgViewer_->setLightingMode(osg::View::SKY_LIGHT);
  851. osg::Light *light = osgViewer_->getLight();
  852. light->setPosition(osg::Vec4(50000, -50000, 70000, 1));
  853. light->setDirection(osg::Vec3(-1, 1, -1));
  854. float ambient = 0.4;
  855. light->setAmbient(osg::Vec4(ambient, ambient, 0.9*ambient, 1));
  856. light->setDiffuse(osg::Vec4(0.8, 0.8, 0.7, 1));
  857. osgViewer_->realize();
  858. // Overlay text
  859. osg::ref_ptr<osg::Geode> textGeode = new osg::Geode;
  860. osg::Vec4 layoutColor(0.9f, 0.9f, 0.9f, 1.0f);
  861. float layoutCharacterSize = 12.0f;
  862. infoText = new osgText::Text;
  863. infoText->setColor(layoutColor);
  864. infoText->setCharacterSize(layoutCharacterSize);
  865. infoText->setAxisAlignment(osgText::Text::SCREEN);
  866. infoText->setPosition(osg::Vec3(10, 10, 0));
  867. infoText->setDataVariance(osg::Object::DYNAMIC);
  868. textGeode->addDrawable(infoText);
  869. infoTextCamera = new osg::Camera;
  870. infoTextCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
  871. infoTextCamera->setClearMask(GL_DEPTH_BUFFER_BIT);
  872. infoTextCamera->setRenderOrder(osg::Camera::POST_RENDER, 10);
  873. infoTextCamera->setAllowEventFocus(false);
  874. infoTextCamera->addChild(textGeode.get());
  875. infoTextCamera->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
  876. osg::GraphicsContext* context = dynamic_cast<osgViewer::GraphicsWindow*>(osgViewer_->getCamera()->getGraphicsContext());
  877. SetInfoTextProjection(context->getTraits()->width, context->getTraits()->height);
  878. rootnode_->addChild(infoTextCamera);
  879. }
  880. void Viewer::clearLidar()
  881. {
  882. for (size_t i=0; i< entities_Lidar.size(); i++)
  883. {
  884. delete(entities_Lidar[i]);
  885. }
  886. entities_Lidar.clear();
  887. }
  888. Viewer::~Viewer()
  889. {
  890. osgViewer_->setDone(true);
  891. for (size_t i=0; i< entities_.size(); i++)
  892. {
  893. delete(entities_[i]);
  894. }
  895. entities_.clear();
  896. delete osgViewer_;
  897. osgViewer_ = 0;
  898. }
  899. void Viewer::SetCameraMode(int mode)
  900. {
  901. if (mode < 0 || mode >= osgGA::RubberbandManipulator::RB_NUM_MODES)
  902. {
  903. return;
  904. }
  905. camMode_ = mode;
  906. rubberbandManipulator_->setMode(camMode_);
  907. }
  908. EntityModel* Viewer::AddLidarModel(osg::Vec3 trail_color,std::string name,double length,double width, double height)
  909. {
  910. osg::ref_ptr<osg::Group> group = 0;
  911. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  912. geode->addDrawable(new osg::ShapeDrawable(new osg::Box()));
  913. osg::ref_ptr<osg::Group> bbGroup = new osg::Group;
  914. osg::ref_ptr<osg::PositionAttitudeTransform> tx = new osg::PositionAttitudeTransform;
  915. osg::Material* material = new osg::Material();
  916. // Set color of vehicle based on its index
  917. double* color;
  918. double b = 1.5; // brighness
  919. color = color_green;
  920. material->setDiffuse(osg::Material::FRONT, osg::Vec4(b * color[0], b * color[1], b * color[2], 1.0));
  921. material->setAmbient(osg::Material::FRONT, osg::Vec4(b * color[0], b * color[1], b * color[2], 1.0));
  922. if (group == 0)
  923. {
  924. // If no model loaded, make a shaded copy of bounding box as model
  925. osg::ref_ptr<osg::Geode> geodeCopy = dynamic_cast<osg::Geode*>(geode->clone(osg::CopyOp::DEEP_COPY_ALL));
  926. group = new osg::Group;
  927. tx->addChild(geodeCopy);
  928. // geodeCopy->setNodeMask(NodeMask::NODE_MASK_OSI_LINES);
  929. geodeCopy->setNodeMask(NodeMask::NODE_MASK_ENTITY_MODEL);
  930. }
  931. // Set dimensions of the entity "box"
  932. // Scale to something car-ish
  933. tx->setScale(osg::Vec3(length, width, height));
  934. tx->setPosition(osg::Vec3(1.5, 0, 0.75));
  935. tx->addChild(geode);
  936. tx->getOrCreateStateSet()->setAttribute(material);
  937. bbGroup->setName("BoundingBox");
  938. bbGroup->addChild(tx);
  939. group->addChild(bbGroup);
  940. group->setName(name);
  941. EntityModel* model;
  942. // if (type == EntityModel::EntityType::ENTITY_TYPE_VEHICLE)
  943. // {
  944. model = new EntityModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  945. // model = new CarModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  946. // }
  947. // else
  948. // {
  949. // model = new EntityModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  950. // }
  951. model->state_set_ = model->lod_->getOrCreateStateSet(); // Creating material
  952. model->blend_color_ = new osg::BlendColor(osg::Vec4(1, 1, 1, 1));
  953. model->state_set_->setAttributeAndModes(model->blend_color_);
  954. model->blend_color_->setDataVariance(osg::Object::DYNAMIC);
  955. osg::BlendFunc* bf = new osg::BlendFunc(osg::BlendFunc::CONSTANT_ALPHA, osg::BlendFunc::ONE_MINUS_CONSTANT_ALPHA);
  956. model->state_set_->setAttributeAndModes(bf);
  957. model->state_set_->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
  958. model->state_set_->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
  959. entities_Lidar.push_back(model);
  960. return entities_Lidar.back();
  961. }
  962. EntityModel* Viewer::AddRadarModel(osg::Vec3 trail_color,std::string name)
  963. {
  964. osg::ref_ptr<osg::Group> group = 0;
  965. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  966. geode->addDrawable(new osg::ShapeDrawable(new osg::Box()));
  967. osg::ref_ptr<osg::Group> bbGroup = new osg::Group;
  968. osg::ref_ptr<osg::PositionAttitudeTransform> tx = new osg::PositionAttitudeTransform;
  969. osg::Material* material = new osg::Material();
  970. // Set color of vehicle based on its index
  971. double* color;
  972. double b = 1.5; // brighness
  973. color = color_blue;
  974. material->setDiffuse(osg::Material::FRONT, osg::Vec4(b * color[0], b * color[1], b * color[2], 1.0));
  975. material->setAmbient(osg::Material::FRONT, osg::Vec4(b * color[0], b * color[1], b * color[2], 1.0));
  976. if (group == 0)
  977. {
  978. // If no model loaded, make a shaded copy of bounding box as model
  979. osg::ref_ptr<osg::Geode> geodeCopy = dynamic_cast<osg::Geode*>(geode->clone(osg::CopyOp::DEEP_COPY_ALL));
  980. group = new osg::Group;
  981. tx->addChild(geodeCopy);
  982. geodeCopy->setNodeMask(NodeMask::NODE_MASK_ENTITY_MODEL);
  983. }
  984. // Set dimensions of the entity "box"
  985. // Scale to something car-ish
  986. tx->setScale(osg::Vec3(0.5, 0.5, 1.5));
  987. tx->setPosition(osg::Vec3(1.5, 0, 0.75));
  988. tx->addChild(geode);
  989. tx->getOrCreateStateSet()->setAttribute(material);
  990. bbGroup->setName("BoundingBox");
  991. bbGroup->addChild(tx);
  992. group->addChild(bbGroup);
  993. group->setName(name);
  994. EntityModel* model;
  995. // if (type == EntityModel::EntityType::ENTITY_TYPE_VEHICLE)
  996. // {
  997. model = new EntityModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  998. // model = new CarModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  999. // }
  1000. // else
  1001. // {
  1002. // model = new EntityModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  1003. // }
  1004. model->state_set_ = model->lod_->getOrCreateStateSet(); // Creating material
  1005. model->blend_color_ = new osg::BlendColor(osg::Vec4(1, 1, 1, 1));
  1006. model->state_set_->setAttributeAndModes(model->blend_color_);
  1007. model->blend_color_->setDataVariance(osg::Object::DYNAMIC);
  1008. osg::BlendFunc* bf = new osg::BlendFunc(osg::BlendFunc::CONSTANT_ALPHA, osg::BlendFunc::ONE_MINUS_CONSTANT_ALPHA);
  1009. model->state_set_->setAttributeAndModes(bf);
  1010. model->state_set_->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
  1011. model->state_set_->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
  1012. entities_Radar.push_back(model);
  1013. // // Focus on first added car
  1014. // if (entities_.size() == 1)
  1015. // {
  1016. // currentCarInFocus_ = 0;
  1017. // rubberbandManipulator_->setTrackNode(entities_.back()->txNode_,
  1018. // rubberbandManipulator_->getMode() == osgGA::RubberbandManipulator::CAMERA_MODE::RB_MODE_TOP ? false : true);
  1019. // nodeTrackerManipulator_->setTrackNode(entities_.back()->txNode_);
  1020. // }
  1021. // if (type == EntityModel::EntityType::ENTITY_TYPE_VEHICLE)
  1022. // {
  1023. // CarModel* vehicle = (CarModel*)entities_.back();
  1024. // CreateRoadSensors(vehicle);
  1025. // if (road_sensor)
  1026. // {
  1027. // vehicle->road_sensor_->Show();
  1028. // }
  1029. // else
  1030. // {
  1031. // vehicle->road_sensor_->Hide();
  1032. // }
  1033. // }
  1034. return entities_Radar.back();
  1035. }
  1036. EntityModel* Viewer::AddEntityModel(std::string modelFilepath, osg::Vec3 trail_color, EntityModel::EntityType type,
  1037. bool road_sensor, std::string name, OSCBoundingBox* boundingBox)
  1038. {
  1039. // Load 3D model
  1040. std::string path = modelFilepath;
  1041. osg::ref_ptr<osg::Group> group = 0;
  1042. std::vector<std::string> file_name_candidates;
  1043. file_name_candidates.push_back(path);
  1044. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(DirNameOf(exe_path_) + "/../resources/models", path));
  1045. // Finally check registered paths
  1046. for (size_t i = 0; i < SE_Env::Inst().GetPaths().size(); i++)
  1047. {
  1048. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], path));
  1049. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], std::string("../models/" + path)));
  1050. }
  1051. for (size_t i = 0; i < SE_Env::Inst().GetPaths().size(); i++)
  1052. {
  1053. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], path));
  1054. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], std::string("./models/" + path)));
  1055. }
  1056. for (size_t i = 0; i < file_name_candidates.size(); i++)
  1057. {
  1058. if (FileExists(file_name_candidates[i].c_str()))
  1059. {
  1060. if (group = LoadEntityModel(file_name_candidates[i].c_str()))
  1061. {
  1062. break;
  1063. }
  1064. }
  1065. }
  1066. if (boundingBox || group == 0)
  1067. {
  1068. // Create a bounding box visual representation
  1069. if (path == "")
  1070. {
  1071. LOG("No filename specified for model! - creating a dummy model");
  1072. }
  1073. else if (group == 0)
  1074. {
  1075. LOG("Failed to load visual model %s. %s", path.c_str(), file_name_candidates.size() > 1 ? "Also tried the following paths:" : "");
  1076. for (size_t i = 1; i < file_name_candidates.size(); i++)
  1077. {
  1078. LOG(" %s", file_name_candidates[i].c_str());
  1079. }
  1080. LOG("Creating a dummy model instead");
  1081. }
  1082. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  1083. geode->addDrawable(new osg::ShapeDrawable(new osg::Box()));
  1084. osg::ref_ptr<osg::Group> bbGroup = new osg::Group;
  1085. osg::ref_ptr<osg::PositionAttitudeTransform> tx = new osg::PositionAttitudeTransform;
  1086. osg::Material* material = new osg::Material();
  1087. // Set color of vehicle based on its index
  1088. double* color;
  1089. double b = 1.5; // brighness
  1090. int index = entities_.size() % 4;
  1091. if (index == 0) color = color_white;
  1092. else if (index == 1) color = color_red;
  1093. else if (index == 2) color = color_blue;
  1094. else color = color_yellow;
  1095. material->setDiffuse(osg::Material::FRONT, osg::Vec4(b * color[0], b * color[1], b * color[2], 1.0));
  1096. material->setAmbient(osg::Material::FRONT, osg::Vec4(b * color[0], b * color[1], b * color[2], 1.0));
  1097. if (group == 0)
  1098. {
  1099. // If no model loaded, make a shaded copy of bounding box as model
  1100. osg::ref_ptr<osg::Geode> geodeCopy = dynamic_cast<osg::Geode*>(geode->clone(osg::CopyOp::DEEP_COPY_ALL));
  1101. group = new osg::Group;
  1102. tx->addChild(geodeCopy);
  1103. geodeCopy->setNodeMask(NodeMask::NODE_MASK_ENTITY_MODEL);
  1104. }
  1105. // Set dimensions of the entity "box"
  1106. if (boundingBox)
  1107. {
  1108. tx->setScale(osg::Vec3(boundingBox->dimensions_.length_, boundingBox->dimensions_.width_, boundingBox->dimensions_.height_));
  1109. tx->setPosition(osg::Vec3(boundingBox->center_.x_, boundingBox->center_.y_, boundingBox->center_.z_));
  1110. // Draw only wireframe
  1111. osg::PolygonMode* polygonMode = new osg::PolygonMode;
  1112. polygonMode->setMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE);
  1113. osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet(); // Get the StateSet of the group
  1114. stateset->setAttributeAndModes(polygonMode, osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON);
  1115. stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1116. geode->setNodeMask(NodeMask::NODE_MASK_ENTITY_BB);
  1117. osg::ref_ptr<osg::Geode> center = new osg::Geode;
  1118. center->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0, 0, 0), 0.2)));
  1119. center->setNodeMask(NodeMask::NODE_MASK_ENTITY_BB);
  1120. bbGroup->addChild(center);
  1121. }
  1122. else
  1123. {
  1124. // Scale to something car-ish
  1125. tx->setScale(osg::Vec3(4.5, 1.8, 1.5));
  1126. tx->setPosition(osg::Vec3(1.5, 0, 0.75));
  1127. }
  1128. tx->addChild(geode);
  1129. tx->getOrCreateStateSet()->setAttribute(material);
  1130. bbGroup->setName("BoundingBox");
  1131. bbGroup->addChild(tx);
  1132. group->addChild(bbGroup);
  1133. group->setName(name);
  1134. }
  1135. EntityModel* model;
  1136. if (type == EntityModel::EntityType::ENTITY_TYPE_VEHICLE)
  1137. {
  1138. model = new CarModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  1139. }
  1140. else
  1141. {
  1142. model = new EntityModel(osgViewer_, group, rootnode_, trails_, dot_node_, trail_color, name);
  1143. }
  1144. model->state_set_ = model->lod_->getOrCreateStateSet(); // Creating material
  1145. model->blend_color_ = new osg::BlendColor(osg::Vec4(1, 1, 1, 1));
  1146. model->state_set_->setAttributeAndModes(model->blend_color_);
  1147. model->blend_color_->setDataVariance(osg::Object::DYNAMIC);
  1148. osg::BlendFunc* bf = new osg::BlendFunc(osg::BlendFunc::CONSTANT_ALPHA, osg::BlendFunc::ONE_MINUS_CONSTANT_ALPHA);
  1149. model->state_set_->setAttributeAndModes(bf);
  1150. model->state_set_->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);
  1151. model->state_set_->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
  1152. entities_.push_back(model);
  1153. // Focus on first added car
  1154. if (entities_.size() == 1)
  1155. {
  1156. currentCarInFocus_ = 0;
  1157. rubberbandManipulator_->setTrackNode(entities_.back()->txNode_,
  1158. rubberbandManipulator_->getMode() == osgGA::RubberbandManipulator::CAMERA_MODE::RB_MODE_TOP ? false : true);
  1159. nodeTrackerManipulator_->setTrackNode(entities_.back()->txNode_);
  1160. }
  1161. if (type == EntityModel::EntityType::ENTITY_TYPE_VEHICLE)
  1162. {
  1163. CarModel* vehicle = (CarModel*)entities_.back();
  1164. CreateRoadSensors(vehicle);
  1165. if (road_sensor)
  1166. {
  1167. vehicle->road_sensor_->Show();
  1168. }
  1169. else
  1170. {
  1171. vehicle->road_sensor_->Hide();
  1172. }
  1173. }
  1174. return entities_.back();
  1175. }
  1176. void Viewer::RemoveCar(std::string name)
  1177. {
  1178. for (size_t i = 0; i < entities_.size(); i++)
  1179. {
  1180. if (entities_[i]->name_ == name)
  1181. {
  1182. entities_.erase(entities_.begin() + i);
  1183. }
  1184. }
  1185. }
  1186. osg::ref_ptr<osg::Group> Viewer::LoadEntityModel(const char *filename)
  1187. {
  1188. osg::ref_ptr<osg::PositionAttitudeTransform> shadow_tx = 0;
  1189. osg::ref_ptr<osg::Node> node;
  1190. osg::ref_ptr<osg::Group> group = new osg::Group;
  1191. node = osgDB::readNodeFile(filename);
  1192. if (!node)
  1193. {
  1194. return 0;
  1195. }
  1196. osg::ComputeBoundsVisitor cbv;
  1197. node->accept(cbv);
  1198. osg::BoundingBox boundingBox = cbv.getBoundingBox();
  1199. double xc, yc, dx, dy;
  1200. dx = boundingBox._max.x() - boundingBox._min.x();
  1201. dy = boundingBox._max.y() - boundingBox._min.y();
  1202. xc = (boundingBox._max.x() + boundingBox._min.x()) / 2;
  1203. yc = (boundingBox._max.y() + boundingBox._min.y()) / 2;
  1204. if (!shadow_node_)
  1205. {
  1206. LoadShadowfile(filename);
  1207. }
  1208. node->setNodeMask(NodeMask::NODE_MASK_ENTITY_MODEL);
  1209. group->addChild(node);
  1210. if (shadow_node_)
  1211. {
  1212. shadow_tx = new osg::PositionAttitudeTransform;
  1213. shadow_tx->setPosition(osg::Vec3d(xc, yc, 0.0));
  1214. shadow_tx->setScale(osg::Vec3d(SHADOW_SCALE*(dx / 2), SHADOW_SCALE*(dy / 2), 1.0));
  1215. shadow_tx->addChild(shadow_node_);
  1216. shadow_tx->setNodeMask(NodeMask::NODE_MASK_ENTITY_MODEL);
  1217. group->addChild(shadow_tx);
  1218. }
  1219. return group;
  1220. }
  1221. bool Viewer::CreateRoadMarkLines(roadmanager::OpenDrive* od)
  1222. {
  1223. double z_offset = 0.10;
  1224. osg::Vec3 point(0, 0, 0);
  1225. for (int r = 0; r < od->GetNumOfRoads(); r++)
  1226. {
  1227. roadmanager::Road *road = od->GetRoadByIdx(r);
  1228. for (int i = 0; i < road->GetNumberOfLaneSections(); i++)
  1229. {
  1230. roadmanager::LaneSection *lane_section = road->GetLaneSectionByIdx(i);
  1231. for (int j = 0; j < lane_section->GetNumberOfLanes(); j++)
  1232. {
  1233. roadmanager::Lane *lane = lane_section->GetLaneByIdx(j);
  1234. for (int k = 0; k < lane->GetNumberOfRoadMarks(); k++)
  1235. {
  1236. roadmanager::LaneRoadMark *lane_roadmark = lane->GetLaneRoadMarkByIdx(k);
  1237. for (int m = 0; m < lane_roadmark->GetNumberOfRoadMarkTypes(); m++)
  1238. {
  1239. roadmanager::LaneRoadMarkType * lane_roadmarktype = lane_roadmark->GetLaneRoadMarkTypeByIdx(m);
  1240. for (int n = 0; n < lane_roadmarktype->GetNumberOfRoadMarkTypeLines(); n++)
  1241. {
  1242. roadmanager::LaneRoadMarkTypeLine * lane_roadmarktypeline = lane_roadmarktype->GetLaneRoadMarkTypeLineByIdx(n);
  1243. roadmanager::OSIPoints curr_osi_rm;
  1244. curr_osi_rm = lane_roadmarktypeline->GetOSIPoints();
  1245. if (lane_roadmark->GetType() == roadmanager::LaneRoadMark::RoadMarkType::BROKEN)
  1246. {
  1247. for (int q = 0; q < curr_osi_rm.GetPoints().size(); q+=2)
  1248. {
  1249. roadmanager::OSIPoints::OSIPointStruct osi_point1 = curr_osi_rm.GetPoint(q);
  1250. roadmanager::OSIPoints::OSIPointStruct osi_point2 = curr_osi_rm.GetPoint(q+1);
  1251. // osg references for road mark osi points
  1252. osg::ref_ptr<osg::Geometry> osi_rm_geom = new osg::Geometry;
  1253. osg::ref_ptr<osg::Vec3Array> osi_rm_points = new osg::Vec3Array;
  1254. osg::ref_ptr<osg::Vec4Array> osi_rm_color = new osg::Vec4Array;
  1255. osg::ref_ptr<osg::Point> osi_rm_point = new osg::Point();
  1256. // osg references for drawing lines between each road mark osi points
  1257. osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
  1258. osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;
  1259. osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
  1260. osg::ref_ptr<osg::LineWidth> lineWidth = new osg::LineWidth();
  1261. // start point of each road mark
  1262. point.set(osi_point1.x, osi_point1.y, osi_point1.z + z_offset);
  1263. osi_rm_points->push_back(point);
  1264. // end point of each road mark
  1265. point.set(osi_point2.x, osi_point2.y, osi_point2.z + z_offset);
  1266. osi_rm_points->push_back(point);
  1267. osi_rm_color->push_back(osg::Vec4(color_white[0], color_white[1], color_white[2], 1.0));
  1268. // Put points at the start and end of the roadmark
  1269. osi_rm_point->setSize(6.0f);
  1270. osi_rm_geom->setVertexArray(osi_rm_points.get());
  1271. osi_rm_geom->setColorArray(osi_rm_color.get());
  1272. osi_rm_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
  1273. osi_rm_geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, osi_rm_points->size()));
  1274. osi_rm_geom->getOrCreateStateSet()->setAttributeAndModes(osi_rm_point, osg::StateAttribute::ON);
  1275. osi_rm_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1276. osiPoints_->addChild(osi_rm_geom);
  1277. // Draw lines from the start of the roadmark to the end of the roadmark
  1278. lineWidth->setWidth(OSI_LINE_WIDTH);
  1279. geom->setVertexArray(osi_rm_points.get());
  1280. geom->setColorArray(osi_rm_color.get());
  1281. geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
  1282. geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, osi_rm_points->size()));
  1283. geom->getOrCreateStateSet()->setAttributeAndModes(lineWidth, osg::StateAttribute::ON);
  1284. geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1285. osiLines_->addChild(geom);
  1286. }
  1287. }
  1288. else if(lane_roadmark->GetType() == roadmanager::LaneRoadMark::RoadMarkType::SOLID)
  1289. {
  1290. // osg references for road mark osi points
  1291. osg::ref_ptr<osg::Geometry> osi_rm_geom = new osg::Geometry;
  1292. osg::ref_ptr<osg::Vec3Array> osi_rm_points = new osg::Vec3Array;
  1293. osg::ref_ptr<osg::Vec4Array> osi_rm_color = new osg::Vec4Array;
  1294. osg::ref_ptr<osg::Point> osi_rm_point = new osg::Point();
  1295. // osg references for drawing lines between each road mark osi points
  1296. osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
  1297. osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;
  1298. osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
  1299. osg::ref_ptr<osg::LineWidth> lineWidth = new osg::LineWidth();
  1300. // Creating points for the given roadmark
  1301. for (int s = 0; s < curr_osi_rm.GetPoints().size(); s++)
  1302. {
  1303. point.set(curr_osi_rm.GetPoint(s).x, curr_osi_rm.GetPoint(s).y, curr_osi_rm.GetPoint(s).z + z_offset);
  1304. osi_rm_points->push_back(point);
  1305. osi_rm_color->push_back(osg::Vec4(color_white[0], color_white[1], color_white[2], 1.0));
  1306. }
  1307. // Put points on selected locations
  1308. osi_rm_point->setSize(6.0f);
  1309. osi_rm_geom->setVertexArray(osi_rm_points.get());
  1310. osi_rm_geom->setColorArray(osi_rm_color.get());
  1311. osi_rm_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
  1312. osi_rm_geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, osi_rm_points->size()));
  1313. osi_rm_geom->getOrCreateStateSet()->setAttributeAndModes(osi_rm_point, osg::StateAttribute::ON);
  1314. osi_rm_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1315. osiPoints_->addChild(osi_rm_geom);
  1316. // Draw lines between each selected points
  1317. lineWidth->setWidth(OSI_LINE_WIDTH);
  1318. color->push_back(osg::Vec4(color_white[0], color_white[1], color_white[2], 1.0));
  1319. geom->setVertexArray(osi_rm_points.get());
  1320. geom->setColorArray(color.get());
  1321. geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
  1322. geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, osi_rm_points->size()));
  1323. geom->getOrCreateStateSet()->setAttributeAndModes(lineWidth, osg::StateAttribute::ON);
  1324. geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1325. osiLines_->addChild(geom);
  1326. }
  1327. }
  1328. }
  1329. }
  1330. }
  1331. }
  1332. }
  1333. return true;
  1334. }
  1335. bool Viewer::CreateRoadLines(roadmanager::OpenDrive* od)
  1336. {
  1337. double z_offset = 0.10;
  1338. roadmanager::Position* pos = new roadmanager::Position();
  1339. osg::Vec3 point(0, 0, 0);
  1340. roadmanager::OSIPoints* curr_osi;
  1341. for (int r = 0; r < od->GetNumOfRoads(); r++)
  1342. {
  1343. roadmanager::Road *road = od->GetRoadByIdx(r);
  1344. // Road key points
  1345. osg::ref_ptr<osg::Geometry> kp_geom = new osg::Geometry;
  1346. osg::ref_ptr<osg::Vec3Array> kp_points = new osg::Vec3Array;
  1347. osg::ref_ptr<osg::Vec4Array> kp_color = new osg::Vec4Array;
  1348. osg::ref_ptr<osg::Point> kp_point = new osg::Point();
  1349. roadmanager::Geometry *geom = nullptr;
  1350. for (int i = 0; i < road->GetNumberOfGeometries()+1; i++)
  1351. {
  1352. if (i < road->GetNumberOfGeometries())
  1353. {
  1354. geom = road->GetGeometry(i);
  1355. pos->SetTrackPos(road->GetId(), geom->GetS(), 0);
  1356. }
  1357. else
  1358. {
  1359. pos->SetTrackPos(road->GetId(), geom->GetS()+geom->GetLength(), 0);
  1360. }
  1361. point.set(pos->GetX(), pos->GetY(), pos->GetZ() + z_offset);
  1362. kp_points->push_back(point);
  1363. if (i == 0)
  1364. {
  1365. kp_color->push_back(osg::Vec4(color_yellow[0], color_yellow[1], color_yellow[2], 1.0));
  1366. }
  1367. else
  1368. {
  1369. kp_color->push_back(osg::Vec4(color_red[0], color_red[1], color_red[2], 1.0));
  1370. }
  1371. }
  1372. kp_point->setSize(12.0f);
  1373. kp_geom->setVertexArray(kp_points.get());
  1374. kp_geom->setColorArray(kp_color.get());
  1375. kp_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
  1376. kp_geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, kp_points->size()));
  1377. kp_geom->getOrCreateStateSet()->setAttributeAndModes(kp_point, osg::StateAttribute::ON);
  1378. kp_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1379. odrLines_->addChild(kp_geom);
  1380. for (int i = 0; i < road->GetNumberOfLaneSections(); i++)
  1381. {
  1382. roadmanager::LaneSection *lane_section = road->GetLaneSectionByIdx(i);
  1383. for (int j = 0; j < lane_section->GetNumberOfLanes(); j++)
  1384. {
  1385. roadmanager::Lane *lane = lane_section->GetLaneByIdx(j);
  1386. // visualize both lane center and lane boundary
  1387. for (int k = 0; k < 2; k++)
  1388. {
  1389. // skip lane center for all non driving lanes except center lane
  1390. if ((k == 0 && lane->GetId() != 0 && !lane->IsDriving()) ||
  1391. // skip lane boundary for center lane
  1392. (k == 1 && lane->GetId() == 0))
  1393. {
  1394. continue;
  1395. }
  1396. // osg references for osi points on the lane center
  1397. osg::ref_ptr<osg::Geometry> osi_geom = new osg::Geometry;
  1398. osg::ref_ptr<osg::Vec3Array> osi_points = new osg::Vec3Array;
  1399. osg::ref_ptr<osg::Vec4Array> osi_color = new osg::Vec4Array;
  1400. osg::ref_ptr<osg::Point> osi_point = new osg::Point();
  1401. // osg references for drawing lines on the lane center using osi points
  1402. osg::ref_ptr<osg::Geometry> line_geom = new osg::Geometry;
  1403. osg::ref_ptr<osg::Vec3Array> points = new osg::Vec3Array;
  1404. osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array;
  1405. osg::ref_ptr<osg::LineWidth> lineWidth = new osg::LineWidth();
  1406. if (k == 0)
  1407. {
  1408. curr_osi = lane->GetOSIPoints();
  1409. }
  1410. else
  1411. {
  1412. curr_osi = lane->GetLaneBoundary()->GetOSIPoints();
  1413. }
  1414. if (curr_osi == 0)
  1415. {
  1416. continue;
  1417. }
  1418. for (int m = 0; m < curr_osi->GetPoints().size(); m++)
  1419. {
  1420. roadmanager::OSIPoints::OSIPointStruct osi_point_s = curr_osi->GetPoint(m);
  1421. point.set(osi_point_s.x, osi_point_s.y, osi_point_s.z + z_offset);
  1422. osi_points->push_back(point);
  1423. osi_color->push_back(osg::Vec4(color_blue[0], color_blue[1], color_blue[2], 1.0));
  1424. }
  1425. osi_point->setSize(6.0f);
  1426. osi_geom->setVertexArray(osi_points.get());
  1427. osi_geom->setColorArray(osi_color.get());
  1428. osi_geom->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
  1429. osi_geom->addPrimitiveSet(new osg::DrawArrays(GL_POINTS, 0, osi_points->size()));
  1430. osi_geom->getOrCreateStateSet()->setAttributeAndModes(osi_point, osg::StateAttribute::ON);
  1431. osi_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1432. osiPoints_->addChild(osi_geom);
  1433. if (lane->GetId() == 0)
  1434. {
  1435. lineWidth->setWidth(4.0f);
  1436. color->push_back(osg::Vec4(color_red[0], color_red[1], color_red[2], 1.0));
  1437. }
  1438. else if (k==0)
  1439. {
  1440. lineWidth->setWidth(1.5f);
  1441. color->push_back(osg::Vec4(color_blue[0], color_blue[1], color_blue[2], 1.0));
  1442. }
  1443. else
  1444. {
  1445. lineWidth->setWidth(1.5f);
  1446. color->push_back(osg::Vec4(color_gray[0], color_gray[1], color_gray[2], 1.0));
  1447. }
  1448. line_geom->setVertexArray(osi_points.get());
  1449. line_geom->setColorArray(color.get());
  1450. line_geom->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
  1451. line_geom->addPrimitiveSet(new osg::DrawArrays(GL_LINE_STRIP, 0, osi_points->size()));
  1452. line_geom->getOrCreateStateSet()->setAttributeAndModes(lineWidth, osg::StateAttribute::ON);
  1453. line_geom->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1454. odrLines_->addChild(line_geom);
  1455. }
  1456. }
  1457. }
  1458. }
  1459. delete pos;
  1460. return true;
  1461. }
  1462. int Viewer::CreateOutlineObject(roadmanager::Outline *outline)
  1463. {
  1464. if (outline == 0) return -1;
  1465. bool roof = outline->closed_ ? true : false;
  1466. // nrPoints will be corners + 1 if the outline should be closed, reusing first corner as last
  1467. int nrPoints = outline->closed_ ? outline->corner_.size() + 1 : outline->corner_.size();
  1468. osg::ref_ptr<osg::Group> group = new osg::Group();
  1469. osg::Vec4 color = osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f);
  1470. osg::ref_ptr<osg::Vec4Array> color_outline = new osg::Vec4Array;
  1471. color_outline->push_back(color);
  1472. osg::ref_ptr<osg::Vec3Array> vertices_sides = new osg::Vec3Array(nrPoints * 2); // one set at bottom and one at top
  1473. osg::ref_ptr<osg::Vec3Array> vertices_top = new osg::Vec3Array(nrPoints); // one set at bottom and one at top
  1474. // Set vertices
  1475. for (size_t i = 0; i < outline->corner_.size(); i++)
  1476. {
  1477. double x, y, z;
  1478. roadmanager::OutlineCorner* corner = outline->corner_[i];
  1479. corner->GetPos(x, y, z);
  1480. (*vertices_sides)[i * 2 + 0].set(x, y, z + corner->GetHeight());
  1481. (*vertices_sides)[i * 2 + 1].set(x, y, z);
  1482. (*vertices_top)[i].set(x, y, z + corner->GetHeight());
  1483. }
  1484. // Close geometry
  1485. if (outline->closed_)
  1486. {
  1487. (*vertices_sides)[2 * nrPoints - 2].set((*vertices_sides)[0]);
  1488. (*vertices_sides)[2 * nrPoints - 1].set((*vertices_sides)[1]);
  1489. (*vertices_top)[nrPoints-1].set((*vertices_top)[0]);
  1490. }
  1491. // Finally create and add geometry
  1492. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  1493. osg::ref_ptr<osg::Geometry> geom[] = { new osg::Geometry, new osg::Geometry };
  1494. geom[0]->setVertexArray(vertices_sides.get());
  1495. geom[0]->addPrimitiveSet(new osg::DrawArrays(GL_QUAD_STRIP, 0, 2 * nrPoints));
  1496. if (roof)
  1497. {
  1498. geom[1]->setVertexArray(vertices_top.get());
  1499. geom[1]->addPrimitiveSet(new osg::DrawArrays(GL_POLYGON, 0, nrPoints));
  1500. osgUtil::Tessellator tessellator;
  1501. tessellator.retessellatePolygons(*geom[1]);
  1502. }
  1503. int nrGeoms = roof ? 2 : 1;
  1504. for (int i = 0; i < nrGeoms; i++)
  1505. {
  1506. osgUtil::SmoothingVisitor::smooth(*geom[i], 0.5);
  1507. geom[i]->setColorArray(color_outline);
  1508. geom[i]->setColorBinding(osg::Geometry::BIND_OVERALL);
  1509. geom[i]->setDataVariance(osg::Object::STATIC);
  1510. geom[i]->setUseDisplayList(true);
  1511. geode->addDrawable(geom[i]);
  1512. }
  1513. osg::ref_ptr<osg::Material> material_ = new osg::Material;
  1514. material_->setDiffuse(osg::Material::FRONT_AND_BACK, color);
  1515. material_->setAmbient(osg::Material::FRONT_AND_BACK, color);
  1516. geode->getOrCreateStateSet()->setAttributeAndModes(material_.get());
  1517. group->addChild(geode);
  1518. envTx_->addChild(group);
  1519. return 0;
  1520. }
  1521. int Viewer::LoadRoadFeature(roadmanager::Road *road, std::string filename, double s, double t,
  1522. double z_offset, double scale_x, double scale_y, double scale_z, double heading_offset)
  1523. {
  1524. roadmanager::Position* pos = new roadmanager::Position();
  1525. osg::ref_ptr<osg::Node> node;
  1526. osg::ref_ptr<osg::PositionAttitudeTransform> xform;
  1527. // Load file, try multiple paths
  1528. std::vector<std::string> file_name_candidates;
  1529. file_name_candidates.push_back(filename);
  1530. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(DirNameOf(exe_path_) + "/../resources/models", filename));
  1531. // Finally check registered paths
  1532. for (size_t i = 0; i < SE_Env::Inst().GetPaths().size(); i++)
  1533. {
  1534. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], filename));
  1535. file_name_candidates.push_back(CombineDirectoryPathAndFilepath(SE_Env::Inst().GetPaths()[i], std::string("../models/" + filename)));
  1536. }
  1537. for (size_t i = 0; i < file_name_candidates.size(); i++)
  1538. {
  1539. if (FileExists(file_name_candidates[i].c_str()))
  1540. {
  1541. node = osgDB::readNodeFile(file_name_candidates[i]);
  1542. if (!node)
  1543. {
  1544. return 0;
  1545. }
  1546. pos->SetTrackPos(road->GetId(), s, t);
  1547. xform = new osg::PositionAttitudeTransform;
  1548. xform->setPosition(osg::Vec3(pos->GetX(), pos->GetY(), z_offset + pos->GetZ()));
  1549. xform->setAttitude(osg::Quat(pos->GetH() + heading_offset, osg::Vec3(0, 0, 1)));
  1550. xform->setScale(osg::Vec3(scale_x, scale_y, scale_z));
  1551. xform->addChild(node);
  1552. rootnode_->addChild(xform);
  1553. }
  1554. }
  1555. return 0;
  1556. }
  1557. int Viewer::CreateRoadSignsAndObjects(roadmanager::OpenDrive* od)
  1558. {
  1559. for (int r = 0; r < od->GetNumOfRoads(); r++)
  1560. {
  1561. roadmanager::Road* road = od->GetRoadByIdx(r);
  1562. for (size_t s = 0; s < road->GetNumberOfSignals(); s++)
  1563. {
  1564. roadmanager::Signal* signal = road->GetSignal(s);
  1565. double orientation = signal->GetOrientation() == roadmanager::Signal::Orientation::NEGATIVE ? M_PI : 0.0;
  1566. if (LoadRoadFeature(road, signal->GetName() + ".osgb", signal->GetS(), signal->GetT(), signal->GetZOffset(), 1.0, 1.0, 1.0, orientation + signal->GetHOffset()) != 0)
  1567. {
  1568. return -1;
  1569. }
  1570. }
  1571. for (size_t o = 0; o < road->GetNumberOfObjects(); o++)
  1572. {
  1573. roadmanager::Object* object = road->GetObject(o);
  1574. if (object->GetNumberOfOutlines() > 0)
  1575. {
  1576. for (size_t j = 0; j < object->GetNumberOfOutlines(); j++)
  1577. {
  1578. roadmanager::Outline* outline = object->GetOutline(j);
  1579. CreateOutlineObject(outline);
  1580. }
  1581. LOG("Created outline geometry for object %s.", object->GetName().c_str());
  1582. LOG(" if it looks strange, e.g.faces too dark or light color, ");
  1583. LOG(" check that corners are defined counter-clockwise (as OpenGL default).");
  1584. }
  1585. else
  1586. {
  1587. // Assume name is representing a 3D model filename
  1588. double orientation = object->GetOrientation() == roadmanager::Signal::Orientation::NEGATIVE ? M_PI : 0.0;
  1589. if (LoadRoadFeature(road, object->GetName() + ".osgb", object->GetS(), object->GetT(), object->GetZOffset(),
  1590. 1.0, 1.0, object->GetHeight(), orientation + object->GetHOffset()) != 0)
  1591. {
  1592. return -1;
  1593. }
  1594. }
  1595. }
  1596. }
  1597. return 0;
  1598. }
  1599. bool Viewer::CreateRoadSensors(CarModel *vehicle_model)
  1600. {
  1601. vehicle_model->road_sensor_ = CreateSensor(color_yellow, true, false, 0.25, 2.5);
  1602. vehicle_model->lane_sensor_ = CreateSensor(color_yellow, true, true, 0.25, 2.5);
  1603. return true;
  1604. }
  1605. PointSensor* Viewer::CreateSensor(double color[], bool create_ball, bool create_line, double ball_radius, double line_width)
  1606. {
  1607. PointSensor *sensor = new PointSensor();
  1608. sensor->group_ = new osg::Group();
  1609. // Point
  1610. if (create_ball)
  1611. {
  1612. osg::ref_ptr<osg::Geode> geode = new osg::Geode;
  1613. geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere()));
  1614. sensor->ball_ = new osg::PositionAttitudeTransform;
  1615. sensor->ball_->setScale(osg::Vec3(ball_radius, ball_radius, ball_radius));
  1616. sensor->ball_->addChild(geode);
  1617. osg::ref_ptr<osg::Material> material = new osg::Material();
  1618. material->setDiffuse(osg::Material::FRONT, osg::Vec4(color[0], color[1], color[2], 1.0));
  1619. material->setAmbient(osg::Material::FRONT, osg::Vec4(color[0], color[1], color[2], 1.0));
  1620. sensor->ball_->getOrCreateStateSet()->setAttribute(material);
  1621. sensor->ball_radius_ = ball_radius;
  1622. sensor->group_->addChild(sensor->ball_);
  1623. }
  1624. // line
  1625. if (create_line)
  1626. {
  1627. sensor->line_vertex_data_ = new osg::Vec3Array;
  1628. sensor->line_vertex_data_->push_back(osg::Vec3d(0, 0, 0));
  1629. sensor->line_vertex_data_->push_back(osg::Vec3d(0, 0, 0));
  1630. osg::ref_ptr<osg::Group> group = new osg::Group;
  1631. sensor->line_ = new osg::Geometry();
  1632. group->addChild(sensor->line_);
  1633. //sensor->line_->setCullingActive(false);
  1634. sensor->line_->setVertexArray(sensor->line_vertex_data_.get());
  1635. sensor->line_->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_STRIP, 0, 2));
  1636. osg::ref_ptr<osg::LineWidth> lineWidth = new osg::LineWidth();
  1637. lineWidth->setWidth(line_width);
  1638. sensor->line_->getOrCreateStateSet()->setAttributeAndModes(lineWidth, osg::StateAttribute::ON);
  1639. sensor->line_->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
  1640. osg::ref_ptr<osg::Vec4Array> color_ = new osg::Vec4Array;
  1641. color_->push_back(osg::Vec4(color[0], color[1], color[2], 1.0));
  1642. sensor->line_->setColorArray(color_.get());
  1643. sensor->line_->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
  1644. //sensor->line_->setDataVariance(osg::Object::DYNAMIC);
  1645. sensor->group_->addChild(group);
  1646. }
  1647. // Make sensor visible as default
  1648. roadSensors_->addChild(sensor->group_);
  1649. sensor->Show();
  1650. return sensor;
  1651. }
  1652. void Viewer::UpdateRoadSensors(PointSensor *road_sensor, PointSensor *lane_sensor, roadmanager::Position *pos)
  1653. {
  1654. if (road_sensor == 0 || lane_sensor == 0)
  1655. {
  1656. return;
  1657. }
  1658. roadmanager::Position track_pos(*pos);
  1659. track_pos.SetTrackPos(pos->GetTrackId(), pos->GetS(), 0);
  1660. SensorSetPivotPos(road_sensor, pos->GetX(), pos->GetY(), pos->GetZ());
  1661. SensorSetTargetPos(road_sensor, track_pos.GetX(), track_pos.GetY(), track_pos.GetZ());
  1662. UpdateSensor(road_sensor);
  1663. roadmanager::Position lane_pos(*pos);
  1664. lane_pos.SetLanePos(pos->GetTrackId(), pos->GetLaneId(), pos->GetS(), 0);
  1665. SensorSetPivotPos(lane_sensor, pos->GetX(), pos->GetY(), pos->GetZ());
  1666. SensorSetTargetPos(lane_sensor, lane_pos.GetX(), lane_pos.GetY(), lane_pos.GetZ());
  1667. UpdateSensor(lane_sensor);
  1668. }
  1669. void Viewer::SensorSetPivotPos(PointSensor *sensor, double x, double y, double z)
  1670. {
  1671. double z_offset = 0.2;
  1672. sensor->pivot_pos = osg::Vec3(x, y, z + MAX(sensor->ball_radius_ / 3.0, z_offset));
  1673. }
  1674. void Viewer::SensorSetTargetPos(PointSensor *sensor, double x, double y, double z)
  1675. {
  1676. double z_offset = 0.2;
  1677. sensor->target_pos = osg::Vec3(x, y, z + MAX(sensor->ball_radius_ / 3.0, z_offset));
  1678. }
  1679. void Viewer::UpdateSensor(PointSensor *sensor)
  1680. {
  1681. if (sensor == 0)
  1682. {
  1683. return;
  1684. }
  1685. // Line
  1686. if (sensor->line_)
  1687. {
  1688. sensor->line_vertex_data_->clear();
  1689. sensor->line_vertex_data_->push_back(sensor->pivot_pos);
  1690. sensor->line_vertex_data_->push_back(sensor->target_pos);
  1691. sensor->line_->dirtyGLObjects();
  1692. sensor->line_->dirtyBound();
  1693. sensor->line_vertex_data_->dirty();
  1694. }
  1695. // Point/ball
  1696. if (sensor->ball_)
  1697. {
  1698. sensor->ball_->setPosition(sensor->target_pos);
  1699. }
  1700. }
  1701. int Viewer::LoadShadowfile(std::string vehicleModelFilename)
  1702. {
  1703. // Load shadow geometry - assume it resides in the same resource folder as the vehicle model
  1704. std::string shadowFilename = DirNameOf(vehicleModelFilename).append("/" + std::string(SHADOW_MODEL_FILEPATH));
  1705. if (FileExists(shadowFilename.c_str()))
  1706. {
  1707. shadow_node_ = osgDB::readNodeFile(shadowFilename);
  1708. }
  1709. if (!shadow_node_)
  1710. {
  1711. LOG("Failed to locate shadow model %s based on vehicle model filename %s - continue without",
  1712. SHADOW_MODEL_FILEPATH, vehicleModelFilename.c_str());
  1713. return -1;
  1714. }
  1715. return 0;
  1716. }
  1717. int Viewer::AddEnvironment(const char* filename)
  1718. {
  1719. // remove current model, if any
  1720. if (environment_ != 0)
  1721. {
  1722. printf("Removing current env\n");
  1723. envTx_->removeChild(environment_);
  1724. }
  1725. // load and apply new model
  1726. // First, assume absolute path or relative current directory
  1727. if (strcmp(FileNameOf(filename).c_str(), ""))
  1728. {
  1729. if ((environment_ = osgDB::readNodeFile(filename)) == 0)
  1730. {
  1731. return -1;
  1732. }
  1733. envTx_->addChild(environment_);
  1734. }
  1735. else
  1736. {
  1737. LOG("AddEnvironment: No environment 3D model specified (%s) - go ahead without\n", filename);
  1738. }
  1739. return 0;
  1740. }
  1741. void Viewer::ShowInfoText(bool show)
  1742. {
  1743. showInfoText = show;
  1744. }
  1745. void Viewer::SetInfoText(const char* text)
  1746. {
  1747. if (showInfoText)
  1748. {
  1749. infoText->setText(text);
  1750. }
  1751. else
  1752. {
  1753. infoText->setText("");
  1754. }
  1755. }
  1756. void Viewer::SetNodeMaskBits(int bits)
  1757. {
  1758. osgViewer_->getCamera()->setCullMask(osgViewer_->getCamera()->getCullMask() | bits);
  1759. }
  1760. void Viewer::SetNodeMaskBits(int mask, int bits)
  1761. {
  1762. osgViewer_->getCamera()->setCullMask((osgViewer_->getCamera()->getCullMask() & ~mask) | bits);
  1763. }
  1764. void Viewer::ClearNodeMaskBits(int bits)
  1765. {
  1766. osgViewer_->getCamera()->setCullMask(osgViewer_->getCamera()->getCullMask() & ~bits);
  1767. }
  1768. void Viewer::ToggleNodeMaskBits(int bits)
  1769. {
  1770. osgViewer_->getCamera()->setCullMask(osgViewer_->getCamera()->getCullMask() ^ bits);
  1771. }
  1772. int Viewer::GetNodeMaskBit(int mask)
  1773. {
  1774. return osgViewer_->getCamera()->getCullMask() & mask;
  1775. }
  1776. void Viewer::SetInfoTextProjection(int width, int height)
  1777. {
  1778. infoTextCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, width, 0, height));
  1779. }
  1780. void Viewer::SetVehicleInFocus(int idx)
  1781. {
  1782. currentCarInFocus_ = idx;
  1783. if (entities_.size() > idx)
  1784. {
  1785. rubberbandManipulator_->setTrackNode(entities_[currentCarInFocus_]->txNode_, false);
  1786. nodeTrackerManipulator_->setTrackNode(entities_[currentCarInFocus_]->txNode_);
  1787. }
  1788. }
  1789. void Viewer::SetWindowTitle(std::string title)
  1790. {
  1791. // Decorate window border with application name
  1792. osgViewer::ViewerBase::Windows wins;
  1793. osgViewer_->getWindows(wins);
  1794. if (wins.size() > 0)
  1795. {
  1796. wins[0]->setWindowName(title);
  1797. }
  1798. }
  1799. void Viewer::SetWindowTitleFromArgs(std::vector<std::string> &args)
  1800. {
  1801. std::string titleString;
  1802. for (int i = 0; i < args.size(); i++)
  1803. {
  1804. std::string arg = args[i];
  1805. if (i == 0)
  1806. {
  1807. arg = FileNameWithoutExtOf(arg);
  1808. if (arg != "esmini")
  1809. {
  1810. arg = "esmini " + arg;
  1811. }
  1812. }
  1813. else if (arg == "--osc" || arg == "--odr" || arg == "--model")
  1814. {
  1815. titleString += std::string(arg) + " ";
  1816. i++;
  1817. arg = FileNameOf(std::string(args[i]));
  1818. }
  1819. else if (arg == "--window")
  1820. {
  1821. i += 4;
  1822. continue;
  1823. }
  1824. titleString += std::string(arg) + " ";
  1825. }
  1826. SetWindowTitle(titleString);
  1827. }
  1828. void Viewer::SetWindowTitleFromArgs(int argc, char* argv[])
  1829. {
  1830. std::vector<std::string> args;
  1831. for (int i = 0; i < argc; i++)
  1832. {
  1833. args.push_back(argv[i]);
  1834. }
  1835. SetWindowTitleFromArgs(args);
  1836. }
  1837. void Viewer::RegisterKeyEventCallback(KeyEventCallbackFunc func, void* data)
  1838. {
  1839. KeyEventCallback cb;
  1840. cb.func = func;
  1841. cb.data = data;
  1842. callback_.push_back(cb);
  1843. }
  1844. bool ViewerEventHandler::handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter&)
  1845. {
  1846. switch (ea.getEventType())
  1847. {
  1848. case(osgGA::GUIEventAdapter::RESIZE):
  1849. viewer_->SetInfoTextProjection(ea.getWindowWidth(), ea.getWindowHeight());
  1850. break;
  1851. }
  1852. switch (ea.getKey())
  1853. {
  1854. case(osgGA::GUIEventAdapter::KEY_K):
  1855. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1856. {
  1857. viewer_->camMode_ += 1;
  1858. if (viewer_->camMode_ >= osgGA::RubberbandManipulator::RB_NUM_MODES)
  1859. {
  1860. viewer_->camMode_ = 0;
  1861. }
  1862. viewer_->rubberbandManipulator_->setMode(viewer_->camMode_);
  1863. }
  1864. break;
  1865. case(osgGA::GUIEventAdapter::KEY_O):
  1866. {
  1867. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1868. {
  1869. viewer_->ToggleNodeMaskBits(viewer::NodeMask::NODE_MASK_ODR_FEATURES);
  1870. }
  1871. }
  1872. break;
  1873. case(osgGA::GUIEventAdapter::KEY_U):
  1874. {
  1875. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1876. {
  1877. viewer_->ToggleNodeMaskBits(viewer::NodeMask::NODE_MASK_OSI_LINES);
  1878. }
  1879. }
  1880. break;
  1881. case(osgGA::GUIEventAdapter::KEY_Y):
  1882. {
  1883. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1884. {
  1885. viewer_->ToggleNodeMaskBits(viewer::NodeMask::NODE_MASK_OSI_POINTS);
  1886. }
  1887. }
  1888. break;
  1889. case(osgGA::GUIEventAdapter::KEY_P):
  1890. {
  1891. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1892. {
  1893. viewer_->ToggleNodeMaskBits(NodeMask::NODE_MASK_ENV_MODEL);
  1894. }
  1895. }
  1896. break;
  1897. case(osgGA::GUIEventAdapter::KEY_Right):
  1898. {
  1899. viewer_->setKeyRight(ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN);
  1900. }
  1901. break;
  1902. case(osgGA::GUIEventAdapter::KEY_Left):
  1903. {
  1904. viewer_->setKeyLeft(ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN);
  1905. }
  1906. break;
  1907. case(osgGA::GUIEventAdapter::KEY_Up):
  1908. {
  1909. viewer_->setKeyUp(ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN);
  1910. }
  1911. break;
  1912. case(osgGA::GUIEventAdapter::KEY_Down):
  1913. {
  1914. viewer_->setKeyDown(ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN);
  1915. }
  1916. break;
  1917. case(osgGA::GUIEventAdapter::KEY_Tab):
  1918. {
  1919. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1920. {
  1921. int idx = viewer_->currentCarInFocus_ + ((ea.getModKeyMask() & osgGA::GUIEventAdapter::KEY_Shift_L) ? -1 : 1);
  1922. if (idx >= (int)viewer_->entities_.size())
  1923. {
  1924. idx = 0;
  1925. }
  1926. else if (idx < 0)
  1927. {
  1928. idx = viewer_->entities_.size() - 1;
  1929. }
  1930. viewer_->SetVehicleInFocus(idx);
  1931. }
  1932. }
  1933. break;
  1934. case(osgGA::GUIEventAdapter::KEY_Comma):
  1935. {
  1936. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1937. {
  1938. int mask = viewer_->GetNodeMaskBit(
  1939. viewer::NodeMask::NODE_MASK_ENTITY_MODEL |
  1940. viewer::NodeMask::NODE_MASK_ENTITY_BB) / viewer::NodeMask::NODE_MASK_ENTITY_MODEL;
  1941. // Toggle between modes: 0: none, 1: model only, 2: bounding box, 3. model + Bounding box
  1942. mask = ((mask + 1) % 4) * viewer::NodeMask::NODE_MASK_ENTITY_MODEL;
  1943. viewer_->SetNodeMaskBits(viewer::NodeMask::NODE_MASK_ENTITY_MODEL |
  1944. viewer::NodeMask::NODE_MASK_ENTITY_BB, mask);
  1945. }
  1946. }
  1947. break;
  1948. case(osgGA::GUIEventAdapter::KEY_I):
  1949. {
  1950. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1951. {
  1952. viewer_->showInfoText = !viewer_->showInfoText;
  1953. viewer_->infoTextCamera->setNodeMask(viewer_->showInfoText ? 0xffffffff : 0x0);
  1954. }
  1955. }
  1956. break;
  1957. case(osgGA::GUIEventAdapter::KEY_J):
  1958. {
  1959. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1960. {
  1961. viewer_->ToggleNodeMaskBits(viewer::NodeMask::NODE_MASK_TRAILS);
  1962. }
  1963. }
  1964. break;
  1965. case(osgGA::GUIEventAdapter::KEY_R):
  1966. {
  1967. if (ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN)
  1968. {
  1969. viewer_->ToggleNodeMaskBits(viewer::NodeMask::NODE_MASK_OBJECT_SENSORS);
  1970. }
  1971. }
  1972. break;
  1973. case(osgGA::GUIEventAdapter::KEY_Escape):
  1974. {
  1975. viewer_->SetQuitRequest(true);
  1976. viewer_->osgViewer_->setDone(true);
  1977. }
  1978. break;
  1979. }
  1980. // Send key event to registered callback subscribers
  1981. if (ea.getKey() > 0)
  1982. {
  1983. for (size_t i = 0; i < viewer_->callback_.size(); i++)
  1984. {
  1985. KeyEvent ke = { ea.getKey(), ea.getModKeyMask(), ea.getEventType() & osgGA::GUIEventAdapter::KEYDOWN ? true : false };
  1986. viewer_->callback_[i].func(&ke, viewer_->callback_[i].data);
  1987. }
  1988. }
  1989. if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Space)
  1990. {
  1991. // prevent OSG "view reset" action on space key
  1992. return true;
  1993. }
  1994. else
  1995. {
  1996. // forward all other key events to OSG
  1997. return false;
  1998. }
  1999. }