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);