的笔记

随时随地编辑

相机坐标、视景体、变换矩阵

引子
有这样一个问题,动态显示当前实体的世界坐标、相机坐标、透视投影坐标,以及当前视图坐标变换矩阵、透视投影矩阵。

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}

posted on 2011-06-20 21:51 的笔记 阅读(1335) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理