场景的组织结构场景图形采用一种自顶向下的,分层的树状数据结构来组织空间数据集,以提升渲染的效率下图描述了一个场景图形,其中包含了地形,奶牛和卡车的模型1.场景图的空间数据组织形式osgosg提供了非常丰富的提供了非常丰富的GroupGroup节点,实现某些特定节点,实现某些特定功能,下面分别介绍:功能,下面分别介绍:(3.1)(3.1)空间变换节点空间变换节点osg::Transformosg::Transform通过改变自身在三维空间的位置和姿态,进而影响通过改变自身在三维空间的位置和姿态,进而影响其子节点的空间位置变化为了正确使用该节点,其子节点的空间位置变化为了正确使用该节点,需要用到需要用到绝对参考系绝对参考系(absolute reference frame):(absolute reference frame):只是作用于绝对坐标系只是作用于绝对坐标系相对参考系相对参考系(relative reference frame)(relative reference frame)::只是作用于给定对象的局部坐标系只是作用于给定对象的局部坐标系////设置节点的参考坐标系设置节点的参考坐标系void setReferenceFrame(ReferenceFrame rf)void setReferenceFrame(ReferenceFrame rf)osg::MatrixTransform类:直接设置空间变换矩阵//设置空间变换矩阵void setMatrix(const Matrix& mat);//获取空间变换矩阵const Matrix& getMatrix()const;osg::MatrixModel-view transformations can be done with osg::Matrix, so osg::Matrix is a very kind of important data type.osg::Matrix is 4*4.n nmakeTranslate(),makeRotate(),makeScale() reset the current matrix and create a 4*4 translation, rotation, and scale matrix. n nStatic method can create a new matrix:translate(), rotate(),scale().osg::Matrixosg::Matrix mat1=osg::Matrix::scale(sx,sy,sz);osg::Matrix mat2=osg::Matrix::translate(tx,ty,tz);osg::Matrix resultMat=mat1*mat2;osg::MatrixTransformosg::MatrixTransform is also a node in scene. It can manipulate the position and attitude of a model by internally applied 4*4 matrix.two member functions:void setMatrix();osg::Matrix getMatrix();osg::PositionAttitudeTransform类:直接设置平移、旋转和缩放值,比较直观。
//设置和获取平移的距离void setPosition(const Vec3&);const Vec3& getPosition()const;//设置和获取旋转的四元数void setAttitude(const Quat& quat);const Quat& getAttitude()const; osg::PositoinAttitudein the development practice, osg::MatrixTransform is not easy to use. So we have osg::PositionAttitude. this class provides several public member funcitons:void setPosition();void setScale();void setAttitude();the first two require osg::Vec3 as input value.osg::PositoinAttitudesetAttitude() uses osg::Quat variable as the parameter.setAttitude() uses osg::Quat variable as the parameter.osg::Quat is a quaternion, which is used to represent an osg::Quat is a quaternion, which is used to represent an orientation. we can define a quaternion instance as orientation. we can define a quaternion instance as follow:follow:osg::Quat quat(xAngle,osg::X_AXIS,osg::Quat quat(xAngle,osg::X_AXIS, yAngle,osg::Y_AXIS, yAngle,osg::Y_AXIS, zAngle,osg::z_AXIS); zAngle,osg::z_AXIS);// // 创建一个四元数,实现围绕创建一个四元数,实现围绕axis axis 旋转旋转theta theta 弧度。
弧度 Float theta( M_PI * .5f );Float theta( M_PI * .5f ); osg::Vec3 axis( .707f, .707f, 0.f ); osg::Vec3 axis( .707f, .707f, 0.f ); osg::Quat q0( theta, axis ); osg::Quat q0( theta, axis );////获取节点的参考坐标系获取节点的参考坐标系ReferenceFrame getReferenceFrame()const;ReferenceFrame getReferenceFrame()const;////计算从局部坐标系到世界坐标系的级联矩阵,计算从局部坐标系到世界坐标系的级联矩阵,bool computeLocalToWorldMatrix(Matrix& m,bool computeLocalToWorldMatrix(Matrix& m, NodeVisitor* nv)const; NodeVisitor* nv)const;////计算从世界坐标系到局部坐标系的级联矩阵计算从世界坐标系到局部坐标系的级联矩阵bool computeWorldToLocalMatrix(Matrix& m,bool computeWorldToLocalMatrix(Matrix& m, NodeVisitor* nv)const NodeVisitor* nv)const在实际开发中,常用在实际开发中,常用osg::Transformosg::Transform的派生类:的派生类:osg::MatrixTransformosg::MatrixTransform类类osg::PositionAttitudeTransformosg::PositionAttitudeTransform类类osg::DOFTransformosg::DOFTransform类类////设置和获取缩放的倍数设置和获取缩放的倍数void setScale(const Vec3&);void setScale(const Vec3&);const Vec3& getScale()const;const Vec3& getScale()const;////设置和获取缩放与旋转的轴心位置设置和获取缩放与旋转的轴心位置void setPivotPoint(const Vec3&);void setPivotPoint(const Vec3&);const Vec3& getPivotPoint()const;const Vec3& getPivotPoint()const;osg::DOFTransformosg::DOFTransform类:即自由度节点,通过对三种基类:即自由度节点,通过对三种基本旋转量,即航偏角度本旋转量,即航偏角度(Heading/Yaw,(Heading/Yaw,沿沿Z Z轴旋转轴旋转) )、、摇摆角度摇摆角度(pitch,(pitch,沿沿Y Y轴旋转轴旋转) )、横滚角度、横滚角度(Roll,(Roll,沿沿X X轴旋轴旋转转) )的复合运算,得到以旋转为主的空间变换结果。
的复合运算,得到以旋转为主的空间变换结果(3.2)开关节点osg::Switch类其作用是隐藏和显示某些节点,即控制节点的显示其作用是隐藏和显示某些节点,即控制节点的显示////添加一个子节点并设置其开关值添加一个子节点并设置其开关值bool addChild(Node* child,bool);bool addChild(Node* child,bool);////设置给定子节点的开关值设置给定子节点的开关值void setValue(unsigned int pos,bool);void setValue(unsigned int pos,bool);////获取给定位置的子节点的开关值获取给定位置的子节点的开关值bool getValue(unsigned int pos)const;bool getValue(unsigned int pos)const;(3.3)细节层次节点osg::LOD类(3.4)相机节点osg::CameraNode类(3.5)渲染属性节点代码举例osg::ref_ptr geode;osg::ref_ptr geode;osg::ref_ptr lod = new osg::LOD;osg::ref_ptr lod = new osg::LOD;// // 当距离在当距离在0.f 0.f 与与1000.f 1000.f 之间时,显示之间时,显示geodegeode。
lod->addChild( geode.get(), 0.f, 1000.f );lod->addChild( geode.get(), 0.f, 1000.f );如果子节点的范围有交叠,如果子节点的范围有交叠,LOD LOD 将同时显示多个子节点将同时显示多个子节点osg::ref_ptr geode0, geode1;osg::ref_ptr geode0, geode1;osg::ref_ptr lod = new osg::LOD;osg::ref_ptr lod = new osg::LOD;// // 当距离在当距离在0.f 0.f 与与1050.f 1050.f 之间时,显示之间时,显示geode0geode0lod->addChild( geode0.get(), 0.f, 1050.f );lod->addChild( geode0.get(), 0.f, 1050.f );// // 当距离在当距离在950.f 950.f 与与2000.f 2000.f 之间时,显示之间时,显示geode1geode1。
lod->addChild( geode1.get(), 950.f, 2000.f );lod->addChild( geode1.get(), 950.f, 2000.f );// // 因此,当距离在因此,当距离在950.f 950.f 到到1050.f 1050.f 之间时,将同时显示之间时,将同时显示//geode0 //geode0 和和geode1geode1LOD的自定义中心点n n缺省条件下,缺省条件下,LOD LOD 计算视点到物体包络体中心点的距离计算视点到物体包络体中心点的距离如果这样并不符合渲染要求,那么用户可以指定一个自定如果这样并不符合渲染要求,那么用户可以指定一个自定义的中心点义的中心点n n代码举例:代码举例:osg::ref_ptr lod = new osg::LOD;osg::ref_ptr lod = new osg::LOD;// // 使用用户定义的中心点来计算距离使用用户定义的中心点来计算距离lod->setCenterMode(lod->setCenterMode( osg::LOD::USER_DEFINED_CENTER ); osg::LOD::USER_DEFINED_CENTER );// // 设置自定义中心点的设置自定义中心点的X X 坐标坐标1010,,Y Y 坐标坐标100100。
Lod->setCenter( osg::Vec3( 10.f, 100.f, 0.f ) );Lod->setCenter( osg::Vec3( 10.f, 100.f, 0.f ) );n n如果要重新设置距离计算的缺省特性为物体的包络球,如果要重新设置距离计算的缺省特性为物体的包络球, 可以调用可以调用osg::LOD::setCenterMode(osg::LOD::USE_BOUNDIosg::LOD::setCenterMode(osg::LOD::USE_BOUNDING_SPHERE_CENTER )NG_SPHERE_CENTER );;。