mirror of
https://github.com/minetest/irrlicht.git
synced 2024-11-08 03:10:40 +01:00
Bugfix: FPS camera animator on X11 no longer tries grabbing mouse events.
Basically behavior about that is back to how it was in Irrlicht 1.8 - not perfect, but useable. So window still jumps a bit when dragging toolbar, but no longer outside the sreen. And it's possible again to alt+tab to other windows. The problem was caused by a combination of FPS camera changes and that we stopped doing mouse-coordinate clipping in the Linux device in r5593. Basically that clipping had the side-effect that the fps-camera never considered a mouse "outside" on Linux. Now on Linux we only update after we get a mouse-event (which we still get when the mouse is outside the window). On Windows we still grab the mouse in the camera, thought that's likely _not_ the best way to do that. Windows has some mouse-grabbing support, and I suppose we could use that (or camera should check if that is used as it also can be set by users I think). So maybe in future this can be further improved. Other operating systems (OSX) should behave like in 1.8 I hope, but as usual I can't test. Also did a few minor cleanups in the camera. - Back to using animateNode time instead of real-time. That's because that was not causing the problems I thought back then it might cause as time is only used for keyboard input and not mouse input. - Moved updating CursorPos to the rest of the code checking CursorControl Note: A future improvement would be to add support for systems without CursorControl object (could still use mouse-events to get it working usually). git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6142 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
parent
08ae93126c
commit
91cb559caa
|
@ -9,7 +9,6 @@
|
||||||
#include "ICursorControl.h"
|
#include "ICursorControl.h"
|
||||||
#include "ICameraSceneNode.h"
|
#include "ICameraSceneNode.h"
|
||||||
#include "ISceneNodeAnimatorCollisionResponse.h"
|
#include "ISceneNodeAnimatorCollisionResponse.h"
|
||||||
#include "os.h"
|
|
||||||
|
|
||||||
namespace irr
|
namespace irr
|
||||||
{
|
{
|
||||||
|
@ -21,10 +20,19 @@ CSceneNodeAnimatorCameraFPS::CSceneNodeAnimatorCameraFPS(gui::ICursorControl* cu
|
||||||
f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed,
|
f32 rotateSpeed, f32 moveSpeed, f32 jumpSpeed,
|
||||||
SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY, float rotateSpeedKeyboard)
|
SKeyMap* keyMapArray, u32 keyMapSize, bool noVerticalMovement, bool invertY, float rotateSpeedKeyboard)
|
||||||
: CursorControl(cursorControl), MaxVerticalAngle(88.0f), NoVerticalMovement(noVerticalMovement),
|
: CursorControl(cursorControl), MaxVerticalAngle(88.0f), NoVerticalMovement(noVerticalMovement),
|
||||||
MoveSpeed(moveSpeed), RotateSpeedKeyboard(rotateSpeedKeyboard), RotateSpeed(rotateSpeed),
|
MoveSpeed(moveSpeed),
|
||||||
|
// On X11 we get events even when mouse is not inside the Irrlicht window, on Windows we don't.
|
||||||
|
// It might be possible to add grabbing on Windows as well in which case this has to be somewhat changed.
|
||||||
|
// TODO: I don't know about OSX, but in theory it should be like old Irrlicht 1.8 behavior whatever that was there.
|
||||||
|
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
|
||||||
|
GrabMouse(false),
|
||||||
|
#else
|
||||||
|
GrabMouse(true),
|
||||||
|
#endif
|
||||||
|
RotateSpeedKeyboard(rotateSpeedKeyboard), RotateSpeed(rotateSpeed),
|
||||||
JumpSpeed(jumpSpeed),
|
JumpSpeed(jumpSpeed),
|
||||||
MouseYDirection(invertY ? -1.0f : 1.0f),
|
MouseYDirection(invertY ? -1.0f : 1.0f),
|
||||||
LastAnimationTime(0), firstUpdate(true), firstInput(true)
|
LastAnimationTime(0), HadMouseEvent(false), firstUpdate(true), firstInput(true)
|
||||||
{
|
{
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("CCameraSceneNodeAnimatorFPS");
|
setDebugName("CCameraSceneNodeAnimatorFPS");
|
||||||
|
@ -80,6 +88,9 @@ bool CSceneNodeAnimatorCameraFPS::OnEvent(const SEvent& evt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case EET_MOUSE_INPUT_EVENT:
|
||||||
|
HadMouseEvent = true;
|
||||||
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -94,8 +105,6 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
|
||||||
if (!node || node->getType() != ESNT_CAMERA)
|
if (!node || node->getType() != ESNT_CAMERA)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
timeMs = os::Timer::getRealTime(); // User input is always in real-time
|
|
||||||
|
|
||||||
ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);
|
ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);
|
||||||
|
|
||||||
if (firstUpdate)
|
if (firstUpdate)
|
||||||
|
@ -129,9 +138,6 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
|
||||||
if(smgr && smgr->getActiveCamera() != camera)
|
if(smgr && smgr->getActiveCamera() != camera)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if ( CursorControl )
|
|
||||||
CursorPos = CursorControl->getRelativePosition();
|
|
||||||
|
|
||||||
// get time
|
// get time
|
||||||
f32 timeDiff = (f32) ( timeMs - LastAnimationTime );
|
f32 timeDiff = (f32) ( timeMs - LastAnimationTime );
|
||||||
LastAnimationTime = timeMs;
|
LastAnimationTime = timeMs;
|
||||||
|
@ -144,6 +150,9 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
|
||||||
{
|
{
|
||||||
bool reset = false;
|
bool reset = false;
|
||||||
|
|
||||||
|
if ( HadMouseEvent || GrabMouse)
|
||||||
|
CursorPos = CursorControl->getRelativePosition();
|
||||||
|
|
||||||
if (CursorPos != CenterCursor)
|
if (CursorPos != CenterCursor)
|
||||||
{
|
{
|
||||||
relativeRotation.Y -= (CenterCursor.X - CursorPos.X) * RotateSpeed;
|
relativeRotation.Y -= (CenterCursor.X - CursorPos.X) * RotateSpeed;
|
||||||
|
@ -152,12 +161,8 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
|
||||||
reset = true;
|
reset = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !reset )
|
if ( GrabMouse && !reset)
|
||||||
{
|
{
|
||||||
// TODO: not sure if this case is still needed. Might be it was only something
|
|
||||||
// that was necessary when someone tried to use mouse-events in the past.
|
|
||||||
// But not too expensive, test on all platforms before removing.
|
|
||||||
|
|
||||||
// Special case, mouse is whipped outside of window before it can update.
|
// Special case, mouse is whipped outside of window before it can update.
|
||||||
video::IVideoDriver* driver = smgr->getVideoDriver();
|
video::IVideoDriver* driver = smgr->getVideoDriver();
|
||||||
core::vector2d<u32> mousepos(u32(CursorPos.X), u32(CursorPos.Y));
|
core::vector2d<u32> mousepos(u32(CursorPos.X), u32(CursorPos.Y));
|
||||||
|
@ -174,6 +179,7 @@ void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs)
|
||||||
CursorPos = CenterCursor;
|
CursorPos = CenterCursor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
HadMouseEvent = false;
|
||||||
|
|
||||||
// keyboard rotation
|
// keyboard rotation
|
||||||
if (CursorKeys[EKA_ROTATE_LEFT])
|
if (CursorKeys[EKA_ROTATE_LEFT])
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace scene
|
||||||
void allKeysUp();
|
void allKeysUp();
|
||||||
|
|
||||||
gui::ICursorControl *CursorControl;
|
gui::ICursorControl *CursorControl;
|
||||||
|
bool GrabMouse;
|
||||||
|
|
||||||
f32 MaxVerticalAngle;
|
f32 MaxVerticalAngle;
|
||||||
bool NoVerticalMovement;
|
bool NoVerticalMovement;
|
||||||
|
@ -129,6 +130,7 @@ namespace scene
|
||||||
|
|
||||||
core::array<SKeyMap> KeyMap;
|
core::array<SKeyMap> KeyMap;
|
||||||
core::position2d<f32> CenterCursor, CursorPos;
|
core::position2d<f32> CenterCursor, CursorPos;
|
||||||
|
bool HadMouseEvent;
|
||||||
|
|
||||||
bool CursorKeys[EKA_COUNT];
|
bool CursorKeys[EKA_COUNT];
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user