前言
最近在开发OSG的项目的时候,经常性的对坐标转换不理解,其中对场景的旋转、平移、缩放等操作所牵涉的矩阵变换还没有理解。刚好在《osg三维渲染引擎编程指南》书中的坐标系进行了详细学习。
1.1 坐标系统
1.世界坐标系
世界坐标系是一种特殊的坐标系,世界坐标系建立了描述其他坐标系所需要的参考框架,世界坐标系描述的是整个场景中的所有对象,可以理解为绝对坐标系。所有对象都是绝对坐标。在整体上讲,世界坐标系为所有对象提供了一个绝对的标准。从而避免了物体之间由于独立的坐标系所带来的坐标系混乱。
世界坐标系描述的问题是一些对象的初始位置以及场景中对象的变换的过程。其中描述的对象主要是摄像机和描绘的模型对象。
2.物体坐标系
物体坐标系主要是针对物体所建立的坐标系。其中在OSG的场景中,每个物体都有自己的坐标系。而当物体发生变换的时候,反映到坐标系中就是物体坐标系对于世界坐标系所发生的变换。
物体坐标系对于描述物体的位置非常的方便。假如场景中只使用世界坐标系来进行场景的描述,那么任何一个场景的变换计算量都会变的很大。然而在定义了物体的坐标系后变换就会变得相对容易的多了。只需要对物体坐标系和世界坐标系进行变换就可以实现最终的矩阵变换。
物体坐标系描述的对象一般是模型内部的对象。比如物体的顶点,物体的法向量和物体纹理坐标等等。
3.摄像机坐标系
摄像机坐标系对观察者的观看至关重要,摄像机坐标系和屏幕的坐标系相似,差别在于摄像机坐标系是3D的坐标系,屏幕坐标系是2D的坐标系.摄像机坐标是一种特殊的坐标系,该物体坐标系定义在摄像机的屏幕可视区域.摄像机坐标系管理者那些物体需要进行渲染,并且在屏幕上进行显示,其中主要解决的问题包括物体可是区域渲染,物体的遮挡显示等.因此摄像机坐标系的描述问题是非常复杂的.
OSG中采用的坐标系是左手坐标系,和OpenGL所使用的坐标系是相同的,但是他们的坐标轴不一样.左手坐标系如下图所示:
OSG中采用的X轴正方向向右,Y轴正方向朝里,Z轴正方向向上。
OSG中采用的X轴正方向向右,Y轴正方向朝上,Z轴正方向朝外。
两个坐标轴如下图所示:
1.2 坐标系变换
1.世界坐标系转物体坐标系
世界坐标系转物体坐标系是相对比较容易的,其描述的问题主要包括在物体身上。在OSG中,有下面的两个类实现了基本变换的过程:
osg::PositionAttitudeTransform; //位置变换类
osg::MatrixTransform;//矩阵变换类 ### 2. 物体坐标系转世界坐标系 物体坐标系转世界坐标系是有一定的难度的。对于场景中图形中的某一个Node节点,他和场景的根节点是存在一些变换节点的,如果要变换到根节点的世界坐标系,那么我们需要得到场景中根节点到场景中某个节点的所有变换节点。OSG的场景系统中提供了场景节点和其父节点的变换矩阵。这些变换矩阵中包括了相对的坐标。那么计算世界坐标系只需要对根节点和场景节点之间的所有变换矩阵相乘即可。 <br> OSG中提供了对于节点的访问机制。可以通过回调或者访问器来实现。其中OSG回调方式没有可操作性,并且会增加额外的计算开销。所以更多的是使用节点访问器来实现计算世界坐标系。OSG中节点访问器通过获得路经上的转换坐标进行连乘。具体步骤如下图所示:
3.世界坐标系转换屏幕坐标系
在场景中,所有的实体对象都需要一系列的变换最后才能在屏幕显示器上进行显示,其中这些变换包括:
(1) 模型变换(将实体对象放在场景中)
(2) 投影变换(将实体对象投影到垂直于视线方向或者是二维平面方向上)
(3) 视口变换(投影变换后的坐标需要经过视区变换才会最终的窗口坐标)
具体实现步骤代码不在贴了,具体实现在《osg三维渲染引擎编程指南》32-33页。
总结
最近项目开发到了结尾部分,对于OSG了解的更加的深刻了,下一步还会继续深入研究OSG,同时抽时间看一下游戏引擎unity3d的开发原理。