#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<)
{
angle = angle + 1.57;
}
}
else
{
angle = -1.57 - atan((iter1->y() - position1.y()) / (iter1->x() - position1.x()));
if (angle>)
{
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(), ));
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(, ,, , );
return viewer1->run();
}