天天看点

NxOgre缓冲摄像机(及摄像机抖动解决办法) (转载)

重新对摄像机进行了封装,增加了缓冲功能,使赛车的操作真实感提升了不少,关于缓冲摄像机可以参考Ogre wiki上的第三人称摄像机那篇文章

其原理是:                 使用两个SceneNode, 一个绑定摄像机,另一个用来绑定代表赛车的节点, 赛车移动的时候   摄像机的位置始终以一定速度向赛车节点靠近,这个速度跟摄像机与赛车子节点的全局坐标距离成正比.   并不断跟新两节点位置.

关于摄像机更新抖动的问题,NxOgre和Ogre使用两个不同的FrameListener来更新场景,可能会使帧更新一致,我的解决办法是在创建NxOgre::Scene的时候将 mProcessingPriority = NxOgre::Enums::Priority_Low设置成最低优先级,即不对场景进行处理(默认情况下为Priority_Medium),之后再手动更新场景 mScene->advance(timeSinceLastFrame * 0.015, NxOgre::Enums::Priority_Low);

  1. //创建场景,并设置场景基本属性
  2. NxOgre::SceneDescription desc;
  3. //设置重力
  4. desc.mGravity = NxOgre::Vec3(0.0f, -9.8f, 0.0f);
  5. desc.mName = "Racing World";
  6. desc.mProcessingPriority = NxOgre::Enums::Priority_Low;
  7. mScene = mWorld->createScene(desc);

摄像机的封装

  1. #ifndef __VEHICLECAMERA_H__
  2. #define __VEHICLECAMERA_H__
  3. #include <Ogre.h>
  4. #include <string>
  5. #include "Util.h"
  6. class VehicleCamera
  7. {
  8. public:
  9. VehicleCamera(const std::string &playerName);
  10. ~VehicleCamera();
  11. // 设置摄像机缓冲程度值越大越硬,越小越柔和
  12. void setTightness ( Real tightness );
  13. float getTightness ( )const;
  14. // 设定绑定节点, cameraNode为赛车上摄像机位置的节点, lookAtNode为赛车上车体的节点
  15. void setTarget ( Ogre::SceneNode* cameraNode,Ogre::SceneNode* lookAtNode );
  16. // 手动更新节点位置, 与赛车同步
  17. void instantUpdate ( );
  18. void update (float timeSinceLastFrame );
  19. private:
  20. Ogre::SceneNode *mBaseCamerNode;
  21. Ogre::SceneNode *mBaseLookedAtNode;
  22. Ogre::SceneNode *mCameraLookAtNode;
  23. Ogre::SceneNode *mCameraNode;
  24. Ogre::Camera *mCamera;
  25. // 设置摄像机缓冲程度值越大越硬,越小越柔和
  26. float mTightness;
  27. };
  28. #endif
  1. #include "VehicleCamera.h"
  2. VehicleCamera::VehicleCamera(const std::string &playerName) :
  3.                mTightness(2.0),
  4.                mCameraNode(0),
  5.                mCameraLookAtNode(0),
  6.                mBaseLookedAtNode(0),
  7.                mBaseCamerNode(0)
  8. {
  9.     Ogre::SceneManager* sceneMgr = Util::getSceneManager();
  10.     mCamera = Util::getSceneManager()->createCamera(playerName +"VehicleCamera");
  11.     mCamera->setNearClipDistance ( 0.1f );
  12.     Util::removeAllViewports();
  13.     Ogre::Viewport*viewport = Util::addViewport(mCamera);
  14.     mCamera->setAspectRatio(Real(viewport->getActualWidth()) /
  15.        Real(viewport->getActualHeight()));
  16.     // 构造绑定摄像机的节点
  17.     mCameraNode = sceneMgr->getRootSceneNode ()->createChildSceneNode ();
  18.     mCameraLookAtNode = sceneMgr->getRootSceneNode ()->createChildSceneNode ();
  19.     // 使绑定摄像机的节点自动追踪赛车节点
  20.     mCameraNode->setAutoTracking ( true, mCameraLookAtNode );
  21.     // [重要]设置只能延Y轴旋转,
  22.     mCameraNode->setFixedYawAxis ( true );       
  23.     mCameraNode->attachObject ( mCamera );
  24.     // 开启N02加速模糊
  25.     Util::addCompositor(viewport, "Bloom");
  26.     Util::setCompositorEnabled(viewport,"Bloom",true);
  27. }
  28. VehicleCamera::~VehicleCamera()
  29. {
  30.     mCameraNode->detachAllObjects ();
  31.     Util::removeAllViewports();
  32.     Util::getSceneManager()->destroyCamera(mCamera);
  33.     Util::getSceneManager()->destroySceneNode ( mCameraNode );
  34.     Util::getSceneManager()->destroySceneNode ( mCameraLookAtNode );
  35.     mCamera = 0;
  36. }
  37. void VehicleCamera::setTightness ( Real tightness )
  38. {
  39.     mTightness = tightness;
  40. }
  41. float VehicleCamera::getTightness ( )const
  42. {
  43.     return mTightness;
  44. }
  45. // 设定绑定节点, cameraNode为赛车上摄像机位置的节点, lookAtNode为赛车上车体的节点
  46. void VehicleCamera::setTarget ( Ogre::SceneNode* cameraNode,
  47.                                Ogre::SceneNode* lookAtNode )
  48. {
  49.     mBaseCamerNode = cameraNode;
  50.     mBaseLookedAtNode = lookAtNode;
  51.     instantUpdate ( );
  52. }
  53. // 手动更新节点位置, 与赛车同步
  54. void VehicleCamera::instantUpdate ( )
  55. {
  56.     mCameraNode->setPosition ( mBaseCamerNode->_getDerivedPosition() );
  57.     mCameraLookAtNode->setPosition ( mBaseLookedAtNode->_getDerivedPosition() );
  58. }
  59. void VehicleCamera::update (float timeSinceLastFrame )
  60. {
  61.     if (mCameraNode)
  62.     {
  63.         Ogre::Vector3 displacement;
  64.         float rate = mTightness * timeSinceLastFrame;
  65.         displacement = ( mBaseCamerNode->_getDerivedPosition() -
  66.                          mCameraNode->_getDerivedPosition() );
  67.         mCameraNode->translate ( displacement  * rate);
  68.         displacement = ( mBaseLookedAtNode->_getDerivedPosition() -
  69.                          mCameraLookAtNode->_getDerivedPosition() );
  70.         mCameraLookAtNode->translate ( displacement  * rate);
  71.     }
  72. }