OpenSceneGraph开发预备知识

开发的预备知识

OpenSceneGraph开发时,需要调用各种各样的类方法,因此这里需要提前了解一些C++中的类的一些基本概念,可以参考这篇文章:一篇搞懂C++面向对象

向量

既有大小又有方向的量被称为向量

模长为1的向量被称为单位向量,n维向量的模长公式:

image.png

在OSG中坐标轴方向如图(V是在空间内的任意一个向量):

image.png

OSG中的向量类型

image.png

Byte类型就是char类型(字符类型),由上图可知,单精度浮点数Float类型的向量有两种定义方式。

向量(vector)对应的方法(以Vec3f类为例):

Vec3f()    //默认构造函数,建立一个零向量
Vec3f(float x,float y,float z)     //构造函数,直接设置向量的三个分量
Vec3f(const Vec2f& v2,float w)  //构造函数,通过已知的二维向量和一个第三分量的值来构建

float operator*(const Vec3f& )const   //执行两向量的点乘,并返回浮点数值
const Vec3f operator^(const Vec3f& )const   //执行两向量的叉乘,并返回新的向量
float& operator[](unsigned int i)     //获取向量中某一分量的值


float length()const      //计算向量的模长
float length2()const      //计算向量的模长的平方值

float normalize()    //对向量进行归一化处理,即向量模长变为1,返回值为改变前的向量模长

image.png

四元数

image.png
图中i,j,k为虚数,也可以理解为x,y,z三条坐标轴,前面三个表示向量轴的坐标,后面一个w表示要旋转的角度。

四元数可以表达物体绕任意向量轴的旋转!!!!!!!

image.png

V是一个三维空间里任意的向量。

OSG中使用Quat类来表示四元数。下面是该类的一些方法:

Quat()  //默认构造函数,构造一个没有旋转的四元数
Quat(double x,double y,double z,double w) //构造函数,直接设置四元数的四个分量
Quat(float angle,const Vec3f& axis)   //构造函数,使四元数沿某个向量轴旋转一定角度

const Quat operator*(const Quat& )const    //两个四元数相乘,相当于将两个旋转动作叠加

void makeRotate(
    double angle,         //使四元数沿某个向量轴旋转一定角度
    double x,double y,double z)
    
void makeRotate(
    double angle,         //使四元数沿某个向量轴旋转一定角度
    const Vec3f& vec) 
    
    
void makeRotate(
    float angle1,const Vec3f& axis1,
    float angle2,const Vec3f& axis2,
    float angle3,const Vec3f& axis3) 
//使四元数沿3个坐标轴各自旋转一定角度

void makeRotate(
const Vec3f& vec1,    //使四元数从向量轴vec1旋转到向量轴vec2
const Vec3f& vec2)

image.png

矩阵

OSG中表达矩阵的类是Matrix类(矩阵4x4),osg::Matrixf或osg::Matrix表示矩阵中的元素为float浮点数,osg::Matrixd表示矩阵中的数为double浮点数。

下面是该类的一些方法:

Matrix()   //默认构造函数,这将构建一个单位矩阵
Matrix(
double,double,double,double,    //构造函数,构建4x4的矩阵
double,double,double,double,
double,double,double,double,
double,double,double,double)

double operator()(int row,int col)   //获取指定行列的矩阵元素

bool invert(const Matrixd& ) //生成指定矩阵的逆矩阵并传递给当前矩阵

Vec3d preMult(const Vec3d& )    //矩阵右乘一个行向量。常用于向量的空间变换
Vec3d preMultTranslate(const Vec3d& )   //矩阵右乘一个平移向量
Vec3d preMultRotate(const Vec3d& )   //矩阵右乘一个旋转向量
Vec3d preMultScale(const Vec3d& )   //矩阵右乘一个缩放向量


Martrixd operator*(const Matrixd& )const   //矩阵相乘,叠加两个矩阵的效果

static Martrixd translate(const Vec3d& )  //定义一个平移矩阵
static Martrixd rotate(const Quat& )  //定义一个旋转矩阵
static Martrixd scale(const Vec3d& )  //定义一个缩放矩阵

static Matrixd frustum(        //设置透视投影矩阵
double left,double right,
double bottom,double top,
double zNear,double zFar)

static Matrixd lookAt(      //设置一个观察矩阵
    const Vec3d& eye,
    const Vec3d& center,
    const Vec3d& up)

image.png
image.png

上面代码先执行了Z轴方向的放大,再执行了X方向的旋转,最后执行了Y轴的平移

下面这段代码与上面的代码效果一样。
image.png

包围体

包围体主要用于记录一些必要的属性信息(如中心,包围半径等),分为包围球和包围盒。

image.png

包围球采用BoundingSphereImpl类来定义,下面是该类的一些方法:

BoundingSphereImpl(            //构造函数,传入包围球中心和半径
const vec_type& center,
value_type radius)

void expandRadiusBy(const vec_type& )   //拓展包围球,使其能容纳指定的顶点,
                                        //且在拓展时不会变动当前包围球的中心
                                        
void expandBy(const vec_type& )   //拓展包围球,使其能容纳指定的顶点,
                                        //且在拓展时会变动当前包围球的中心

void expandRadiusBy(const BoundingSphereImpl& ) //拓展包围球,使其能容纳指定的包围球,
                                        //且在拓展时不会变动当前包围球的中心
                                        
void expandBy(const BoundingSphereImpl& )   //拓展包围球,使其能容纳指定的包围球,
                                        //且在拓展时会变动当前包围球的中心

void expandRadiusBy(const BoundingBoxImpl& )    //拓展包围球,使其能容纳指定的包围盒,
                                        //且在拓展时不会变动当前包围球的中心
                                        
                                        
void expandBy(const BoundingBoxImpl& ) //拓展包围球,使其能容纳指定的包围盒,
                                        //且在拓展时会变动当前包围球的中心

bool contains(const vec_type& )const    //判断包围球是否含有某个顶点

bool intersects(const BoundingSphereImpl& )const 
                                    //判断包围球是否与另一个包围球相交

image.png

包围盒采用BoundingBoxImpl类来定义,该类的方法与包围球类似,这里就不一一赘述了。

下图最后一个方法是包围盒独有的:
image.png

数组对象

OSG中数组类的基类是Array

下面是该类的一些方法:

Array(
Type arrayType,
GLint dataSize,      //构造函数,三个参数为 数组类型,
                    //各元素分量数(即各个数据的大小),数据类型
GLenum datatype)

const GLvoid* getDataPointer() const  //虚函数,获取数组第一个元素的地址指针
unsigned int getTotalDataSize() const  //虚函数,获取数组元素的总大小,
                                        //即元素个数*各元素分量数
                                        
unsigned int getNumElements() const  //虚函数,获取数组元素的总个数

image.png

例程代码:
image.png
image.png

OSG内存管理机制

image.png

总结下来就是每个对象都类似于C++11里面的智能指针的共享指针一样,关于C++共享指针,可以参考这篇文章:C++11智能指针详解

image.png

OSG中的智能指针

OSG中的智能指针类似于C++中的共享指针,OSG中智能指针形式:osg::ref_ptr<>

例程代码:

image.png
捕获.PNG

方法:

.get()   //通过智能指针获得所指对象地址,智能指针仍然指向对象地址
.release()    //真正获得了对象地址,且原智能指针已置空

image.png
image.png

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

freejackman

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值