OpenSG
节点核心
一、变换核心
1、
变换核心
图形的变换是通过变换核心实现的,先定义一个节点,将该节点的核心设为变换核心,在变换核心中放置变换矩阵,并将需要变换的图形作为该变换节点的子节点,此时变换节点的所有字节点均根据变换节点的核心中变换矩阵完成图形变换。具体步骤如下:
1、
定义变换矩阵:
Matrix m;
2、
对变换矩阵进行变换,使之满足变换要求。
3、
定义变换核心:
TransformPtr planetTransform;
4、
通过
setMatrix()
方法设置变换矩阵:
planetTransform->setMatrix(m);
5、
定义变换节点:
NodePtr planetTransformNode = Node::create();
6、
将变换核心作为变换节点的核心:
planetTransformNode->setCore(planetTransform);
7
、定义需要变换的图形:
NodePtr planet = makeSphere(3, 3);
8
、添加需要变换的图形节点作为该变换节点的字节点
planetTransformNode->addChild(planet);
整个变换树的构造可以有不同种方法,其中之一为按照逻辑顺序构建图
形变化树,对需要变换多次的图形经过多步变换完成,该种方法逻辑清晰,
但效率不高,另一种是将变换的图形均作为根节点的字节点,所有的变换在
一次变换中完成,该种方法可能与现实逻辑不符,但有较高的效率。
注:当我们需要通过多次变换才能得到最终变换结果时,我们必须将变
换矩阵依次相乘,否则无法得到正确结果。
2
、变换矩阵
变换矩阵式图形变换中的重中之重,图形变换是通过对象坐标乘以变换节点的变换核心中的变换矩阵得到的,基本的图形变换有平移变换、缩放变换,旋转变换等,其他复杂变换通过基本图形变换的组合得到。基本的矩阵变换操作如下:
1
、矩阵规格化:
m.setIdentity()
2
、设置矩阵的平移变换:
m.setTranslate(20,0,0,)
3
、设置矩阵旋转变换:
m.setRotate(planetRot)
注:参数
planetRot
为
Quaternion
类型
4
、设置矩阵缩放变换:
m.setScale()
5
、设置矩阵各种变换:
m.setTransform()
该函数被重载多次,参数可以为:
const VectorType3f &t
const QuaternionType &r
const VectorType3f &t, const QuaternionType &r
const VectorType3f &t, const QuaternionType &r, const VectorType3f &s
const VectorType3f &t, const QuaternionType &r, const VectorType3f &s,
const QuaternionType &so
const VectorType3f &translation, const QuaternionType &rotation, const
VectorType3f &scaleFactor, const QuaternionType &scaleOrientation, const
VectorType3f ¢er
5
、矩阵相乘:
r.mult(t) //
在
r
中存放相乘结果
5
、矩阵赋值:
m.setValue()
6
、矩阵转置:
m.transposed()
二、
综合变换核心
综合变换核心完成了对图形变换矩阵的封装,它使得我们不用首先一次
性构造完毕变换矩阵,再将最终变换矩阵添加到变换核心中去;而是在综合变换核心中分别设置平移变换矩阵、旋转变换矩、缩放变换矩阵等基本变换矩阵,该核心自动
所有设置的变换矩阵的乘积作为最终变换矩阵。
当我们需要改变某一个或几个变换时我们仅需要对所需变换的相应变换矩阵进行设置,而不必重新构造整体变换矩阵。
综合变换核心的定义:
ComponentTransformPtr ct = ComponentTransform::create()
综合变换核心的平移变换:
ct->setTranslation(Vec3f(20,0,0))
综合变换核心的旋转变换:
ct->setRotation(Quaternion(0,1,0),PI/4)
综合变换核心的缩放变换:
ct->setScale(Vec3f(1,3,1))
beginEditCP(ct, ComponentTransform::TranslationFieldMask |
ComponentTransform::RotationFieldMask);
ct->setTranslation(Vec3f(20,0,0));
ct->setRotation(Quaternion(Vec3f(0,1,0),PI/4));
endEditCP(ct, ComponentTransform::TranslationFieldMask |
ComponentTransform::RotationFieldMask);
注:在综合变换核心中
三、
材质
1
、材质属性的设置
材质是物体的固有属性,包括物体对漫反射光、镜面反射光、环境光等光的反射程度以及物体的透明度、光泽度等特性。
物体材质的定义:
SimpleMaterialPtr m = SimpleMaterial::create()
对物体的漫反射程度的设置:
m->setDiffuse(Color3f(1,0,0))
对物体的镜面反射程度的设置:
m->setAmbient(Color3f(0.2,0.2,0.2))
对物体的镜面反射指数的设置:
m->setShininess(0.8)
对物体透明度的设置:
m->setTransparency(0.5)
beginEditCP(m,SimpleMaterial::DiffuseColorFileMask|
SimpleMaterial::AmbientColorFieldMask|
SimpleMaterial::TransparencyFiledMask|
SimpleMaterial::ShininessFieldMask)
m->setDiffuse(Color3f(1,0,0))
m->setAmbient(Color3f(0.2,0.2,0.2))
m->setTransparency(0.5)
endEditCP(m, SimpleMaterial::DiffuseColorFileMask|
SimpleMaterial::AmbientColorFieldMask|
SimpleMaterial::TransparencyFiledMask|
SimpleMaterial::ShininessFieldMask)
2
、材质的使用
材质不可以直接作为核心添加到节点中,它的使用有两种方式:
第一种方式是通过定义材质组指针(可理解为材质类型的核心指针,与变换类型核心节点类似)来实现,通过
setMaterial()
方法设置材质组指针,再将材质组指针作为核心添加到节点中,此种方法可以设置多个物体的材质属性,即对该节点以下的所有子节点进行材质属性设置。具体实现步骤如下:
1
、定义材质组核心变量:
MaterialGroupPtr mg = MaterialGroup::create()
2
、为材质组核心变量赋值:
beginEditCP(mg)
mg->setMaterial(m)
endEditCP(mg)
3
、将材质组核心添加到节点中:
NodePtr n = Node::create()
beginEditPtr(n)
n->setCore(mg)
n->addChild(someNode)
endEditPtr(n)
第二种方式是直接对几何体设置其材质属性。该种方式只能对特定的几何体的材质属性进行设置,而对其子节点没有影响。
GeometryPtr geo = Geometry::create()
Geo->setMaterial(mg)
四、
选择模式
OpenSG
中的选择模式是通过选择类型节点核心来实现的,我们定义一个选择类型的节点核心放入选择类型的节点中,将要显示的多个图形作为选择节点的子节点,我们可以通过设置该选择核心的
setChoise()
方法来选择显示该节点的那个子节点中的图形。
定义选择类型节点核心:
SwitchPtr switch = switch::create()
设置要选择的子节点:
switchsetChoise(2)
五、
细节水平
从不同的距离观察物体,我们看到的物体是不同的,当距离近时,我们更能够看清物体的细节,而当我们距离物体较远时我们无法看清物体的细节,在
OpenSG
中能通过
DistanceLOD
来实现这种效果,当然可能以后还有可能推出其他的由于观察者观察物体的角度不同而产生的不同效果的实现,但现在我们只有距离细节水平类型的节点核心可用。
定义距离细节水平核心:
DistanceLOD lod = DistanceLOD::create()
设置中心位置:
lod->getSFCenter()->setValue(Pnt3f(0,0,0))
设置距离:
lod->getMFRange()->push_back(200)