54std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
61GUIOSGBuilder::buildOSGScene(osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu, osg::Node*
const pole) {
62 osgUtil::Tessellator tesselator;
63 osg::Group* root =
new osg::Group();
66 for (
const MSEdge* e : net->getEdgeControl().getEdges()) {
67 if (!e->isInternal()) {
68 buildOSGEdgeGeometry(*e, *root, tesselator);
78 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
80 buildTrafficLightDetails(vars, tlg, tly, tlr, tlu, pole, *root);
83 const MSLane* lastLane = 0;
85 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
86 if ((*j).size() == 0) {
89 const MSLane*
const lane = (*j)[0];
93 if (lane == lastLane) {
97 d.
centerX = pos.
x() - 1.5 * sin(angle);
98 d.
centerY = pos.
y() - 1.5 * cos(angle);
100 osg::PositionAttitudeTransform* tlNode = getTrafficLight(d, vars, vars.
getActive()->
getLinksAt(idx)[0],
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
false, .25, -1, 1.);
101 tlNode->setName(
"tlLogic:" + *i);
102 root->addChild(tlNode);
108 for (
const auto& entry : net->getShapeContainer().getPolygons()) {
109 buildPolygonGeometry(*entry.second, *root, tesselator);
111 for (
const auto& entry : net->getShapeContainer().getPOIs()) {
112 buildPoIGeometry(*entry.second, *root, tesselator);
121 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
123 light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
124 light->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0));
125 light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
126 light->setAmbient(osg::Vec4(1.0, 1.0, 1.0, 1.0));
128 osg::LightSource* lightSource =
new osg::LightSource();
129 lightSource->setLight(light);
130 lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
131 lightSource->setStateSetModes(*addTo.getOrCreateStateSet(), osg::StateAttribute::ON);
133 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
134 lightTransform->addChild(lightSource);
136 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
137 addTo.addChild(lightTransform);
142GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
144 osgUtil::Tessellator& tessellator) {
145 const std::vector<MSLane*>& lanes = edge.
getLanes();
146 for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
151 const int originalSize = (int)shape.size();
152 osg::Geode* geode =
new osg::Geode();
153 osg::Geometry* geom =
new osg::Geometry();
154 geode->addDrawable(geom);
155 geode->setName(
"lane:" + l->
getID());
156 addTo.addChild(geode);
158 const int upperShapeSize = originalSize * geomFactor;
159 const int totalShapeSize = (extrude) ? originalSize * 2 * geomFactor : originalSize * geomFactor;
160 const float zOffset = (extrude) ? (edge.
isCrossing()) ? 0.01f : 0.1f : 0.f;
161 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
162 (*osg_colors)[0].set(128, 128, 128, 255);
163 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
164 osg::Vec3Array* osg_coords =
new osg::Vec3Array(totalShapeSize);
165 geom->setVertexArray(osg_coords);
168 int index = upperShapeSize - 1;
169 for (
int k = 0; k < upperShapeSize; ++k, --index) {
170 (*osg_coords)[index].set((
float)shape[k].x(), (
float)shape[k].y(), (
float)shape[k].z() + zOffset);
172 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, upperShapeSize));
177 for (
int k = (
int)rshape.size() - 1; k >= 0; --k, ++index) {
178 (*osg_coords)[index].set((
float)rshape[k].x(), (float)rshape[k].y(), (float)rshape[k].z() + zOffset);
182 for (
int k = 0; k < (int)lshape.size(); ++k, ++index) {
183 (*osg_coords)[index].set((
float)lshape[k].x(), (float)lshape[k].y(), (float)lshape[k].z() + zOffset);
185 sizeDiff = (int)rshape.size() + (int)lshape.size() - upperShapeSize;
186 int minSize =
MIN2((
int)rshape.size(), (
int)lshape.size());
187 osg::DrawElementsUInt* surface =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP, 0);
188 for (
int i = 0; i < minSize; ++i) {
189 surface->push_back(i);
190 surface->push_back(upperShapeSize + sizeDiff - 1 - i);
192 geom->addPrimitiveSet(surface);
195 int index = upperShapeSize;
196 for (
int k = 0; k < upperShapeSize + sizeDiff; ++k, ++index) {
197 (*osg_coords)[index].set((*osg_coords)[k].x(), (*osg_coords)[k].y(), (*osg_coords)[k].z() - zOffset);
200 for (
int i = 0; i < upperShapeSize + sizeDiff; ++i) {
201 osg::Vec3 surfaceVec = (*osg_coords)[i] - (*osg_coords)[(i + 1) % (upperShapeSize + sizeDiff)];
202 if (surfaceVec.length() > 0.) {
203 osg::DrawElementsUInt* kerb =
new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0);
205 kerb->push_back(upperShapeSize + i);
206 kerb->push_back(upperShapeSize + (i + 1) % (upperShapeSize + sizeDiff));
207 kerb->push_back((i + 1) % (upperShapeSize + sizeDiff));
208 geom->addPrimitiveSet(kerb);
213 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
214 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
215 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
217 if (shape.size() > 2) {
218 tessellator.retessellatePolygons(*geom);
221 std::cout <<
"l=" << l->
getID() <<
" origPoints=" << shape.size() <<
" geomSize=" << geom->getVertexArray()->getNumElements() <<
" points=";
222 for (
int i = 0; i < (int)geom->getVertexArray()->getNumElements(); i++) {
223 const osg::Vec3& p = (*((osg::Vec3Array*)geom->getVertexArray()))[i];
224 std::cout << p.x() <<
"," << p.y() <<
"," << p.z() <<
" ";
229 osgUtil::SmoothingVisitor sv;
230#if OSG_MIN_VERSION_REQUIRED(3,5,4)
231 sv.setCreaseAngle(0.6 * osg::PI);
234 static_cast<GUILane*
>(l)->setGeometry(geom);
242 osgUtil::Tessellator& tessellator) {
244 osg::Geode* geode =
new osg::Geode();
245 osg::Geometry* geom =
new osg::Geometry();
246 geode->addDrawable(geom);
248 addTo.addChild(geode);
249 dynamic_cast<GUIGlObject&
>(junction).setNode(geode);
250 osg::Vec3Array* osg_coords =
new osg::Vec3Array((
int)shape.size());
251 geom->setVertexArray(osg_coords);
252 for (
int k = 0; k < (int)shape.size(); ++k) {
253 (*osg_coords)[k].set((
float)shape[k].x(), (float)shape[k].y(), (float)shape[k].z());
255 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
256 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
257 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
258 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
259 (*osg_colors)[0].set(128, 128, 128, 255);
260 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
261 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
263 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
264 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
265 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
267 if (shape.size() > 4) {
268 tessellator.retessellatePolygons(*geom);
270 junction.setGeometry(geom);
275GUIOSGBuilder::buildPolygonGeometry(
const SUMOPolygon& poly, osg::Group& addTo, osgUtil::Tessellator& tessellator) {
277 const std::vector<PositionVector>& holes = poly.
getHoles();
281 osg::Geode* geode =
new osg::Geode();
282 osg::Geometry* geom =
new osg::Geometry();
283 geode->addDrawable(geom);
284 geode->setName(
"polygon:" + poly.
getID());
285 addTo.addChild(geode);
286 osg::Vec3Array* osg_coords =
new osg::Vec3Array((
int)shape.size());
287 geom->setVertexArray(osg_coords);
288 for (
int k = 0; k < (int)shape.size(); ++k) {
289 (*osg_coords)[k].set((
float)shape[k].x(), (float)shape[k].y(), 0.1f);
292 if (holes.size() > 0) {
295 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
296 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
297 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
298 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
301 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
302 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
304 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
305 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
306 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
308 if (shape.size() > 4) {
309 tessellator.retessellatePolygons(*geom);
315GUIOSGBuilder::buildPoIGeometry(
const PointOfInterest& poi, osg::Group& addTo, osgUtil::Tessellator& tessellator) {
316 osg::Geode* geode =
new osg::Geode();
317 osg::Geometry* geom =
new osg::Geometry();
318 geode->addDrawable(geom);
319 geode->setName(
"poi:" + poi.
getID());
320 addTo.addChild(geode);
321 osg::Vec3Array* osg_coords =
new osg::Vec3Array(4);
322 geom->setVertexArray(osg_coords);
325 const double width = poi.
getWidth();
328 shape.push_back(
Position(center.
x() - 0.5 * width, center.
y() + 0.5 * height));
329 shape.push_back(
Position(center.
x() + 0.5 * width, center.
y() + 0.5 * height));
330 shape.push_back(
Position(center.
x() + 0.5 * width, center.
y() - 0.5 * height));
331 shape.push_back(
Position(center.
x() - 0.5 * width, center.
y() - 0.5 * height));
332 for (
unsigned int k = 0; k < shape.size(); ++k) {
333 (*osg_coords)[k].set((
float)shape[k].x(), (
float)shape[k].y(), 0.2f);
335 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
336 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
337 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
338 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
341 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
342 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
344 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
345 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
346 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
348 if (shape.size() > 4) {
349 tessellator.retessellatePolygons(*geom);
355GUIOSGBuilder::buildTrafficLightDetails(
MSTLLogicControl::TLSLogicVariants& vars, osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu, osg::Node* poleBase, osg::Group& addTo) {
357 osg::ComputeBoundsVisitor bboxCalc;
358 poleBase->accept(bboxCalc);
359 const double poleDiameter = bboxCalc.getBoundingBox().yMax() - bboxCalc.getBoundingBox().yMin();
360 tlg->accept(bboxCalc);
361 const double tlWidth = bboxCalc.getBoundingBox().yMax() - bboxCalc.getBoundingBox().yMin();
366 std::set<const MSEdge*> seenEdges;
369 for (
const MSLink* tlLink : lv) {
371 const MSEdge* approach = &tlLink->getLaneBefore()->getEdge();
372 if (!approach->
isWalkingArea() && seenEdges.find(approach) != seenEdges.end()) {
375 const std::vector<MSLane*> appLanes = approach->
getLanes();
377 const double poleMinHeight = 5.;
378 const double poleOffset = .5;
379 double angle = 90. - appLanes[0]->getShape().rotationDegreeAtOffset(-1.);
381 Position pos = appLanes[0]->getShape().back();
382 double skipWidth = 0.;
383 int firstSignalLaneIx = 0;
384 std::vector<std::pair<osg::Group*, osg::Vec3d>> repeaters;
386 osg::PositionAttitudeTransform* appBase =
new osg::PositionAttitudeTransform();
387 osg::PositionAttitudeTransform* rightPoleBase =
new osg::PositionAttitudeTransform();
388 osg::PositionAttitudeTransform* rightPoleScaleNode =
new osg::PositionAttitudeTransform();
389 rightPoleScaleNode->addChild(poleBase);
390 rightPoleBase->addChild(rightPoleScaleNode);
391 appBase->addChild(rightPoleBase);
392 rightPoleBase->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()));
393 rightPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
394 0., osg::Vec3d(0, 1, 0),
395 DEG2RAD(angle), osg::Vec3d(0, 0, 1)));
397 rightPoleScaleNode->setScale(osg::Vec3d(.12 / poleDiameter, .12 / poleDiameter, 2.8));
401 appBase->setPosition(appBase->getPosition() + offset * (poleOffset + approach->
getLength()));
402 appBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
403 0., osg::Vec3d(0, 1, 0),
404 DEG2RAD(angle + 180), osg::Vec3d(0, 0, 1)));
406 pos = tlLink->getLane()->getShape().back();
407 angle = 90. - tlLink->getLane()->getShape().rotationDegreeAtOffset(-1.);
408 rightPoleBase->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()) - osg::Vec3d(poleOffset * cos(
DEG2RAD(angle)), poleOffset * sin(
DEG2RAD(angle)), 0.));
409 rightPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
410 0., osg::Vec3d(0, 1, 0),
411 DEG2RAD(angle), osg::Vec3d(0, 0, 1)));
412 if (tlLink->getLane()->getLinkCont()[0]->getTLIndex() < 0) {
413 osg::PositionAttitudeTransform* leftPoleBase =
new osg::PositionAttitudeTransform();
414 osg::PositionAttitudeTransform* leftPoleScaleNode =
new osg::PositionAttitudeTransform();
415 appBase->addChild(leftPoleBase);
416 leftPoleScaleNode->addChild(poleBase);
417 leftPoleScaleNode->setScale(osg::Vec3d(.12 / poleDiameter, .12 / poleDiameter, 2.8));
418 leftPoleBase->addChild(leftPoleScaleNode);
419 double otherAngle = 90. - tlLink->getLane()->getShape().rotationDegreeAtOffset(1.);
420 Position otherPosRel = tlLink->getLane()->getShape().front();
421 osg::Vec3d leftPolePos(otherPosRel.
x(), otherPosRel.
y(), otherPosRel.
z());
422 leftPoleBase->setPosition(leftPolePos + osg::Vec3d(poleOffset * cos(
DEG2RAD(otherAngle)), poleOffset * sin(
DEG2RAD(otherAngle)), 0.));
423 leftPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1., 0., 0.),
424 0., osg::Vec3d(0., 1., 0.),
425 DEG2RAD(angle + 180.), osg::Vec3d(0., 0., 1.)));
426 repeaters.push_back({ leftPoleBase, osg::Vec3d(0., 0., leftPoleBase->getPosition().z())});
429 double laneWidth = appLanes[0]->getWidth();
430 osg::Vec3d offset(-poleOffset * cos(
DEG2RAD(angle)) - (.5 * laneWidth - skipWidth + poleOffset) * sin(
DEG2RAD(angle)), poleOffset * sin(
DEG2RAD(angle)) + (.5 * laneWidth - skipWidth + poleOffset) * cos(
DEG2RAD(angle)), 0.);
431 rightPoleBase->setPosition(rightPoleBase->getPosition() + offset);
435 if (!
noVehicles(appLanes.back()->getPermissions())) {
436 for (
MSLane* appLane : appLanes) {
439 skipWidth += appLane->getWidth();
446 const double laneWidth = appLanes[0]->getWidth();
447 const double horizontalWidth = approach->
getWidth() - skipWidth;
448 const int laneCount = (int)appLanes.size() - firstSignalLaneIx;
449 osg::Vec3d offset(-poleOffset * cos(
DEG2RAD(angle)) - (.5 * laneWidth - skipWidth + poleOffset) * sin(
DEG2RAD(angle)), -poleOffset * sin(
DEG2RAD(angle)) + (.5 * laneWidth - skipWidth + poleOffset) * cos(
DEG2RAD(angle)), 0.);
450 rightPoleBase->setPosition(rightPoleBase->getPosition() + offset);
453 const double cantiWidth = horizontalWidth - .1 * appLanes.back()->getWidth() + poleOffset;
454 const double holderWidth = cantiWidth - .4 * appLanes.back()->getWidth();
455 const double holderAngle = 7.5;
456 const double extraHeight = sin(
DEG2RAD(holderAngle)) * holderWidth;
457 rightPoleScaleNode->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight + extraHeight));
458 osg::PositionAttitudeTransform* cantileverBase =
new osg::PositionAttitudeTransform();
459 cantileverBase->setPosition(osg::Vec3d(0., 0., poleMinHeight));
460 cantileverBase->setAttitude(osg::Quat(
DEG2RAD(90.), osg::Vec3d(1, 0, 0),
461 0., osg::Vec3d(0, 1, 0),
462 0., osg::Vec3d(0, 0, 1)));
463 cantileverBase->setScale(osg::Vec3d(1., 1., cantiWidth));
464 cantileverBase->addChild(poleBase);
465 rightPoleBase->addChild(cantileverBase);
466 osg::PositionAttitudeTransform* cantileverHolderBase =
new osg::PositionAttitudeTransform();
467 cantileverHolderBase->setPosition(osg::Vec3d(0., 0., poleMinHeight + extraHeight - .02));
468 cantileverHolderBase->setAttitude(osg::Quat(
DEG2RAD(90. + holderAngle), osg::Vec3d(1, 0, 0),
469 0., osg::Vec3d(0, 1, 0),
470 0., osg::Vec3d(0, 0, 1)));
471 cantileverHolderBase->setScale(osg::Vec3d(.04 / poleDiameter, .04 / poleDiameter, sqrt(pow(holderWidth, 2.) + pow(extraHeight, 2.))));
472 cantileverHolderBase->addChild(poleBase);
473 rightPoleBase->addChild(cantileverHolderBase);
475 rightPoleScaleNode->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight));
476 osg::PositionAttitudeTransform* leftPoleBase =
new osg::PositionAttitudeTransform();
477 leftPoleBase->addChild(poleBase);
478 leftPoleBase->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight));
479 osg::Vec3d leftPolePos = osg::Vec3d(0, -(horizontalWidth + 2. * poleOffset), 0.);
480 leftPoleBase->setPosition(leftPolePos);
481 rightPoleBase->addChild(leftPoleBase);
482 osg::PositionAttitudeTransform* bridgeBase =
new osg::PositionAttitudeTransform();
483 bridgeBase->setPosition(osg::Vec3d(0., 0., poleMinHeight - .125));
484 bridgeBase->setAttitude(osg::Quat(
DEG2RAD(90.), osg::Vec3d(1, 0, 0),
485 0., osg::Vec3d(0, 1, 0),
486 0., osg::Vec3d(0, 0, 1)));
487 bridgeBase->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, leftPolePos.length()));
488 bridgeBase->addChild(poleBase);
489 rightPoleBase->addChild(bridgeBase);
492 seenEdges.insert(approach);
495 double refPos = poleOffset ;
496 std::vector<MSLane*>::const_iterator it = appLanes.begin();
497 for (std::advance(it, firstSignalLaneIx); it != appLanes.end(); it++) {
499 const std::vector<MSLink*>& links = (*it)->getLinkCont();
500 std::set<int> tlIndices;
501 for (
MSLink* link : links) {
502 if (link->getTLIndex() > -1) {
503 tlIndices.insert(link->getTLIndex());
506 std::set<int> seenTlIndices;
507 bool placeRepeaters =
true;
508 for (
MSLink* link : links) {
509 std::vector<std::pair<osg::Group*, osg::Vec3d>> signalTransforms = { {rightPoleBase, osg::Vec3d(0., 0., 0.)} };
510 if (placeRepeaters) {
511 signalTransforms.insert(signalTransforms.end(), repeaters.begin(), repeaters.end());
513 placeRepeaters =
false;
515 int tlIndex = link->getTLIndex();
516 if (tlIndex < 0 || seenTlIndices.find(tlIndex) != seenTlIndices.end()) {
519 for (
const std::pair<osg::Group*, osg::Vec3d>& transform : signalTransforms) {
521 d.
centerX = transform.second.x() + 0.15;
522 d.
centerY = (onlyPedCycle) ? 0. : -(refPos + .5 * (*it)->getWidth() - ((double)tlIndices.size() / 2. - 1. + (double)seenTlIndices.size()) * 1.5 * tlWidth);
523 d.
centerY += transform.second.y();
524 d.
centerZ = (onlyPedCycle) ? 2.2 : 3.8;
525 d.
centerZ += transform.second.z();
526 d.
altitude = (onlyPedCycle) ? 0.6 : -1;
527 osg::PositionAttitudeTransform* tlNode = getTrafficLight(d, vars, links[0], tlg, tly, tlr, tlu, poleBase,
false);
528 tlNode->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
529 0., osg::Vec3d(0, 1, 0),
530 DEG2RAD(180.0), osg::Vec3d(0, 0, 1)));
531 transform.first->addChild(tlNode);
533 seenTlIndices.insert(tlIndex);
539 refPos += (*it)->getWidth();
542 appBase->setNodeMask(GUIOSGView::NODESET_TLSMODELS);
543 appBase->setName(
"tlLogic:" + tlLogic->
getID());
544 addTo.addChild(appBase);
552 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
553 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
555 if (pLoadedModel ==
nullptr) {
557 osg::Image* pImage = osgDB::readImageFile(d.
filename);
558 if (pImage ==
nullptr) {
563 osg::Texture2D* texture =
new osg::Texture2D();
564 texture->setImage(pImage);
565 osg::Geometry* quad = osg::createTexturedQuadGeometry(osg::Vec3d(-0.5 * d.
width, -0.5 * d.
height, 0.), osg::Vec3d(d.
width, 0., 0.), osg::Vec3d(0., d.
height, 0.));
566 quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);
567 osg::Geode*
const pModel =
new osg::Geode();
568 pModel->addDrawable(quad);
569 base->addChild(pModel);
572 osg::ShadeModel* sm =
new osg::ShadeModel();
573 sm->setMode(osg::ShadeModel::FLAT);
574 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
575 base->addChild(pLoadedModel);
577 osg::ComputeBoundsVisitor bboxCalc;
578 base->accept(bboxCalc);
579 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
581 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
582 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
583 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
585 xScale = yScale = zScale;
587 base->setScale(osg::Vec3d(xScale, yScale, zScale));
589 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3d(1, 0, 0),
590 osg::DegreesToRadians(d.
tilt), osg::Vec3d(0, 1, 0),
591 osg::DegreesToRadians(d.
rot), osg::Vec3d(0, 0, 1)));
592 addTo.addChild(base);
596osg::PositionAttitudeTransform*
597GUIOSGBuilder::getTrafficLight(
const GUISUMOAbstractView::Decal& d,
MSTLLogicControl::TLSLogicVariants& vars,
const MSLink* link, osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu, osg::Node*
const pole,
const bool withPole,
const double size,
double poleHeight,
double transparency) {
598 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
599 double xScale = 1., yScale = 1., zScale = 1.;
600 if (tlg !=
nullptr) {
601 osg::ComputeBoundsVisitor bboxCalc;
602 tlg->accept(bboxCalc);
603 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
604 xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
605 yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
606 double addHeight = (withPole) ? poleHeight : 0.;
607 zScale = d.
altitude > 0 ? d.
altitude / (addHeight + bbox.zMax() - bbox.zMin()) : 1.;
610 xScale = yScale = zScale;
612 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
613 osg::Switch* switchNode =
new osg::Switch();
614 switchNode->addChild(createTrafficLightState(d, tlg, withPole, size, osg::Vec4d(0., 1., 0., transparency)));
615 switchNode->addChild(createTrafficLightState(d, tly, withPole, size, osg::Vec4d(1., 1., 0., transparency)));
616 switchNode->addChild(createTrafficLightState(d, tlr, withPole, size, osg::Vec4d(1., 0., 0., transparency)));
617 switchNode->addChild(createTrafficLightState(d, tlu, withPole, size, osg::Vec4d(1., .5, 0., transparency)));
618 base->addChild(switchNode);
621 base->setPosition(osg::Vec3d(0., 0., poleHeight));
622 osg::PositionAttitudeTransform* poleBase =
new osg::PositionAttitudeTransform();
623 poleBase->addChild(pole);
624 poleBase->setScale(osg::Vec3d(1., 1., poleHeight));
625 ret->addChild(poleBase);
627 ret->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
628 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
629 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
631 ret->setScale(osg::Vec3d(xScale, yScale, zScale));
637osg::PositionAttitudeTransform*
638GUIOSGBuilder::createTrafficLightState(
const GUISUMOAbstractView::Decal& d, osg::Node* tl,
const double withPole,
const double size, osg::Vec4d color) {
639 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
644 unsigned int nodeMask = (withPole) ? GUIOSGView::NodeSetGroup::NODESET_TLSDOMES : GUIOSGView::NodeSetGroup::NODESET_TLSLINKMARKERS;
645 osg::Geode* geode =
new osg::Geode();
646 osg::Vec3d center = osg::Vec3d(0., 0., (withPole) ? -1.8 : 0.);
647 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, (
float)size));
648 geode->addDrawable(shape);
649 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
650 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
651 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
652 shape->setColor(color);
653 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
654 ellipse->addChild(geode);
655 ellipse->setPosition(center);
656 ellipse->setPivotPoint(center);
658 ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.
altitude + 1.1));
660 ellipse->setScale(osg::Vec3d(4., 4., 1.1));
662 ellipse->setNodeMask(nodeMask);
663 ret->addChild(ellipse);
670GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
671 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
672 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
673 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
677GUIOSGView::OSGMovable
679 GUIOSGView::OSGMovable m;
680 m.pos =
new osg::PositionAttitudeTransform();
681 double enlarge = 0.05;
682 const std::string& osgFile = type.
getOSGFile();
683 if (myCars.find(osgFile) == myCars.end()) {
684 myCars[osgFile] = osgDB::readNodeFile(osgFile);
685 if (myCars[osgFile] == 0) {
686 WRITE_ERRORF(
TL(
"Could not load '%'. The model is replaced by a cone shape."), osgFile);
687 osg::PositionAttitudeTransform* rot =
new osg::PositionAttitudeTransform();
688 rot->addChild(
new osg::ShapeDrawable(
new osg::Cone(osg::Vec3d(0, 0, 0), 1.0f, 1.0f)));
689 rot->setAttitude(osg::Quat(osg::DegreesToRadians(90.), osg::Vec3(1, 0, 0),
690 0., osg::Vec3(0, 1, 0),
691 0., osg::Vec3(0, 0, 1)));
692 myCars[osgFile] = rot;
695 osg::Node* carNode = myCars[osgFile];
696 if (carNode !=
nullptr) {
697 osg::ComputeBoundsVisitor bboxCalc;
698 carNode->accept(bboxCalc);
699 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
700 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
701 base->addChild(carNode);
702 base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
703 base->setScale(osg::Vec3d(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
704 type.
getLength() / (bbox.yMax() - bbox.yMin()),
705 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
707 m.pos->addChild(base);
710 m.mat =
new osg::Material();
711 osg::ref_ptr<osg::StateSet> ss = base->getOrCreateStateSet();
712 ss->setAttribute(m.mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
713 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
714 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
717 m.lights =
new osg::Switch();
718 for (
double sideFactor = -1.; sideFactor < 2.5; sideFactor += 2.) {
719 osg::Geode* geode =
new osg::Geode();
720 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3d((type.
getWidth() / 2. + enlarge)*sideFactor, 0., type.
getHeight() / 2.), 0.2f));
721 geode->addDrawable(right);
723 setShapeState(right);
724 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
725 osg::Sequence* seq =
new osg::Sequence();
727 seq->addChild(geode, .33);
728 seq->addChild(
new osg::Geode(), .33);
730 seq->setInterval(osg::Sequence::LOOP, 0, -1);
732 seq->setDuration(1.0f, -1);
734 seq->setMode(osg::Sequence::START);
735 m.lights->addChild(seq);
737 osg::Geode* geode =
new osg::Geode();
738 osg::CompositeShape* comp =
new osg::CompositeShape();
739 comp->addChild(
new osg::Sphere(osg::Vec3d(-(type.
getWidth() / 2. + enlarge), type.
getLength() + enlarge, type.
getHeight() / 2.), .2f));
740 comp->addChild(
new osg::Sphere(osg::Vec3d(type.
getWidth() / 2. + enlarge, type.
getLength() + enlarge, type.
getHeight() / 2.), .2f));
741 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
742 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
743 geode->addDrawable(brake);
744 setShapeState(brake);
745 m.lights->addChild(geode);
747 osg::Vec3d center(0, -type.
getLength() / 2., 0.);
748 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
749 ellipse->addChild(geode);
750 ellipse->addChild(m.lights);
751 ellipse->setPivotPoint(center);
752 ellipse->setPosition(center);
753 m.pos->addChild(ellipse);
761GUIOSGBuilder::buildPlane(
const float length) {
762 osg::Geode* geode =
new osg::Geode();
763 osg::Geometry* geom =
new osg::Geometry;
764 geode->addDrawable(geom);
765 osg::Vec3Array* coords =
new osg::Vec3Array(4);
766 geom->setVertexArray(coords);
767 (*coords)[0].set(.5f * length, .5f * length, -0.1f);
768 (*coords)[1].set(.5f * length, -.5f * length, -0.1f);
769 (*coords)[2].set(-.5f * length, -.5f * length, -0.1f);
770 (*coords)[3].set(-.5f * length, .5f * length, -0.1f);
771 osg::Vec3Array* normals =
new osg::Vec3Array(1);
772 (*normals)[0].set(0, 0, 1);
773 geom->setNormalArray(normals, osg::Array::BIND_PER_PRIMITIVE_SET);
774 osg::Vec4ubArray* colors =
new osg::Vec4ubArray(1);
775 (*colors)[0].set(0, 255, 0, 255);
776 geom->setColorArray(colors, osg::Array::BIND_OVERALL);
777 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, 4));
779 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
780 ss->setRenderingHint(osg::StateSet::OPAQUE_BIN);
781 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
#define WRITE_MESSAGEF(...)
#define WRITE_ERRORF(...)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permissions is a forbidden edge.
bool isSidewalk(SVCPermissions permissions)
Returns whether an edge with the given permissions is a sidewalk.
bool noVehicles(SVCPermissions permissions)
Returns whether an edge with the given permissions forbids vehicles.
bool isBikepath(SVCPermissions permissions)
Returns whether an edge with the given permissions is a bicycle edge.
long long int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
@ SVC_PEDESTRIAN
pedestrian
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
const MSJunction & getJunction() const
Returns the represented junction.
Representation of a lane in the micro simulation (gui-version)
A MSNet extended by some values for usage within the gui.
std::vector< GUIJunctionWrapper * > myJunctionWrapper
Wrapped MS-junctions.
A road/street connecting two junctions.
bool isCrossing() const
return whether this edge is a pedestrian crossing
SVCPermissions getPermissions() const
Returns the combined permissions of all lanes of this edge.
bool isWalkingArea() const
return whether this edge is walking area
const std::vector< MSLane * > & getLanes() const
Returns this edge's lanes.
double getLength() const
return the length of the edge
double getWidth() const
Returns the edges's width (sum over all lanes)
const PositionVector & getShape() const
Returns this junction's shape.
Representation of a lane in the micro simulation.
SVCPermissions getPermissions() const
Returns the vehicle class permissions for this lane.
virtual const PositionVector & getShape(bool) const
double getWidth() const
Returns the lane's width.
static MSNet * getInstance()
Returns the pointer to the unique instance of MSNet (singleton).
MSTLLogicControl & getTLSControl()
Returns the tls logics control.
Storage for all programs of a single tls.
void addSwitchCommand(OnSwitchAction *c)
MSTrafficLightLogic * getActive() const
std::vector< std::string > getAllTLIds() const
TLSLogicVariants & get(const std::string &id) const
Returns the variants of a named tls.
The parent class for traffic light logics.
const LinkVectorVector & getLinks() const
Returns the list of lists of all affected links.
std::vector< LaneVector > LaneVectorVector
Definition of a list that holds lists of lanes that do have the same attribute.
const LaneVectorVector & getLaneVectors() const
Returns the list of lists of all lanes controlled by this tls.
const LinkVector & getLinksAt(int i) const
Returns the list of links that are controlled by the signals at the given position.
std::vector< LinkVector > LinkVectorVector
Definition of a list that holds lists of links that do have the same attribute.
std::vector< MSLink * > LinkVector
Definition of the list of links that are subjected to this tls.
The car-following model and parameter.
double getWidth() const
Get the width which vehicles of this class shall have when being drawn.
SUMOVehicleClass getVehicleClass() const
Get this vehicle type's vehicle class.
std::string getOSGFile() const
Get this vehicle type's 3D model file name.
double getHeight() const
Get the height which vehicles of this class shall have when being drawn.
double getLength() const
Get vehicle's length [m].
const std::string & getID() const
Returns the id.
Position getCenter() const
Returns the image center of the POI.
double getHeight() const
Returns the image height of the POI.
double getWidth() const
Returns the image width of the POI.
A point in 2D or 3D with translation and scaling methods.
double x() const
Returns the x-position.
double z() const
Returns the z-position.
double y() const
Returns the y-position.
double rotationDegreeAtOffset(double pos) const
Returns the rotation at the given length.
void move2side(double amount, double maxExtension=100)
move position vector to side using certain amount
unsigned char red() const
Returns the red-amount of the color.
unsigned char green() const
Returns the green-amount of the color.
unsigned char blue() const
Returns the blue-amount of the color.
void set(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
assigns new values
const PositionVector & getShape() const
Returns the shape of the polygon.
const std::vector< PositionVector > & getHoles() const
Returns the holers of the polygon.
const RGBColor & getShapeColor() const
Returns the color of the Shape.
A decal (an image) that can be shown.
double tilt
The tilt of the image to the ground plane (in degrees)
double centerX
The center of the image in x-direction (net coordinates, in m)
double height
The height of the image (net coordinates in y-direction, in m)
double width
The width of the image (net coordinates in x-direction, in m)
double rot
The rotation of the image in the ground plane (in degrees)
double layer
The layer of the image.
double altitude
The altitude of the image (net coordinates in z-direction, in m)
double centerY
The center of the image in y-direction (net coordinates, in m)
double centerZ
The center of the image in z-direction (net coordinates, in m)
std::string filename
The path to the file the image is located at.
double roll
The roll of the image to the ground plane (in degrees)