How to attach roof to the buildings using osgearth

classic Classic list List threaded Threaded
1 message Options
Rambabu Rambabu
Reply | Threaded
Open this post in threaded view
|

How to attach roof to the buildings using osgearth

Hi iam working on creation of buildings on the terrain using osgearth,iam able to draw the roof but roof and buildings are not attaching how can i solve this ?

Buildings and roof code i mentioned below

Roof image
 


 virtual void apply(osg::Group& node)
        {
               
        osg::Group * group = dynamic_cast <osg::Group *> (&node);
        if (group) {
        osg::Geode * geode = dynamic_cast <osg::Geode *> (group);
        if (geode) {
        for (unsigned int i = 0; i < geode->getNumDrawables(); i++) {
        osg::Geometry * geometry = dynamic_cast <osg::Geometry *>(geode->getChild(i));
        if (geometry) {
        osg::Array * array = dynamic_cast <osg::Array *> (geometry->getVertexArray());
        if (array) {
        osg::Vec3Array * array3f = dynamic_cast <osg::Vec3Array *> (array);
        if (array3f) {
             if (checkifBuilding(*geometry))
            {
              //std::vector<osg::Vec3d> roofVec1;
                Buildings::buildingData tempData;
                tempData.buildingType = "buildings";
                for (unsigned int i = 0; i < array3f->size(); i = i++) { //storing the base values
                double x = (*array3f)[i].x();
                double y = (*array3f)[i].y();
                double z = (*array3f)[i].z();
                osg::Vec3d temp(x, y, z);
tempData.vertices.push_back(osg::Vec3d(temp.y(), temp.x(), temp.z()));
                                                                                //roofVec1.push_back(osg::Vec3d(temp.y(), temp.x(), temp.z()));
                                                                        }
                                                                /* if (roofVec1.size() == 8)
                                                                        {
                                                                                buildingVertex.push_back(roofVec1);
                                                                        }*/
                                                                        _modelsObj->buildingsLatLonPosVec.push_back(tempData);
                                                                        std::cout << "it is a Building and Vertices :" << tempData.vertices.size()<< std::endl;
                                                                }
                                                        }
                                                }
                                        }
                                }

                        }
                }
                _level++;
                traverse(node);
                _level--;
        }

osg::ref_ptr<osg::Geometry> draw_BuildingWall(double dist, osg::ref_ptr<osg::Vec4Array> colors)
{
        cout << "Distance:" << dist;
        static int wallCount = 0;
        osg::ref_ptr<osg::Vec3Array> verticesArray = new osg::Vec3Array;
        verticesArray->push_back(osg::Vec3d(0, 0, 0));
        verticesArray->push_back(osg::Vec3d(0, 0, 20));
        verticesArray->push_back(osg::Vec3d(0, dist, 20));
        verticesArray->push_back(osg::Vec3d(0, dist, 0));

        osg::ref_ptr<osg::Geometry> quad = new osg::Geometry;
        quad->setVertexArray(verticesArray.get());
        quad->setColorArray(colors.get());
        quad->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
        quad->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
        wallCount++;
        return quad.release();
}

void Buildings::optimize_BuildingssRendering_WithRespectTo_CameraPosition()
{
   static double prevLat(0), prevLon(0);
   osg::Vec3d curCamPos = _ig->curCamMatrix.getTrans();
   osg::Vec3d curLatLonHt = IG::Utilities::instance()->convertXYZToLatLonHeight(curCamPos.x(),        curCamPos.y(), curCamPos.z());
  osgEarth::GeoMath mathObj;
  double distance = mathObj.distance(osg::DegreesToRadians(prevLat), osg::DegreesToRadians(prevLon), osg::DegreesToRadians(curLatLonHt.x()), osg::DegreesToRadians(curLatLonHt.y()));

        if (distance < 1000) return;

        if (buildingsRoot)
        {
                for (int i = 0; i < buildingsRoot->getNumChildren();)
                {
                        buildingsRoot->removeChild(i);
                }
                buildingsRoot.release();
        }

        buildingsRoot = new osg::Group();

        for (int building = 0; building < buildingsLatLonPosVec.size(); building++)
        {
                if (!buildingsLatLonPosVec[building].vertices.size()) continue;

                double distance = mathObj.distance(osg::DegreesToRadians(curLatLonHt.x()),      osg::DegreesToRadians(curLatLonHt.y()), osg::DegreesToRadians(buildingsLatLonPosVec[building].vertices[0].x()), osg::DegreesToRadians(buildingsLatLonPosVec[building].vertices[0].y()));
               
                if (distance > 1000) continue;

                osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
                colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.0f));

                osg::Vec3d origin = buildingsLatLonPosVec[building].vertices[0];
                for (int buildVertx = 0; buildVertx < (buildingsLatLonPosVec[building].vertices.size() - 1);)
                {
                        osg::Vec3d base1 = buildingsLatLonPosVec[building].vertices[buildVertx];
                        osg::Vec3d base2 = buildingsLatLonPosVec[building].vertices[++buildVertx];
                        distBtWn = mathObj.distance(osg::DegreesToRadians(base1.x()), osg::DegreesToRadians(base1.y()), osg::DegreesToRadians(base2.x()), osg::DegreesToRadians(base2.y()));
                        float bearingBtWn = osg::RadiansToDegrees(mathObj.bearing(osg::DegreesToRadians(base1.x()), osg::DegreesToRadians(base1.y()), osg::DegreesToRadians(base2.x()), osg::DegreesToRadians(base2.y())));

                        IG::Utilities::instance()->calculateDistBearBtw2Point(base1.x(), base1.y(), base2.x(), base2.y(),&distBtWn,&bearingBtWn);
                        distBtWn *= 1000;

                        osg::ref_ptr<osg::Geometry> quad;
                        quad = draw_BuildingWall(distBtWn, colors);
                        osg::ref_ptr<osg::Geode> root         = new osg::Geode;
                        osg::ref_ptr<osg::MatrixTransform> mx = new osg::MatrixTransform;
                        root->addDrawable(quad.get());


                      osg::Matrixd matrix_buildings;
                       
                        if (buildVertx  == 11)//Roof drawing coordinates
                        {
                                osg::ref_ptr<osg::Vec3Array> verticesArray = new osg::Vec3Array;
                                verticesArray->push_back(osg::Vec3d( 0.0,  distBtWn - 20.0, 0.0));
                                verticesArray->push_back(osg::Vec3d( 50.0, distBtWn - 20.0, 0.0));
                                verticesArray->push_back(osg::Vec3d( 45.0, 0.0, 10.0));
                                verticesArray->push_back(osg::Vec3d( 5.0, 0.0, 10.0));

                                osg::ref_ptr<osg::Vec3Array> verticesArray1 = new osg::Vec3Array;
                                verticesArray1->push_back(osg::Vec3d( 5.0,  0.0, 10.0));
                                verticesArray1->push_back(osg::Vec3d( 45.0, 0.0,10.0));
                                verticesArray1->push_back(osg::Vec3d( 50.0, distBtWn - 20.0, 20.0));
                                verticesArray1->push_back(osg::Vec3d( 0.0, distBtWn - 20.0, 20.0));

                                osg::ref_ptr<osg::Vec3Array> verticesArray2 = new osg::Vec3Array;
                                verticesArray2->push_back(osg::Vec3d( 45.0, 0.0, 10.0));
                                verticesArray2->push_back(osg::Vec3d( 50.0, distBtWn - 20.0, 0.0));
                                verticesArray2->push_back(osg::Vec3d( 50.0, distBtWn - 20.0, 20.0));

                                osg::ref_ptr<osg::Vec3Array> verticesArray3 = new osg::Vec3Array;
                                verticesArray3->push_back(osg::Vec3d( 5.0, 0.0, 10.0));
                                verticesArray3->push_back(osg::Vec3d( 0.0, distBtWn - 20.0, 0.0));
                                verticesArray3->push_back(osg::Vec3d( 0.0, distBtWn - 20.0, 20.0));

                                osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
                                colors->push_back(osg::Vec4(1.0f, 0.0f, 0.0f, 0.0f));

                                osg::ref_ptr<osg::Vec4Array> colors1 = new osg::Vec4Array;
                                colors1->push_back(osg::Vec4(0.0f, 1.0f, 0.0f, 0.0f));

                                osg::ref_ptr<osg::Vec4Array> colors2 = new osg::Vec4Array;
                                colors2->push_back(osg::Vec4(1.0, 1.0, 0.0, 0.0));

                                osg::ref_ptr<osg::Vec4Array> colors3 = new osg::Vec4Array;
                                colors3->push_back(osg::Vec4(1.0, 0.0, 1.0, 0.0));

                                osg::ref_ptr<osg::Geometry> quad1 = new osg::Geometry;
                                quad1->setVertexArray(verticesArray.get());
                                quad1->setColorArray(colors.get());
                                quad1->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
                                quad1->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, verticesArray->size()));

                                osg::ref_ptr<osg::Geometry> quad2 = new osg::Geometry;
                                quad2->setVertexArray(verticesArray1.get());
                                quad2->setColorArray(colors1.get());
                                quad2->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
                                quad2->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, verticesArray1->size()));

                                osg::ref_ptr<osg::Geometry> quad3 = new osg::Geometry;
                                quad3->setVertexArray(verticesArray2.get());
                                quad3->setColorArray(colors2.get());
                                quad3->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
                                quad3->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, verticesArray2->size()));

                                osg::ref_ptr<osg::Geometry> quad4 = new osg::Geometry;
                                quad4->setVertexArray(verticesArray3.get());
                                quad4->setColorArray(colors3.get());
                                quad4->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
                                quad4->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, verticesArray3->size()));

                                rootRoof->addDrawable(quad1);
                                rootRoof->addDrawable(quad2);
                                rootRoof->addDrawable(quad3);
                                rootRoof->addDrawable(quad4);
        root->addChild(rootRoof);
                               
                    }

        osg::Matrixd matrix;
                        IG::Utilities::instance()->calculateWorldMatrixFromLatLongHeight(base1.x(), base1.y(), base1.z(), matrix);
                        matrix.preMultRotate(osg::Quat(osg::DegreesToRadians(-bearingBtWn),osg::Vec3d(0,0,1)));
                        osg::ref_ptr<osg::MatrixTransform> mxTrns = new osg::MatrixTransform();
                        mxTrns->addChild(root.get());
                        //mxTrns->addChild(rootRoof);
                        mxTrns->setMatrix(matrix);
                        buildingsRoot->addChild(mxTrns.get());
                }

        }

        if (buildingsRoot)
        {
                _ig->getScene()->asGroup()->addChild(buildingsRoot.get());
                 prevLat = curLatLonHt.x();
                prevLon = curLatLonHt.y();
        }
}

Iam getting the output as below kept picture

Any Help is appreciated.

Thanks,
R.Rambabu