33 #include <osg/Version> 34 #include <osgViewer/ViewerEventHandlers> 35 #include <osgGA/TrackballManipulator> 36 #include <osgDB/ReadFile> 37 #include <osgDB/WriteFile> 38 #include <osg/ShapeDrawable> 42 #include <osg/Geometry> 43 #include <osg/Sequence> 44 #include <osg/Texture2D> 45 #include <osgViewer/Viewer> 46 #include <osgUtil/Tessellator> 47 #include <osg/PositionAttitudeTransform> 48 #include <osg/ShadeModel> 50 #include <osg/LightSource> 70 #ifdef CHECK_MEMORY_LEAKS 72 #endif // CHECK_MEMORY_LEAKS 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 for (MSEdgeVector::const_iterator i = edges.begin(); i != edges.end(); ++i) {
93 buildOSGEdgeGeometry(**i, *root, tesselator);
103 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
106 const MSLane* lastLane = 0;
108 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
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::Vec4(0.1, 0.5, 0.1, 1.0), .25),
false);
122 switchNode->addChild(getTrafficLight(d, tly, osg::Vec4(0.5, 0.5, 0.1, 1.0), .25),
false);
123 switchNode->addChild(getTrafficLight(d, tlr, osg::Vec4(0.5, 0.1, 0.1, 1.0), .25),
false);
124 switchNode->addChild(getTrafficLight(d, tlu, osg::Vec4(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::Vec3(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 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shape.size() * 2);
171 geom->setVertexArray(osg_coords);
175 for (
unsigned int k = 0; k < rshape.size(); ++k, ++index) {
176 (*osg_coords)[index].set(rshape[k].x(), rshape[k].y(), rshape[k].z());
180 for (
int k = (
int) lshape.size() - 1; k >= 0; --k, ++index) {
181 (*osg_coords)[index].set(lshape[k].x(), lshape[k].y(), lshape[k].z());
183 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
184 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
185 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 186 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
188 geom->setNormalArray(osg_normals);
189 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
191 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
192 (*osg_colors)[0].set(128, 128, 128, 255);
193 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 194 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
196 geom->setColorArray(osg_colors);
197 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
199 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shape.size() * 2));
201 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
202 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
203 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
205 if (shape.size() > 2) {
206 tessellator.retessellatePolygons(*geom);
208 static_cast<GUILane*
>(l)->setGeometry(geom);
216 osgUtil::Tessellator& tessellator) {
218 osg::Geode* geode =
new osg::Geode();
219 osg::Geometry* geom =
new osg::Geometry();
220 geode->addDrawable(geom);
221 addTo.addChild(geode);
222 osg::Vec3Array* osg_coords =
new osg::Vec3Array(shape.size());
223 geom->setVertexArray(osg_coords);
224 for (
unsigned int k = 0; k < shape.size(); ++k) {
225 (*osg_coords)[k].set(shape[k].x(), shape[k].y(), shape[k].z());
227 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
228 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
229 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 230 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
232 geom->setNormalArray(osg_normals);
233 geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE);
235 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
236 (*osg_colors)[0].set(128, 128, 128, 255);
237 #if OSG_MIN_VERSION_REQUIRED(3,2,0) 238 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
240 geom->setColorArray(osg_colors);
241 geom->setColorBinding(osg::Geometry::BIND_OVERALL);
243 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, shape.size()));
245 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
246 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
247 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
249 if (shape.size() > 4) {
250 tessellator.retessellatePolygons(*geom);
252 junction.setGeometry(geom);
258 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
259 if (pLoadedModel == 0) {
263 osg::ShadeModel* sm =
new osg::ShadeModel();
264 sm->setMode(osg::ShadeModel::FLAT);
265 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
266 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
267 base->addChild(pLoadedModel);
268 GUIOSGBoundingBoxCalculator bboxCalc;
269 pLoadedModel->accept(bboxCalc);
270 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
276 xScale = yScale = zScale;
278 base->setScale(osg::Vec3(xScale, yScale, zScale));
280 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
281 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
282 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
283 addTo.addChild(base);
287 osg::PositionAttitudeTransform*
289 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
291 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
293 GUIOSGBoundingBoxCalculator bboxCalc;
294 tl->accept(bboxCalc);
295 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
300 xScale = yScale = zScale;
302 base->setScale(osg::Vec3(xScale, yScale, zScale));
304 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
305 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
306 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
309 osg::Geode* geode =
new osg::Geode();
311 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, size));
312 geode->addDrawable(shape);
313 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
314 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
315 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
316 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
317 ellipse->addChild(geode);
318 ellipse->setPivotPoint(center);
319 ellipse->setPosition(center);
320 ellipse->setScale(osg::Vec3(4., 4., 2.5 * d.
altitude + 1.1));
321 shape->setColor(color);
322 ret->addChild(ellipse);
328 GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
329 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
330 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
331 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
335 GUIOSGView::OSGMovable
337 GUIOSGView::OSGMovable m;
338 m.pos =
new osg::PositionAttitudeTransform();
340 const std::string& osgFile = type.
getOSGFile();
341 if (myCars.find(osgFile) == myCars.end()) {
342 myCars[osgFile] = osgDB::readNodeFile(osgFile);
343 if (myCars[osgFile] == 0) {
347 osg::Node* carNode = myCars[osgFile];
349 GUIOSGBoundingBoxCalculator bboxCalc;
350 carNode->accept(bboxCalc);
351 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
352 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
353 base->addChild(carNode);
354 base->setPivotPoint(osg::Vec3((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
355 base->setScale(osg::Vec3(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
356 type.
getLength() / (bbox.yMax() - bbox.yMin()),
357 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
358 m.pos->addChild(base);
361 m.lights =
new osg::Switch();
362 for (
SUMOReal offset = -0.3; offset < 0.5; offset += 0.6) {
363 osg::Geode* geode =
new osg::Geode();
364 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3(offset, (type.
getLength() - .9) / 2., (type.
getHeight() - .5) / 2.), .1f));
365 geode->addDrawable(right);
366 setShapeState(right);
367 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
368 osg::Sequence* seq =
new osg::Sequence();
370 seq->addChild(geode, .33);
371 seq->addChild(
new osg::Geode(), .33);
373 seq->setInterval(osg::Sequence::LOOP, 0, -1);
375 seq->setDuration(1.0f, -1);
377 seq->setMode(osg::Sequence::START);
378 m.lights->addChild(seq);
381 osg::Geode* geode =
new osg::Geode();
382 osg::CompositeShape*
comp =
new osg::CompositeShape();
383 comp->addChild(
new osg::Sphere(osg::Vec3(-0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
384 comp->addChild(
new osg::Sphere(osg::Vec3(0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
385 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
386 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
387 geode->addDrawable(brake);
388 setShapeState(brake);
389 m.lights->addChild(geode);
391 geode =
new osg::Geode();
393 m.geom =
new osg::ShapeDrawable(
new osg::Sphere(center, .5f));
394 geode->addDrawable(m.geom);
395 setShapeState(m.geom);
396 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
397 ellipse->addChild(geode);
398 ellipse->addChild(m.lights);
399 ellipse->setPivotPoint(center);
400 ellipse->setPosition(center);
402 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)
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.
const LinkVector & getLinksAt(unsigned int i) const
Returns the list of links that are controlled by the signals at the given position.
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)
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.