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