NxOgre缓冲摄像机(及摄像机抖动解决办法)
来源:互联网 发布:centos下安装图形界面 编辑:程序博客网 时间:2024/05/18 09:48
重新对摄像机进行了封装,增加了缓冲功能,使赛车的操作真实感提升了不少,关于缓冲摄像机可以参考Ogre wiki上的第三人称摄像机那篇文章
其原理是:
使用两个SceneNode, 一个绑定摄像机,另一个用来绑定代表赛车的节点, 赛车移动的时候摄像机的位置始终以一定速度向赛车节点靠近,这个速度跟摄像机与赛车子节点的全局坐标距离成正比.并不断跟新两节点位置.
关于摄像机更新抖动的问题,NxOgre和Ogre使用两个不同的FrameListener来更新场景,可能会使帧更新一致,我的解决办法是在创建NxOgre::Scene的时候将mProcessingPriority = xOgre::Enums::Priority_Low
设置成最低优先级,即不对场景进行处理(默认情况下为Priority_Medium),之后再手动更新场景
mScene->advance(timeSinceLastFrame * 0.015, NxOgre::Enums::Priority_Low);
//创建场景,并设置场景基本属性
NxOgre::SceneDescription desc;
//设置重力
desc.mGravity = NxOgre::Vec3(0.0f, -9.8f, 0.0f);
desc.mName = "Racing World";
/**
注:
(mProcessingPriority参数默认为中等)
设置不更新场景,保持与Ogre渲染同步,避免摄像机抖动现象
并在update调用mScene->advance(timeSinceLastFrame * 0.075, NxOgre::Enums::Priority_Low);
*/
desc.mProcessingPriority = NxOgre::Enums::Priority_Low;
mScene = mWorld->createScene(desc);
摄像机的封装
#ifndef __VEHICLECAMERA_H__
#define __VEHICLECAMERA_H__
#include <Ogre.h>
#include <string>
#include "Util.h"
/**
赛车缓冲摄像机原理:
使用两个SceneNode, 一个绑定摄像机,另一个用来绑定代表赛车的节点, 赛车移动的时候
摄像机的位置始终以一定速度向赛车节点靠近,这个速度跟摄像机与赛车子节点的全局坐标距离成正比.
并不断跟新两节点位置.
例如: 在这里每20帧跟新一次两节点坐标(与赛车同步),并更新节点相对位置.
// 根据当前赛车速度和帧数来设定缓冲大小
if (isBoundingCamera())
{
float speed = getSpeed() / 30;
// 提供刹车时的缓冲
if (speed < 1.0f)
speed = 1.0f;
// 时时跟新摄像机,
mVehicleCamer->update(timeSinceLastFrame * speed) ;
}
*/
class VehicleCamera
{
public:
VehicleCamera(const std::string &playerName);
~VehicleCamera();
// 设置摄像机缓冲程度值越大越硬,越小越柔和
void setTightness ( Real tightness );
float getTightness ( ) const;
// 设定绑定节点, cameraNode为赛车上摄像机位置的节点, lookAtNode为赛车上车体的节点
void setTarget ( Ogre::SceneNode*cameraNode, Ogre::SceneNode* lookAtNode );
// 手动更新节点位置, 与赛车同步
void instantUpdate ( );
void update ( float timeSinceLastFrame );
private:
Ogre::SceneNode *mBaseCamerNode;
Ogre::SceneNode *mBaseLookedAtNode;
Ogre::SceneNode *mCameraLookAtNode;
Ogre::SceneNode *mCameraNode;
Ogre::Camera *mCamera;
// 设置摄像机缓冲程度值越大越硬,越小越柔和
float mTightness;
};
#endif
实现:
#include "VehicleCamera.h"
VehicleCamera::VehicleCamera(const std::string &playerName) :
mTightness(2.0), mCameraNode(0),
mCameraLookAtNode(0),
mBaseLookedAtNode(0),
mBaseCamerNode(0)
{
Ogre::SceneManager* sceneMgr = Util::getSceneManager();
mCamera = Util::getSceneManager()->createCamera( playerName + "VehicleCamera");
mCamera->setNearClipDistance ( 0.1f );
Util::removeAllViewports();
Ogre::Viewport*viewport = Util::addViewport(mCamera);
mCamera->setAspectRatio(Real(viewport->getActualWidth()) / Real(viewport->getActualHeight()));
// 构造绑定摄像机的节点
mCameraNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
mCameraLookAtNode = sceneMgr->getRootSceneNode()->createChildSceneNode();
// 使绑定摄像机的节点自动追踪赛车节点
mCameraNode->setAutoTracking ( true, mCameraLookAtNode );
// [重要]设置只能延Y轴旋转,
mCameraNode->setFixedYawAxis ( true );
mCameraNode->attachObject ( mCamera );
// 开启N02加速模糊
Util::addCompositor(viewport, "Bloom");
Util::setCompositorEnabled(viewport,"Bloom",true);
}
VehicleCamera::~VehicleCamera()
{
mCameraNode->detachAllObjects ();
Util::removeAllViewports();
Util::getSceneManager()->destroyCamera(mCamera);
Util::getSceneManager()->destroySceneNode ( mCameraNode );
Util::getSceneManager()->destroySceneNode ( mCameraLookAtNode );
mCamera = 0;
}
void VehicleCamera::setTightness ( Real tightness )
{
mTightness = tightness;
}
float VehicleCamera::getTightness ( ) const
{
return mTightness;
}
// 设定绑定节点, cameraNode为赛车上摄像机位置的节点, lookAtNode为赛车上车体的节点
void VehicleCamera::setTarget ( Ogre::SceneNode* cameraNode, Ogre::SceneNode* lookAtNode )
{
mBaseCamerNode = cameraNode;
mBaseLookedAtNode = lookAtNode;
instantUpdate ( );
}
// 手动更新节点位置, 与赛车同步
void VehicleCamera::instantUpdate ( )
{
mCameraNode->setPosition ( mBaseCamerNode->_getDerivedPosition() );
mCameraLookAtNode->setPosition ( mBaseLookedAtNode->_getDerivedPosition() );
}
void VehicleCamera::update ( float timeSinceLastFrame )
{
if (mCameraNode)
{
Ogre::Vector3 displacement;
float rate = mTightness * timeSinceLastFrame;
displacement = ( mBaseCamerNode->_getDerivedPosition()- mCameraNode->_getDerivedPosition() );
mCameraNode->translate ( displacement * rate);
displacement = ( mBaseLookedAtNode->_getDerivedPosition()- mCameraLookAtNode->_getDerivedPosition() );
mCameraLookAtNode->translate ( displacement * rate);
}
}
- NxOgre缓冲摄像机(及摄像机抖动解决办法)
- NxOgre缓冲摄像机(及摄像机抖动解决办法) (转载)
- unity3d 摄像机抖动特效
- 摄像机
- 摄像机
- 摄像机
- 摄像机
- 摄像机
- 摄像机
- 摄像机
- 摄像机
- 摄像机
- unity3d 摄像机抖动情况和解决方案汇总
- Uninty之iTween实现摄像机抖动
- 摄像机及工厂
- 摄像机属性及妙用
- 摄像机主要指标及参数
- 摄像机属性及妙用详解
- Extjs中的Date格式
- expdp
- log4j问题解决
- impdp
- sqlload 介绍
- NxOgre缓冲摄像机(及摄像机抖动解决办法)
- Qt二题:QString的输出和QDialog的退出
- 大文件导出方法
- ftp传输数据文件脚本
- 舞出我人生
- Silverlight 4 + RIA Services之商业应用系列----1 使用RIA Services
- 链表
- 什么是多态?
- 哈夫曼编码