29 #pragma warning(disable: 4127) // do not warn about constant conditional expression 31 #include <osg/Version> 32 #include <osgViewer/ViewerEventHandlers> 33 #include <osgGA/TrackballManipulator> 34 #include <osgDB/ReadFile> 35 #include <osgDB/WriteFile> 36 #include <osg/ShapeDrawable> 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> 48 #include <osg/LightSource> 76 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
83 GUIOSGBuilder::buildOSGScene(osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu) {
84 osgUtil::Tessellator tesselator;
85 osg::Group* root =
new osg::Group();
89 if (!e->isInternal()) {
90 buildOSGEdgeGeometry(*e, *root, tesselator);
100 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
103 const MSLane* lastLane = 0;
105 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
106 if ((*j).size() == 0) {
109 const MSLane*
const lane = (*j)[0];
113 if (lane == lastLane) {
117 d.
centerX = pos.
x() - 1.5 * sin(angle);
118 d.
centerY = pos.
y() - 1.5 * cos(angle);
120 osg::Switch* switchNode =
new osg::Switch();
121 switchNode->addChild(getTrafficLight(d, tlg, osg::Vec4d(0.1, 0.5, 0.1, 1.0), .25),
false);
122 switchNode->addChild(getTrafficLight(d, tly, osg::Vec4d(0.5, 0.5, 0.1, 1.0), .25),
false);
123 switchNode->addChild(getTrafficLight(d, tlr, osg::Vec4d(0.5, 0.1, 0.1, 1.0), .25),
false);
124 switchNode->addChild(getTrafficLight(d, tlu, osg::Vec4d(0.8, 0.4, 0.0, 1.0), .25),
false);
125 root->addChild(switchNode);
138 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
140 light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
141 light->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0));
142 light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
143 light->setAmbient(osg::Vec4(1.0, 1.0, 1.0, 1.0));
145 osg::LightSource* lightSource =
new osg::LightSource();
146 lightSource->setLight(light);
147 lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
148 lightSource->setStateSetModes(*addTo.getOrCreateStateSet(), osg::StateAttribute::ON);
150 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
151 lightTransform->addChild(lightSource);
153 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
154 addTo.addChild(lightTransform);
159 GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
161 osgUtil::Tessellator& tessellator) {
162 const std::vector<MSLane*>& lanes = edge.
getLanes();
163 for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
166 osg::Geode* geode =
new osg::Geode();
167 osg::Geometry* geom =
new osg::Geometry();
168 geode->addDrawable(geom);
169 addTo.addChild(geode);
170 const int shapeSize = (int)(edge.
isWalkingArea() ? shape.size() : shape.size() * 2);
172 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shapeSize);
173 geom->setVertexArray(osg_coords);
176 for (
int k = 0; k < (int)shape.size(); ++k, ++index) {
177 (*osg_coords)[index].set((
float)shape[k].x(), (
float)shape[k].y(), (
float)shape[k].z() + zOffset);
183 for (
int k = 0; k < (int)rshape.size(); ++k, ++index) {
184 (*osg_coords)[index].set((
float)rshape[k].x(), (
float)rshape[k].y(), (
float)rshape[k].z() + zOffset);
188 for (
int k = (
int) lshape.size() - 1; k >= 0; --k, ++index) {
189 (*osg_coords)[index].set((
float)lshape[k].x(), (
float)lshape[k].y(), (
float)lshape[k].z() + zOffset);
192 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
193 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
194 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 195 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
197 geom->setNormalArray(osg_normals);
198 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
200 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
201 (*osg_colors)[0].set(128, 128, 128, 255);
202 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 203 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
205 geom->setColorArray(osg_colors);
206 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
208 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shapeSize));
210 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
211 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
212 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
214 if (shape.size() > 2) {
215 tessellator.retessellatePolygons(*geom);
217 static_cast<GUILane*
>(l)->setGeometry(geom);
225 osgUtil::Tessellator& tessellator) {
227 osg::Geode* geode =
new osg::Geode();
228 osg::Geometry* geom =
new osg::Geometry();
229 geode->addDrawable(geom);
230 addTo.addChild(geode);
231 osg::Vec3Array* osg_coords =
new osg::Vec3Array((
int)shape.size());
232 geom->setVertexArray(osg_coords);
233 for (
int k = 0; k < (int)shape.size(); ++k) {
234 (*osg_coords)[k].set((
float)shape[k].x(), (
float)shape[k].y(), (
float)shape[k].z());
236 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
237 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
238 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 239 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
241 geom->setNormalArray(osg_normals);
242 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
244 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
245 (*osg_colors)[0].set(128, 128, 128, 255);
246 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 247 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
249 geom->setColorArray(osg_colors);
250 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
252 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
254 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
255 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
256 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
258 if (shape.size() > 4) {
259 tessellator.retessellatePolygons(*geom);
261 junction.setGeometry(geom);
267 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
268 if (pLoadedModel == 0) {
272 osg::ShadeModel* sm =
new osg::ShadeModel();
273 sm->setMode(osg::ShadeModel::FLAT);
274 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
275 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
276 base->addChild(pLoadedModel);
277 GUIOSGBoundingBoxCalculator bboxCalc;
278 pLoadedModel->accept(bboxCalc);
279 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
281 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
282 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
283 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
285 xScale = yScale = zScale;
287 base->setScale(osg::Vec3d(xScale, yScale, zScale));
289 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3d(1, 0, 0),
290 osg::DegreesToRadians(d.
tilt), osg::Vec3d(0, 1, 0),
291 osg::DegreesToRadians(d.
rot), osg::Vec3d(0, 0, 1)));
292 addTo.addChild(base);
296 osg::PositionAttitudeTransform*
297 GUIOSGBuilder::getTrafficLight(
const GUISUMOAbstractView::Decal& d, osg::Node* tl,
const osg::Vec4& color,
const double size) {
298 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
300 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
302 GUIOSGBoundingBoxCalculator bboxCalc;
303 tl->accept(bboxCalc);
304 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
305 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
306 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
307 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
309 xScale = yScale = zScale;
311 base->setScale(osg::Vec3d(xScale, yScale, zScale));
313 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
314 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
315 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
318 osg::Geode* geode =
new osg::Geode();
320 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, (
float)size));
321 geode->addDrawable(shape);
322 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
323 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
324 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
325 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
326 ellipse->addChild(geode);
327 ellipse->setPivotPoint(center);
328 ellipse->setPosition(center);
329 ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.
altitude + 1.1));
330 shape->setColor(color);
331 ret->addChild(ellipse);
337 GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
338 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
339 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
340 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
344 GUIOSGView::OSGMovable
346 GUIOSGView::OSGMovable m;
347 m.pos =
new osg::PositionAttitudeTransform();
349 const std::string& osgFile = type.
getOSGFile();
350 if (myCars.find(osgFile) == myCars.end()) {
351 myCars[osgFile] = osgDB::readNodeFile(osgFile);
352 if (myCars[osgFile] == 0) {
356 osg::Node* carNode = myCars[osgFile];
358 GUIOSGBoundingBoxCalculator bboxCalc;
359 carNode->accept(bboxCalc);
360 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
361 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
362 base->addChild(carNode);
363 base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
364 base->setScale(osg::Vec3d(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
365 type.
getLength() / (bbox.yMax() - bbox.yMin()),
366 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
367 m.pos->addChild(base);
370 m.lights =
new osg::Switch();
371 for (
double offset = -0.3; offset < 0.5; offset += 0.6) {
372 osg::Geode* geode =
new osg::Geode();
373 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3d(offset, (type.
getLength() - .9) / 2., (type.
getHeight() - .5) / 2.), .1f));
374 geode->addDrawable(right);
375 setShapeState(right);
376 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
377 osg::Sequence* seq =
new osg::Sequence();
379 seq->addChild(geode, .33);
380 seq->addChild(
new osg::Geode(), .33);
382 seq->setInterval(osg::Sequence::LOOP, 0, -1);
384 seq->setDuration(1.0f, -1);
386 seq->setMode(osg::Sequence::START);
387 m.lights->addChild(seq);
390 osg::Geode* geode =
new osg::Geode();
391 osg::CompositeShape* comp =
new osg::CompositeShape();
392 comp->addChild(
new osg::Sphere(osg::Vec3d(-0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
393 comp->addChild(
new osg::Sphere(osg::Vec3d(0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
394 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
395 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
396 geode->addDrawable(brake);
397 setShapeState(brake);
398 m.lights->addChild(geode);
400 geode =
new osg::Geode();
402 m.geom =
new osg::ShapeDrawable(
new osg::Sphere(center, .5f));
403 geode->addDrawable(m.geom);
404 setShapeState(m.geom);
405 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
406 ellipse->addChild(geode);
407 ellipse->addChild(m.lights);
408 ellipse->setPivotPoint(center);
409 ellipse->setPosition(center);
411 m.pos->addChild(ellipse);
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.
double z() const
Returns the z-position.
double y() const
Returns the y-position.
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
double x() const
Returns the x-position.
double centerX
The center of the image in x-direction (net coordinates, in m)
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
const PositionVector & getShape() const
Returns this lane's shape.
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's width.
The car-following model and parameter.
Representation of a lane in the micro simulation (gui-version)
double roll
The roll of the image to the ground plane (in degrees)
A road/street connecting two junctions.
void addSwitchCommand(OnSwitchAction *c)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
A point in 2D or 3D with translation and scaling methods.
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
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
void move2side(double amount)
move position vector to side using certain ammount
double width
The width of the image (net coordinates in x-direction, in m)
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.
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'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
MSEdgeControl & getEdgeControl()
Returns the edge control.
std::string getOSGFile() const
Get this vehicle type'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)
Representation of a lane in the micro simulation.
const PositionVector & getShape() const
Returns this junction's shape.