zoukankan      html  css  js  c++  java
  • OSG:幼儿园篇 第六章 碰撞检测类

    一.简介

    osgUtil::LineSegmentIntersector 类继承自 osgUtil::Intersector 类,用于检测指定线段和场景图形之间相交情况,该类提供了一种定义

    二.osgUtil::Intersector(相交类)

    三.osgUtil::LineSegmentIntersector(线段相交类)

    1.类定义

    
    
    typedef std::vector< Node* > NodePath;

    class
    OSGUTIL_EXPORT LineSegmentIntersector : public Intersector{

    public:
    //Intersection 线段是一个结构体 struct OSGUTIL_EXPORT Intersection
      {
      Intersection():ratio(-1.0),primitiveIndex(0) {}

        bool operator < (const Intersection& rhs) const { return ratio < rhs.ratio; }

        typedef std::vector<unsigned int>   IndexList;
        typedef std::vector<double>         RatioList;

        double                          ratio;
        osg::NodePath                   nodePath;
        osg::ref_ptr<osg::Drawable>     drawable;
        osg::ref_ptr<osg::RefMatrix>    matrix;
        osg::Vec3d                      localIntersectionPoint;
        osg::Vec3                       localIntersectionNormal;
        IndexList                       indexList;
        RatioList                       ratioList;
        unsigned int                    primitiveIndex;

        const osg::Vec3d& getLocalIntersectPoint() const { return localIntersectionPoint; }
        osg::Vec3d getWorldIntersectPoint() const { return matrix.valid() ? localIntersectionPoint * (*matrix) : localIntersectionPoint; }

        const osg::Vec3& getLocalIntersectNormal() const { return localIntersectionNormal; }
        osg::Vec3 getWorldIntersectNormal() const { return matrix.valid() ? osg::Matrix::transform3x3(osg::Matrix::inverse(*matrix),localIntersectionNormal) : localIntersectionNormal; }
      
        osg::Texture* getTextureLookUp(osg::Vec3& tc) const;

      };

     //Intersections 线段列表是一个集合
    typedef std::multiset<Intersection> Intersections;

    protectd:
      LineSegmentIntersector* _parent;
      osg::Vec3d _start;
      osg::Vec3d _end;
    
      Intersections _intersections;
    
    };
    class OSGUTIL_EXPORT LineSegmentIntersector : public Intersector
    {
    public:
      LineSegmentIntersector(const osg::Vec3d& start, const osg::Vec3d& end)
      LineSegmentIntersector(CoordinateFrame cf, const osg::Vec3d& start, const osg::Vec3d& end, LineSegmentIntersector* parent = NULL, osgUtil::Intersector::IntersectionLimit intersectionLimit = osgUtil::Intersector::NO_LIMIT);
      LineSegmentIntersector(CoordinateFrame cf, double x, double y);
      
      
      inline void insertIntersection(const Intersection& intersection) { getIntersections().insert(intersection); }
      inline Intersections& getIntersections() { return _parent ? _parent->_intersections : _intersections; }
      inline Intersection getFirstIntersection() { Intersections& intersectios = getIntersections(); return intersections.empty() ? Intersection() : *(intersections.begin()); }
    inline
    void setStart(const osg::Vec3d& start) { _start = start; } inline const osg::Vec3d& getStart() const { return _start; } inline void setEnd(const osg::Vec3d& end) { _end = end; } inline const osg::Vec3d& getEnd() const { return _end; } public: virtual Intersector* clone(osgUtil::IntersectionVisitor& iv) virtual bool enter(const osg::Node& node) virtual void leave() virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable) virtual void intersect(osgUtil::IntersectionVisitor& iv, osg::Drawable* drawable, const osg::Vec3d& s, cosnt osg::Vec3d& e) virtual void set() virtual bool containsIntersections(){ return !getIntersections().empty(); } static osg::Matrix getTransformation(osgUtil::IntersectionVisitor& iv, CoordinateFrame cf) protected: bool intersects(const osg::BoundingSphere& bs) bool intersectAndClip(osg::Vec3d& s, osg::Vec3d& e, const osg::BoundingBox& bb) };

    2.使用步骤

    #include <osgDB/ReadFile>
    #include <osgViewer/Viewer>
    #include <osg/Group>
    #include <osgFX/Scribe>
    #include <osgGA/GUIEventHandler>
    #include <osgUtil/LineSegmentIntersector>
    
    
    
    class CPickHandler : public osgGA::GUIEventHandler
    {
    
    public:
        CPickHandler(osgViewer::Viewer* viewer):mViewer(viewer){}
    
        //重写虚函数处理器
        virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
        {
            switch(ea.getEventType())
            {
    
            case (osgGA::GUIEventAdapter::PUSH):
                if(ea.getButton() == 1)
                {
                    //输入当前鼠标点击位置
                    Pick(ea.getX(), ea.getY());
                }
                return true;
            }
            return false;
        }
    
    protected:
    
        void Pick(float x, float y)
        {
            //点击位置是否发生射线交集,intersections里面存放了所有触碰到的节点
            osgUtil::LineSegmentIntersector::Intersections intersections;
            if(mViewer->computeIntersections(x, y, intersections))
            {
                //获取交集迭代器,begin是点击到距离我们最近的那个物体
                osgUtil::LineSegmentIntersector::Intersections::iterator hitr;
                for(hitr = intersections.begin(); hitr != intersections.end(); ++hitr)
                {
                    if(!hitr->nodePath.empty() && !(hitr->nodePath.back()->getName().empty()))
                    {    
                      {
                        //获取交集的节点路径
                        const osg::NodePath& np = hitr->nodePath;
                        for(int i = np.size() - 1; i >= 0; --i)
                        {
                            osgFX::Scribe* sc = dynamic_cast<osgFX::Scribe*>(np[i]);
                            if(sc != NULL)
                                if(sc->getNodeMask() != 0)
                                    sc->setNodeMask(0);
                        }
                      }
                    }
                }
            }
            
        }
        osgViewer::Viewer* mViewer;
    };
    
    
    int main(int, char**)
    {
        osgViewer::Viewer viewer;
        osg::ref_ptr<osg::Group> root = new osg::Group();
        root->addChild(osgDB::readNodeFile("cessna.osg"));
        osg::ref_ptr<osg::Node> cow = osgDB::readNodeFile("cow.osg");
        
    
        osg::ref_ptr<osgFX::Scribe> sc = new osgFX::Scribe();
        sc->addChild(cow.get());
    
        root->addChild(cow.get());
        root->addChild(sc.get());
    
        viewer.setSceneData(root.get());
        viewer.addEventHandler(new CPickHandler(&viewer));
        viewer.realize();
        viewer.run();
    
        return 0;
    }

    四.osgUtil::IntersectionVisitor(相交访问器)

  • 相关阅读:
    js 对象数组 排序
    sql 时间条件查询
    idea和Pycharm 等系列产品激活激活方法和激活码 100 年
    开源协议简介
    面试题
    VIM|基础命令
    git|基础命令
    VIM|复制
    lua|基础教程
    Printf格式输出详解
  • 原文地址:https://www.cnblogs.com/k5bg/p/11499117.html
Copyright © 2011-2022 走看看