2.建立场景图形-2叶节点(Geode)和几何信息

〇、 提要:

《OSG快速入门指导》 下载地址

一 、Geometry 概述

osg::ref_ptr<osg::Node> createSceneGraph() 
{ 
 // 创建一个用于保存几何信息的对象
 osg::ref_ptr<osg::Geometry> geom = new osg::Geometry; 
 
 // 创建四个顶点的数组
 osg::ref_ptr<osg::Vec3Array> v = new osg::Vec3Array; 
 geom->setVertexArray( v.get() ); 
 v->push_back( osg::Vec3( -1.f, 0.f, -1.f ) ); 
 v->push_back( osg::Vec3( 1.f, 0.f, -1.f ) ); 
 v->push_back( osg::Vec3( 1.f, 0.f, 1.f ) ); 
 v->push_back( osg::Vec3( -1.f, 0.f, 1.f ) ); 
 
 // 创建四种颜色的数组
 osg::ref_ptr<osg::Vec4Array> c = new osg::Vec4Array; 
 geom->setColorArray( c.get() ); 
 geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 
 c->push_back( osg::Vec4( 1.f, 0.f, 0.f, 1.f ) ); 
 c->push_back( osg::Vec4( 0.f, 1.f, 0.f, 1.f ) ); 
 c->push_back( osg::Vec4( 0.f, 0.f, 1.f, 1.f ) ); 
 c->push_back( osg::Vec4( 1.f, 1.f, 1.f, 1.f ) ); 
 
 // 为唯一的法线创建一个数组
 osg::ref_ptr<osg::Vec3Array> n = new osg::Vec3Array; 
 geom->setNormalArray( n.get() ); 
 
 geom->setNormalBinding( osg::Geometry::BIND_OVERALL ); 
 n->push_back( osg::Vec3( 0.f, -1.f, 0.f ) ); 
 
 // 由保存的数据绘制四个顶点的多边形
 geom->addPrimitiveSet( 
 new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) ); 
 
 // 向 Geode 类添加几何体(Drawable)并返回 Geode 
 osg::ref_ptr<osg::Geode> geode = new osg::Geode; 
 geode->addDrawable( geom.get() ); 
 return geode.get(); 
}

1. 操作方法

  1. 创建顶点、颜色、法线的数组
  2. 创建osg::Geometry ,a.顶点、颜色、法线放入Geometry b.osg::DrawArrays指定绘制方式
  3. osg::Geode 场景实例化,几何信息放入 节点 中
setVertexArray
addDrawable
setColorArray
setNormalArray
顶点
osg::Geometry
Drawable
osg::Geode
颜色
法线

2.向量与数组类

说明用途
osg::Vec2二维浮点数组2D纹理
osg::Vec3三维浮点数组顶点、法线数据
以下是std::vector<>版本
osg::Vec2Arrayvec2的数组纹理坐标数组
osg::Vec3Arrayvec3的数组顶点数组
osg::Vec4Arrayvec4的数组颜色数组

提示:vector的用法 resize() operator[] 可以减少重新分配内存

3.Drawable类 - Geometry

  1. 用于保存渲染数据
  2. Drawable是一个无法直接实例化的虚基类
    Drawable 子类
osg::Drawable
osg::DrawPixels
glDrawPixels
osg::ShapeDrawble
预定义几何实体圆柱球
osg::Geometry
最灵活的
glVertexPointer
glNormalPointer
  1. Geometry
Geometry函数OpenGL对应函数说明
设置VBO数据(相当于)
setVertexArrayglVertextPointer()存入顶点,说白了就是核心的VAO+VBO
setColorArrayglColorPointer()存入颜色
setNormalArrayglNormalPointer()存入向量
分行指定其他变量和顶点是否在一行
setColorBindingsetColorBinding(osg::Geometry::BIND_PER_VERTEX)相当于Core模式下,在一行中
setNormalBindingsetColorBinding(osg::Geometry::OVERALL)相当于Core模式下,在每一行都有
addPrimitiveSet()addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) );设置渲染方式
  1. addPrimitiveSet(osg::PrimitiveSet*) 和 osg::DrawArrays
geom->addPrimitiveSet( new osg::DrawArrays( osg::PrimitiveSet::QUADS, 0, 4 ) ); 

解释:
addPrimitiveSet(↓)
a. osg::DrawArrays(QUADS)–按照顺序画方形
b. osg::DrawElementsUByte(QUADS)–按照指定顺序画方形
c. osg::DrawElementsUByte(POINTS)–按照指定顺序画点
这个就是最重要的那句–画

4.PrimitiveSet 类图

PrimitiveSet DrawArrays DrawElementsUByte DrawElementsUShort DrawElementsUInt
类型
DrawArrays按照顺序绘制DrawArrays(mode)
DrawElementsUInt按照指定点绘制

DrawArrays mode类型

OSGGL
osg::PrimitiveSet::POINTSGL_POINT
osg::PrimitiveSet::LINESGL_LINES

二、叶节点(Geode)

  1. 叶节点(Geode)不再有子节点了
  2. 保存几何(Geometry)以便渲染
  3. Geode::addDrawable(Drawable–Geometry)
addDrawable
Geode
Geometry
setVertexArray
顶点坐标
setColorArray+setColorBinding
颜色
addPrimitiveSet
PrimitiveSet
DrawArrays
DrawElements

三、组节点(osg::Group)

提要:Group 定义了针对子节点的接口,所有派生自Group的节点都支持子节点 (Geode是例外,他没有Group属性)
在这里插入图片描述

1 子接口 – 来自osg::Group

内部数据: std::vector< ref_ptr > child

class Group:public Node
{
	//内部数据
	std::vector< ref_ptr<Node> > child;
	//增 删 改 查
	bool addChild(Node*);
	bool removeChild(Node*);
	bool replaceChild(Node*);
	bool containChild(Node*);
	//个数
	unsigned int getNumChildren();
}

2 父接口–来自osg::Node

内部列表:std::vector<Group*> ParentList;
因为只是引用,不用管理析构,所有就是普通指针

class Node: public Object
{
	//定义类型
	typedef std::vector<Group*> ParentList;

	//查询
	ParentList& getParents();
	Group* getParent(unsigned int I);

}

对比

类型父接口-来自Node子接口-来自Group
存储std::vector<Group*> ParentList
ParentList parents
std::vector< ref_ptr<Node> > child


bool addChild(Node*);
bool removeChild(Node*);
bool replaceChild(Node*);
bool containChild(Node*)ParentList& getParents();
Group* getParent(unsigned int I);
Object Node parentList Group child
typedef std::vector<Group*> ParentList;

a. 子节点不需要管理父节点内存,直接保存普通指针,因为只有父节点可以释放子节点
b. 子节点保存了多个父节点
c. 这个指针是自动清除管理的
d. 通常:一个节点有一个父节点 (getNumParents( )==0),获取 getParent(0)

在这里插入图片描述

3.变换节点(Transform)

osg::Group 提供子节点功能
osg::Transform 纯虚类变换节点
osg::MatrixTransform
osg::PositionAttitudeTransform
Matrix 矩阵计算类
TransformMatrix
类名osg::Transform
osg:: MatrixTransform
osg::PositionAttitudeTransform
osg::Matrix
功能节点:记录所有变换矩阵-计算工具

3.1 Matrix 计算工具

osg::Matrix = 4×4 矩阵
Matrix 本身就是一个4×4 矩阵(16个float),是用来纯计算的

  1. 矩阵赋值
osg::Matrix m;
m(0,1) = 0.f;  //第0行 第1列
m(1,2)= 0.f;   //第1行 第2列
  1. 向量×矩阵 矩阵×矩阵
osg::Matrix T;
T.makeTranslate(x,y,z);

osg:Matrix R;
R.makeRotate(angle,axis);

Vec3 vPrime= v*R*T;

OSG和OpenGL的矩阵乘法对比

OSGOpenGL
左乘右乘
v2= v1×R×T;v2 = T×R×v1
OSG右乘按照数学乘法
  1. 矩阵右乘,导致节点连接方式变化
图示说明
首先,创建一个移动的MT的MatrixTransform,产生了移动节点


之后,创建一个旋转的MR的MatrixTransform,产生了旋转节点,把这个节点挂在移动节点下


最后,将Geode挂到旋转节点

3.2 矩阵变换节点(MatrixTransform)

类名类型说明
MatrixTransform节点Reference - 自然支持 ref_ptr<>就是为了接住matrix
Matrix计算工具普通类,不支持智能指针就是为了计算
osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
osg::Matrix m;
m.setTtranslate(x,y,z);
mt->setMatrix(m);

Matrix::set函数 ,按照列传入;

osg::Matrix m;
m.set( 1.f, 0.f, 0.f, 0.f, 
 0.f, 1.f, 0.f, 0.f, 
 0.f, 0.f, 1.f, 0.f, 
 10.f, 0.f, 0.f, 1.f );

osg::ref_ptr<osg::MatrixTransform> mt = new osg::MatrixTransform;
mt.setMatrix(m);

3.3 位置属性变换节点(PositionAttitudeTransform)

猜测:

MatrixTransformPositionAttitudeTransform
是AutoCAD中的Matrix矩阵是Bentley中的 yaw pitch roll 的方式
  1. 四元数 osg::Quat
    转多少度,绕着哪个轴

  2. 绕着一个轴转
    osg::Quat q0(弧度,轴);

Float angle(M_PI*0.5f);
osg::Vec3 axis(0.7f,0.7f,0.f);//倾斜的轴

osg::Quat q0(angle,axis);
  1. 绕着 yaw pitch roll 转
    osg::Quat q0(弧度yaw,弧度pitch,弧度roll,轴yaw,轴pitch,轴roll);
osg::Vec3 yawAxis(0.f,0.f,1.f);
osg::Vec3 pitchAxis(1.f,0.f,0.f);
osg::Vec3 rollAxis(0.f,1.f,0.f);

osg::Quat q1(yawRad,yawAxis,pitchRad,pitchAxis,rollRad,rollAxis);

四 LOD 细节层次节点

  1. LOD可以加子节点
Group 提供子节点功能
LOD,可以指定子节点
  1. LOD可以控制子节点的显示
    在这里插入图片描述
    解释:
    上图:LOD有三个子节点,当观察点的距离符合第一个子节点的有效范围时,才显示

  2. 代码

osg::ref_ptr<osg::Geode> geode1;
osg::ref_ptr<osg::Geode> geode2;

osg::ref_ptr<osg::LOD> lod = new osg::LOD;
lod->addChild(geode1.get(),0.f,1000.f);
lod->addChild(geode2.get(),950.f,1200.f);

0.f_1000.f
900.f_1200.f
LOD
geode1 子叶1
geode2 子叶2

解释:
a.当视点与这个子节点距离小于1000个单位时显示
b.LOD 是针对每一个子节点可以指定范围

五 开关节点(osg::Switch)

osg::ref_ptr<osg::Switch> sw= new osg::Switch;

sw->addChild(group0.get(),true);
sw->addChild(group1.get(),false);
sw->addChild(geode.get(),false);
true
true
false
Switch
group0组0
group1组1
geode子叶
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值