- FPS camera now supports keyboard rotation.

- Base FPS-camera movement on last position of mouse instead of always center (works better on platforms where cursor-placement is not allowed).


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5448 dfc29bdd-3216-0410-991c-e03cc46cb475
master
cutealien 2017-04-21 14:29:07 +00:00
parent bc6313ff60
commit fabd6cda44
5 changed files with 63 additions and 26 deletions

View File

@ -1,6 +1,8 @@
--------------------------
Changes in 1.9 (not yet released)
- FPS camera now supports keyboard rotation.
- Base FPS-camera movement on last position of mouse instead of always center (works better on platforms where cursor-placement is not allowed)
- Octrees with other vertex types than EVT_2TCOORDS can now also use VBO's.
- Add IOctreeSceneNode interface to control parameters like VBO usage and polygon clipping checks for octree scene nodes.
- Add support for different geometric primitivs to meshbuffers. Thanks @gerdb for patch proposal (http://irrlicht.sourceforge.net/forum/viewtopic.php?f=7&t=45999)

View File

@ -30,13 +30,19 @@ namespace scene
//! Sets the speed of movement in units per millisecond
virtual void setMoveSpeed(f32 moveSpeed) = 0;
//! Returns the rotation speed in degrees
//! Returns the rotation speed when using keyboard
virtual f32 getRotateSpeedKeyboard() const = 0;
//! Set the rotation speed when using keyboard
virtual void setRotateSpeedKeyboard(f32 rotateSpeed) = 0;
//! Returns the rotation speed in degrees when using mouse
/** The degrees are equivalent to a half screen movement of the mouse,
i.e. if the mouse cursor had been moved to the border of the screen since
the last animation. */
virtual f32 getRotateSpeed() const = 0;
//! Set the rotation speed in degrees
//! Set the rotation speed in degrees when using mouse
virtual void setRotateSpeed(f32 rotateSpeed) = 0;
//! Sets the keyboard mapping for this animator (old style)

View File

@ -19,6 +19,8 @@ namespace irr
EKA_STRAFE_RIGHT,
EKA_JUMP_UP,
EKA_CROUCH,
EKA_ROTATE_LEFT,
EKA_ROTATE_RIGHT,
EKA_COUNT,
//! This value is not used. It only forces this enumeration to compile in 32 bit.

View File

@ -18,9 +18,10 @@ namespace scene
//! constructor
CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cursorControl,
f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed,
SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY)
SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY, float rotateSpeedKeyboard)
: CursorControl(cursorControl), MaxVerticalAngle(88.0f), NoVerticalMovement(noVerticalMovement),
MoveSpeed(moveSpeed), RotateSpeed(rotateSpeed), JumpSpeed(jumpSpeed),
MoveSpeed(moveSpeed), RotateSpeedKeyboard(rotateSpeedKeyboard), RotateSpeed(rotateSpeed),
JumpSpeed(jumpSpeed),
MouseYDirection(invertY ? -1.0f : 1.0f),
LastAnimationTime(0), firstUpdate(true), firstInput(true)
{
@ -39,9 +40,13 @@ CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cu
// create default key map
KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_UP));
KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_DOWN));
KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_LEFT));
KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_RIGHT));
KeyMap.push_back(SKeyMap(EKA_MOVE_FORWARD, irr::KEY_KEY_W));
KeyMap.push_back(SKeyMap(EKA_MOVE_BACKWARD, irr::KEY_KEY_S));
KeyMap.push_back(SKeyMap(EKA_STRAFE_LEFT, irr::KEY_KEY_A));
KeyMap.push_back(SKeyMap(EKA_STRAFE_RIGHT, irr::KEY_KEY_D));
KeyMap.push_back(SKeyMap(EKA_JUMP_UP, irr::KEY_KEY_J));
KeyMap.push_back(SKeyMap(EKA_ROTATE_LEFT, irr::KEY_LEFT));
KeyMap.push_back(SKeyMap(EKA_ROTATE_RIGHT, irr::KEY_RIGHT));
}
else
{
@ -149,22 +154,8 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
{
if (CursorPos != CenterCursor)
{
relativeRotation.Y -= (0.5f - CursorPos.X) * RotateSpeed;
relativeRotation.X -= (0.5f - CursorPos.Y) * RotateSpeed * MouseYDirection;
// X < MaxVerticalAngle or X > 360-MaxVerticalAngle
if (relativeRotation.X > MaxVerticalAngle*2 &&
relativeRotation.X < 360.0f-MaxVerticalAngle)
{
relativeRotation.X = 360.0f-MaxVerticalAngle;
}
else
if (relativeRotation.X > MaxVerticalAngle &&
relativeRotation.X < 360.0f-MaxVerticalAngle)
{
relativeRotation.X = MaxVerticalAngle;
}
relativeRotation.Y -= (CenterCursor.X - CursorPos.X) * RotateSpeed;
relativeRotation.X -= (CenterCursor.Y - CursorPos.Y) * RotateSpeed * MouseYDirection;
// Do the fix as normal, special case below
// reset cursor position to the centre of the window.
@ -192,6 +183,28 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
}
}
// keyboard rotation
if (CursorKeys[EKA_ROTATE_LEFT])
relativeRotation.Y -= timeDiff * RotateSpeedKeyboard;
if (CursorKeys[EKA_ROTATE_RIGHT])
relativeRotation.Y += timeDiff * RotateSpeedKeyboard;
// X < MaxVerticalAngle or X > 360-MaxVerticalAngle
if (relativeRotation.X > MaxVerticalAngle*2 &&
relativeRotation.X < 360.0f-MaxVerticalAngle)
{
relativeRotation.X = 360.0f-MaxVerticalAngle;
}
else
if (relativeRotation.X > MaxVerticalAngle &&
relativeRotation.X < 360.0f-MaxVerticalAngle)
{
relativeRotation.X = MaxVerticalAngle;
}
// set target
target.set(0,0, core::max_(1.f, pos.getLength()));
@ -299,7 +312,6 @@ f32 CSceneNodeAnimatorCameraFPS::getMoveSpeed() const
return MoveSpeed;
}
//! Sets the keyboard mapping for this animator
void CSceneNodeAnimatorCameraFPS::setKeyMap(SKeyMap *map, u32 count)
{
@ -358,6 +370,7 @@ void CSceneNodeAnimatorCameraFPS::serializeAttributes(io::IAttributes* out, io::
out->addFloat("MaxVerticalAngle", MaxVerticalAngle);
out->addBool("NoVerticalMovement", NoVerticalMovement);
out->addFloat("MoveSpeed", MoveSpeed);
out->addFloat("RotateSpeedKeyboard", RotateSpeedKeyboard);
out->addFloat("RotateSpeed", RotateSpeed);
out->addFloat("JumpSpeed", JumpSpeed);
out->addFloat("MouseYDirection", MouseYDirection);
@ -380,6 +393,7 @@ void CSceneNodeAnimatorCameraFPS::deserializeAttributes(io::IAttributes* in, io:
MaxVerticalAngle = in->getAttributeAsFloat("MaxVerticalAngle", MaxVerticalAngle);
NoVerticalMovement = in->getAttributeAsBool("NoVerticalMovement", NoVerticalMovement);
MoveSpeed = in->getAttributeAsFloat("MoveSpeed", MoveSpeed);
RotateSpeedKeyboard = in->getAttributeAsFloat("RotateSpeedKeyboard", RotateSpeedKeyboard);
RotateSpeed = in->getAttributeAsFloat("RotateSpeed", RotateSpeed);
JumpSpeed = in->getAttributeAsFloat("JumpSpeed", JumpSpeed);
MouseYDirection = in->getAttributeAsFloat("MouseYDirection", MouseYDirection);

View File

@ -30,7 +30,7 @@ namespace scene
CSceneNodeAnimatorCameraFPS(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);
bool invertY=false, float rotateSpeedKeyboard = 0.3f);
//! Destructor
virtual ~CSceneNodeAnimatorCameraFPS();
@ -47,12 +47,24 @@ namespace scene
//! Sets the speed of movement in units per second
virtual void setMoveSpeed(f32 moveSpeed) _IRR_OVERRIDE_;
//! Returns the rotation speed
//! Returns the rotation speed when moving mouse
virtual f32 getRotateSpeed() const _IRR_OVERRIDE_;
//! Set the rotation speed
//! Set the rotation speed when moving mouse
virtual void setRotateSpeed(f32 rotateSpeed) _IRR_OVERRIDE_;
//! Returns the rotation speed when using keyboard
virtual f32 getRotateSpeedKeyboard() const _IRR_OVERRIDE_
{
return RotateSpeedKeyboard;
}
//! Set the rotation speed when using keyboard
virtual void setRotateSpeedKeyboard(f32 rotateSpeed) _IRR_OVERRIDE_
{
RotateSpeedKeyboard = rotateSpeed;
}
//! Sets the keyboard mapping for this animator (old style)
//! \param keymap: an array of keyboard mappings, see SKeyMap
//! \param count: the size of the keyboard map array
@ -107,6 +119,7 @@ namespace scene
bool NoVerticalMovement;
f32 MoveSpeed;
f32 RotateSpeedKeyboard;
f32 RotateSpeed;
f32 JumpSpeed;
// -1.0f for inverted mouse, defaults to 1.0f