修改Irrlicht的FPSCamera默认光标操作

来源:互联网 发布:linux怎么全局翻墙 编辑:程序博客网 时间:2024/06/05 14:58

Title:修改Irrlicht的FPSCamera默认光标操作
Author:kagula
Date:2012-3-26

环境:
[1]VS2010SP1
[2]Irrlicht1.7.3

正文:
  FPSCamera默认移动鼠标就改变视图区域(头转到哪里),现在我们要把它改成
按住鼠标左键,才改变视图区域。

[S1]打开..\irrlicht-1.7.3\source\Irrlicht\CSceneNodeAnimatorCameraFPS.h文件
用下面的源文件内容替换

// Copyright (C) 2002-2010 Nikolaus Gebhardt// This file is part of the "Irrlicht Engine".// For conditions of distribution and use, see copyright notice in irrlicht.h#ifndef __C_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__#define __C_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__#include "ISceneNodeAnimatorCameraFPS.h"#include "vector2d.h"#include "position2d.h"#include "SKeyMap.h"#include "irrArray.h"namespace irr{namespace gui{class ICursorControl;}namespace scene{//! Special scene node animator for FPS camerasclass CSceneNodeAnimatorCameraFPS : public ISceneNodeAnimatorCameraFPS{public://! ConstructorCSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl,f32 rotateSpeed = 100.0f, f32 moveSpeed = .5f, f32 jumpSpeed=0.f,SKeyMap* keyMapArray=0, u32 keyMapSize=0, bool noVerticalMovement=false,bool invertY=false);//! Destructorvirtual ~CSceneNodeAnimatorCameraFPS();//! Animates the scene node, currently only works on camerasvirtual void animateNode(ISceneNode* node, u32 timeMs);//! Event receivervirtual bool OnEvent(const SEvent& event);//! Returns the speed of movement in units per secondvirtual f32 getMoveSpeed() const;//! Sets the speed of movement in units per secondvirtual void setMoveSpeed(f32 moveSpeed);//! Returns the rotation speedvirtual f32 getRotateSpeed() const;//! Set the rotation speedvirtual void setRotateSpeed(f32 rotateSpeed);//! Sets the keyboard mapping for this animator//! \param keymap: an array of keyboard mappings, see SKeyMap//! \param count: the size of the keyboard map arrayvirtual void setKeyMap(SKeyMap *map, u32 count);//! Sets whether vertical movement should be allowed.virtual void setVerticalMovement(bool allow);//! Sets whether the Y axis of the mouse should be inverted./** If enabled then moving the mouse down will causethe camera to look up. It is disabled by default. */virtual void setInvertMouse(bool invert);//! This animator will receive events when attached to the active cameravirtual bool isEventReceiverEnabled() const{return true;}//! Returns the type of this animatorvirtual ESCENE_NODE_ANIMATOR_TYPE getType() const{return ESNAT_CAMERA_FPS;}//! Creates a clone of this animator./** Please note that you will have to drop(IReferenceCounted::drop()) the returned pointer once you'redone with it. */virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager=0);struct SCamKeyMap{SCamKeyMap() {};SCamKeyMap(s32 a, EKEY_CODE k) : action(a), keycode(k) {}s32 action;EKEY_CODE keycode;};//! Sets the keyboard mapping for this animator/** Helper function for the clone method.\param keymap the new keymap array */void setKeyMap(const core::array<SCamKeyMap>& keymap);private:void allKeysUp();gui::ICursorControl *CursorControl;f32 MaxVerticalAngle;f32 MoveSpeed;f32 RotateSpeed;f32 JumpSpeed;// -1.0f for inverted mouse, defaults to 1.0ff32 MouseYDirection;s32 LastAnimationTime;core::array<SCamKeyMap> KeyMap;//core::position2d<f32> CenterCursor, CursorPos;//comment by lijun//add by lijunbool m_bLeftPressed;core::position2d<f32> OldCursor, CursorPos;bool CursorKeys[6];bool firstUpdate;bool NoVerticalMovement;};} // end namespace scene} // end namespace irr#endif // __C_SCENE_NODE_ANIMATOR_CAMERA_FPS_H_INCLUDED__


 

[S2]打开..\irrlicht-1.7.3\source\Irrlicht\CSceneNodeAnimatorCameraFPS.cpp文件
用下面的源文件内容替换

// Copyright (C) 2002-2010 Nikolaus Gebhardt// This file is part of the "Irrlicht Engine".// For conditions of distribution and use, see copyright notice in irrlicht.h#include "CSceneNodeAnimatorCameraFPS.h"#include "IVideoDriver.h"#include "ISceneManager.h"#include "Keycodes.h"#include "ICursorControl.h"#include "ICameraSceneNode.h"#include "ISceneNodeAnimatorCollisionResponse.h"namespace irr{namespace scene{//! constructorCSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl,f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed,SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY): CursorControl(cursorControl), MaxVerticalAngle(88.0f),MoveSpeed(moveSpeed), RotateSpeed(rotateSpeed), JumpSpeed(jumpSpeed),MouseYDirection(invertY ? -1.0f : 1.0f),LastAnimationTime(0), firstUpdate(true), NoVerticalMovement(noVerticalMovement){#ifdef _DEBUGsetDebugName("CCameraSceneNodeAnimatorFPS");#endifif (CursorControl)CursorControl->grab();allKeysUp();// create key mapif (!keyMapArray || !keyMapSize){// create default key mapKeyMap.push_back(SCamKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP));KeyMap.push_back(SCamKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN));KeyMap.push_back(SCamKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT));KeyMap.push_back(SCamKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT));KeyMap.push_back(SCamKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J));}else{// create custom key mapsetKeyMap(keyMapArray, keyMapSize);}}//! destructorCSceneNodeAnimatorCameraFPS::~CSceneNodeAnimatorCameraFPS(){if (CursorControl)CursorControl->drop();}//! It is possible to send mouse and key events to the camera. Most cameras//! may ignore this input, but camera scene nodes which are created for//! example with scene::ISceneManager::addMayaCameraSceneNode or//! scene::ISceneManager::addFPSCameraSceneNode, may want to get this input//! for changing their position, look at target or whatever.bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt){switch(evt.EventType){case EET_KEY_INPUT_EVENT:for (u32 i=0; i<KeyMap.size(); ++i){if (KeyMap[i].keycode == evt.KeyInput.Key){CursorKeys[KeyMap[i].action] = evt.KeyInput.PressedDown;return true;}}break;case EET_MOUSE_INPUT_EVENT:if (evt.MouseInput.Event == EMIE_MOUSE_MOVED){if(evt.MouseInput.isLeftPressed()==true){CursorPos = CursorControl->getRelativePosition();m_bLeftPressed = true;return true;}else{OldCursor = CursorControl->getRelativePosition();m_bLeftPressed = false;}}break;default:break;}return false;}void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs){if (!node || node->getType() != ESNT_CAMERA)return;ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);if (firstUpdate){camera->updateAbsolutePosition();if (CursorControl && camera){CursorControl->setPosition(0.5f, 0.5f);CursorPos = OldCursor = CursorControl->getRelativePosition();}LastAnimationTime = timeMs;firstUpdate = false;}// If the camera isn't the active camera, and receiving input, then don't process it.if(!camera->isInputReceiverEnabled())return;scene::ISceneManager * smgr = camera->getSceneManager();if(smgr && smgr->getActiveCamera() != camera)return;// get timef32 timeDiff = (f32) ( timeMs - LastAnimationTime );LastAnimationTime = timeMs;// update positioncore::vector3df pos = camera->getPosition();// Update rotationcore::vector3df target = (camera->getTarget() - camera->getAbsolutePosition());core::vector3df relativeRotation = target.getHorizontalAngle();if (CursorControl){if (CursorPos != OldCursor&&m_bLeftPressed){relativeRotation.Y -= (OldCursor.X - CursorPos.X) * RotateSpeed;relativeRotation.X -= (OldCursor.Y - CursorPos.Y) * RotateSpeed * MouseYDirection;// X < MaxVerticalAngle or X > 360-MaxVerticalAngleif (relativeRotation.X > MaxVerticalAngle*2 &&relativeRotation.X < 360.0f-MaxVerticalAngle){relativeRotation.X = 360.0f-MaxVerticalAngle;}elseif (relativeRotation.X > MaxVerticalAngle &&relativeRotation.X < 360.0f-MaxVerticalAngle){relativeRotation.X = MaxVerticalAngle;}// Do the fix as normal, special case below// reset cursor position to the centre of the window.//CursorControl->setPosition(0.5f, 0.5f);OldCursor = CursorControl->getRelativePosition();// needed to avoid problems when the event receiver is disabledCursorPos = OldCursor;}}// set targettarget.set(0,0, core::max_(1.f, pos.getLength()));core::vector3df movedir = target;core::matrix4 mat;mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0));mat.transformVect(target);if (NoVerticalMovement){mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0));mat.transformVect(movedir);}else{movedir = target;}movedir.normalize();if (CursorKeys[EKA_MOVE_FORWARD])pos += movedir * timeDiff * MoveSpeed;if (CursorKeys[EKA_MOVE_BACKWARD])pos -= movedir * timeDiff * MoveSpeed;// strafingcore::vector3df strafevect = target;strafevect = strafevect.crossProduct(camera->getUpVector());if (NoVerticalMovement)strafevect.Y = 0.0f;strafevect.normalize();if (CursorKeys[EKA_STRAFE_LEFT])pos += strafevect * timeDiff * MoveSpeed;if (CursorKeys[EKA_STRAFE_RIGHT])pos -= strafevect * timeDiff * MoveSpeed;// For jumping, we find the collision response animator attached to our camera// and if it's not falling, we tell it to jump.if (CursorKeys[EKA_JUMP_UP]){const ISceneNodeAnimatorList& animators = camera->getAnimators();ISceneNodeAnimatorList::ConstIterator it = animators.begin();while(it != animators.end()){if(ESNAT_COLLISION_RESPONSE == (*it)->getType()){ISceneNodeAnimatorCollisionResponse * collisionResponse =static_cast<ISceneNodeAnimatorCollisionResponse *>(*it);if(!collisionResponse->isFalling())collisionResponse->jump(JumpSpeed);}it++;}}// write translationcamera->setPosition(pos);// write right targettarget += pos;camera->setTarget(target);}void CSceneNodeAnimatorCameraFPS::allKeysUp(){for (u32 i=0; i<6; ++i)CursorKeys[i] = false;}//! Sets the rotation speedvoid CSceneNodeAnimatorCameraFPS::setRotateSpeed(f32 speed){RotateSpeed = speed;}//! Sets the movement speedvoid CSceneNodeAnimatorCameraFPS::setMoveSpeed(f32 speed){MoveSpeed = speed;}//! Gets the rotation speedf32 CSceneNodeAnimatorCameraFPS::getRotateSpeed() const{return RotateSpeed;}// Gets the movement speedf32 CSceneNodeAnimatorCameraFPS::getMoveSpeed() const{return MoveSpeed;}//! Sets the keyboard mapping for this animatorvoid CSceneNodeAnimatorCameraFPS::setKeyMap(SKeyMap *map, u32 count){// clear the keymapKeyMap.clear();// add actionsfor (u32 i=0; i<count; ++i){switch(map[i].Action){case EKA_MOVE_FORWARD: KeyMap.push_back(SCamKeyMap(EKA_MOVE_FORWARD, map[i].KeyCode));break;case EKA_MOVE_BACKWARD: KeyMap.push_back(SCamKeyMap(EKA_MOVE_BACKWARD, map[i].KeyCode));break;case EKA_STRAFE_LEFT: KeyMap.push_back(SCamKeyMap(EKA_STRAFE_LEFT, map[i].KeyCode));break;case EKA_STRAFE_RIGHT: KeyMap.push_back(SCamKeyMap(EKA_STRAFE_RIGHT, map[i].KeyCode));break;case EKA_JUMP_UP: KeyMap.push_back(SCamKeyMap(EKA_JUMP_UP, map[i].KeyCode));break;default:break;}}}//! Sets whether vertical movement should be allowed.void CSceneNodeAnimatorCameraFPS::setVerticalMovement(bool allow){NoVerticalMovement = !allow;}//! Sets whether the Y axis of the mouse should be inverted.void CSceneNodeAnimatorCameraFPS::setInvertMouse(bool invert){if (invert)MouseYDirection = -1.0f;elseMouseYDirection = 1.0f;}ISceneNodeAnimator* CSceneNodeAnimatorCameraFPS::createClone(ISceneNode* node, ISceneManager* newManager){CSceneNodeAnimatorCameraFPS * newAnimator =new CSceneNodeAnimatorCameraFPS(CursorControl,RotateSpeed, MoveSpeed, JumpSpeed,0, 0, NoVerticalMovement);newAnimator->setKeyMap(KeyMap);return newAnimator;}void CSceneNodeAnimatorCameraFPS::setKeyMap(const core::array<SCamKeyMap>& keymap){KeyMap=keymap;}} // namespace scene} // namespace irr


[S3]重新编译Irrlicht1.7.3即可

原创粉丝点击