36 #pragma warning(disable: 4127) // do not warn about constant conditional expression 38 #include <osg/Version> 39 #include <osgViewer/ViewerEventHandlers> 40 #include <osgGA/TrackballManipulator> 41 #include <osgDB/ReadFile> 42 #include <osgDB/WriteFile> 43 #include <osg/ShapeDrawable> 47 #include <osg/Geometry> 48 #include <osg/Sequence> 49 #include <osg/Texture2D> 50 #include <osgViewer/Viewer> 51 #include <osgUtil/Tessellator> 52 #include <osg/PositionAttitudeTransform> 53 #include <osg/ShadeModel> 55 #include <osg/LightSource> 83 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
90 GUIOSGBuilder::buildOSGScene(osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu) {
91 osgUtil::Tessellator tesselator;
92 osg::Group* root =
new osg::Group();
96 for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
98 buildOSGEdgeGeometry(**i, *root, tesselator);
108 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
111 const MSLane* lastLane = 0;
113 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
114 const MSLane*
const lane = (*j)[0];
118 if (lane == lastLane) {
122 d.
centerX = pos.
x() - 1.5 * sin(angle);
123 d.
centerY = pos.
y() - 1.5 * cos(angle);
125 osg::Switch* switchNode =
new osg::Switch();
126 switchNode->addChild(getTrafficLight(d, tlg, osg::Vec4d(0.1, 0.5, 0.1, 1.0), .25),
false);
127 switchNode->addChild(getTrafficLight(d, tly, osg::Vec4d(0.5, 0.5, 0.1, 1.0), .25),
false);
128 switchNode->addChild(getTrafficLight(d, tlr, osg::Vec4d(0.5, 0.1, 0.1, 1.0), .25),
false);
129 switchNode->addChild(getTrafficLight(d, tlu, osg::Vec4d(0.8, 0.4, 0.0, 1.0), .25),
false);
130 root->addChild(switchNode);
143 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
145 light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
146 light->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0));
147 light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
148 light->setAmbient(osg::Vec4(1.0, 1.0, 1.0, 1.0));
150 osg::LightSource* lightSource =
new osg::LightSource();
151 lightSource->setLight(light);
152 lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
153 lightSource->setStateSetModes(*addTo.getOrCreateStateSet(), osg::StateAttribute::ON);
155 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
156 lightTransform->addChild(lightSource);
158 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
159 addTo.addChild(lightTransform);
164 GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
166 osgUtil::Tessellator& tessellator) {
167 const std::vector<MSLane*>& lanes = edge.
getLanes();
168 for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
171 osg::Geode* geode =
new osg::Geode();
172 osg::Geometry* geom =
new osg::Geometry();
173 geode->addDrawable(geom);
174 addTo.addChild(geode);
175 osg::Vec3dArray* osg_coords =
new osg::Vec3dArray((
int)shape.size() * 2);
176 geom->setVertexArray(osg_coords);
180 for (
int k = 0; k < (int)rshape.size(); ++k, ++index) {
181 (*osg_coords)[index].set(rshape[k].x(), rshape[k].y(), rshape[k].z());
185 for (
int k = (
int) lshape.size() - 1; k >= 0; --k, ++index) {
186 (*osg_coords)[index].set(lshape[k].x(), lshape[k].y(), lshape[k].z());
188 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
189 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
190 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 191 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
193 geom->setNormalArray(osg_normals);
194 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
196 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
197 (*osg_colors)[0].set(128, 128, 128, 255);
198 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 199 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
201 geom->setColorArray(osg_colors);
202 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
204 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size() * 2));
206 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
207 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
208 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
210 if (shape.size() > 2) {
211 tessellator.retessellatePolygons(*geom);
213 static_cast<GUILane*
>(l)->setGeometry(geom);
221 osgUtil::Tessellator& tessellator) {
223 osg::Geode* geode =
new osg::Geode();
224 osg::Geometry* geom =
new osg::Geometry();
225 geode->addDrawable(geom);
226 addTo.addChild(geode);
227 osg::Vec3dArray* osg_coords =
new osg::Vec3dArray((
int)shape.size());
228 geom->setVertexArray(osg_coords);
229 for (
int k = 0; k < (int)shape.size(); ++k) {
230 (*osg_coords)[k].set(shape[k].x(), shape[k].y(), shape[k].z());
232 osg::Vec3dArray* osg_normals =
new osg::Vec3dArray(1);
233 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
234 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 235 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
237 geom->setNormalArray(osg_normals);
238 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
240 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
241 (*osg_colors)[0].set(128, 128, 128, 255);
242 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 243 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
245 geom->setColorArray(osg_colors);
246 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
248 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
250 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
251 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
252 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
254 if (shape.size() > 4) {
255 tessellator.retessellatePolygons(*geom);
257 junction.setGeometry(geom);
263 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
264 if (pLoadedModel == 0) {
268 osg::ShadeModel* sm =
new osg::ShadeModel();
269 sm->setMode(osg::ShadeModel::FLAT);
270 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
271 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
272 base->addChild(pLoadedModel);
273 GUIOSGBoundingBoxCalculator bboxCalc;
274 pLoadedModel->accept(bboxCalc);
275 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
277 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
278 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
279 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
281 xScale = yScale = zScale;
283 base->setScale(osg::Vec3d(xScale, yScale, zScale));
285 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3d(1, 0, 0),
286 osg::DegreesToRadians(d.
tilt), osg::Vec3d(0, 1, 0),
287 osg::DegreesToRadians(d.
rot), osg::Vec3d(0, 0, 1)));
288 addTo.addChild(base);
292 osg::PositionAttitudeTransform*
293 GUIOSGBuilder::getTrafficLight(
const GUISUMOAbstractView::Decal& d, osg::Node* tl,
const osg::Vec4& color,
const double size) {
294 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
296 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
298 GUIOSGBoundingBoxCalculator bboxCalc;
299 tl->accept(bboxCalc);
300 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
301 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
302 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
303 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
305 xScale = yScale = zScale;
307 base->setScale(osg::Vec3d(xScale, yScale, zScale));
309 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
310 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
311 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
314 osg::Geode* geode =
new osg::Geode();
316 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, (
float)size));
317 geode->addDrawable(shape);
318 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
319 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
320 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
321 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
322 ellipse->addChild(geode);
323 ellipse->setPivotPoint(center);
324 ellipse->setPosition(center);
325 ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.
altitude + 1.1));
326 shape->setColor(color);
327 ret->addChild(ellipse);
333 GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
334 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
335 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
336 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
340 GUIOSGView::OSGMovable
342 GUIOSGView::OSGMovable m;
343 m.pos =
new osg::PositionAttitudeTransform();
345 const std::string& osgFile = type.
getOSGFile();
346 if (myCars.find(osgFile) == myCars.end()) {
347 myCars[osgFile] = osgDB::readNodeFile(osgFile);
348 if (myCars[osgFile] == 0) {
352 osg::Node* carNode = myCars[osgFile];
354 GUIOSGBoundingBoxCalculator bboxCalc;
355 carNode->accept(bboxCalc);
356 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
357 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
358 base->addChild(carNode);
359 base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
360 base->setScale(osg::Vec3d(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
361 type.
getLength() / (bbox.yMax() - bbox.yMin()),
362 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
363 m.pos->addChild(base);
366 m.lights =
new osg::Switch();
367 for (
double offset = -0.3; offset < 0.5; offset += 0.6) {
368 osg::Geode* geode =
new osg::Geode();
369 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3d(offset, (type.
getLength() - .9) / 2., (type.
getHeight() - .5) / 2.), .1f));
370 geode->addDrawable(right);
371 setShapeState(right);
372 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
373 osg::Sequence* seq =
new osg::Sequence();
375 seq->addChild(geode, .33);
376 seq->addChild(
new osg::Geode(), .33);
378 seq->setInterval(osg::Sequence::LOOP, 0, -1);
380 seq->setDuration(1.0f, -1);
382 seq->setMode(osg::Sequence::START);
383 m.lights->addChild(seq);
386 osg::Geode* geode =
new osg::Geode();
387 osg::CompositeShape*
comp =
new osg::CompositeShape();
388 comp->addChild(
new osg::Sphere(osg::Vec3d(-0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
389 comp->addChild(
new osg::Sphere(osg::Vec3d(0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
390 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
391 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
392 geode->addDrawable(brake);
393 setShapeState(brake);
394 m.lights->addChild(geode);
396 geode =
new osg::Geode();
398 m.geom =
new osg::ShapeDrawable(
new osg::Sphere(center, .5f));
399 geode->addDrawable(m.geom);
400 setShapeState(m.geom);
401 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
402 ellipse->addChild(geode);
403 ellipse->addChild(m.lights);
404 ellipse->setPivotPoint(center);
405 ellipse->setPosition(center);
407 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)
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)
const double SUMO_const_halfLaneWidth
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.
static int comp(const void *key, const void *target)
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)
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.
std::vector< MSEdge * > MSEdgeVector
MSTrafficLightLogic * getActive() const
std::vector< std::string > getAllTLIds() const
The edge is an internal edge.
#define WRITE_MESSAGE(msg)
Representation of a lane in the micro simulation.
const PositionVector & getShape() const
Returns this junction's shape.