引子
有这样一个问题,动态显示当前实体的世界坐标、相机坐标、透视投影坐标,以及当前视图坐标变换矩阵、透视投影矩阵。
code:
1/**//**
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*/
12bool getTransformationCoords(Ogre::MovableObject* object, Ogre::Camera* camera, Ogre::Vector3&viewPosition , Ogre::Vector3&ProjectionPosition)
13{
14
15 if(!object->isInScene())
16 return false;
17
18 const Ogre::AxisAlignedBox &AABB = object->getWorldBoundingBox(true);
19 /**//**
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
28
29 // Get the center point of the object's bounding box
30 const Ogre::Vector3& point = AABB.getCenter();
31
32 // Is the camera facing that point? If not, return false
33 Ogre::Plane cameraPlane = Plane(Vector3(camera->getDerivedOrientation().zAxis()), camera->getDerivedPosition());
34
35 if(cameraPlane.getSide(point) != Plane::NEGATIVE_SIDE)
36 return false;
37
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
43
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
48 return true;
49} 示意图:
分析:
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}