osg::Geode *RoadObject::createGuardRailGeode() { osg::Geode *guardRailGeode = new osg::Geode(); guardRailGeode->setName(name.c_str()); double h = 4.5; double texlength = 4.5; double texwidth = 0.33; double railLength = length; if (repeatLength > 0) railLength = repeatLength; if (s + railLength > road->getLength()) { railLength = road->getLength() - s; } if (repeatDistance > 0) { h = repeatDistance; texlength = repeatDistance; } osg::Geometry *guardRailGeometry; guardRailGeometry = new osg::Geometry(); guardRailGeode->addDrawable(guardRailGeometry); guardRailGeometry->setUseDisplayList(true); guardRailGeometry->setUseVertexBufferObjects(false); osg::Vec3Array *guardRailVertices; guardRailVertices = new osg::Vec3Array; guardRailGeometry->setVertexArray(guardRailVertices); osg::Vec3Array *guardRailNormals; guardRailNormals = new osg::Vec3Array; guardRailGeometry->setNormalArray(guardRailNormals); guardRailGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg::Vec2Array *guardRailTexCoords; guardRailTexCoords = new osg::Vec2Array; guardRailGeometry->setTexCoordArray(3, guardRailTexCoords); osg::Geometry *guardRailPostGeometry; guardRailPostGeometry = new osg::Geometry(); guardRailGeode->addDrawable(guardRailPostGeometry); osg::Vec3Array *guardRailPostVertices; guardRailPostVertices = new osg::Vec3Array; guardRailPostGeometry->setVertexArray(guardRailPostVertices); osg::Vec2Array *guardRailPostTexCoords; guardRailPostTexCoords = new osg::Vec2Array; guardRailPostGeometry->setTexCoordArray(3, guardRailPostTexCoords); osg::Vec3Array *guardRailPostNormals; guardRailPostNormals = new osg::Vec3Array; guardRailPostGeometry->setNormalArray(guardRailPostNormals); guardRailPostGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); bool up = true; if (s == 0) up = false; // do not go up if we start right at the bginning of a road, then we continue from the last road bool down = false; RoadPoint railPoint; RoadPoint railPoint2; osg::Vec3 n; LaneSection * currentLaneSection = NULL; int currentLaneId = 0; double sSection = s; double d = 0.0; double currentT = t; for (double currentS = s; currentS <= s + railLength; currentS += h) { if (currentS > (s + railLength - (h))) { currentS = (s + railLength); if (fabs(s + railLength - road->getLength()) > 1.0e-6) // only go down if the rail does not extend to the end of the road. { down = true; } } if (road->getLaneSection(currentS) != currentLaneSection) { LaneSection * newLaneSection = road->getLaneSection(currentS); while (currentLaneSection && (currentLaneSection != newLaneSection)) { if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } currentLaneSection = road->getLaneSectionNext(currentLaneSection->getStart() + 1.0e-3); currentLaneId = road->getLaneNumber(currentLaneSection->getStart(), currentT); sSection = currentLaneSection->getStart(); } currentLaneSection = newLaneSection; currentLaneId = road->getLaneNumber(sSection, currentT); if (t < 0) { if (fabs(currentT) < currentLaneSection->getLaneSpanWidth(0, currentLaneId + 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId++; } d = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + currentT; } else if (t > 0) { if (currentT < currentLaneSection->getLaneSpanWidth(0, currentLaneId - 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId--; } d = currentT - currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS); } } if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } railPoint = road->getRoadPoint(currentS, currentT); if (t > 0) railPoint2 = road->getRoadPoint(currentS, currentT + 1.0); else railPoint2 = road->getRoadPoint(currentS, currentT - 1.0); n.set(railPoint2.x() - railPoint.x(), railPoint2.y() - railPoint.y(), railPoint2.z() - railPoint.z()); n.normalize(); osg::Vec3 negn = -n; if (up || down) { guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z() - 0.31)); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0)); guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z())); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0.33 / texwidth)); } else { guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z() + 0.44)); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0)); guardRailVertices->push_back(osg::Vec3(railPoint.x(), railPoint.y(), railPoint.z() + 0.75)); guardRailTexCoords->push_back(osg::Vec2((currentS / texlength), 0.33 / texwidth)); // post osg::Vec3 p1, p2, p3, p4; osg::Vec3 n2; n2.set(railPoint.nx(), railPoint.ny(), railPoint.nz()); n2.normalize(); osg::Vec3 n3 = n2 ^ n; n3.normalize(); p1.set(railPoint.x(), railPoint.y(), railPoint.z()); p1 += n * 0.01; p2 = p1 + (n3 * 0.08); p3 = p2 + (n * 0.06); p4 = p1 + (n * 0.06); osg::Vec3 p5, p6, p7, p8; p5.set(p1.x(), p1.y(), p1.z() + 0.44); p6.set(p2.x(), p2.y(), p2.z() + 0.44); guardRailPostVertices->push_back(p1); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.02)); guardRailPostNormals->push_back(n); guardRailPostVertices->push_back(p2); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.1)); guardRailPostNormals->push_back(n); guardRailPostVertices->push_back(p6); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.1)); guardRailPostNormals->push_back(n); guardRailPostVertices->push_back(p5); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.02)); guardRailPostNormals->push_back(n); p5.set(p1.x(), p1.y(), p1.z() + 0.6); p6.set(p2.x(), p2.y(), p2.z() + 0.6); p7.set(p3.x(), p3.y(), p3.z() + 0.6); p8.set(p4.x(), p4.y(), p4.z() + 0.6); osg::Vec3 negn3 = -n3; guardRailPostVertices->push_back(p2); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.02)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p3); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p7); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p6); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.02)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p1); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.02)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p4); guardRailPostTexCoords->push_back(osg::Vec2(0.02, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p8); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.1)); guardRailPostNormals->push_back(negn3); guardRailPostVertices->push_back(p5); guardRailPostTexCoords->push_back(osg::Vec2(0.1, 0.02)); guardRailPostNormals->push_back(negn3); } if (t > 0) { guardRailNormals->push_back(n); guardRailNormals->push_back(n); } else { guardRailNormals->push_back(negn); guardRailNormals->push_back(negn); } up = false; } osg::DrawArrays *guardRailPosts = new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, guardRailPostVertices->size()); guardRailPostGeometry->addPrimitiveSet(guardRailPosts); osg::DrawArrays *guardRail = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, guardRailVertices->size()); guardRailGeometry->addPrimitiveSet(guardRail); osg::StateSet *guardRailStateSet = guardRailGeode->getOrCreateStateSet(); guardRailStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); //guardRailStateSet->setMode ( GL_LIGHT0, osg::StateAttribute::ON ); //guardRailStateSet->setMode ( GL_LIGHT1, osg::StateAttribute::ON); const char *fileName = coVRFileManager::instance()->getName("share/covise/materials/guardRailTex.jpg"); if (fileName) { osg::Image *guardRailTexImage = osgDB::readImageFile(fileName); osg::Texture2D *guardRailTex = new osg::Texture2D; guardRailTex->setWrap(osg::Texture2D::WRAP_S, osg::Texture::REPEAT); guardRailTex->setWrap(osg::Texture2D::WRAP_T, osg::Texture::REPEAT); if (guardRailTexImage) guardRailTex->setImage(guardRailTexImage); guardRailStateSet->setTextureAttributeAndModes(3, guardRailTex, osg::StateAttribute::ON); } else { std::cerr << "ERROR: no texture found named: share/covise/materials/guardRailTex.jpg"; } return guardRailGeode; }
osg::Geode *RoadObject::createOutlineGeode() { osg::Geode *OutlineGeode = new osg::Geode(); OutlineGeode->setName(name.c_str()); double h = 4.5; double texlength = 4.5; double texwidth = 0.33; double railLength = length; if (repeatLength > 0) railLength = repeatLength; if (s + railLength > road->getLength()) { railLength = road->getLength() - s; } if (repeatDistance > 0) { h = repeatDistance; texlength = repeatDistance; } osg::Geometry *OutlineGeometry; OutlineGeometry = new osg::Geometry(); OutlineGeode->addDrawable(OutlineGeometry); OutlineGeometry->setUseDisplayList(true); OutlineGeometry->setUseVertexBufferObjects(false); osg::Vec3Array *OutlineVertices; OutlineVertices = new osg::Vec3Array; OutlineGeometry->setVertexArray(OutlineVertices); osg::Vec3Array *OutlineNormals; OutlineNormals = new osg::Vec3Array; OutlineGeometry->setNormalArray(OutlineNormals); OutlineGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg::Vec2Array *OutlineTexCoords; OutlineTexCoords = new osg::Vec2Array; OutlineGeometry->setTexCoordArray(3, OutlineTexCoords); RoadPoint railPoint; RoadPoint railPoint2; RoadPoint nextRailPoint; osg::Vec3 n; int numVert = outline->size(); int numSegments = numVert - 1; osg::Vec2 *profile = new osg::Vec2[numVert]; float len=0; float *tcv = new float[numVert]; for (int i = 0; i < numVert; i++) { profile[i] = osg::Vec2(outline->at(i).v, outline->at(i).z); } tcv[0]=0; for (int i = 1; i < numVert; i++) { len += (profile[i] - profile[i-1]).length(); tcv[i]=len; } for (int i = 1; i < numVert; i++) { tcv[i]/= len; } LaneSection * startLaneSection = NULL; int startLaneId = 0; double sSection = s; double d = 0.0; int lengthSegments; double currentT; LaneSection * currentLaneSection; int currentLaneId; for (int pseg = 0; pseg < numSegments; pseg++) { lengthSegments = 0; currentT = t; currentLaneSection = startLaneSection; currentLaneId = startLaneId; for (double currentS = s; currentS <= s + railLength; currentS += h) { if (currentS > (s + railLength - (h))) { currentS = (s + railLength); } if (road->getLaneSection(currentS) != currentLaneSection) { LaneSection * newLaneSection = road->getLaneSection(currentS); while (currentLaneSection && (currentLaneSection != newLaneSection)) { if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, road->getLaneSectionEnd(currentLaneSection->getStart())) + d; } currentLaneSection = road->getLaneSectionNext(currentLaneSection->getStart() + 1.0e-3); currentLaneId = road->getLaneNumber(currentLaneSection->getStart(), currentT); sSection = currentLaneSection->getStart(); } currentLaneSection = newLaneSection; currentLaneId = road->getLaneNumber(sSection, currentT); if (t < 0) { if (fabs(currentT) < currentLaneSection->getLaneSpanWidth(0, currentLaneId + 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId++; } d = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + currentT; } else if (t > 0) { if (currentT < currentLaneSection->getLaneSpanWidth(0, currentLaneId - 1, currentS) + currentLaneSection->getLaneWidth(currentS, currentLaneId)/2) { currentLaneId--; } d = currentT - currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS); } } if (t < 0) { currentT = -currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } else if (t > 0) { currentT = currentLaneSection->getLaneSpanWidth(0, currentLaneId, currentS) + d; } nextRailPoint = road->getRoadPoint(currentS + h, currentT); osg::Vec3 p3(nextRailPoint.x(), nextRailPoint.y(), nextRailPoint.z()); railPoint = road->getRoadPoint(currentS, currentT); if (t > 0) railPoint2 = road->getRoadPoint(currentS, currentT + 1.0); else railPoint2 = road->getRoadPoint(currentS, currentT - 1.0); n.set(railPoint2.x() - railPoint.x(), railPoint2.y() - railPoint.y(), railPoint2.z() - railPoint.z()); n.normalize(); osg::Vec3 negn = -n; osg::Vec3 p1(railPoint.x(), railPoint.y(), railPoint.z()); p1 += n * profile[pseg].x(); p1[2] += profile[pseg].y(); OutlineVertices->push_back(osg::Vec3(p1.x(), p1.y(), p1.z())); OutlineTexCoords->push_back(osg::Vec2((currentS/texlength), tcv[pseg])); osg::Vec3 p2(railPoint.x(), railPoint.y(), railPoint.z()); p2 += n * profile[pseg + 1].x(); p2[2] += profile[pseg + 1].y(); OutlineVertices->push_back(osg::Vec3(p2.x(), p2.y(), p2.z())); OutlineTexCoords->push_back(osg::Vec2((currentS/texlength), tcv[pseg+1])); lengthSegments += 2; osg::Vec3 up = p2 - p1; osg::Vec3 forward = p3 - p1; osg::Vec3 norm = up ^ forward; /* if(p1.z() == p2.z()) { norm.set(0,0,-1); } else if(p1.z() < p2.z()) { osg::Vec3 up = p2-p1; up.normalize(); osg::Vec3 right; if(t>=0) { right= up ^ negn; } else { right= up ^ n; } right.normalize(); norm = up ^ right; norm.normalize(); } else { osg::Vec3 up = p1-p2; up.normalize(); osg::Vec3 right; if(t>=0) { right= up ^ negn; } else { right= up ^ n; } right.normalize(); norm = up ^ right; norm.normalize(); } */ OutlineNormals->push_back(norm); OutlineNormals->push_back(norm); } osg::DrawArrays *OutlineBarrier = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, lengthSegments * pseg, lengthSegments); OutlineGeometry->addPrimitiveSet(OutlineBarrier); } osg::StateSet *OutlineStateSet = OutlineGeode->getOrCreateStateSet(); OutlineStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); if(numSegments>2) { osg::CullFace *cullFace = new osg::CullFace(); cullFace->setMode(osg::CullFace::BACK); OutlineStateSet->setAttributeAndModes(cullFace, osg::StateAttribute::ON); } if(textureFileName!="") { const char *fileName = coVRFileManager::instance()->getName(textureFileName.c_str()); if (fileName) { osg::Image *OutlineTexImage = osgDB::readImageFile(fileName); osg::Texture2D *OutlineTex = new osg::Texture2D; OutlineTex->setWrap(osg::Texture2D::WRAP_S, osg::Texture::REPEAT); OutlineTex->setWrap(osg::Texture2D::WRAP_T, osg::Texture::CLAMP); if (OutlineTexImage) OutlineTex->setImage(OutlineTexImage); OutlineStateSet->setTextureAttributeAndModes(3, OutlineTex, osg::StateAttribute::ON); osg::AlphaFunc *alphaFunc = new osg::AlphaFunc(); alphaFunc->setFunction(osg::AlphaFunc::GEQUAL, 0.1f); OutlineStateSet->setAttributeAndModes(alphaFunc, osg::StateAttribute::ON); } else { std::cerr << "ERROR: no texture found named: "<< textureFileName<< std::endl; } } return OutlineGeode; }
osg::Geode *Road::createRoadGeode() { roadGeode = new osg::Geode(); //int n = 100; //double h = length/n; double h = 0.5; double texlength = 10.0; double texwidth = 10.0; std::map<double, LaneSection *>::iterator lsIt; LaneSection *ls; for (lsIt = laneSectionMap.begin(); lsIt != laneSectionMap.end(); ++lsIt) { double lsStart; double lsEnd; std::map<double, LaneSection *>::iterator nextLsIt = lsIt; ++nextLsIt; ls = (*lsIt).second; lsStart = ls->getStart(); if (lsStart > length) { std::cerr << "Inconsistency: Lane Section defined with start position " << lsStart << " not in road boundaries 0 - " << lsEnd << "!" << std::endl; break; } else if (nextLsIt == laneSectionMap.end()) { lsEnd = length; } else { lsEnd = (*(nextLsIt)).second->getStart(); if (lsEnd > length) lsEnd = length; } osg::Geometry *roadGeometry; roadGeometry = new osg::Geometry(); roadGeode->addDrawable(roadGeometry); osg::Vec3Array *roadVertices; roadVertices = new osg::Vec3Array; roadGeometry->setVertexArray(roadVertices); osg::Vec3Array *roadNormals; roadNormals = new osg::Vec3Array; roadGeometry->setNormalArray(roadNormals); roadGeometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); osg::Vec2Array *roadTexCoords; roadTexCoords = new osg::Vec2Array; roadGeometry->setTexCoordArray(0, roadTexCoords); osg::Vec4Array *roadMarks; roadMarks = new osg::Vec4Array; roadGeometry->setVertexAttribArray(6, roadMarks); roadGeometry->setVertexAttribBinding(6, osg::Geometry::BIND_PER_VERTEX); osg::DrawArrays *roadBase; int firstVertLane = 0; int numVertsLane = 0; for (int i = (ls->getNumLanesLeft()); i >= -(ls->getNumLanesRight()); --i) { if (i == 0) continue; bool lastRound = false; //std::cout << "Lane: " << i << ", lsStart: " << lsStart << ", lsEnd: " << lsEnd << std::endl; for (double s = lsStart; s < (lsEnd + h); s += h) { if (s > lsEnd) { //std::cout << "Last round: s = " << s << ", lsEnd: " << lsEnd << std::endl; s = lsEnd; lastRound = true; } RoadPoint pointLeft; RoadPoint pointRight; double disLeft, disRight; RoadMark *markLeft; RoadMark *markRight; if (i < 0) { getLaneRoadPoints(s, i, pointLeft, pointRight, disLeft, disRight); markLeft = ls->getLaneRoadMark(s, i + 1); markRight = ls->getLaneRoadMark(s, i); } else { getLaneRoadPoints(s, i, pointRight, pointLeft, disRight, disLeft); markLeft = ls->getLaneRoadMark(s, i); markRight = ls->getLaneRoadMark(s, i - 1); } double width = fabs(disLeft - disRight); //std::cerr << "s: " << s << ", i: " << "Outer mark width: " << markOut->getWidth() << ", inner mark width: " << markIn->getWidth() << std::endl; //std::cerr << "s: " << s << ", i: " << i << ", width: " << width << std::endl; //std::cout << "s: " << s << ", i: " << i << ", left Point: x: " << pointLeft.x() << ", y: " << pointLeft.y() << ", z: " << pointLeft.z() << std::endl; //std::cerr << ", outer Point: x: " << pointOut.x() << ", y: " << pointOut.y() << ", z: " << pointOut.z() << std::endl; //std::cout << "s: " << s << ", i: " << i << ", inner Point: x: " << pointIn.nx() << ", y: " << pointIn.ny() << ", z: " << pointIn.nz(); //std::cout << ", outer Point: x: " << pointOut.nx() << ", y: " << pointOut.ny() << ", z: " << pointOut.nz() << std::endl; roadVertices->push_back(osg::Vec3(pointLeft.x(), pointLeft.y(), pointLeft.z())); roadNormals->push_back(osg::Vec3(pointLeft.nx(), pointLeft.ny(), pointLeft.nz())); roadTexCoords->push_back(osg::Vec2(s / texlength, 0.5 + disLeft / texwidth)); roadMarks->push_back(osg::Vec4(-markLeft->getWidth() / width, -markRight->getWidth() / width, -markLeft->getType(), -markRight->getType())); roadVertices->push_back(osg::Vec3(pointRight.x(), pointRight.y(), pointRight.z())); roadNormals->push_back(osg::Vec3(pointRight.nx(), pointRight.ny(), pointRight.nz())); roadTexCoords->push_back(osg::Vec2(s / texlength, 0.5 + disRight / texwidth)); roadMarks->push_back(osg::Vec4(markLeft->getWidth() / width, markRight->getWidth() / width, markLeft->getType(), markRight->getType())); numVertsLane += 2; if (lastRound) s = lsEnd + h; } roadBase = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, firstVertLane, numVertsLane); roadGeometry->addPrimitiveSet(roadBase); firstVertLane += numVertsLane; numVertsLane = 0; } } //osg::StateSet* roadStateSet = roadGeode->getOrCreateStateSet(); //osg::PolygonMode* polygonMode = new osg::PolygonMode(osg::PolygonMode::FRONT_AND_BACK, osg::PolygonMode::LINE); //roadStateSet->setAttributeAndModes(polygonMode); roadGeode->setName(this->id); return roadGeode; }