#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(); }