Eclipse SUMO - Simulation of Urban MObility
GUIOSGBuilder.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2020 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
19 // Builds OSG nodes from microsim objects
20 /****************************************************************************/
21 #include <config.h>
22 
23 #ifdef HAVE_OSG
24 
25 #ifdef _MSC_VER
26 #pragma warning(push)
27 #pragma warning(disable: 4127) // do not warn about constant conditional expression
28 #pragma warning(disable: 4275) // do not warn about the DLL interface for OSG
29 #endif
30 #include <osg/Version>
31 #include <osgViewer/ViewerEventHandlers>
32 #include <osgGA/TrackballManipulator>
33 #include <osgDB/ReadFile>
34 #include <osgDB/WriteFile>
35 #include <osg/ShapeDrawable>
36 #include <osg/Node>
37 #include <osg/Group>
38 #include <osg/Geode>
39 #include <osg/Geometry>
40 #include <osg/Sequence>
41 #include <osg/Texture2D>
42 #include <osgViewer/Viewer>
43 #include <osgUtil/Tessellator>
44 #include <osg/PositionAttitudeTransform>
45 #include <osg/ShadeModel>
46 #include <osg/Light>
47 #include <osg/LightSource>
48 #include <osg/ComputeBoundsVisitor>
49 #ifdef _MSC_VER
50 #pragma warning(pop)
51 #endif
52 
53 #include <microsim/MSNet.h>
54 #include <microsim/MSEdge.h>
55 #include <microsim/MSLane.h>
56 #include <microsim/MSEdgeControl.h>
58 #include <microsim/MSJunction.h>
59 #include <microsim/MSVehicleType.h>
63 #include <guisim/GUINet.h>
64 #include <guisim/GUIEdge.h>
65 #include <guisim/GUILane.h>
68 #include "GUIOSGView.h"
69 #include "GUIOSGBuilder.h"
70 
71 
72 //#define DEBUG_TESSEL
73 
74 // ===========================================================================
75 // static member variables
76 // ===========================================================================
77 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
78 
79 
80 // ===========================================================================
81 // member method definitions
82 // ===========================================================================
83 osg::Group*
84 GUIOSGBuilder::buildOSGScene(osg::Node* const tlg, osg::Node* const tly, osg::Node* const tlr, osg::Node* const tlu) {
85  osgUtil::Tessellator tesselator;
86  osg::Group* root = new osg::Group();
87  GUINet* net = static_cast<GUINet*>(MSNet::getInstance());
88  // build edges
89  for (const MSEdge* e : net->getEdgeControl().getEdges()) {
90  if (!e->isInternal()) {
91  buildOSGEdgeGeometry(*e, *root, tesselator);
92  }
93  }
94  // build junctions
95  for (int index = 0; index < (int)net->myJunctionWrapper.size(); ++index) {
96  buildOSGJunctionGeometry(*net->myJunctionWrapper[index], *root, tesselator);
97  }
98  // build traffic lights
100  const std::vector<std::string> tlids = net->getTLSControl().getAllTLIds();
101  for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
104  const MSLane* lastLane = 0;
105  int idx = 0;
106  for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
107  if ((*j).size() == 0) {
108  continue;
109  }
110  const MSLane* const lane = (*j)[0];
111  const Position pos = lane->getShape().back();
112  const double angle = osg::DegreesToRadians(lane->getShape().rotationDegreeAtOffset(-1.) + 90.);
113  d.centerZ = pos.z() + 4.;
114  if (lane == lastLane) {
115  d.centerX += 1.2 * sin(angle);
116  d.centerY += 1.2 * cos(angle);
117  } else {
118  d.centerX = pos.x() - 1.5 * sin(angle);
119  d.centerY = pos.y() - 1.5 * cos(angle);
120  }
121  osg::Switch* switchNode = new osg::Switch();
122  switchNode->addChild(getTrafficLight(d, tlg, osg::Vec4d(0.1, 0.5, 0.1, 1.0), .25), false);
123  switchNode->addChild(getTrafficLight(d, tly, osg::Vec4d(0.5, 0.5, 0.1, 1.0), .25), false);
124  switchNode->addChild(getTrafficLight(d, tlr, osg::Vec4d(0.5, 0.1, 0.1, 1.0), .25), false);
125  switchNode->addChild(getTrafficLight(d, tlu, osg::Vec4d(0.8, 0.4, 0.0, 1.0), .25), false);
126  root->addChild(switchNode);
127  const MSLink* const l = vars.getActive()->getLinksAt(idx)[0];
128  vars.addSwitchCommand(new GUIOSGView::Command_TLSChange(l, switchNode));
129  lastLane = lane;
130  }
131  }
132  return root;
133 }
134 
135 
136 void
137 GUIOSGBuilder::buildLight(const GUISUMOAbstractView::Decal& d, osg::Group& addTo) {
138  // each light must have a unique number
139  osg::Light* light = new osg::Light(d.filename[5] - '0');
140  // we set the light's position via a PositionAttitudeTransform object
141  light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
142  light->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0));
143  light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
144  light->setAmbient(osg::Vec4(1.0, 1.0, 1.0, 1.0));
145 
146  osg::LightSource* lightSource = new osg::LightSource();
147  lightSource->setLight(light);
148  lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
149  lightSource->setStateSetModes(*addTo.getOrCreateStateSet(), osg::StateAttribute::ON);
150 
151  osg::PositionAttitudeTransform* lightTransform = new osg::PositionAttitudeTransform();
152  lightTransform->addChild(lightSource);
153  lightTransform->setPosition(osg::Vec3d(d.centerX, d.centerY, d.centerZ));
154  lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
155  addTo.addChild(lightTransform);
156 }
157 
158 
159 void
160 GUIOSGBuilder::buildOSGEdgeGeometry(const MSEdge& edge,
161  osg::Group& addTo,
162  osgUtil::Tessellator& tessellator) {
163  const std::vector<MSLane*>& lanes = edge.getLanes();
164  for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
165  MSLane* l = (*j);
166  const PositionVector& shape = l->getShape();
167  osg::Geode* geode = new osg::Geode();
168  osg::Geometry* geom = new osg::Geometry();
169  geode->addDrawable(geom);
170  addTo.addChild(geode);
171  const int shapeSize = (int)(edge.isWalkingArea() ? shape.size() : shape.size() * 2);
172  const float zOffset = edge.isWalkingArea() || edge.isCrossing() ? 0.01f : 0.f;
173  osg::Vec3Array* osg_coords = new osg::Vec3Array(shapeSize);
174  geom->setVertexArray(osg_coords);
175  if (edge.isWalkingArea()) {
176  int index = 0;
177  for (int k = 0; k < (int)shape.size(); ++k, ++index) {
178  (*osg_coords)[index].set((float)shape[k].x(), (float)shape[k].y(), (float)shape[k].z() + zOffset);
179  }
180  } else {
181  PositionVector rshape = shape;
182  rshape.move2side(l->getWidth() / 2);
183  int index = 0;
184  for (int k = 0; k < (int)rshape.size(); ++k, ++index) {
185  (*osg_coords)[index].set((float)rshape[k].x(), (float)rshape[k].y(), (float)rshape[k].z() + zOffset);
186  }
187  PositionVector lshape = shape;
188  lshape.move2side(-l->getWidth() / 2);
189  for (int k = (int) lshape.size() - 1; k >= 0; --k, ++index) {
190  (*osg_coords)[index].set((float)lshape[k].x(), (float)lshape[k].y(), (float)lshape[k].z() + zOffset);
191  }
192  }
193  osg::Vec3Array* osg_normals = new osg::Vec3Array(1);
194  (*osg_normals)[0] = osg::Vec3(0, 0, 1);
195 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
196  geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
197 #else
198  geom->setNormalArray(osg_normals);
199  geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
200 #endif
201  osg::Vec4ubArray* osg_colors = new osg::Vec4ubArray(1);
202  (*osg_colors)[0].set(128, 128, 128, 255);
203 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
204  geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
205 #else
206  geom->setColorArray(osg_colors);
207  geom->setColorBinding(osg::Geometry::BIND_OVERALL);
208 #endif
209  geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shapeSize));
210 
211  osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
212  ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
213  ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
214 
215  if (shape.size() > 2) {
216  tessellator.retessellatePolygons(*geom);
217 #ifdef DEBUG_TESSEL
218  std::cout << "l=" << l->getID() << " origPoints=" << shape.size() << " geomSize=" << geom->getVertexArray()->getNumElements() << " points=";
219  for (int i = 0; i < (int)geom->getVertexArray()->getNumElements(); i++) {
220  const osg::Vec3& p = (*((osg::Vec3Array*)geom->getVertexArray()))[i];
221  std::cout << p.x() << "," << p.y() << "," << p.z() << " ";
222  }
223  std::cout << "\n";
224 #endif
225  }
226  static_cast<GUILane*>(l)->setGeometry(geom);
227  }
228 }
229 
230 
231 void
232 GUIOSGBuilder::buildOSGJunctionGeometry(GUIJunctionWrapper& junction,
233  osg::Group& addTo,
234  osgUtil::Tessellator& tessellator) {
235  const PositionVector& shape = junction.getJunction().getShape();
236  osg::Geode* geode = new osg::Geode();
237  osg::Geometry* geom = new osg::Geometry();
238  geode->addDrawable(geom);
239  addTo.addChild(geode);
240  osg::Vec3Array* osg_coords = new osg::Vec3Array((int)shape.size());
241  geom->setVertexArray(osg_coords);
242  for (int k = 0; k < (int)shape.size(); ++k) {
243  (*osg_coords)[k].set((float)shape[k].x(), (float)shape[k].y(), (float)shape[k].z());
244  }
245  osg::Vec3Array* osg_normals = new osg::Vec3Array(1);
246  (*osg_normals)[0] = osg::Vec3(0, 0, 1);
247 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
248  geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
249 #else
250  geom->setNormalArray(osg_normals);
251  geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
252 #endif
253  osg::Vec4ubArray* osg_colors = new osg::Vec4ubArray(1);
254  (*osg_colors)[0].set(128, 128, 128, 255);
255 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
256  geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
257 #else
258  geom->setColorArray(osg_colors);
259  geom->setColorBinding(osg::Geometry::BIND_OVERALL);
260 #endif
261  geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (int)shape.size()));
262 
263  osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
264  ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
265  ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
266 
267  if (shape.size() > 4) {
268  tessellator.retessellatePolygons(*geom);
269  }
270  junction.setGeometry(geom);
271 }
272 
273 
274 void
275 GUIOSGBuilder::buildDecal(const GUISUMOAbstractView::Decal& d, osg::Group& addTo) {
276  osg::Node* pLoadedModel = osgDB::readNodeFile(d.filename);
277  if (pLoadedModel == nullptr) {
278  WRITE_ERROR("Could not load '" + d.filename + "'.");
279  return;
280  }
281  osg::ShadeModel* sm = new osg::ShadeModel();
282  sm->setMode(osg::ShadeModel::FLAT);
283  pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
284  osg::PositionAttitudeTransform* base = new osg::PositionAttitudeTransform();
285  base->addChild(pLoadedModel);
286  osg::ComputeBoundsVisitor bboxCalc;
287  pLoadedModel->accept(bboxCalc);
288  const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
289  WRITE_MESSAGE("Loaded decal '" + d.filename + "' with bounding box " + toString(Position(bbox.xMin(), bbox.yMin(), bbox.zMin())) + " " + toString(Position(bbox.xMax(), bbox.yMax(), bbox.zMax())) + ".");
290  double xScale = d.width > 0 ? d.width / (bbox.xMax() - bbox.xMin()) : 1.;
291  double yScale = d.height > 0 ? d.height / (bbox.yMax() - bbox.yMin()) : 1.;
292  const double zScale = d.altitude > 0 ? d.altitude / (bbox.zMax() - bbox.zMin()) : 1.;
293  if (d.width < 0 && d.height < 0 && d.altitude > 0) {
294  xScale = yScale = zScale;
295  }
296  base->setScale(osg::Vec3d(xScale, yScale, zScale));
297  base->setPosition(osg::Vec3d(d.centerX, d.centerY, d.centerZ));
298  base->setAttitude(osg::Quat(osg::DegreesToRadians(d.roll), osg::Vec3d(1, 0, 0),
299  osg::DegreesToRadians(d.tilt), osg::Vec3d(0, 1, 0),
300  osg::DegreesToRadians(d.rot), osg::Vec3d(0, 0, 1)));
301  addTo.addChild(base);
302 }
303 
304 
305 osg::PositionAttitudeTransform*
306 GUIOSGBuilder::getTrafficLight(const GUISUMOAbstractView::Decal& d, osg::Node* tl, const osg::Vec4& color, const double size) {
307  osg::PositionAttitudeTransform* ret = new osg::PositionAttitudeTransform();
308  if (tl != nullptr) {
309  osg::PositionAttitudeTransform* base = new osg::PositionAttitudeTransform();
310  base->addChild(tl);
311  osg::ComputeBoundsVisitor bboxCalc;
312  tl->accept(bboxCalc);
313  const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
314  double xScale = d.width > 0 ? d.width / (bbox.xMax() - bbox.xMin()) : 1.;
315  double yScale = d.height > 0 ? d.height / (bbox.yMax() - bbox.yMin()) : 1.;
316  const double zScale = d.altitude > 0 ? d.altitude / (bbox.zMax() - bbox.zMin()) : 1.;
317  if (d.width < 0 && d.height < 0 && d.altitude > 0) {
318  xScale = yScale = zScale;
319  }
320  base->setScale(osg::Vec3d(xScale, yScale, zScale));
321  base->setPosition(osg::Vec3d(d.centerX, d.centerY, d.centerZ));
322  base->setAttitude(osg::Quat(osg::DegreesToRadians(d.roll), osg::Vec3(1, 0, 0),
323  osg::DegreesToRadians(d.tilt), osg::Vec3(0, 1, 0),
324  osg::DegreesToRadians(d.rot), osg::Vec3(0, 0, 1)));
325  ret->addChild(base);
326  }
327  osg::Geode* geode = new osg::Geode();
328  osg::Vec3d center(d.centerX, d.centerY, d.centerZ);
329  osg::ShapeDrawable* shape = new osg::ShapeDrawable(new osg::Sphere(center, (float)size));
330  geode->addDrawable(shape);
331  osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
332  ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
333  ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
334  osg::PositionAttitudeTransform* ellipse = new osg::PositionAttitudeTransform();
335  ellipse->addChild(geode);
336  ellipse->setPivotPoint(center);
337  ellipse->setPosition(center);
338  ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.altitude + 1.1));
339  shape->setColor(color);
340  ret->addChild(ellipse);
341  return ret;
342 }
343 
344 
345 void
346 GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
347  osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
348  ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
349  ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
350 }
351 
352 
353 GUIOSGView::OSGMovable
354 GUIOSGBuilder::buildMovable(const MSVehicleType& type) {
355  GUIOSGView::OSGMovable m;
356  m.pos = new osg::PositionAttitudeTransform();
357  double enlarge = 0.;
358  const std::string& osgFile = type.getOSGFile();
359  if (myCars.find(osgFile) == myCars.end()) {
360  myCars[osgFile] = osgDB::readNodeFile(osgFile);
361  if (myCars[osgFile] == 0) {
362  WRITE_ERROR("Could not load '" + osgFile + "'.");
363  }
364  }
365  osg::Node* carNode = myCars[osgFile];
366  if (carNode != nullptr) {
367  osg::ComputeBoundsVisitor bboxCalc;
368  carNode->accept(bboxCalc);
369  const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
370  osg::PositionAttitudeTransform* base = new osg::PositionAttitudeTransform();
371  base->addChild(carNode);
372  base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
373  base->setScale(osg::Vec3d(type.getWidth() / (bbox.xMax() - bbox.xMin()),
374  type.getLength() / (bbox.yMax() - bbox.yMin()),
375  type.getHeight() / (bbox.zMax() - bbox.zMin())));
376  m.pos->addChild(base);
377  enlarge = type.getMinGap() / 2.;
378  }
379  m.lights = new osg::Switch();
380  for (double offset = -0.3; offset < 0.5; offset += 0.6) {
381  osg::Geode* geode = new osg::Geode();
382  osg::ShapeDrawable* right = new osg::ShapeDrawable(new osg::Sphere(osg::Vec3d(offset, (type.getLength() - .9) / 2., (type.getHeight() - .5) / 2.), .1f));
383  geode->addDrawable(right);
384  setShapeState(right);
385  right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
386  osg::Sequence* seq = new osg::Sequence();
387  // Wikipedia says about 1.5Hz
388  seq->addChild(geode, .33);
389  seq->addChild(new osg::Geode(), .33);
390  // loop through all children
391  seq->setInterval(osg::Sequence::LOOP, 0, -1);
392  // real-time playback, repeat indefinitely
393  seq->setDuration(1.0f, -1);
394  // must be started explicitly
395  seq->setMode(osg::Sequence::START);
396  m.lights->addChild(seq);
397  }
398 
399  osg::Geode* geode = new osg::Geode();
400  osg::CompositeShape* comp = new osg::CompositeShape();
401  comp->addChild(new osg::Sphere(osg::Vec3d(-0.3, (type.getLength() + .8) / 2., (type.getHeight() - .5) / 2.), .1f));
402  comp->addChild(new osg::Sphere(osg::Vec3d(0.3, (type.getLength() + .8) / 2., (type.getHeight() - .5) / 2.), .1f));
403  osg::ShapeDrawable* brake = new osg::ShapeDrawable(comp);
404  brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
405  geode->addDrawable(brake);
406  setShapeState(brake);
407  m.lights->addChild(geode);
408 
409  geode = new osg::Geode();
410  osg::Vec3d center(0, type.getLength() / 2., type.getHeight() / 2.);
411  m.geom = new osg::ShapeDrawable(new osg::Sphere(center, .5f));
412  geode->addDrawable(m.geom);
413  setShapeState(m.geom);
414  osg::PositionAttitudeTransform* ellipse = new osg::PositionAttitudeTransform();
415  ellipse->addChild(geode);
416  ellipse->addChild(m.lights);
417  ellipse->setPivotPoint(center);
418  ellipse->setPosition(center);
419  ellipse->setScale(osg::Vec3d(type.getWidth() + enlarge, type.getLength() + enlarge, type.getHeight() + enlarge));
420  m.pos->addChild(ellipse);
421  m.active = true;
422  return m;
423 }
424 
425 #endif
426 
427 
428 /****************************************************************************/
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:278
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:284
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition: ToString.h:44
const MSJunction & getJunction() const
Returns the represented junction.
Representation of a lane in the micro simulation (gui-version)
Definition: GUILane.h:59
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:81
std::vector< GUIJunctionWrapper * > myJunctionWrapper
Wrapped MS-junctions.
Definition: GUINet.h:362
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
Definition: MSEdge.h:77
bool isCrossing() const
return whether this edge is a pedestrian crossing
Definition: MSEdge.h:261
bool isWalkingArea() const
return whether this edge is walking area
Definition: MSEdge.h:275
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
Definition: MSEdge.h:166
const PositionVector & getShape() const
Returns this junction's shape.
Definition: MSJunction.h:88
Representation of a lane in the micro simulation.
Definition: MSLane.h:82
const PositionVector & getShape() const
Returns this lane's shape.
Definition: MSLane.h:476
double getWidth() const
Returns the lane's width.
Definition: MSLane.h:555
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
Definition: MSNet.cpp:171
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Definition: MSNet.h:444
MSEdgeControl & getEdgeControl()
Returns the edge control.
Definition: MSNet.h:414
Storage for all programs of a single tls.
void addSwitchCommand(OnSwitchAction *c)
MSTrafficLightLogic * getActive() const
std::vector< std::string > getAllTLIds() const
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
std::vector< LaneVector > LaneVectorVector
Definition of a list that holds lists of lanes that do have the same attribute.
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
The car-following model and parameter.
Definition: MSVehicleType.h:62
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
std::string getOSGFile() const
Get this vehicle type's 3D model file name.
double getMinGap() const
Get the free space in front of vehicles of this class.
double getHeight() const
Get the height which vehicles of this class shall have when being drawn.
double getLength() const
Get vehicle's length [m].
const std::string & getID() const
Returns the id.
Definition: Named.h:73
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:36
double x() const
Returns the x-position.
Definition: Position.h:54
double z() const
Returns the z-position.
Definition: Position.h:64
double y() const
Returns the y-position.
Definition: Position.h:59
A list of positions.
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain ammount
A decal (an image) that can be shown.
double tilt
The tilt of the image to the ground plane (in degrees)
double centerX
The center of the image in x-direction (net coordinates, in m)
double height
The height of the image (net coordinates in y-direction, in m)
double width
The width of the image (net coordinates in x-direction, in m)
double rot
The rotation of the image in the ground plane (in degrees)
double altitude
The altitude of the image (net coordinates in z-direction, in m)
double centerY
The center of the image in y-direction (net coordinates, in m)
double centerZ
The center of the image in z-direction (net coordinates, in m)
std::string filename
The path to the file the image is located at.
double roll
The roll of the image to the ground plane (in degrees)