Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}