引子
有这样一个问题,动态显示当前实体的世界坐标、相机坐标、透视投影坐标,以及当前视图坐标变换矩阵、透视投影矩阵。
code:
1![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//**
2
* This little snippet gets the Transformatio coordinates for a MovableObject
3
*
4
* @param object The object to retrieve the coordidnates of.
5
* @param camera The active camera
6
* @param viewPosition The Vector3 to store the view position in
7
* @param ProjectionPosition The Vector3 to store the projection position in
8
*
9
* @return Returns true if the object is visible and the coordinates were
10
* retrieved, false otherwise.
11
*/
12
bool getTransformationCoords(Ogre::MovableObject* object, Ogre::Camera* camera, Ogre::Vector3&viewPosition , Ogre::Vector3&ProjectionPosition)
13![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](/Images/OutliningIndicators/ContractedBlock.gif)
{
14![](/Images/OutliningIndicators/InBlock.gif)
15
if(!object->isInScene())
16
return false;
17![](/Images/OutliningIndicators/InBlock.gif)
18
const Ogre::AxisAlignedBox &AABB = object->getWorldBoundingBox(true);
19![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//**
20
* If you need the point above the object instead of the center point:
21
* This snippet derives the average point between the top-most corners of the bounding box
22
* Ogre::Vector3 point = (AABB.getCorner(AxisAlignedBox::FAR_LEFT_TOP)
23
* + AABB.getCorner(AxisAlignedBox::FAR_RIGHT_TOP)
24
* + AABB.getCorner(AxisAlignedBox::NEAR_LEFT_TOP)
25
* + AABB.getCorner(AxisAlignedBox::NEAR_RIGHT_TOP)) / 4;
26
*/
27![](/Images/OutliningIndicators/InBlock.gif)
28![](/Images/OutliningIndicators/InBlock.gif)
29
// Get the center point of the object's bounding box
30
const Ogre::Vector3& point = AABB.getCenter();
31![](/Images/OutliningIndicators/InBlock.gif)
32
// Is the camera facing that point? If not, return false
33
Ogre::Plane cameraPlane = Plane(Vector3(camera->getDerivedOrientation().zAxis()), camera->getDerivedPosition());
34![](/Images/OutliningIndicators/InBlock.gif)
35
if(cameraPlane.getSide(point) != Plane::NEGATIVE_SIDE)
36
return false;
37![](/Images/OutliningIndicators/InBlock.gif)
38
// Transform the 3D point into screen space
39
//point = camera->getProjectionMatrix() * (camera->getViewMatrix() * point);
40
viewPosition = camera->getViewMatrix() * point;
41
ProjectionPosition = camera->getProjectionMatrix() * viewPosition;
42![](/Images/OutliningIndicators/InBlock.gif)
43![](/Images/OutliningIndicators/InBlock.gif)
44
// Transform from coordinate space [-1, 1] to [0, 1] and update in-value
45
ProjectionPosition.x = (ProjectionPosition.x / 2) + 0.5f;
46
ProjectionPosition.y = 1 - ((ProjectionPosition.y / 2) + 0.5f);
47![](/Images/OutliningIndicators/InBlock.gif)
48
return true;
49
} 示意图:
![](http://www.cppblog.com/images/cppblog_com/flyindark/matrix.jpg)
分析:
1. view坐标显示的是鼠标所在实体的中心点在相机坐标系中的坐标。看代码的line40,视图矩阵乘以点的世界坐标,得到了这个点的在相机坐标系中的坐标。
2. projection坐标(0.2,0.2,1.0)表示的是屏幕坐标系的坐标。代码的line41,透视投影矩阵乘以点的相机坐标,得到了这个点的透视变换坐标。这个坐标的范围是[-1,1],需要变换到[0,1],代码line45、46完成了这项映射变换。
3.矩阵窗口显示的是当前视图变换矩阵和投影变换矩阵。动态运行后可以发现投影矩阵一直不变。视图矩阵随着相机的移动、选择在动态变换。
视图矩阵变换规律:
相机沿着front方向变化:row3的z项变化,其他项均不变。
相机沿着left方向变化,row0的z项目变化,其他项均不变。
相机沿着top方向变化,row2的z项变化,其他项均不变。
相机yaw?pitch?roll?
任何时候row3都不变:{0 ,0 , 0 , 1}