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. /**
  7. 注:
  8.     (mProcessingPriority参数默认为中等)
  9.     设置不更新场景,保持与Ogre渲染同步,避免摄像机抖动现象
  10.     并在update调用mScene->advance(timeSinceLastFrame * 0.075, NxOgre::Enums::Priority_Low);
  11. */
  12. desc.mProcessingPriority = NxOgre::Enums::Priority_Low;
  13. mScene = mWorld->createScene(desc);
摄像机的封装

  1. #ifndef __VEHICLECAMERA_H__
  2. #define __VEHICLECAMERA_H__

  3. #include <Ogre.h>
  4. #include <string>
  5. #include "Util.h"

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

  11. 例如: 在这里每20帧跟新一次两节点坐标(与赛车同步),并更新节点相对位置.

  12. // 根据当前赛车速度和帧数来设定缓冲大小
  13. if (isBoundingCamera())
  14. {
  15.       float speed = getSpeed() / 30;

  16.       // 提供刹车时的缓冲
  17.       if (speed < 1.0f)
  18.            speed = 1.0f;

  19.       // 时时跟新摄像机,
  20.       mVehicleCamer->update(timeSinceLastFrame * speed) ;
  21. }
  22. */
  23. class VehicleCamera
  24. {
  25. public:
  26. VehicleCamera(const std::string &playerName);

  27. ~VehicleCamera();

  28. // 设置摄像机缓冲程度值越大越硬,越小越柔和
  29. void setTightness ( Real tightness );

  30. float getTightness ( )const;

  31. // 设定绑定节点, cameraNode为赛车上摄像机位置的节点, lookAtNode为赛车上车体的节点
  32. void setTarget ( Ogre::SceneNode* cameraNode,Ogre::SceneNode* lookAtNode );

  33. // 手动更新节点位置, 与赛车同步
  34. void instantUpdate ( );

  35. void update (float timeSinceLastFrame );

  36. private:

  37. Ogre::SceneNode *mBaseCamerNode;
  38. Ogre::SceneNode *mBaseLookedAtNode;

  39. Ogre::SceneNode *mCameraLookAtNode;
  40. Ogre::SceneNode *mCameraNode;

  41. Ogre::Camera *mCamera;
  42. // 设置摄像机缓冲程度值越大越硬,越小越柔和
  43. float mTightness;
  44. };

  45. #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. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值