34 #include <osg/Version>
35 #include <osgViewer/ViewerEventHandlers>
36 #include <osgGA/TrackballManipulator>
37 #include <osgDB/ReadFile>
38 #include <osgDB/WriteFile>
39 #include <osg/ShapeDrawable>
43 #include <osg/Geometry>
44 #include <osg/Sequence>
45 #include <osg/Texture2D>
46 #include <osgViewer/Viewer>
47 #include <osgUtil/Tessellator>
48 #include <osg/PositionAttitudeTransform>
49 #include <osg/ShadeModel>
51 #include <osg/LightSource>
71 #ifdef CHECK_MEMORY_LEAKS
73 #endif // CHECK_MEMORY_LEAKS
79 std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
86 GUIOSGBuilder::buildOSGScene(osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu) {
87 osgUtil::Tessellator tesselator;
88 osg::Group* root =
new osg::Group();
92 for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
94 buildOSGEdgeGeometry(**i, *root, tesselator);
104 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
107 const MSLane* lastLane = 0;
109 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
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::Vec4(0.1, 0.5, 0.1, 1.0), .25),
false);
123 switchNode->addChild(getTrafficLight(d, tly, osg::Vec4(0.5, 0.5, 0.1, 1.0), .25),
false);
124 switchNode->addChild(getTrafficLight(d, tlr, osg::Vec4(0.5, 0.1, 0.1, 1.0), .25),
false);
125 switchNode->addChild(getTrafficLight(d, tlu, osg::Vec4(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::Vec3(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 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shape.size() * 2);
172 geom->setVertexArray(osg_coords);
176 for (
int k = 0; k < (int)rshape.size(); ++k, ++index) {
177 (*osg_coords)[index].set(rshape[k].x(), rshape[k].y(), rshape[k].z());
181 for (
int k = (
int) lshape.size() - 1; k >= 0; --k, ++index) {
182 (*osg_coords)[index].set(lshape[k].x(), lshape[k].y(), lshape[k].z());
184 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
185 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
186 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
187 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
189 geom->setNormalArray(osg_normals);
190 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
192 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
193 (*osg_colors)[0].set(128, 128, 128, 255);
194 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
195 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
197 geom->setColorArray(osg_colors);
198 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
200 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shape.size() * 2));
202 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
203 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
204 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
206 if (shape.size() > 2) {
207 tessellator.retessellatePolygons(*geom);
209 static_cast<GUILane*
>(l)->setGeometry(geom);
217 osgUtil::Tessellator& tessellator) {
219 osg::Geode* geode =
new osg::Geode();
220 osg::Geometry* geom =
new osg::Geometry();
221 geode->addDrawable(geom);
222 addTo.addChild(geode);
223 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shape.size());
224 geom->setVertexArray(osg_coords);
225 for (
int k = 0; k < (int)shape.size(); ++k) {
226 (*osg_coords)[k].set(shape[k].x(), shape[k].y(), shape[k].z());
228 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
229 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
230 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
231 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
233 geom->setNormalArray(osg_normals);
234 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
236 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
237 (*osg_colors)[0].set(128, 128, 128, 255);
238 #if OSG_MIN_VERSION_REQUIRED(3,2,0)
239 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
241 geom->setColorArray(osg_colors);
242 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
244 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shape.size()));
246 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
247 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
248 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
250 if (shape.size() > 4) {
251 tessellator.retessellatePolygons(*geom);
253 junction.setGeometry(geom);
259 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
260 if (pLoadedModel == 0) {
264 osg::ShadeModel* sm =
new osg::ShadeModel();
265 sm->setMode(osg::ShadeModel::FLAT);
266 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
267 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
268 base->addChild(pLoadedModel);
269 GUIOSGBoundingBoxCalculator bboxCalc;
270 pLoadedModel->accept(bboxCalc);
271 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
277 xScale = yScale = zScale;
279 base->setScale(osg::Vec3(xScale, yScale, zScale));
281 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
282 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
283 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
284 addTo.addChild(base);
288 osg::PositionAttitudeTransform*
290 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
292 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
294 GUIOSGBoundingBoxCalculator bboxCalc;
295 tl->accept(bboxCalc);
296 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
301 xScale = yScale = zScale;
303 base->setScale(osg::Vec3(xScale, yScale, zScale));
305 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
306 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
307 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
310 osg::Geode* geode =
new osg::Geode();
312 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, size));
313 geode->addDrawable(shape);
314 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
315 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
316 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
317 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
318 ellipse->addChild(geode);
319 ellipse->setPivotPoint(center);
320 ellipse->setPosition(center);
321 ellipse->setScale(osg::Vec3(4., 4., 2.5 * d.
altitude + 1.1));
322 shape->setColor(color);
323 ret->addChild(ellipse);
329 GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
330 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
331 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
332 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
336 GUIOSGView::OSGMovable
338 GUIOSGView::OSGMovable m;
339 m.pos =
new osg::PositionAttitudeTransform();
341 const std::string& osgFile = type.
getOSGFile();
342 if (myCars.find(osgFile) == myCars.end()) {
343 myCars[osgFile] = osgDB::readNodeFile(osgFile);
344 if (myCars[osgFile] == 0) {
348 osg::Node* carNode = myCars[osgFile];
350 GUIOSGBoundingBoxCalculator bboxCalc;
351 carNode->accept(bboxCalc);
352 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
353 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
354 base->addChild(carNode);
355 base->setPivotPoint(osg::Vec3((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
356 base->setScale(osg::Vec3(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
357 type.
getLength() / (bbox.yMax() - bbox.yMin()),
358 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
359 m.pos->addChild(base);
362 m.lights =
new osg::Switch();
363 for (
SUMOReal offset = -0.3; offset < 0.5; offset += 0.6) {
364 osg::Geode* geode =
new osg::Geode();
365 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3(offset, (type.
getLength() - .9) / 2., (type.
getHeight() - .5) / 2.), .1f));
366 geode->addDrawable(right);
367 setShapeState(right);
368 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
369 osg::Sequence* seq =
new osg::Sequence();
371 seq->addChild(geode, .33);
372 seq->addChild(
new osg::Geode(), .33);
374 seq->setInterval(osg::Sequence::LOOP, 0, -1);
376 seq->setDuration(1.0f, -1);
378 seq->setMode(osg::Sequence::START);
379 m.lights->addChild(seq);
382 osg::Geode* geode =
new osg::Geode();
383 osg::CompositeShape*
comp =
new osg::CompositeShape();
384 comp->addChild(
new osg::Sphere(osg::Vec3(-0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
385 comp->addChild(
new osg::Sphere(osg::Vec3(0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
386 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
387 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
388 geode->addDrawable(brake);
389 setShapeState(brake);
390 m.lights->addChild(geode);
392 geode =
new osg::Geode();
394 m.geom =
new osg::ShapeDrawable(
new osg::Sphere(center, .5f));
395 geode->addDrawable(m.geom);
396 setShapeState(m.geom);
397 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
398 ellipse->addChild(geode);
399 ellipse->addChild(m.lights);
400 ellipse->setPivotPoint(center);
401 ellipse->setPosition(center);
403 m.pos->addChild(ellipse);
A decal (an image) that can be shown.
SUMOReal roll
The roll of the image to the ground plane (in degrees)
Storage for all programs of a single tls.
std::vector< GUIJunctionWrapper * > myJunctionWrapper
Wrapped MS-junctions.
std::string getOSGFile() const
Get this vehicle type's 3D model file name.
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
const PositionVector & getShape() const
Returns this junction's shape.
SUMOReal getLength() const
Get vehicle's length [m].
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
std::vector< std::string > getAllTLIds() const
SUMOReal centerZ
The center of the image in z-direction (net coordinates, in m)
SUMOReal width
The width of the image (net coordinates in x-direction, in m)
SUMOReal getHeight() const
Get the height which vehicles of this class shall have when being drawn.
SUMOReal x() const
Returns the x-position.
The car-following model and parameter.
Representation of a lane in the micro simulation (gui-version)
A road/street connecting two junctions.
void addSwitchCommand(OnSwitchAction *c)
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
MSTrafficLightLogic * getActive() const
SUMOReal altitude
The altitude of the image (net coordinates in z-direction, in m)
SUMOReal getMinGap() const
Get the free space in front of vehicles of this class.
A point in 2D or 3D with translation and scaling methods.
SUMOReal centerY
The center of the image in y-direction (net coordinates, in m)
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
SUMOReal z() const
Returns the z-position.
std::string filename
The path to the file the image is located at.
static int comp(const void *key, const void *target)
std::string toString(const T &t, std::streamsize accuracy=OUTPUT_ACCURACY)
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
SUMOReal height
The height of the image (net coordinates in y-direction, in m)
SUMOReal getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOReal rotationDegreeAtOffset(SUMOReal pos) const
Returns the rotation at the given length.
SUMOReal centerX
The center of the image in x-direction (net coordinates, in m)
std::vector< LaneVector > LaneVectorVector
Definition of a list that holds lists of links that do have the same attribute.
A MSNet extended by some values for usage within the gui.
SUMOReal y() const
Returns the y-position.
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
const PositionVector & getShape() const
Returns this lane's shape.
void move2side(SUMOReal amount)
move position vector to side using certain ammount
MSEdgeControl & getEdgeControl()
Returns the edge control.
SUMOReal tilt
The tilt of the image to the ground plane (in degrees)
std::vector< MSEdge * > MSEdgeVector
const SUMOReal SUMO_const_halfLaneWidth
The edge is an internal edge.
#define WRITE_MESSAGE(msg)
const MSJunction & getJunction() const
Returns the represented junction.
Representation of a lane in the micro simulation.
SUMOReal rot
The rotation of the image in the ground plane (in degrees)
const MSEdgeVector & getEdges() const
Returns loaded edges.