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();
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(), 0.);
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);
210 if (shape.size() > 2) {
211 tessellator.retessellatePolygons(*geom);
214 std::cout <<
"l=" << l->
getID() <<
" origPoints=" << shape.size() <<
" geomSize=" << geom->getVertexArray()->getNumElements() <<
" points=";
215 for (
int i = 0; i < (int)geom->getVertexArray()->getNumElements(); i++) {
216 const osg::Vec3& p = (*((osg::Vec3Array*)geom->getVertexArray()))[i];
217 std::cout << p.x() <<
"," << p.y() <<
"," << p.z() <<
" ";
222 osgUtil::SmoothingVisitor sv;
223#if OSG_MIN_VERSION_REQUIRED(3,5,4)
224 sv.setCreaseAngle(0.6 * osg::PI);
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);
241 addTo.addChild(geode);
242 dynamic_cast<GUIGlObject&
>(junction).setNode(geode);
243 osg::Vec3Array* osg_coords =
new osg::Vec3Array((
int)shape.size());
244 geom->setVertexArray(osg_coords);
245 for (
int k = 0; k < (int)shape.size(); ++k) {
246 (*osg_coords)[k].set((
float)shape[k].x(), (float)shape[k].y(), (float)shape[k].z());
248 osg::Vec3Array* osg_normals =
new osg::Vec3Array(1);
249 (*osg_normals)[0] = osg::Vec3(0, 0, 1);
250 geom->setNormalArray(osg_normals, osg::Array::BIND_PER_PRIMITIVE_SET);
251 osg::Vec4ubArray* osg_colors =
new osg::Vec4ubArray(1);
252 (*osg_colors)[0].set(128, 128, 128, 255);
253 geom->setColorArray(osg_colors, osg::Array::BIND_OVERALL);
254 geom->addPrimitiveSet(
new osg::DrawArrays(osg::PrimitiveSet::POLYGON, 0, (
int)shape.size()));
256 osg::ref_ptr<osg::StateSet> ss = geode->getOrCreateStateSet();
257 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
258 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
260 if (shape.size() > 4) {
261 tessellator.retessellatePolygons(*geom);
263 junction.setGeometry(geom);
268GUIOSGBuilder::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) {
270 osg::ComputeBoundsVisitor bboxCalc;
271 poleBase->accept(bboxCalc);
272 const double poleDiameter = bboxCalc.getBoundingBox().yMax() - bboxCalc.getBoundingBox().yMin();
273 tlg->accept(bboxCalc);
274 const double tlWidth = bboxCalc.getBoundingBox().yMax() - bboxCalc.getBoundingBox().yMin();
279 std::set<const MSEdge*> seenEdges;
282 for (
const MSLink* tlLink : lv) {
284 const MSEdge* approach = &tlLink->getLaneBefore()->getEdge();
285 if (!approach->
isWalkingArea() && seenEdges.find(approach) != seenEdges.end()) {
288 const std::vector<MSLane*> appLanes = approach->
getLanes();
290 const double poleMinHeight = 5.;
291 const double poleOffset = .5;
292 double angle = 90. - appLanes[0]->getShape().rotationDegreeAtOffset(-1.);
294 Position pos = appLanes[0]->getShape().back();
295 double skipWidth = 0.;
296 int firstSignalLaneIx = 0;
297 std::vector<std::pair<osg::Group*, osg::Vec3d>> repeaters;
299 osg::PositionAttitudeTransform* appBase =
new osg::PositionAttitudeTransform();
300 osg::PositionAttitudeTransform* rightPoleBase =
new osg::PositionAttitudeTransform();
301 osg::PositionAttitudeTransform* rightPoleScaleNode =
new osg::PositionAttitudeTransform();
302 rightPoleScaleNode->addChild(poleBase);
303 rightPoleBase->addChild(rightPoleScaleNode);
304 appBase->addChild(rightPoleBase);
305 rightPoleBase->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()));
306 rightPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
307 0., osg::Vec3d(0, 1, 0),
308 DEG2RAD(angle), osg::Vec3d(0, 0, 1)));
310 rightPoleScaleNode->setScale(osg::Vec3d(.12 / poleDiameter, .12 / poleDiameter, 2.8));
314 appBase->setPosition(appBase->getPosition() + offset * (poleOffset + approach->
getLength()));
315 appBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
316 0., osg::Vec3d(0, 1, 0),
317 DEG2RAD(angle + 180), osg::Vec3d(0, 0, 1)));
319 pos = tlLink->getLane()->getShape().back();
320 angle = 90. - tlLink->getLane()->getShape().rotationDegreeAtOffset(-1.);
321 rightPoleBase->setPosition(osg::Vec3d(pos.
x(), pos.
y(), pos.
z()) - osg::Vec3d(poleOffset * cos(
DEG2RAD(angle)), poleOffset * sin(
DEG2RAD(angle)), 0.));
322 rightPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
323 0., osg::Vec3d(0, 1, 0),
324 DEG2RAD(angle), osg::Vec3d(0, 0, 1)));
325 if (tlLink->getLane()->getLinkCont()[0]->getTLIndex() < 0) {
326 osg::PositionAttitudeTransform* leftPoleBase =
new osg::PositionAttitudeTransform();
327 osg::PositionAttitudeTransform* leftPoleScaleNode =
new osg::PositionAttitudeTransform();
328 appBase->addChild(leftPoleBase);
329 leftPoleScaleNode->addChild(poleBase);
330 leftPoleScaleNode->setScale(osg::Vec3d(.12 / poleDiameter, .12 / poleDiameter, 2.8));
331 leftPoleBase->addChild(leftPoleScaleNode);
332 double otherAngle = 90. - tlLink->getLane()->getShape().rotationDegreeAtOffset(1.);
333 Position otherPosRel = tlLink->getLane()->getShape().front();
334 osg::Vec3d leftPolePos(otherPosRel.
x(), otherPosRel.
y(), otherPosRel.
z());
335 leftPoleBase->setPosition(leftPolePos + osg::Vec3d(poleOffset * cos(
DEG2RAD(otherAngle)), poleOffset * sin(
DEG2RAD(otherAngle)), 0.));
336 leftPoleBase->setAttitude(osg::Quat(0., osg::Vec3d(1., 0., 0.),
337 0., osg::Vec3d(0., 1., 0.),
338 DEG2RAD(angle + 180.), osg::Vec3d(0., 0., 1.)));
339 repeaters.push_back({ leftPoleBase, osg::Vec3d(0., 0., leftPoleBase->getPosition().z())});
342 double laneWidth = appLanes[0]->getWidth();
343 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.);
344 rightPoleBase->setPosition(rightPoleBase->getPosition() + offset);
348 if (!
noVehicles(appLanes.back()->getPermissions())) {
349 for (
MSLane* appLane : appLanes) {
352 skipWidth += appLane->getWidth();
359 const double laneWidth = appLanes[0]->getWidth();
360 const double horizontalWidth = approach->
getWidth() - skipWidth;
361 const int laneCount = (int)appLanes.size() - firstSignalLaneIx;
362 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.);
363 rightPoleBase->setPosition(rightPoleBase->getPosition() + offset);
366 const double cantiWidth = horizontalWidth - .1 * appLanes.back()->getWidth() + poleOffset;
367 const double holderWidth = cantiWidth - .4 * appLanes.back()->getWidth();
368 const double holderAngle = 7.5;
369 const double extraHeight = sin(
DEG2RAD(holderAngle)) * holderWidth;
370 rightPoleScaleNode->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight + extraHeight));
371 osg::PositionAttitudeTransform* cantileverBase =
new osg::PositionAttitudeTransform();
372 cantileverBase->setPosition(osg::Vec3d(0., 0., poleMinHeight));
373 cantileverBase->setAttitude(osg::Quat(
DEG2RAD(90.), osg::Vec3d(1, 0, 0),
374 0., osg::Vec3d(0, 1, 0),
375 0., osg::Vec3d(0, 0, 1)));
376 cantileverBase->setScale(osg::Vec3d(1., 1., cantiWidth));
377 cantileverBase->addChild(poleBase);
378 rightPoleBase->addChild(cantileverBase);
379 osg::PositionAttitudeTransform* cantileverHolderBase =
new osg::PositionAttitudeTransform();
380 cantileverHolderBase->setPosition(osg::Vec3d(0., 0., poleMinHeight + extraHeight - .02));
381 cantileverHolderBase->setAttitude(osg::Quat(
DEG2RAD(90. + holderAngle), osg::Vec3d(1, 0, 0),
382 0., osg::Vec3d(0, 1, 0),
383 0., osg::Vec3d(0, 0, 1)));
384 cantileverHolderBase->setScale(osg::Vec3d(.04 / poleDiameter, .04 / poleDiameter, sqrt(pow(holderWidth, 2.) + pow(extraHeight, 2.))));
385 cantileverHolderBase->addChild(poleBase);
386 rightPoleBase->addChild(cantileverHolderBase);
388 rightPoleScaleNode->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight));
389 osg::PositionAttitudeTransform* leftPoleBase =
new osg::PositionAttitudeTransform();
390 leftPoleBase->addChild(poleBase);
391 leftPoleBase->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, poleMinHeight));
392 osg::Vec3d leftPolePos = osg::Vec3d(0, -(horizontalWidth + 2. * poleOffset), 0.);
393 leftPoleBase->setPosition(leftPolePos);
394 rightPoleBase->addChild(leftPoleBase);
395 osg::PositionAttitudeTransform* bridgeBase =
new osg::PositionAttitudeTransform();
396 bridgeBase->setPosition(osg::Vec3d(0., 0., poleMinHeight - .125));
397 bridgeBase->setAttitude(osg::Quat(
DEG2RAD(90.), osg::Vec3d(1, 0, 0),
398 0., osg::Vec3d(0, 1, 0),
399 0., osg::Vec3d(0, 0, 1)));
400 bridgeBase->setScale(osg::Vec3d(.25 / poleDiameter, .25 / poleDiameter, leftPolePos.length()));
401 bridgeBase->addChild(poleBase);
402 rightPoleBase->addChild(bridgeBase);
405 seenEdges.insert(approach);
408 double refPos = poleOffset ;
409 std::vector<MSLane*>::const_iterator it = appLanes.begin();
410 for (std::advance(it, firstSignalLaneIx); it != appLanes.end(); it++) {
412 const std::vector<MSLink*>& links = (*it)->getLinkCont();
413 std::set<int> tlIndices;
414 for (
MSLink* link : links) {
415 if (link->getTLIndex() > -1) {
416 tlIndices.insert(link->getTLIndex());
419 std::set<int> seenTlIndices;
420 bool placeRepeaters =
true;
421 for (
MSLink* link : links) {
422 std::vector<std::pair<osg::Group*, osg::Vec3d>> signalTransforms = { {rightPoleBase, osg::Vec3d(0., 0., 0.)} };
423 if (placeRepeaters) {
424 signalTransforms.insert(signalTransforms.end(), repeaters.begin(), repeaters.end());
426 placeRepeaters =
false;
428 int tlIndex = link->getTLIndex();
429 if (tlIndex < 0 || seenTlIndices.find(tlIndex) != seenTlIndices.end()) {
432 for (
const std::pair<osg::Group*, osg::Vec3d>& transform : signalTransforms) {
434 d.
centerX = transform.second.x() + 0.15;
435 d.
centerY = (onlyPedCycle) ? 0. : -(refPos + .5 * (*it)->getWidth() - ((double)tlIndices.size() / 2. - 1. + (double)seenTlIndices.size()) * 1.5 * tlWidth);
436 d.
centerY += transform.second.y();
437 d.
centerZ = (onlyPedCycle) ? 2.2 : 3.8;
438 d.
centerZ += transform.second.z();
439 d.
altitude = (onlyPedCycle) ? 0.6 : -1;
440 osg::PositionAttitudeTransform* tlNode = getTrafficLight(d, vars, links[0], tlg, tly, tlr, tlu, poleBase,
false);
441 tlNode->setAttitude(osg::Quat(0., osg::Vec3d(1, 0, 0),
442 0., osg::Vec3d(0, 1, 0),
443 DEG2RAD(180.0), osg::Vec3d(0, 0, 1)));
444 transform.first->addChild(tlNode);
446 seenTlIndices.insert(tlIndex);
452 refPos += (*it)->getWidth();
455 appBase->setNodeMask(1 << GUIOSGView::NODESET_TLSMODELS);
456 appBase->setName(
"tlLogic:" + tlLogic->
getID());
457 addTo.addChild(appBase);
465 osg::Node* pLoadedModel = osgDB::readNodeFile(d.
filename);
466 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
468 if (pLoadedModel ==
nullptr) {
470 osg::Image* pImage = osgDB::readImageFile(d.
filename);
471 if (pImage ==
nullptr) {
476 osg::Texture2D* texture =
new osg::Texture2D();
477 texture->setImage(pImage);
478 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.));
479 quad->getOrCreateStateSet()->setTextureAttributeAndModes(0, texture);
480 osg::Geode*
const pModel =
new osg::Geode();
481 pModel->addDrawable(quad);
482 base->addChild(pModel);
485 osg::ShadeModel* sm =
new osg::ShadeModel();
486 sm->setMode(osg::ShadeModel::FLAT);
487 pLoadedModel->getOrCreateStateSet()->setAttribute(sm);
488 base->addChild(pLoadedModel);
490 osg::ComputeBoundsVisitor bboxCalc;
491 base->accept(bboxCalc);
492 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
494 double xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
495 double yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
496 const double zScale = d.
altitude > 0 ? d.
altitude / (bbox.zMax() - bbox.zMin()) : 1.;
498 xScale = yScale = zScale;
500 base->setScale(osg::Vec3d(xScale, yScale, zScale));
502 base->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3d(1, 0, 0),
503 osg::DegreesToRadians(d.
tilt), osg::Vec3d(0, 1, 0),
504 osg::DegreesToRadians(d.
rot), osg::Vec3d(0, 0, 1)));
505 addTo.addChild(base);
509osg::PositionAttitudeTransform*
510GUIOSGBuilder::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) {
511 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
512 double xScale = 1., yScale = 1., zScale = 1.;
513 if (tlg !=
nullptr) {
514 osg::ComputeBoundsVisitor bboxCalc;
515 tlg->accept(bboxCalc);
516 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
517 xScale = d.
width > 0 ? d.
width / (bbox.xMax() - bbox.xMin()) : 1.;
518 yScale = d.
height > 0 ? d.
height / (bbox.yMax() - bbox.yMin()) : 1.;
519 double addHeight = (withPole) ? poleHeight : 0.;
520 zScale = d.
altitude > 0 ? d.
altitude / (addHeight + bbox.zMax() - bbox.zMin()) : 1.;
523 xScale = yScale = zScale;
525 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
526 osg::Switch* switchNode =
new osg::Switch();
527 switchNode->addChild(createTrafficLightState(d, tlg, withPole, size, osg::Vec4d(0., 1., 0., transparency)));
528 switchNode->addChild(createTrafficLightState(d, tly, withPole, size, osg::Vec4d(1., 1., 0., transparency)));
529 switchNode->addChild(createTrafficLightState(d, tlr, withPole, size, osg::Vec4d(1., 0., 0., transparency)));
530 switchNode->addChild(createTrafficLightState(d, tlu, withPole, size, osg::Vec4d(1., .5, 0., transparency)));
531 base->addChild(switchNode);
534 base->setPosition(osg::Vec3d(0., 0., poleHeight));
535 osg::PositionAttitudeTransform* poleBase =
new osg::PositionAttitudeTransform();
536 poleBase->addChild(pole);
537 poleBase->setScale(osg::Vec3d(1., 1., poleHeight));
538 ret->addChild(poleBase);
540 ret->setAttitude(osg::Quat(osg::DegreesToRadians(d.
roll), osg::Vec3(1, 0, 0),
541 osg::DegreesToRadians(d.
tilt), osg::Vec3(0, 1, 0),
542 osg::DegreesToRadians(d.
rot), osg::Vec3(0, 0, 1)));
544 ret->setScale(osg::Vec3d(xScale, yScale, zScale));
550osg::PositionAttitudeTransform*
551GUIOSGBuilder::createTrafficLightState(
const GUISUMOAbstractView::Decal& d, osg::Node* tl,
const double withPole,
const double size, osg::Vec4d color) {
552 osg::PositionAttitudeTransform* ret =
new osg::PositionAttitudeTransform();
557 unsigned int nodeMask = (withPole) ? 1 << GUIOSGView::NodeSetGroup::NODESET_TLSDOMES : 1 << GUIOSGView::NodeSetGroup::NODESET_TLSLINKMARKERS;
558 osg::Geode* geode =
new osg::Geode();
559 osg::Vec3d center = osg::Vec3d(0., 0., (withPole) ? -1.8 : 0.);
560 osg::ShapeDrawable* shape =
new osg::ShapeDrawable(
new osg::Sphere(center, (
float)size));
561 geode->addDrawable(shape);
562 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
563 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
564 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
565 shape->setColor(color);
566 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
567 ellipse->addChild(geode);
568 ellipse->setPosition(center);
569 ellipse->setPivotPoint(center);
571 ellipse->setScale(osg::Vec3d(4., 4., 2.5 * d.
altitude + 1.1));
573 ellipse->setScale(osg::Vec3d(4., 4., 1.1));
575 ellipse->setNodeMask(nodeMask);
576 ret->addChild(ellipse);
583GUIOSGBuilder::setShapeState(osg::ref_ptr<osg::ShapeDrawable> shape) {
584 osg::ref_ptr<osg::StateSet> ss = shape->getOrCreateStateSet();
585 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
586 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
590GUIOSGView::OSGMovable
592 GUIOSGView::OSGMovable m;
593 m.pos =
new osg::PositionAttitudeTransform();
595 const std::string& osgFile = type.
getOSGFile();
596 if (myCars.find(osgFile) == myCars.end()) {
597 myCars[osgFile] = osgDB::readNodeFile(osgFile);
598 if (myCars[osgFile] == 0) {
599 WRITE_ERROR(
"Could not load '" + osgFile +
"'. The model is replaced by a cone shape.");
600 osg::PositionAttitudeTransform* rot =
new osg::PositionAttitudeTransform();
601 rot->addChild(
new osg::ShapeDrawable(
new osg::Cone(osg::Vec3d(0, 0, 0), 1.0f, 1.0f)));
602 rot->setAttitude(osg::Quat(osg::DegreesToRadians(90.), osg::Vec3(1, 0, 0),
603 0., osg::Vec3(0, 1, 0),
604 0., osg::Vec3(0, 0, 1)));
605 myCars[osgFile] = rot;
608 osg::Node* carNode = myCars[osgFile];
609 if (carNode !=
nullptr) {
610 osg::ComputeBoundsVisitor bboxCalc;
611 carNode->accept(bboxCalc);
612 const osg::BoundingBox& bbox = bboxCalc.getBoundingBox();
613 osg::PositionAttitudeTransform* base =
new osg::PositionAttitudeTransform();
614 base->addChild(carNode);
615 base->setPivotPoint(osg::Vec3d((bbox.xMin() + bbox.xMax()) / 2., bbox.yMin(), bbox.zMin()));
616 base->setScale(osg::Vec3d(type.
getWidth() / (bbox.xMax() - bbox.xMin()),
617 type.
getLength() / (bbox.yMax() - bbox.yMin()),
618 type.
getHeight() / (bbox.zMax() - bbox.zMin())));
619 m.pos->addChild(base);
623 m.mat =
new osg::Material();
624 osg::ref_ptr<osg::StateSet> ss = base->getOrCreateStateSet();
625 ss->setAttribute(m.mat, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
626 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
627 ss->setMode(GL_BLEND, osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);
629 m.lights =
new osg::Switch();
630 for (
double offset = -0.3; offset < 0.5; offset += 0.6) {
631 osg::Geode* geode =
new osg::Geode();
632 osg::ShapeDrawable* right =
new osg::ShapeDrawable(
new osg::Sphere(osg::Vec3d(offset, (type.
getLength() - .9) / 2., (type.
getHeight() - .5) / 2.), .1f));
633 geode->addDrawable(right);
634 setShapeState(right);
635 right->setColor(osg::Vec4(1.f, .5f, 0.f, .8f));
636 osg::Sequence* seq =
new osg::Sequence();
638 seq->addChild(geode, .33);
639 seq->addChild(
new osg::Geode(), .33);
641 seq->setInterval(osg::Sequence::LOOP, 0, -1);
643 seq->setDuration(1.0f, -1);
645 seq->setMode(osg::Sequence::START);
646 m.lights->addChild(seq);
649 osg::Geode* geode =
new osg::Geode();
650 osg::CompositeShape* comp =
new osg::CompositeShape();
651 comp->addChild(
new osg::Sphere(osg::Vec3d(-0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
652 comp->addChild(
new osg::Sphere(osg::Vec3d(0.3, (type.
getLength() + .8) / 2., (type.
getHeight() - .5) / 2.), .1f));
653 osg::ShapeDrawable* brake =
new osg::ShapeDrawable(comp);
654 brake->setColor(osg::Vec4(1.f, 0.f, 0.f, .8f));
655 geode->addDrawable(brake);
656 setShapeState(brake);
657 m.lights->addChild(geode);
660 osg::PositionAttitudeTransform* ellipse =
new osg::PositionAttitudeTransform();
661 ellipse->addChild(geode);
662 ellipse->addChild(m.lights);
663 ellipse->setPivotPoint(center);
664 ellipse->setPosition(center);
666 m.pos->addChild(ellipse);
#define WRITE_MESSAGE(msg)
bool isForbidden(SVCPermissions permissions)
Returns whether an edge with the given permission is a forbidden edge.
bool isSidewalk(SVCPermissions permissions)
Returns whether an edge with the given permission is a sidewalk.
bool noVehicles(SVCPermissions permissions)
Returns whether an edge with the given permission forbids vehicles.
bool isBikepath(SVCPermissions permissions)
Returns whether an edge with the given permission is a bicycle edge.
int SVCPermissions
bitset where each bit declares whether a certain SVC may use this edge/lane
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.
const MSEdgeVector & getEdges() const
Returns loaded edges.
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.
const PositionVector & getShape() const
Returns this lane's shape.
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.
MSEdgeControl & getEdgeControl()
Returns the edge 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.
std::string getOSGFile() const
Get this vehicle type's 3D model file name.
double getMinGap() const
Get the free space in front of vehicles of this class.
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 ammount
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)