重新对摄像机进行了封装,增加了缓冲功能,使赛车的操作真实感提升了不少,关于缓冲摄像机可以参考Ogre wiki上的第三人称摄像机那篇文章
其原理是:
使用两个SceneNode, 一个绑定摄像机,另一个用来绑定代表赛车的节点, 赛车移动的时候
摄像机的位置始终以一定速度向赛车节点靠近,这个速度跟摄像机与赛车子节点的全局坐标距离成正比.
并不断跟新两节点位置.
关于摄像机更新抖动的问题,NxOgre和Ogre使用两个不同的FrameListener来更新场景,可能会使帧更新一致,我的解决办法是在创建NxOgre::Scene的时候将
mProcessingPriority = NxOgre::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);
- }
- }