zoukankan      html  css  js  c++  java
  • osg 关于LOD

    class  TestLOD : public Group
    {
    public :

     TestLOD();

     /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
     TestLOD(const TestLOD&,const CopyOp& copyop=CopyOp::SHALLOW_COPY);

     META_Node(osg, TestLOD);

     typedef osg::BoundingSphere::vec_type vec_type;
     typedef osg::BoundingSphere::value_type value_type;

     virtual void traverse(NodeVisitor& nv);

     virtual bool addChild(Node *child);

     virtual bool addChild(Node *child, float min, float max);

     virtual bool removeChildren(unsigned int pos,unsigned int numChildrenToRemove=1);

     typedef std::pair<float,float>  MinMaxPair;
     typedef std::vector<MinMaxPair> RangeList;

     /** Modes which control how the center of object should be determined when computing which child is active.*/
     enum CenterMode
     {
      USE_BOUNDING_SPHERE_CENTER,
      USER_DEFINED_CENTER
     };

     /** Set how the center of object should be determined when computing which child is active.*/
     void setCenterMode(CenterMode mode) { _centerMode=mode; }

     /** Get how the center of object should be determined when computing which child is active.*/
     CenterMode getCenterMode() const { return _centerMode; }

     /** Sets the object-space point which defines the center of the osg::TestTestLOD. 
     center is affected by any transforms in the hierarchy above the osg::TestTestLOD.*/
     inline void setCenter(const vec_type& center) { _centerMode=USER_DEFINED_CENTER; _userDefinedCenter = center; }

     /** return the TestTestLOD center point. */
     inline const vec_type& getCenter() const { if (_centerMode==USER_DEFINED_CENTER) return _userDefinedCenter; else return getBound().center(); }


     /** Set the object-space reference radius of the volume enclosed by the TestTestLOD.
     * Used to determine the bounding sphere of the TestTestLOD in the absence of any children.*/
     inline void setRadius(value_type radius) { _radius = radius; }

     /** Get the object-space radius of the volume enclosed by the TestTestLOD.*/
     inline value_type getRadius() const { return _radius; }

     /** Modes that control how the range values should be interpreted when computing which child is active.*/
     enum RangeMode
     {
      DISTANCE_FROM_EYE_POINT,
      PIXEL_SIZE_ON_SCREEN
     };

     /** Set how the range values should be interpreted when computing which child is active.*/
     void setRangeMode(RangeMode mode) { _rangeMode = mode; }

     /** Get how the range values should be interpreted when computing which child is active.*/
     RangeMode getRangeMode() const { return _rangeMode; }


     /** Sets the min and max visible ranges of range of specific child.
     Values are floating point distance specified in local objects coordinates.*/
     void setRange(unsigned int childNo, float min,float max);

     /** returns the min visible range for specified child.*/
     inline float getMinRange(unsigned int childNo) const { return _rangeList[childNo].first; }

     /** returns the max visible range for specified child.*/
     inline float getMaxRange(unsigned int childNo) const { return _rangeList[childNo].second; }

     /** returns the number of ranges currently set.
     * An TestTestLOD which has been fully set up will have getNumChildren()==getNumRanges(). */
     inline unsigned int getNumRanges() const { return _rangeList.size(); }

     /** set the list of MinMax ranges for each child.*/
     inline void setRangeList(const RangeList& rangeList) { _rangeList=rangeList; }

     /** return the list of MinMax ranges for each child.*/
     inline const RangeList& getRangeList() const { return _rangeList; }

     virtual BoundingSphere computeBound() const;

    protected :
     virtual ~TestLOD() {}

     CenterMode                      _centerMode;
     vec_type                        _userDefinedCenter;
     value_type                      _radius;

     RangeMode                       _rangeMode;
     RangeList                       _rangeList;

    };
    //--------------------------------------------------------------------
    TestLOD::TestLOD():
    _centerMode(USE_BOUNDING_SPHERE_CENTER),
    _radius(-1.0f),
    _rangeMode(DISTANCE_FROM_EYE_POINT)
    {
    }

    TestLOD::TestLOD(const TestLOD& TestLOD,const CopyOp& copyop):
    Group(TestLOD,copyop),
    _centerMode(TestLOD._centerMode),
    _userDefinedCenter(TestLOD._userDefinedCenter),
    _radius(TestLOD._radius),
    _rangeMode(TestLOD._rangeMode),
    _rangeList(TestLOD._rangeList)
    {
    }


    void TestLOD::traverse(NodeVisitor& nv)
    {
       float required_range = 0;
       if (_rangeMode==DISTANCE_FROM_EYE_POINT)
       {
        required_range = nv.getDistanceToViewPoint(getCenter(),true);//getCenter()得到包围盒的节点或者自定义节点
       }
       unsigned int numChildren = _children.size();
       if (_rangeList.size()<numChildren) numChildren=_rangeList.size();

       for(unsigned int i=0;i<numChildren;++i)
       {   
        if (_rangeList[i].first<=required_range && required_range<_rangeList[i].second)
        {
         _children[i]->accept(nv);//使用访问者渲染节点
        }
       }
     
    }

    BoundingSphere TestLOD::computeBound() const
    {
     if (_centerMode==USER_DEFINED_CENTER && _radius>=0.0f)
     {
      return BoundingSphere(_userDefinedCenter,_radius);
     }
     else
     {
      return Group::computeBound();
     }
    }

    bool TestLOD::addChild( Node *child )
    {
     if (Group::addChild(child))
     {

      if (_children.size()>_rangeList.size())
      {
       float maxRange = !_rangeList.empty() ? _rangeList.back().second : 0.0f;

       _rangeList.resize(_children.size(),MinMaxPair(maxRange,maxRange));
      }

      return true;
     }
     return false;
    }


    bool TestLOD::addChild(Node *child, float min, float max)
    {
     if (Group::addChild(child))
     {
      if (_children.size()>_rangeList.size()) _rangeList.resize(_children.size(),MinMaxPair(min,min));
      _rangeList[_children.size()-1].first = min;
      _rangeList[_children.size()-1].second = max;//把某个节点的最大值和最小值存入
      return true;
     }
     return false;
    }

    bool TestLOD::removeChildren( unsigned int pos,unsigned int numChildrenToRemove)
    {
     if (pos<_rangeList.size()) _rangeList.erase(_rangeList.begin()+pos, osg::minimum(_rangeList.begin()+(pos+numChildrenToRemove), _rangeList.end()) );

     return Group::removeChildren(pos,numChildrenToRemove);
    }

    void TestLOD::setRange(unsigned int childNo, float min,float max)
    {
     if (childNo>=_rangeList.size()) _rangeList.resize(childNo+1,MinMaxPair(min,min));
     _rangeList[childNo].first=min;
     _rangeList[childNo].second=max;
    }

  • 相关阅读:
    推荐一个c++小巧开源且跨平台的图像解码库
    设计模式---桥接模式
    redis数据结构及其使用场景、持久化、缓存淘汰策略
    mysql------explain工具
    mysql索引数据结构
    java8(2)--- Stream API
    java8(1)--- lambda
    springboot自动装配(2)---实现一个自定义自动装配组件
    springboot自动装配(1)---@SpringBootApplication注解怎么自动装配各种组件
    自己挖的坑跪着也要填完---mapper配置文件和java源文件在同一包下
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1673055.html
Copyright © 2011-2022 走看看