osg 场景漫游

#ifdef _WIN32
#include <Windows.h>
#endif // _WIN32

#include <osg/Group>
#include <osg/Camera>
#include <osgDB/ReadFile>
#include <osg/Node>

#include <osg/Geometry>
#include <osg/Image>
#include <osg/ShapeDrawable>
#include <osg/Texture2D>

#include <osg/MatrixTransform>
#include <osg/AnimationPath>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/DriveManipulator>
#include <osgGA/GUIEventHandler>
#include <osgGA/GUIEventAdapter>
#include <osgGA/GUIActionAdapter>

#include <osgGA/AnimationPathManipulator>

#include <osgUtil/LineSegmentIntersector>

#include <iostream>
using namespace std;


class PickHandler :public osgGA::GUIEventHandler
{
public:
    PickHandler(osgViewer::Viewer *viewerParam)
    {
        viewer1 = viewerParam;
        controls = new osg::Vec3Array;
    }

    osg::AnimationPath* createPath()
    {
        osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath;
        animationPath->setLoopMode(osg::AnimationPath::LOOP);

        float time = 0.0;
        float angle = 0.0;
        float degrees = osg::inDegrees(90.0);

        if (controls.valid())
        {
            osg::Vec3Array::iterator iter1 = controls->begin();
            for (;;)
            {
                osg::Vec3 position1(*iter1);
                iter1++;
                if (iter1 != controls->end())
                {
                    if (iter1->x() > position1.x())
                    {
                        angle = 1.57 - atan((iter1->y() - position1.y()) / (iter1->x() - position1.x()));
                        if (angle<0)
                        {
                            angle = angle + 1.57;
                        }
                    }
                    else
                    {
                        angle = -1.57 - atan((iter1->y() - position1.y()) / (iter1->x() - position1.x()));
                        if (angle>0)
                        {
                            angle = -(1.57 - angle);
                        }
                    }
                
                    osg::Quat rotation1(osg::Quat(degrees, osg::Vec3(1.0, 0.0, 0.0))*osg::Quat(-angle, osg::Vec3(0.0, 0.0, 1.0)));
                    animationPath->insert(time, osg::AnimationPath::ControlPoint(position1, rotation1));
                    time += calculateDistance(position1, *iter1);
                }
                else 
                {
                    break;
                }
            }
        }
    
        return animationPath.release();
    }

    float calculateDistance(osg::Vec3 vecStart,osg::Vec3 vecEnd)
    {
        float speed = 0.4;
        float dis1 = sqrt((vecStart.x() - vecEnd.x())*(vecStart.x() - vecEnd.x()) + (vecStart.y() - vecEnd.y())*(vecStart.y() - vecEnd.y()));
        return dis1*speed;
    }

    osg::Geode* createBox(osg::Vec3 centers)
    {
        osg::ref_ptr<osg::Geode> gnode = new osg::Geode;
        gnode->addDrawable(new osg::ShapeDrawable(new osg::Box(centers, 7.0, 7.0, 7.0)));
        return gnode.release();
    }

    bool handle(const osgGA::GUIEventAdapter& gea, osgGA::GUIActionAdapter& gaa) 
    {
        switch (gea.getEventType())
        {
        case osgGA::GUIEventAdapter::DOUBLECLICK:
            if (viewer1)
            {
                float x=0.0, y=0.0;
                x = gea.getX();
                y = gea.getY();
                //申请一个存放交叉点的集合
                osgUtil::LineSegmentIntersector::Intersections inters;
                // bool computeIntersections(float x,float y, osgUtil::LineSegmentIntersector::Intersections& intersections,osg::Node::NodeMask traversalMask = 0xffffffff);
                if (viewer1->computeIntersections(x,y,inters))
                {
                    osgUtil::LineSegmentIntersector::Intersections::iterator iter1 = inters.begin();
                    std::cout <<"x:"<< iter1->getWorldIntersectPoint().x()<<"     y:"<<iter1->getWorldIntersectPoint().y()<< std::endl;
                    //controls->push_back(iter1->getWorldIntersectPoint());
                    controls->push_back(osg::Vec3(iter1->getWorldIntersectPoint().x(), iter1->getWorldIntersectPoint().y(), 5));
                    viewer1->getSceneData()->asGroup()->addChild(createBox(iter1->getWorldIntersectPoint()));
                    //osg::ref_ptr<osg::Node> node2 = viewer1->getSceneData();
                    //osg::ref_ptr<osg::Group> group2 = new osg::Group;
                    //group2->addChild(node2);
                    //group2->addChild(createBox(iter1->getWorldIntersectPoint()));
                    //viewer1->setSceneData(group2);

                }
            }
            break;

        case osgGA::GUIEventAdapter::KEYDOWN:
            //F:70  0:96
            if (gea.getKey()== 0x20)
            {
                if (viewer1)
                {
                    osgGA::AnimationPathManipulator* animationPathManipulator1 = new osgGA::AnimationPathManipulator;
                    animationPathManipulator1->setAnimationPath(createPath());
                    viewer1->setCameraManipulator(animationPathManipulator1);
                }
            }

            break;

        default:
            break;
        }

        return false;
    }

private:
    osgViewer::Viewer *viewer1;
    osg::ref_ptr<osg::Vec3Array> controls;
};

int main()
{
    osg::ref_ptr<osgViewer::Viewer> viewer1 = new osgViewer::Viewer;
    osg::ref_ptr<osg::Group> group1 = new osg::Group;
    osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile("D:\\参考手册\\BIM\\osg\\build20190628.osgb");

    group1->addChild(node1.get());
    viewer1->setSceneData(group1.get());
    viewer1->addEventHandler(new PickHandler(viewer1));

    viewer1->setUpViewInWindow(200, 200,800, 600, 0);

    return viewer1->run();
}

posted @ 2019-07-03 11:05  西北逍遥  阅读(742)  评论(1编辑  收藏  举报