OpenSceneGraph之场景图与矩阵变换

179 阅读4分钟

OSG代码整体结构

捕获.PNG

根节点(Node):全局只能有唯一一个根节点,Node类是绝大部分类类的基类。

组节点(Group):其下面可以有多个子节点,即可以产生分支。

叶节点(Geode): 不能再有分支的节点。

绘制体: 用于保存要渲染的数据,Drawable 是一个无法直接实例化的虚基类,有三个子类,其中最常用的子类就是osg::Geometry,通过叶节点Geode类的类方法addDrawable(绘制体对象名);将绘制体与叶节点进行绑定。

父节点的各种属性,纹理,状态,其子节点都默认自动继承。

各个类的关系: image.png

Referenced 类(命名空间:osg)实现了对内存区段的引用计数器功能,类似C++中的共享指针,是所有节点和数据的基类。

Transform 类 用于控制节点的空间属性变换。

变换节点之矩阵变换

变换节点(osg::Transform) :它是Group 类的子类,其中在矩阵变换时,用户应当使用 osg::MatrixTransform 或 在位置变换时,使用osg::PositionAttitudeTransform 来替代它,这两者均继承自 Transform类。

//要创建一个执行变换的MatrixTransform (矩阵变换)节点,首先要 创建变换矩阵Matrix 并将其关联到MatrixTransform:

osg::ref_ptr<osg::MatrixTransform> mt=new osg::MatrixTransform; 

osg::Matrix m;                    //创建了矩阵m
m.setTranslate(x, y, z);     //矩阵平移(x轴上的点移动x个单位,
                                          //y上的点移动y个单位,
                            //z上的点移动z个单位)
mt->setMatrix(m);          //将矩阵m与矩阵变换节点绑定

//同时进行平移,缩放,旋转的代码:
		osg::MatrixTransform* mt = new osg::MatrixTransform;
		mt->setMatrix(osg::Matrix::translate(v)*    
		osg::Matrix::scale(size,size,size)*	   
		osg::Matrix::rotate(osg::inDegrees(-90.0f),
                                             0.0f,0.0f,1.0f));
                
 //v表示移动量,是一个Vec3,比如(0, 0, 1)表示向z轴移动一个单位
//size表示物体缩放比例,如果size=2,则物体尺寸将放大2倍
//参数1为角度(弧度),后面3个为中心轴坐标
                            //(即绕哪个向量旋转。这里是绕z轴)
//先旋转再平移与先平移再旋转是不同的

使用 PositionAttitudeTransform (位置变换)节点可以实现使用 Vec3 位置坐标和一个四元数完成的变换操作

//OSG 使用 osg::Quat 来保存四元数方位数据
//四元数:一般可表示为a + bi+ cj + dk,其中a、b、c 、d是实数,i,j,k为
                              //虚数单位( i² = j² = k² = -1)
                                             
//对于i、j和k本身的几何意义可以理解为一种旋转,其中
//i旋转代表Z轴与Y轴相交平面中Z轴正向向Y轴正向的旋转,
//j旋转代表X轴与Z轴相交平面中X轴正向向Z轴正向的旋转,
//k旋转代表Y轴与X轴相交平面中Y轴正向向X轴正向的旋转,
//-i、-j、-k分别代表i、j、k旋转的反向旋转。

// 创建一个四元数,实现围绕 axis 旋转 theta 弧度
//float theta(.5f);        //旋转弧度
//osg::Vec3 axis(.707f, .707f, 0.f);  //中心轴坐标
//osg::Quat q0(theta, axis);    //保存该四元数


// 使用 yaw(绕 Z 轴)、pitch(绕 X 轴)、roll(绕 Y 轴)角度
// 创建一个四元数。
osg::Vec3 yawAxis(0.f, 1.f, 0.f);   //y轴上的点移动1个单位
osg::Vec3 pitchAxis(1.f, 0.f, 0.f);   //x轴上的点移动1个单位
osg::Vec3 rollAxis(0.f, 0.f, 1.f);    //z轴上的点移动1个单位
osg::Quat q1(yawRad, yawAxis, pitchRad, 
            pitchAxis, rollRad, rollAxis);
//yawRad y轴上的点旋转弧度,pitchRad x轴上的点旋转弧度 rollRad z轴
                                            //上的点旋转弧度

组节点(Group)与Node节点

Group 类中的方法

添加一个子节点: bool addChild(Node* child);

删除一个子节点,如果输入节点不是子节点,那么放弃操作并返回 false: bool removeChild(Node* child);

用新的子节点替换一个子节点: bool replaceChild(Node* origChild, Node* newChild);

返回子节点的数目: unsigned int getNumChildren() const;

如果指定节点是一个子节点,那么返回 true: bool containsNode(const Node* node) const

Node类中的方法:

(typedef std::vector<Group*> ParentList;在该类中父节点列表的定义)

返回父节点的列表: const ParentList& getParents() const;

返回指定索引处父节点的指针: Group* getParent(unsigned int I);

返回父节点的数目 unsigned int getNumParents() const;