35 #pragma warning(disable: 4127) // do not warn about constant conditional expression 37 #include <osg/Version> 38 #include <osgViewer/ViewerEventHandlers> 39 #include <osgGA/TrackballManipulator> 40 #include <osgDB/ReadFile> 41 #include <osgDB/WriteFile> 42 #include <osg/ShapeDrawable> 46 #include <osg/Geometry> 47 #include <osg/Sequence> 48 #include <osg/Texture2D> 49 #include <osgViewer/Viewer> 50 #include <osgUtil/Tessellator> 51 #include <osg/PositionAttitudeTransform> 52 #include <osg/ShadeModel> 54 #include <osg/LightSource> 82 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
89 GUIOSGBuilder::buildOSGScene(osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu) {
90 osgUtil::Tessellator tesselator;
91 osg::Group* root =
new osg::Group();
95 for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
96 if (!(*i)->isInternal()) {
97 buildOSGEdgeGeometry(**i, *root, tesselator);
107 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
110 const MSLane* lastLane = 0;
112 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
113 const MSLane*
const lane = (*j)[0];
117 if (lane == lastLane) {
121 d.
centerX = pos.
x() - 1.5 * sin(angle);
122 d.
centerY = pos.
y() - 1.5 * cos(angle);
124 osg::Switch* switchNode =
new osg::Switch();
125 switchNode->addChild(getTrafficLight(d, tlg, osg::Vec4d(0.1, 0.5, 0.1, 1.0), .25),
false);
126 switchNode->addChild(getTrafficLight(d, tly, osg::Vec4d(0.5, 0.5, 0.1, 1.0), .25),
false);
127 switchNode->addChild(getTrafficLight(d, tlr, osg::Vec4d(0.5, 0.1, 0.1, 1.0), .25),
false);
128 switchNode->addChild(getTrafficLight(d, tlu, osg::Vec4d(0.8, 0.4, 0.0, 1.0), .25),
false);
129 root->addChild(switchNode);
142 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
144 light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
145 light->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0));
146 light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
147 light->setAmbient(osg::Vec4(1.0, 1.0, 1.0, 1.0));
149 osg::LightSource* lightSource =
new osg::LightSource();
150 lightSource->setLight(light);
151 lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
152 lightSource->setStateSetModes(*addTo.getOrCreateStateSet(), osg::StateAttribute::ON);
154 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
155 lightTransform->addChild(lightSource);
157 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
158 addTo.addChild(lightTransform);
163 GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
165 osgUtil::Tessellator& tessellator) {
166 const std::vector<MSLane*>& lanes = edge.
getLanes();
167 for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
170 osg::Geode* geode =
new osg::Geode();
171 osg::Geometry* geom =
new osg::Geometry();
172 geode->addDrawable(geom);
173 addTo.addChild(geode);
174 osg::Vec3dArray* osg_coords =
new osg::Vec3dArray((
int)shape.size() * 2);
175 geom->setVertexArray(osg_coords);
179 for (
int k = 0; k < (int)rshape.size(); ++k, ++index) {
180 (*osg_coords)[index].set(rshape[k].x(), rshape[k].y(), rshape[k].z());
184 for (
int k = (
int) lshape.size() - 1; k >= 0; --k, ++index) {
185 (*osg_coords)[index].set(lshape[k].x(), lshape[k].y(), lshape[k].z());
187 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
188 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
189 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 190 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
192 geom->setNormalArray(osg_normals);
193 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
195 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
196 (*osg_colors)[0].set(128, 128, 128, 255);
197 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 198 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
200 geom->setColorArray(osg_colors);
201 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
203 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size() * 2));
205 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
206 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
207 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
209 if (shape.size() > 2) {
210 tessellator.retessellatePolygons(*geom);
212 static_cast<GUILane*
>(l)->setGeometry(geom);
220 osgUtil::Tessellator& tessellator) {
222 osg::Geode* geode =
new osg::Geode();
223 osg::Geometry* geom =
new osg::Geometry();
224 geode->addDrawable(geom);
225 addTo.addChild(geode);
226 osg::Vec3dArray* osg_coords =
new osg::Vec3dArray((
int)shape.size());
227 geom->setVertexArray(osg_coords);
228 for (
int k = 0; k < (int)shape.size(); ++k) {
229 (*osg_coords)[k].set(shape[k].x(), shape[k].y(), shape[k].z());
231 osg::Vec3dArray* osg_normals =
new osg::Vec3dArray(1);
232 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
233 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 234 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
236 geom->setNormalArray(osg_normals);
237 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
239 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
240 (*osg_colors)[0].set(128, 128, 128, 255);
241 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 242 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
244 geom->setColorArray(osg_colors);
245 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
247 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
249 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
250 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
251 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
253 if (shape.size() > 4) {
254 tessellator.retessellatePolygons(*geom);
256 junction.setGeometry(geom);
262 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
263 if (pLoadedModel == 0) {
267 osg::ShadeModel* sm =
new osg::ShadeModel();
268 sm->setMode(osg::ShadeModel::FLAT);
269 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
270 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
271 base->addChild(pLoadedModel);
272 GUIOSGBoundingBoxCalculator bboxCalc;
273 pLoadedModel->accept(bboxCalc);
274 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
276 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
277 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
278 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
280 xScale = yScale = zScale;
282 base->setScale(osg::Vec3d(xScale, yScale, zScale));
284 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3d(1, 0, 0),
285 osg::DegreesToRadians(d.
tilt), osg::Vec3d(0, 1, 0),
286 osg::DegreesToRadians(d.
rot), osg::Vec3d(0, 0, 1)));
287 addTo.addChild(base);
291 osg::PositionAttitudeTransform*
292 GUIOSGBuilder::getTrafficLight(
const GUISUMOAbstractView::Decal& d, osg::Node* tl,
const osg::Vec4& color,
const double size) {
293 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
295 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
297 GUIOSGBoundingBoxCalculator bboxCalc;
298 tl->accept(bboxCalc);
299 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
300 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
301 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
302 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
304 xScale = yScale = zScale;
306 base->setScale(osg::Vec3d(xScale, yScale, zScale));
308 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
309 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
310 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
313 osg::Geode* geode =
new osg::Geode();
315 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, (
float)size));
316 geode->addDrawable(shape);
317 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
318 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
319 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
320 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
321 ellipse->addChild(geode);
322 ellipse->setPivotPoint(center);
323 ellipse->setPosition(center);
324 ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.
altitude + 1.1));
325 shape->setColor(color);
326 ret->addChild(ellipse);
332 GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
333 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
334 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
335 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
339 GUIOSGView::OSGMovable
341 GUIOSGView::OSGMovable m;
342 m.pos =
new osg::PositionAttitudeTransform();
344 const std::string& osgFile = type.
getOSGFile();
345 if (myCars.find(osgFile) == myCars.end()) {
346 myCars[osgFile] = osgDB::readNodeFile(osgFile);
347 if (myCars[osgFile] == 0) {
351 osg::Node* carNode = myCars[osgFile];
353 GUIOSGBoundingBoxCalculator bboxCalc;
354 carNode->accept(bboxCalc);
355 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
356 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
357 base->addChild(carNode);
358 base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
359 base->setScale(osg::Vec3d(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
360 type.
getLength() / (bbox.yMax() - bbox.yMin()),
361 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
362 m.pos->addChild(base);
365 m.lights =
new osg::Switch();
366 for (
double offset = -0.3; offset < 0.5; offset += 0.6) {
367 osg::Geode* geode =
new osg::Geode();
368 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3d(offset, (type.
getLength() - .9) / 2., (type.
getHeight() - .5) / 2.), .1f));
369 geode->addDrawable(right);
370 setShapeState(right);
371 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
372 osg::Sequence* seq =
new osg::Sequence();
374 seq->addChild(geode, .33);
375 seq->addChild(
new osg::Geode(), .33);
377 seq->setInterval(osg::Sequence::LOOP, 0, -1);
379 seq->setDuration(1.0f, -1);
381 seq->setMode(osg::Sequence::START);
382 m.lights->addChild(seq);
385 osg::Geode* geode =
new osg::Geode();
386 osg::CompositeShape* comp =
new osg::CompositeShape();
387 comp->addChild(
new osg::Sphere(osg::Vec3d(-0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
388 comp->addChild(
new osg::Sphere(osg::Vec3d(0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
389 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
390 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
391 geode->addDrawable(brake);
392 setShapeState(brake);
393 m.lights->addChild(geode);
395 geode =
new osg::Geode();
397 m.geom =
new osg::ShapeDrawable(
new osg::Sphere(center, .5f));
398 geode->addDrawable(m.geom);
399 setShapeState(m.geom);
400 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
401 ellipse->addChild(geode);
402 ellipse->addChild(m.lights);
403 ellipse->setPivotPoint(center);
404 ellipse->setPosition(center);
406 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.
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
#define WRITE_MESSAGE(msg)
Representation of a lane in the micro simulation.
const PositionVector & getShape() const
Returns this junction's shape.