Ogre中的摄像机

来源:互联网 发布:淘宝相关性是什么意思 编辑:程序博客网 时间:2024/05/16 18:49

一个摄像机就像真实世界的模拟一样:它从一个特定的方向为你场景的每一帧“照相”(就是说它有一个位置点和一个方向)。它不是一个典型的可渲染的物体,所以即使你在场景中已经有了一个摄像机,这个摄像机也不会被渲染。摄像机既可以被连接到场景的节点上也可以存在于自由的空间中(which means you get to move them around manually if you want their position and/or orientation changed each frame)。就像所提到的那样,摄像机具有拥有一个近切片和一个远切片的视域(field of view)。

我们假设你想要一个具有标准的4:3比例的区域,其近切片距离为5单位,原切片距离为1000单位,摄像机中心轴和上下界的角度皆为30度,下面的代码就创建了这样一个摄像机:

// sceneMgr is an existing instance of a SceneManager implementation. We are

// creating a camera named "MainCam" here.

Camera *camera = sceneMgr->createCamera("MainCam");

// normally you would calculate this from the size of the viewport

camera->setAspectRatio(1.33333f);

// 30 degrees will give more of a long, telescopic view

camera->setFOVy(30.0f);

camera->setNearClipDistance(5.0f);

camera->setFarClipDistance(1000.0f);

渲染模式

摄像机可以用三种不同模式中的一种来渲染场景:wireframe(线框图),solid(实体图),或者“points”(只有点被渲染)。

camera->setPolygonMode(PM_WIREFRAME);

camera->setPolygonMode(PM_POINTS);

camera->setPolygonMode(PM_SOLID);

PolygonMode mode = camera->getPolygonMode();

模式设定在以后的动画中会继续强制执行,直到它被另一个调用改变为止(也就是说这不是一个单帧的设定)。默认的模式是PM_SOLID。

位置和变换

一个摄像机是一个可以移动的物体,并享有MovableObject类中的所有的函数和方法。MovableObject最常见的功能是可以连接到场景中的一个节点并且伴随着可渲染的物体移动(“piggyback” the camera along with renderable objects)。你会有需要这么做,比如各种摄像机追踪镜头的技术。你会在后面的章节中看到各种第三人称摄影技术。现在,我们只讨论固定位置和方向的摄像机。

// assume camera is a pointer to an existing, valid instance of "Camera"

camera->setPosition(200, 10, 200);

// you can also use a Vector3 to position the camera, useful for using the

// position obtained from a scene node getter

// camera->setPosition(Vector3(200, 10, 200));

这段代码会把摄像机放置在绝对坐标(200,10,200)处。这和move()与moveRelative()方法是不同的,后面所说的这些方法分别是在世界坐标和本地坐标中针对当前位置移动物体。

// camera is at world space 200, 10, 200 from before

camera->move(10, 0, 0); // camera moves to 210, 10, 200

camera->moveRelative(0, 0, 10); // camera moves to 210, 10, 210

我们必须注意moveRelative()。因为它发生在本地坐标系中,这种移动的实施和摄像机当时的方向有关。在前面所述的例子中,我们假定摄像机是和主轴线对齐的,指向正Z轴方向。如果摄像机向右转了90度,例如,moveRelative(0,0,10)会把摄像机移到(220,10,200)的地方。

方向、指向和“面向”(Direction, Orientation, and ”Look-At”)

OGRE提供了一系列丰富的方法来放置你的摄像机:

void setDirection(Real x, Real y, Real z);

void setDirection(const Vector3& vec);

Vector3 getDirection(void) const;

Vector3 getUp(void) const;

Vector3 getRight(void) const;

void lookAt( const Vector3& targetPoint );

void lookAt(Real x, Real y, Real z);

void roll(const Radian& angle);

void roll(Real degrees) { roll ( Angle(degrees) ); }

void yaw(const Radian& angle);

void yaw(Real degrees) { yaw ( Angle(degrees) ); }

void pitch(const Radian& angle);

void pitch(Real degrees) { pitch ( Angle(degrees) ); }

void rotate(const Vector3& axis, const Radian& angle);

void rotate(const Vector3& axis, Real degrees) {

rotate ( axis, Angle(degrees) ); }

void rotate(const Quaternion& q);

void setFixedYawAxis( bool useFixed, const Vector3& fixedAxis =

const Quaternion& getOrientation(void) const;

void setOrientation(const Quaternion& q);

void setAutoTracking(bool enabled, SceneNode* target = 0,

const Vector3& offset = Vector3::ZERO);

这些方法的功能大多数从名字来看是显而易见(self-explanatory)的。roll(), yaw(), 和pitch()做的正好就是他们所描述的。setDirection()会让摄像机指向该向量定义的方向。rotate()会使摄像机沿着给定的坐标轴旋转一个角度。lookAt()是非常常用的,它可以使一个摄像机指向一个目标点或目标物体的中心,并且不需要用欧氏几何的方法去计算该指向的四元矩阵。最后,setFixedYawAxis()允许你打破摄像机自有的偏移轴的约束(break the camera free from its own yaw (Y) axis)。在第一人称射击游戏中,摄像机通常能够检视X-Z平面。正因如此,你希望的默认动作,是沿着摄像机本地坐标的Y轴偏移。但是,在飞行模拟游戏中,你希望能打破这种约束来创造一个完全自由的摄像机。

setAutoTracking()是一个有趣的功能,如果你希望摄像机总是沿着场景中特定的一点。注意这和真正的第三人称视点的摄像机不同,因为那种摄像机通常不是面向一个特定点的,而是总是面向你的角色所看的方向的。第一个参数指出是否采用追踪,这在任何一帧开始渲染前都可以做,并且在被追踪前必须先删除这个节点。被追踪的节点是第二个参数,这个节点必须存在于这个方法被调用之前。这个参数只能在第一个参数是false的情况下定为NULL。如果被追踪的物体是巨大的并且不适合面向正中间来观察,你可以用第三个参数(偏移offset)来协调一下实际的视点,该参数在本地坐标中操作被追踪的节点。

以下的方法可以用来获得摄像机实际方向的信息,注意把旋转操作和平移操作对被连接的节点的影响考虑在内:

const Quaternion& getDerivedOrientation(void) const;

const Vector3& getDerivedPosition(void) const;

Vector3 getDerivedDirection(void) const;

Vector3 getDerivedUp(void) const;

Vector3 getDerivedRight(void) const;

const Quaternion& getRealOrientation(void) const;

const Vector3& getRealPosition(void) const;

Vector3 getRealDirection(void) const;

Vector3 getRealUp(void) const;

Vector3 getRealRight(void) const;

Real的方法返回的是世界坐标中的值,但是Derived返回的是在本地坐标中的值。

进阶摄像机功能

OGRE通过setFrustumOffset()和setFocalLength()方法支持真实的渲染。例如,你可以通过水平地适配一个摄像机来模拟眼睛间的距离。这会在适配的摄像机中渲染出一个有微小角度区别的画面,以此产生真实的输出。当然,这种技术是高度专业化和细节很多的,但是它确被提供给这种需要的人。

OGRE也允许你直接操作视点和法线的矩阵。这当然是更高级的话题了,回到我们先前所说的“只有在你确信知道你所做并且为何这么做的时候才做”上来,因为这些矩阵在你设定摄像机的时候就已经为你计算好了。下面的方法是用来操作view/projection的矩阵的:

const Matrix4& getProjectionMatrixRS(void) const;

const Matrix4& getProjectionMatrixWithRSDepth(void) const;

const Matrix4& getProjectionMatrix(void) const;

const Matrix4& getViewMatrix(void) const;

void setCustomViewMatrix(bool enable,

const Matrix4& viewMatrix = Matrix4::IDENTITY);

bool isCustomViewMatrixEnabled(void) const;

void setCustomProjectionMatrix(bool enable,

const Matrix4& projectionMatrix = Matrix4::IDENTITY);

bool isCustomProjectionMatrixEnabled(void) const;

列出的前两行代码返回渲染系统设定的法线矩阵。getProjectionMatrixRS()会返回渲染系统得本地坐标,而getProjectionMatrixWithRSDepth()会以OGRE本身的格式(右手坐标系的方式)返回矩阵。区别是深度值(depth value)会根据所用的渲染系统而覆盖[0,1]或[-1,1]的范围。你可以用调用getProjectionMatrix()来避免这些使其总是返回[-1,1]间的一个值。

原创粉丝点击