27 #pragma warning(disable: 4127)
28 #pragma warning(disable: 4275)
30 #include <osg/Version>
31 #include <osgViewer/ViewerEventHandlers>
32 #include <osgGA/TrackballManipulator>
33 #include <osgDB/ReadFile>
34 #include <osgDB/WriteFile>
35 #include <osg/ShapeDrawable>
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>
47 #include <osg/LightSource>
48 #include <osg/ComputeBoundsVisitor>
77 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
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();
90 if (!e->isInternal()) {
91 buildOSGEdgeGeometry(*e, *root, tesselator);
101 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
104 const MSLane* lastLane = 0;
106 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
107 if ((*j).size() == 0) {
110 const MSLane*
const lane = (*j)[0];
114 if (lane == lastLane) {
118 d.
centerX = pos.
x() - 1.5 * sin(angle);
119 d.
centerY = pos.
y() - 1.5 * cos(angle);
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);
139 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
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));
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);
151 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
152 lightTransform->addChild(lightSource);
154 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
155 addTo.addChild(lightTransform);
160 GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
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) {
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);
173 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shapeSize);
174 geom->setVertexArray(osg_coords);
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);
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);
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);
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);
198 geom->setNormalArray(osg_normals);
199 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
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);
206 geom->setColorArray(osg_colors);
207 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
209 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shapeSize));
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);
215 if (shape.size() > 2) {
216 tessellator.retessellatePolygons(*geom);
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() <<
" ";
226 static_cast<GUILane*
>(l)->setGeometry(geom);
234 osgUtil::Tessellator& tessellator) {
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());
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);
250 geom->setNormalArray(osg_normals);
251 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
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);
258 geom->setColorArray(osg_colors);
259 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
261 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
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);
267 if (shape.size() > 4) {
268 tessellator.retessellatePolygons(*geom);
270 junction.setGeometry(geom);
276 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
277 if (pLoadedModel ==
nullptr) {
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();
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.;
294 xScale = yScale = zScale;
296 base->setScale(osg::Vec3d(xScale, yScale, zScale));
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);
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();
309 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
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.;
318 xScale = yScale = zScale;
320 base->setScale(osg::Vec3d(xScale, yScale, zScale));
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)));
327 osg::Geode* geode =
new osg::Geode();
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);
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);
353 GUIOSGView::OSGMovable
355 GUIOSGView::OSGMovable m;
356 m.pos =
new osg::PositionAttitudeTransform();
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) {
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);
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();
388 seq->addChild(geode, .33);
389 seq->addChild(
new osg::Geode(), .33);
391 seq->setInterval(osg::Sequence::LOOP, 0, -1);
393 seq->setDuration(1.0f, -1);
395 seq->setMode(osg::Sequence::START);
396 m.lights->addChild(seq);
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);
409 geode =
new osg::Geode();
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);
420 m.pos->addChild(ellipse);
#define WRITE_MESSAGE(msg)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
const MSJunction & getJunction() const
Returns the represented junction.
Representation of a lane in the micro simulation (gui-version)
A MSNet extended by some values for usage within the gui.
std::vector< GUIJunctionWrapper * > myJunctionWrapper
Wrapped MS-junctions.
const MSEdgeVector & getEdges() const
Returns loaded edges.
A road/street connecting two junctions.
bool isCrossing() const
return whether this edge is a pedestrian crossing
bool isWalkingArea() const
return whether this edge is walking area
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
const PositionVector & getShape() const
Returns this junction's shape.
Representation of a lane in the micro simulation.
const PositionVector & getShape() const
Returns this lane's shape.
double getWidth() const
Returns the lane's width.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
MSEdgeControl & getEdgeControl()
Returns the edge control.
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.
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.
A point in 2D or 3D with translation and scaling methods.
double x() const
Returns the x-position.
double z() const
Returns the z-position.
double y() const
Returns the y-position.
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)