53std::map<std::string, osg::ref_ptr<osg::Node> > GUIOSGBuilder::myCars;
60GUIOSGBuilder::buildOSGScene(osg::Node*
const tlg, osg::Node*
const tly, osg::Node*
const tlr, osg::Node*
const tlu, osg::Node*
const pole) {
61 osgUtil::Tessellator tesselator;
62 osg::Group* root =
new osg::Group();
65 for (
const MSEdge* e : net->getEdgeControl().getEdges()) {
66 if (!e->isInternal()) {
67 buildOSGEdgeGeometry(*e, *root, tesselator);
77 for (std::vector<std::string>::const_iterator i = tlids.begin(); i != tlids.end(); ++i) {
79 buildTrafficLightDetails(vars, tlg, tly, tlr, tlu, pole, *root);
82 const MSLane* lastLane = 0;
84 for (MSTrafficLightLogic::LaneVectorVector::const_iterator j = lanes.begin(); j != lanes.end(); ++j, ++idx) {
85 if ((*j).size() == 0) {
88 const MSLane*
const lane = (*j)[0];
92 if (lane == lastLane) {
96 d.
centerX = pos.
x() - 1.5 * sin(angle);
97 d.
centerY = pos.
y() - 1.5 * cos(angle);
99 osg::PositionAttitudeTransform* tlNode = getTrafficLight(d, vars, vars.
getActive()->
getLinksAt(idx)[0],
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
false, .25, -1, 1.);
100 tlNode->setName(
"tlLogic:" + *i);
101 root->addChild(tlNode);
112 osg::Light* light =
new osg::Light(d.
filename[5] -
'0');
114 light->setPosition(osg::Vec4(0.0, 0.0, 0.0, 1.0));
115 light->setDiffuse(osg::Vec4(1.0, 1.0, 1.0, 1.0));
116 light->setSpecular(osg::Vec4(1.0, 1.0, 1.0, 1.0));
117 light->setAmbient(osg::Vec4(1.0, 1.0, 1.0, 1.0));
119 osg::LightSource* lightSource =
new osg::LightSource();
120 lightSource->setLight(light);
121 lightSource->setLocalStateSetModes(osg::StateAttribute::ON);
122 lightSource->setStateSetModes(*addTo.getOrCreateStateSet(), osg::StateAttribute::ON);
124 osg::PositionAttitudeTransform* lightTransform =
new osg::PositionAttitudeTransform();
125 lightTransform->addChild(lightSource);
127 lightTransform->setScale(osg::Vec3d(0.1, 0.1, 0.1));
128 addTo.addChild(lightTransform);
133GUIOSGBuilder::buildOSGEdgeGeometry(
const MSEdge& edge,
135 osgUtil::Tessellator& tessellator) {
136 const std::vector<MSLane*>& lanes = edge.
getLanes();
137 for (std::vector<MSLane*>::const_iterator j = lanes.begin(); j != lanes.end(); ++j) {
142 const int originalSize = (int)shape.size();
143 osg::Geode* geode =
new osg::Geode();
144 osg::Geometry* geom =
new osg::Geometry();
145 geode->addDrawable(geom);
146 geode->setName(
"lane:" + l->
getID());
147 addTo.addChild(geode);
149 const int upperShapeSize = originalSize * geomFactor;
150 const int totalShapeSize = (extrude) ? originalSize * 2 * geomFactor : originalSize * geomFactor;
151 const float zOffset = (extrude) ? (edge.
isCrossing()) ? 0.01f : 0.1f : 0.f;
152 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
153 (*osg_colors)[0].set(128, 128, 128, 255);
154 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
155 osg::Vec3Array* osg_coords =
new osg::Vec3Array(totalShapeSize);
156 geom->setVertexArray(osg_coords);
159 int index = upperShapeSize - 1;
160 for (
int k = 0; k < upperShapeSize; ++k, --index) {
161 (*osg_coords)[index].set((
float)shape[k].x(), (
float)shape[k].y(), (
float)shape[k].z() + zOffset);
163 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, upperShapeSize));
168 for (
int k = (
int)rshape.size() - 1; k >= 0; --k, ++index) {
169 (*osg_coords)[index].set((
float)rshape[k].x(), (float)rshape[k].y(), (float)rshape[k].z() + zOffset);
173 for (
int k = 0; k < (int)lshape.size(); ++k, ++index) {
174 (*osg_coords)[index].set((
float)lshape[k].x(), (float)lshape[k].y(), (float)lshape[k].z() + zOffset);
176 sizeDiff = (int)rshape.size() + (int)lshape.size() - upperShapeSize;
177 int minSize =
MIN2((
int)rshape.size(), (
int)lshape.size());
178 osg::DrawElementsUInt* surface =
new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP, 0);
179 for (
int i = 0; i < minSize; ++i) {
180 surface->push_back(i);
181 surface->push_back(upperShapeSize + sizeDiff - 1 - i);
183 geom->addPrimitiveSet(surface);
186 int index = upperShapeSize;
187 for (
int k = 0; k < upperShapeSize + sizeDiff; ++k, ++index) {
188 (*osg_coords)[index].set((*osg_coords)[k].x(), (*osg_coords)[k].y(), (*osg_coords)[k].z() - zOffset);
191 for (
int i = 0; i < upperShapeSize + sizeDiff; ++i) {
192 osg::Vec3 surfaceVec = (*osg_coords)[i] - (*osg_coords)[(i + 1) % (upperShapeSize + sizeDiff)];
193 if (surfaceVec.length() > 0.) {
194 osg::DrawElementsUInt* kerb =
new osg::DrawElementsUInt(osg::PrimitiveSet::POLYGON, 0);
196 kerb->push_back(upperShapeSize + i);
197 kerb->push_back(upperShapeSize + (i + 1) % (upperShapeSize + sizeDiff));
198 kerb->push_back((i + 1) % (upperShapeSize + sizeDiff));
199 geom->addPrimitiveSet(kerb);
204 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
205 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
206 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
208 if (shape.size() > 2) {
209 tessellator.retessellatePolygons(*geom);
212 std::cout <<
"l=" << l->
getID() <<
" origPoints=" << shape.size() <<
" geomSize=" << geom->getVertexArray()->getNumElements() <<
" points=";
213 for (
int i = 0; i < (int)geom->getVertexArray()->getNumElements(); i++) {
214 const osg::Vec3& p = (*((osg::Vec3Array*)geom->getVertexArray()))[i];
215 std::cout << p.x() <<
"," << p.y() <<
"," << p.z() <<
" ";
220 osgUtil::SmoothingVisitor sv;
221#if OSG_MIN_VERSION_REQUIRED(3,5,4)
222 sv.setCreaseAngle(0.6 * osg::PI);
225 static_cast<GUILane*
>(l)->setGeometry(geom);
233 osgUtil::Tessellator& tessellator) {
235 osg::Geode* geode =
new osg::Geode();
236 osg::Geometry* geom =
new osg::Geometry();
237 geode->addDrawable(geom);
239 addTo.addChild(geode);
240 dynamic_cast<GUIGlObject&
>(junction).setNode(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 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
249 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
250 (*osg_colors)[0].set(128, 128, 128, 255);
251 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
252 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
254 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
255 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
256 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
258 if (shape.size() > 4) {
259 tessellator.retessellatePolygons(*geom);
261 junction.setGeometry(geom);
266GUIOSGBuilder::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) {
268 osg::ComputeBoundsVisitor bboxCalc;
269 poleBase->accept(bboxCalc);
270 const double poleDiameter = bboxCalc.getBoundingBox().yMax() - bboxCalc.getBoundingBox().yMin();
271 tlg->accept(bboxCalc);
272 const double tlWidth = bboxCalc.getBoundingBox().yMax() - bboxCalc.getBoundingBox().yMin();
277 std::set<const MSEdge*> seenEdges;
280 for (
const MSLink* tlLink : lv) {
282 const MSEdge* approach = &tlLink->getLaneBefore()->getEdge();
283 if (!approach->
isWalkingArea() && seenEdges.find(approach) != seenEdges.end()) {
286 const std::vector<MSLane*> appLanes = approach->
getLanes();
288 const double poleMinHeight = 5.;
289 const double poleOffset = .5;
290 double angle = 90. - appLanes[0]->getShape().rotationDegreeAtOffset(-1.);
292 Position pos = appLanes[0]->getShape().back();
293 double skipWidth = 0.;
294 int firstSignalLaneIx = 0;
295 std::vector<std::pair<osg::Group*, osg::Vec3d>> repeaters;
297 osg::PositionAttitudeTransform* appBase =
new osg::PositionAttitudeTransform();
298 osg::PositionAttitudeTransform* rightPoleBase =
new osg::PositionAttitudeTransform();
299 osg::PositionAttitudeTransform* rightPoleScaleNode =
new osg::PositionAttitudeTransform();
300 rightPoleScaleNode->addChild(poleBase);
301 rightPoleBase->addChild(rightPoleScaleNode);
302 appBase->addChild(rightPoleBase);
303 rightPoleBase->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()));
304 rightPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
305 0., osg::Vec3d(0, 1, 0),
306 DEG2RAD(angle), osg::Vec3d(0, 0, 1)));
308 rightPoleScaleNode->setScale(osg::Vec3d(.12 / poleDiameter, .12 / poleDiameter, 2.8));
312 appBase->setPosition(appBase->getPosition() + offset * (poleOffset + approach->
getLength()));
313 appBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
314 0., osg::Vec3d(0, 1, 0),
315 DEG2RAD(angle + 180), osg::Vec3d(0, 0, 1)));
317 pos = tlLink->getLane()->getShape().back();
318 angle = 90. - tlLink->getLane()->getShape().rotationDegreeAtOffset(-1.);
319 rightPoleBase->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()) - osg::Vec3d(poleOffset * cos(
DEG2RAD(angle)), poleOffset * sin(
DEG2RAD(angle)), 0.));
320 rightPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
321 0., osg::Vec3d(0, 1, 0),
322 DEG2RAD(angle), osg::Vec3d(0, 0, 1)));
323 if (tlLink->getLane()->getLinkCont()[0]->getTLIndex() < 0) {
324 osg::PositionAttitudeTransform* leftPoleBase =
new osg::PositionAttitudeTransform();
325 osg::PositionAttitudeTransform* leftPoleScaleNode =
new osg::PositionAttitudeTransform();
326 appBase->addChild(leftPoleBase);
327 leftPoleScaleNode->addChild(poleBase);
328 leftPoleScaleNode->setScale(osg::Vec3d(.12 / poleDiameter, .12 / poleDiameter, 2.8));
329 leftPoleBase->addChild(leftPoleScaleNode);
330 double otherAngle = 90. - tlLink->getLane()->getShape().rotationDegreeAtOffset(1.);
331 Position otherPosRel = tlLink->getLane()->getShape().front();
332 osg::Vec3d leftPolePos(otherPosRel.
x(), otherPosRel.
y(), otherPosRel.
z());
333 leftPoleBase->setPosition(leftPolePos + osg::Vec3d(poleOffset * cos(
DEG2RAD(otherAngle)), poleOffset * sin(
DEG2RAD(otherAngle)), 0.));
334 leftPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1., 0., 0.),
335 0., osg::Vec3d(0., 1., 0.),
336 DEG2RAD(angle + 180.), osg::Vec3d(0., 0., 1.)));
337 repeaters.push_back({ leftPoleBase, osg::Vec3d(0., 0., leftPoleBase->getPosition().z())});
340 double laneWidth = appLanes[0]->getWidth();
341 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.);
342 rightPoleBase->setPosition(rightPoleBase->getPosition() + offset);
346 if (!
noVehicles(appLanes.back()->getPermissions())) {
347 for (
MSLane* appLane : appLanes) {
350 skipWidth += appLane->getWidth();
357 const double laneWidth = appLanes[0]->getWidth();
358 const double horizontalWidth = approach->
getWidth() - skipWidth;
359 const int laneCount = (int)appLanes.size() - firstSignalLaneIx;
360 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.);
361 rightPoleBase->setPosition(rightPoleBase->getPosition() + offset);
364 const double cantiWidth = horizontalWidth - .1 * appLanes.back()->getWidth() + poleOffset;
365 const double holderWidth = cantiWidth - .4 * appLanes.back()->getWidth();
366 const double holderAngle = 7.5;
367 const double extraHeight = sin(
DEG2RAD(holderAngle)) * holderWidth;
368 rightPoleScaleNode->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight + extraHeight));
369 osg::PositionAttitudeTransform* cantileverBase =
new osg::PositionAttitudeTransform();
370 cantileverBase->setPosition(osg::Vec3d(0., 0., poleMinHeight));
371 cantileverBase->setAttitude(osg::Quat(
DEG2RAD(90.), osg::Vec3d(1, 0, 0),
372 0., osg::Vec3d(0, 1, 0),
373 0., osg::Vec3d(0, 0, 1)));
374 cantileverBase->setScale(osg::Vec3d(1., 1., cantiWidth));
375 cantileverBase->addChild(poleBase);
376 rightPoleBase->addChild(cantileverBase);
377 osg::PositionAttitudeTransform* cantileverHolderBase =
new osg::PositionAttitudeTransform();
378 cantileverHolderBase->setPosition(osg::Vec3d(0., 0., poleMinHeight + extraHeight - .02));
379 cantileverHolderBase->setAttitude(osg::Quat(
DEG2RAD(90. + holderAngle), osg::Vec3d(1, 0, 0),
380 0., osg::Vec3d(0, 1, 0),
381 0., osg::Vec3d(0, 0, 1)));
382 cantileverHolderBase->setScale(osg::Vec3d(.04 / poleDiameter, .04 / poleDiameter, sqrt(pow(holderWidth, 2.) + pow(extraHeight, 2.))));
383 cantileverHolderBase->addChild(poleBase);
384 rightPoleBase->addChild(cantileverHolderBase);
386 rightPoleScaleNode->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight));
387 osg::PositionAttitudeTransform* leftPoleBase =
new osg::PositionAttitudeTransform();
388 leftPoleBase->addChild(poleBase);
389 leftPoleBase->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight));
390 osg::Vec3d leftPolePos = osg::Vec3d(0, -(horizontalWidth + 2. * poleOffset), 0.);
391 leftPoleBase->setPosition(leftPolePos);
392 rightPoleBase->addChild(leftPoleBase);
393 osg::PositionAttitudeTransform* bridgeBase =
new osg::PositionAttitudeTransform();
394 bridgeBase->setPosition(osg::Vec3d(0., 0., poleMinHeight - .125));
395 bridgeBase->setAttitude(osg::Quat(
DEG2RAD(90.), osg::Vec3d(1, 0, 0),
396 0., osg::Vec3d(0, 1, 0),
397 0., osg::Vec3d(0, 0, 1)));
398 bridgeBase->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, leftPolePos.length()));
399 bridgeBase->addChild(poleBase);
400 rightPoleBase->addChild(bridgeBase);
403 seenEdges.insert(approach);
406 double refPos = poleOffset ;
407 std::vector<MSLane*>::const_iterator it = appLanes.begin();
408 for (std::advance(it, firstSignalLaneIx); it != appLanes.end(); it++) {
410 const std::vector<MSLink*>& links = (*it)->getLinkCont();
411 std::set<int> tlIndices;
412 for (
MSLink* link : links) {
413 if (link->getTLIndex() > -1) {
414 tlIndices.insert(link->getTLIndex());
417 std::set<int> seenTlIndices;
418 bool placeRepeaters =
true;
419 for (
MSLink* link : links) {
420 std::vector<std::pair<osg::Group*, osg::Vec3d>> signalTransforms = { {rightPoleBase, osg::Vec3d(0., 0., 0.)} };
421 if (placeRepeaters) {
422 signalTransforms.insert(signalTransforms.end(), repeaters.begin(), repeaters.end());
424 placeRepeaters =
false;
426 int tlIndex = link->getTLIndex();
427 if (tlIndex < 0 || seenTlIndices.find(tlIndex) != seenTlIndices.end()) {
430 for (
const std::pair<osg::Group*, osg::Vec3d>& transform : signalTransforms) {
432 d.
centerX = transform.second.x() + 0.15;
433 d.
centerY = (onlyPedCycle) ? 0. : -(refPos + .5 * (*it)->getWidth() - ((double)tlIndices.size() / 2. - 1. + (double)seenTlIndices.size()) * 1.5 * tlWidth);
434 d.
centerY += transform.second.y();
435 d.
centerZ = (onlyPedCycle) ? 2.2 : 3.8;
436 d.
centerZ += transform.second.z();
437 d.
altitude = (onlyPedCycle) ? 0.6 : -1;
438 osg::PositionAttitudeTransform* tlNode = getTrafficLight(d, vars, links[0], tlg, tly, tlr, tlu, poleBase,
false);
439 tlNode->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
440 0., osg::Vec3d(0, 1, 0),
441 DEG2RAD(180.0), osg::Vec3d(0, 0, 1)));
442 transform.first->addChild(tlNode);
444 seenTlIndices.insert(tlIndex);
450 refPos += (*it)->getWidth();
453 appBase->setNodeMask(GUIOSGView::NODESET_TLSMODELS);
454 appBase->setName(
"tlLogic:" + tlLogic->
getID());
455 addTo.addChild(appBase);
463 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
464 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
466 if (pLoadedModel ==
nullptr) {
468 osg::Image* pImage = osgDB::readImageFile(d.
filename);
469 if (pImage ==
nullptr) {
474 osg::Texture2D* texture =
new osg::Texture2D();
475 texture->setImage(pImage);
476 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.));
477 quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);
478 osg::Geode*
const pModel =
new osg::Geode();
479 pModel->addDrawable(quad);
480 base->addChild(pModel);
483 osg::ShadeModel* sm =
new osg::ShadeModel();
484 sm->setMode(osg::ShadeModel::FLAT);
485 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
486 base->addChild(pLoadedModel);
488 osg::ComputeBoundsVisitor bboxCalc;
489 base->accept(bboxCalc);
490 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
492 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
493 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
494 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
496 xScale = yScale = zScale;
498 base->setScale(osg::Vec3d(xScale, yScale, zScale));
500 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3d(1, 0, 0),
501 osg::DegreesToRadians(d.
tilt), osg::Vec3d(0, 1, 0),
502 osg::DegreesToRadians(d.
rot), osg::Vec3d(0, 0, 1)));
503 addTo.addChild(base);
507osg::PositionAttitudeTransform*
508GUIOSGBuilder::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) {
509 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
510 double xScale = 1., yScale = 1., zScale = 1.;
511 if (tlg !=
nullptr) {
512 osg::ComputeBoundsVisitor bboxCalc;
513 tlg->accept(bboxCalc);
514 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
515 xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
516 yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
517 double addHeight = (withPole) ? poleHeight : 0.;
518 zScale = d.
altitude > 0 ? d.
altitude / (addHeight + bbox.zMax() - bbox.zMin()) : 1.;
521 xScale = yScale = zScale;
523 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
524 osg::Switch* switchNode =
new osg::Switch();
525 switchNode->addChild(createTrafficLightState(d, tlg, withPole, size, osg::Vec4d(0., 1., 0., transparency)));
526 switchNode->addChild(createTrafficLightState(d, tly, withPole, size, osg::Vec4d(1., 1., 0., transparency)));
527 switchNode->addChild(createTrafficLightState(d, tlr, withPole, size, osg::Vec4d(1., 0., 0., transparency)));
528 switchNode->addChild(createTrafficLightState(d, tlu, withPole, size, osg::Vec4d(1., .5, 0., transparency)));
529 base->addChild(switchNode);
532 base->setPosition(osg::Vec3d(0., 0., poleHeight));
533 osg::PositionAttitudeTransform* poleBase =
new osg::PositionAttitudeTransform();
534 poleBase->addChild(pole);
535 poleBase->setScale(osg::Vec3d(1., 1., poleHeight));
536 ret->addChild(poleBase);
538 ret->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
539 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
540 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
542 ret->setScale(osg::Vec3d(xScale, yScale, zScale));
548osg::PositionAttitudeTransform*
549GUIOSGBuilder::createTrafficLightState(
const GUISUMOAbstractView::Decal& d, osg::Node* tl,
const double withPole,
const double size, osg::Vec4d color) {
550 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
555 unsigned int nodeMask = (withPole) ? GUIOSGView::NodeSetGroup::NODESET_TLSDOMES : GUIOSGView::NodeSetGroup::NODESET_TLSLINKMARKERS;
556 osg::Geode* geode =
new osg::Geode();
557 osg::Vec3d center = osg::Vec3d(0., 0., (withPole) ? -1.8 : 0.);
558 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, (
float)size));
559 geode->addDrawable(shape);
560 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
561 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
562 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
563 shape->setColor(color);
564 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
565 ellipse->addChild(geode);
566 ellipse->setPosition(center);
567 ellipse->setPivotPoint(center);
569 ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.
altitude + 1.1));
571 ellipse->setScale(osg::Vec3d(4., 4., 1.1));
573 ellipse->setNodeMask(nodeMask);
574 ret->addChild(ellipse);
581GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
582 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
583 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
584 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
588GUIOSGView::OSGMovable
590 GUIOSGView::OSGMovable m;
591 m.pos =
new osg::PositionAttitudeTransform();
592 double enlarge = 0.05;
593 const std::string& osgFile = type.
getOSGFile();
594 if (myCars.find(osgFile) == myCars.end()) {
595 myCars[osgFile] = osgDB::readNodeFile(osgFile);
596 if (myCars[osgFile] == 0) {
597 WRITE_ERRORF(
TL(
"Could not load '%'. The model is replaced by a cone shape."), osgFile);
598 osg::PositionAttitudeTransform* rot =
new osg::PositionAttitudeTransform();
599 rot->addChild(
new osg::ShapeDrawable(
new osg::Cone(osg::Vec3d(0, 0, 0), 1.0f, 1.0f)));
600 rot->setAttitude(osg::Quat(osg::DegreesToRadians(90.), osg::Vec3(1, 0, 0),
601 0., osg::Vec3(0, 1, 0),
602 0., osg::Vec3(0, 0, 1)));
603 myCars[osgFile] = rot;
606 osg::Node* carNode = myCars[osgFile];
607 if (carNode !=
nullptr) {
608 osg::ComputeBoundsVisitor bboxCalc;
609 carNode->accept(bboxCalc);
610 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
611 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
612 base->addChild(carNode);
613 base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
614 base->setScale(osg::Vec3d(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
615 type.
getLength() / (bbox.yMax() - bbox.yMin()),
616 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
617 m.pos->addChild(base);
620 m.mat =
new osg::Material();
621 osg::ref_ptr<osg::StateSet> ss = base->getOrCreateStateSet();
622 ss->setAttribute(m.mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
623 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
624 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
627 m.lights =
new osg::Switch();
628 for (
double sideFactor = -1.; sideFactor < 2.5; sideFactor += 2.) {
629 osg::Geode* geode =
new osg::Geode();
630 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3d((type.
getWidth() / 2. + enlarge)*sideFactor, 0., type.
getHeight() / 2.), 0.2f));
631 geode->addDrawable(right);
633 setShapeState(right);
634 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
635 osg::Sequence* seq =
new osg::Sequence();
637 seq->addChild(geode, .33);
638 seq->addChild(
new osg::Geode(), .33);
640 seq->setInterval(osg::Sequence::LOOP, 0, -1);
642 seq->setDuration(1.0f, -1);
644 seq->setMode(osg::Sequence::START);
645 m.lights->addChild(seq);
647 osg::Geode* geode =
new osg::Geode();
648 osg::CompositeShape* comp =
new osg::CompositeShape();
649 comp->addChild(
new osg::Sphere(osg::Vec3d(-(type.
getWidth() / 2. + enlarge), type.
getLength() + enlarge, type.
getHeight() / 2.), .2f));
650 comp->addChild(
new osg::Sphere(osg::Vec3d(type.
getWidth() / 2. + enlarge, type.
getLength() + enlarge, type.
getHeight() / 2.), .2f));
651 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
652 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
653 geode->addDrawable(brake);
654 setShapeState(brake);
655 m.lights->addChild(geode);
657 osg::Vec3d center(0, -type.
getLength() / 2., 0.);
658 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
659 ellipse->addChild(geode);
660 ellipse->addChild(m.lights);
661 ellipse->setPivotPoint(center);
662 ellipse->setPosition(center);
663 m.pos->addChild(ellipse);
671GUIOSGBuilder::buildPlane(
const float length) {
672 osg::Geode* geode =
new osg::Geode();
673 osg::Geometry* geom =
new osg::Geometry;
674 geode->addDrawable(geom);
675 osg::Vec3Array* coords =
new osg::Vec3Array(4);
676 geom->setVertexArray(coords);
677 (*coords)[0].set(.5f * length, .5f * length, -0.1f);
678 (*coords)[1].set(.5f * length, -.5f * length, -0.1f);
679 (*coords)[2].set(-.5f * length, -.5f * length, -0.1f);
680 (*coords)[3].set(-.5f * length, .5f * length, -0.1f);
681 osg::Vec3Array* normals =
new osg::Vec3Array(1);
682 (*normals)[0].set(0, 0, 1);
683 geom->setNormalArray(normals, osg::Array::BIND_PER_PRIMITIVE_SET);
684 osg::Vec4ubArray* colors =
new osg::Vec4ubArray(1);
685 (*colors)[0].set(0, 255, 0, 255);
686 geom->setColorArray(colors, osg::Array::BIND_OVERALL);
687 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, 4));
689 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
690 ss->setRenderingHint(osg::StateSet::OPAQUE_BIN);
691 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.
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
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)