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> 49 #include <osg/ComputeBoundsVisitor> 78 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
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();
91 if (!e->isInternal()) {
92 buildOSGEdgeGeometry(*e, *root, tesselator);
102 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
105 const MSLane* lastLane = 0;
107 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
108 if ((*j).size() == 0) {
111 const MSLane*
const lane = (*j)[0];
115 if (lane == lastLane) {
119 d.
centerX = pos.
x() - 1.5 * sin(angle);
120 d.
centerY = pos.
y() - 1.5 * cos(angle);
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);
140 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
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));
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);
152 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
153 lightTransform->addChild(lightSource);
155 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
156 addTo.addChild(lightTransform);
161 GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
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) {
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);
174 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shapeSize);
175 geom->setVertexArray(osg_coords);
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);
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);
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);
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);
199 geom->setNormalArray(osg_normals);
200 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
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);
207 geom->setColorArray(osg_colors);
208 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
210 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shapeSize));
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);
216 if (shape.size() > 2) {
217 tessellator.retessellatePolygons(*geom);
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() <<
" ";
227 static_cast<GUILane*
>(l)->setGeometry(geom);
235 osgUtil::Tessellator& tessellator) {
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());
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);
251 geom->setNormalArray(osg_normals);
252 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
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);
259 geom->setColorArray(osg_colors);
260 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
262 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
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);
268 if (shape.size() > 4) {
269 tessellator.retessellatePolygons(*geom);
271 junction.setGeometry(geom);
277 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
278 if (pLoadedModel ==
nullptr) {
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();
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.;
295 xScale = yScale = zScale;
297 base->setScale(osg::Vec3d(xScale, yScale, zScale));
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);
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();
310 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
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.;
319 xScale = yScale = zScale;
321 base->setScale(osg::Vec3d(xScale, yScale, zScale));
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)));
328 osg::Geode* geode =
new osg::Geode();
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);
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);
354 GUIOSGView::OSGMovable
356 GUIOSGView::OSGMovable m;
357 m.pos =
new osg::PositionAttitudeTransform();
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) {
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);
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();
389 seq->addChild(geode, .33);
390 seq->addChild(
new osg::Geode(), .33);
392 seq->setInterval(osg::Sequence::LOOP, 0, -1);
394 seq->setDuration(1.0f, -1);
396 seq->setMode(osg::Sequence::START);
397 m.lights->addChild(seq);
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);
410 geode =
new osg::Geode();
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);
421 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 std::string & getID() const
Returns the id.
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.
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
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.