重新对摄像机进行了封装,增加了缓冲功能,使赛车的操作真实感提升了不少,关于缓冲摄像机可以参考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";
- desc.mProcessingPriority = NxOgre::Enums::Priority_Low;
- mScene = mWorld->createScene(desc);
摄像机的封装
- #ifndef __VEHICLECAMERA_H__
- #define __VEHICLECAMERA_H__
- #include <Ogre.h>
- #include <string>
- #include "Util.h"
- 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);
- }
- }