Mouse capture using OIS
-
- Kobold
- Posts: 32
- Joined: Thu Aug 11, 2011 10:00 pm
Mouse capture using OIS
Hello,
I am developing a small game engine and I need to provide a functionality that allows a FPS-style player control. In an earlier version of the engine based on another render and input system, I used SetMousePosition(int,int) to replace the mouse at the center of the window each frame. The, at the end of the game loop, the mouse position was read and subtracted to the position of the center of the window. The difference was applied as a rotation to the camera.
The problem with OGRE+OIS is that I don't know how to move the mouse at the center of the window, and if I don't, the cursor gets stuck at the edge of teh screen, preventing further rotation. In a classic FPS you can move your mouse 2000px to the left and the player would turn around continuously but if I don't move the mouse back to the center the movement stops when the mouse hits the edge of the screen.
Any help would be greatly appreciated
I am developing a small game engine and I need to provide a functionality that allows a FPS-style player control. In an earlier version of the engine based on another render and input system, I used SetMousePosition(int,int) to replace the mouse at the center of the window each frame. The, at the end of the game loop, the mouse position was read and subtracted to the position of the center of the window. The difference was applied as a rotation to the camera.
The problem with OGRE+OIS is that I don't know how to move the mouse at the center of the window, and if I don't, the cursor gets stuck at the edge of teh screen, preventing further rotation. In a classic FPS you can move your mouse 2000px to the left and the player would turn around continuously but if I don't move the mouse back to the center the movement stops when the mouse hits the edge of the screen.
Any help would be greatly appreciated
- Jabberwocky
- OGRE Moderator
- Posts: 2819
- Joined: Mon Mar 05, 2007 11:17 pm
- Location: Canada
- x 218
- Contact:
Re: Mouse capture using OIS
This is sort of a confusing question.
OIS has no idea what the "edge of the screen" is. Are you talking about your GUI's mouse cursor? If so, then how you move the mouse cursor will depend on what GUI you're using. Is it just the default GUI stuff that comes with ogre, that it uses in the sample browser?
OIS has no idea what the "edge of the screen" is. Are you talking about your GUI's mouse cursor? If so, then how you move the mouse cursor will depend on what GUI you're using. Is it just the default GUI stuff that comes with ogre, that it uses in the sample browser?
-
- Kobold
- Posts: 32
- Joined: Thu Aug 11, 2011 10:00 pm
Re: Mouse capture using OIS
Thanks for your answer,
I'm currently using the default GUI for Ogre, that comes with the TutorialApplication, so yes.
I tried to use the os' setCursor functions but they are very platform-dependant and produce confusing results with OIS.
I'm currently using the default GUI for Ogre, that comes with the TutorialApplication, so yes.
I tried to use the os' setCursor functions but they are very platform-dependant and produce confusing results with OIS.
- Jabberwocky
- OGRE Moderator
- Posts: 2819
- Joined: Mon Mar 05, 2007 11:17 pm
- Location: Canada
- x 218
- Contact:
Re: Mouse capture using OIS
The GUI that comes with Ogre is a very simple GUI, that is defined in a file called SdkTrays.h
I've never used it (outside of running the ogre samples), but I had a quick look at the source code.
It looks like you can retrieve the cursor using this function:
Defined in SdkTrays.h:
And then you can call these functions to set the cursor position on the returned cursor:
I don't know if that will work or not, but give it a shot.
I've never used it (outside of running the ogre samples), but I had a quick look at the source code.
It looks like you can retrieve the cursor using this function:
Defined in SdkTrays.h:
Code: Select all
Ogre::OverlayContainer* getCursorContainer() { return mCursor; }
Code: Select all
/** Sets the left of this element in relation to the screen (where 0 = far left, 1.0 = far right) */
void setLeft(Real left);
/** Sets the top of this element in relation to the screen (where 0 = top, 1.0 = bottom) */
void setTop(Real Top);
-
- Kobold
- Posts: 32
- Joined: Thu Aug 11, 2011 10:00 pm
Re: Mouse capture using OIS
In the meantime I actually moved on to CEGUI, which I managed to integrate correctly. I know there in a function in CEGUI to change the mouse position, injectMouseMove, but that would only set a parameter that is internal to CEGUI, with no effect on the mouse getting to the edge of the screen, isn't it ?
How are FPS usually made with OGRE ? I suppose there must be some kind of solution or workaround ?
How are FPS usually made with OGRE ? I suppose there must be some kind of solution or workaround ?
- Jabberwocky
- OGRE Moderator
- Posts: 2819
- Joined: Mon Mar 05, 2007 11:17 pm
- Location: Canada
- x 218
- Contact:
Re: Mouse capture using OIS
If I were you, I wouldn't use the cursor position at all. I'd just read the mouse input directly from OIS and control the player with that. This way, you don't need to worry about the edge of the screen.
So instead of:
OIS -> UI mouse position -> player controls
use:
OIS -> player controls
So instead of:
OIS -> UI mouse position -> player controls
use:
OIS -> player controls
-
- Kobold
- Posts: 32
- Joined: Thu Aug 11, 2011 10:00 pm
Re: Mouse capture using OIS
Great, that was just what I've been looking for ! However I couldn't find in the OIS api how I can read the OIS input directly, it seems to me that you can only get the muse position with OIS, using MouseMoved and getMouseState...
- Jabberwocky
- OGRE Moderator
- Posts: 2819
- Joined: Mon Mar 05, 2007 11:17 pm
- Location: Canada
- x 218
- Contact:
Re: Mouse capture using OIS
getMouseState is what you're after.
Your code will look something like this:
Also make sure you're calling pMouse->capture() at the top of, or somewhere before that function. That's what queries OIS for the mouse state. You need to call capture once every frame.
Track down your OIS header files - you're probably going to need to consult the documentation and functions in those files at some point.
Your code will look something like this:
Code: Select all
void Controls::ReadMouseInput( OIS::Mouse* i_pMouse )
{
// x and y are mouse movements, horizontal and vertical, that have occurred this frame.
int xMouse = i_pMouse->getMouseState().X.rel;
int yMouse = i_pMouse->getMouseState().Y.rel;
// z is the mouse wheel
int zMouse = i_pMouse->getMouseState().Z.rel;
// ... do something with these values.
}
Track down your OIS header files - you're probably going to need to consult the documentation and functions in those files at some point.
-
- Kobold
- Posts: 32
- Joined: Thu Aug 11, 2011 10:00 pm
Re: Mouse capture using OIS
Here are the results I got. For each test i moved the mouse slowly to the left edge of my screen.
The mouse behaved normally and stopped at the left edge of the screen as expected. OIS was not able to detect any mouse input after the mouse touched the left edge.
Second test :
I added this code to the program
As soon as the mouse hits the left border of the winow, it jumps back to the center of the screen. This confuses OIS and CEGUI but hopefully I'll be able to switch dynamically between grabbed and free mouse when the view shifts from FPS to 3rd person and vice-versa.
I put Ogre to fullscreen mode :
The mouse stopped when hitting the left edge of the screen, and stayed stuck on the left border (and OIS outputed 0). however, when I moved it back a few pixels, it jumped back to the center. This is becoming confusing...
Fourth test :
I used a system-specific function to replace the cursor at the center of the screen :
Results :
Predictably, ODE understands the jump-backs as positive X movements...
Fifth test :
I added a OIS injection to set the apply the cursor position (in an attempt to avoid the back-jumps being interpreted as mouse movements) :
Results :
I guess I could apply a compensation after each mouse position reset to compensate this effect. I'll try that tomorrow...
Code: Select all
const OIS::MouseState &ms=mMouse->getMouseState();
std::cout<<"_mouse relX="<<ms.X.rel<<std::endl;
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-6
_mouse relX=-4
_mouse relX=-8
_mouse relX=0
_mouse relX=-11
_mouse relX=-2
_mouse relX=-3
_mouse relX=-4
_mouse relX=-6
_mouse relX=-6
_mouse relX=-4
_mouse relX=-9
_mouse relX=-2
_mouse relX=-6
_mouse relX=-6
_mouse relX=-7
_mouse relX=-4
_mouse relX=-8
_mouse relX=-10
_mouse relX=0
_mouse relX=-9
_mouse relX=-3
_mouse relX=-12
_mouse relX=-6
_mouse relX=-18
_mouse relX=-5
_mouse relX=-13
_mouse relX=-4
_mouse relX=-13
_mouse relX=-4
_mouse relX=-20
_mouse relX=0
_mouse relX=-9
_mouse relX=0
_mouse relX=-12
_mouse relX=-8
_mouse relX=-5
_mouse relX=-11
_mouse relX=-3
_mouse relX=-7
_mouse relX=-3
_mouse relX=-4
_mouse relX=-7
_mouse relX=-19
_mouse relX=-11
_mouse relX=-4
_mouse relX=-8
_mouse relX=-8
_mouse relX=-7
_mouse relX=-6
_mouse relX=-8
_mouse relX=-3
_mouse relX=-12
_mouse relX=-3
_mouse relX=-6
_mouse relX=-6
_mouse relX=-5
_mouse relX=-3
_mouse relX=-6
_mouse relX=-7
_mouse relX=-5
_mouse relX=-7
_mouse relX=-6
_mouse relX=-2
_mouse relX=-6
_mouse relX=-4
_mouse relX=-4
_mouse relX=-2
_mouse relX=-2
_mouse relX=-1
_mouse relX=-2
_mouse relX=-1
_mouse relX=-2
_mouse relX=-3
_mouse relX=-1
_mouse relX=-1
_mouse relX=0
_mouse relX=-2
_mouse relX=-1
_mouse relX=-2
_mouse relX=-2
_mouse relX=-5
_mouse relX=-2
_mouse relX=-5
_mouse relX=0
_mouse relX=-4
_mouse relX=-2
_mouse relX=-9
_mouse relX=-3
_mouse relX=-10
_mouse relX=-4
_mouse relX=-4
_mouse relX=-2
_mouse relX=-1
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
Second test :
I added this code to the program
Code: Select all
pl.insert(std::make_pair(std::string("x11_mouse_grab"), std::string("true")));
Third test :_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-7
_mouse relX=-6
_mouse relX=-46
_mouse relX=-16
_mouse relX=-41
_mouse relX=-49
_mouse relX=-83
_mouse relX=-23
_mouse relX=-69
_mouse relX=-22
_mouse relX=-61
_mouse relX=-20
_mouse relX=-46
_mouse relX=-15
_mouse relX=-8
_mouse relX=-512
_mouse relX=-33
_mouse relX=0
_mouse relX=-36
_mouse relX=-14
_mouse relX=-47
_mouse relX=-19
_mouse relX=-51
_mouse relX=-17
_mouse relX=-36
_mouse relX=-38
_mouse relX=-41
_mouse relX=-21
_mouse relX=-57
_mouse relX=-18
_mouse relX=-42
_mouse relX=-12
_mouse relX=-30
_mouse relX=-512
_mouse relX=-535
_mouse relX=11
_mouse relX=-42
_mouse relX=-12
_mouse relX=-36
_mouse relX=-15
_mouse relX=-44
_mouse relX=-16
_mouse relX=-34
_mouse relX=-40
_mouse relX=-36
_mouse relX=-56
_mouse relX=0
_mouse relX=-80
_mouse relX=0
_mouse relX=-56
_mouse relX=-33
_mouse relX=-67
_mouse relX=0
_mouse relX=-52
_mouse relX=-17
_mouse relX=-43
_mouse relX=0
_mouse relX=-43
_mouse relX=-7
_mouse relX=-17
_mouse relX=-34
_mouse relX=0
_mouse relX=-17
_mouse relX=-4
_mouse relX=-11
_mouse relX=-3
_mouse relX=-11
_mouse relX=0
_mouse relX=-11
_mouse relX=-8
_mouse relX=-20
_mouse relX=-4
_mouse relX=-11
_mouse relX=-5
_mouse relX=-18
_mouse relX=-11
_mouse relX=-29
_mouse relX=0
_mouse relX=-23
_mouse relX=0
_mouse relX=-18
_mouse relX=-4
_mouse relX=-17
_mouse relX=-5
_mouse relX=-16
_mouse relX=0
_mouse relX=-15
_mouse relX=-10
_mouse relX=-27
_mouse relX=-10
_mouse relX=-38
_mouse relX=-13
_mouse relX=-27
_mouse relX=-14
_mouse relX=-57
_mouse relX=-76
_mouse relX=-23
_mouse relX=-72
_mouse relX=0
_mouse relX=-70
_mouse relX=0
_mouse relX=-44
_mouse relX=-32
_mouse relX=-100
_mouse relX=-61
_mouse relX=-55
I put Ogre to fullscreen mode :
Code: Select all
rs->setConfigOption("Full Screen", "Yes");
Fourth test :
I used a system-specific function to replace the cursor at the center of the screen :
Code: Select all
unsigned int width=0;
unsigned int height=0;
unsigned int colourDepth=0;
int left=0;
int top=0;
TutorialApplication::mainApp->mWindow->getMetrics(width, height, colourDepth, left, top);
int x=width/2;
int y=height/2;
#ifndef _WIN32
XWarpPointer(TutorialApplication::mainApp->display, None, TutorialApplication::mainApp->root, 0, 0, 0, 0, x, y);
XFlush(TutorialApplication::mainApp->display);
#endif
Results :
Code: Select all
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-9
_mouse relX=0
_mouse relX=-23
_mouse relX=-4
_mouse relX=34
_mouse relX=-1
_mouse relX=-2
_mouse relX=0
_mouse relX=5
_mouse relX=-2
_mouse relX=2
_mouse relX=-1
_mouse relX=-1
_mouse relX=1
_mouse relX=1
_mouse relX=-2
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-3
_mouse relX=-5
_mouse relX=-2
_mouse relX=7
_mouse relX=3
_mouse relX=-2
_mouse relX=-6
_mouse relX=-2
_mouse relX=11
_mouse relX=-5
_mouse relX=4
_mouse relX=0
_mouse relX=-1
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-1
_mouse relX=1
_mouse relX=0
_mouse relX=2
_mouse relX=0
_mouse relX=-7
_mouse relX=0
_mouse relX=7
_mouse relX=0
_mouse relX=1
_mouse relX=-1
_mouse relX=0
_mouse relX=-3
_mouse relX=-3
_mouse relX=-2
_mouse relX=-4
_mouse relX=-1
_mouse relX=13
_mouse relX=0
_mouse relX=1
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-1
_mouse relX=1
_mouse relX=-1
_mouse relX=-3
_mouse relX=3
_mouse relX=-2
_mouse relX=-1
_mouse relX=0
_mouse relX=0
_mouse relX=4
_mouse relX=-7
_mouse relX=0
_mouse relX=7
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-2
_mouse relX=-3
_mouse relX=-5
_mouse relX=-4
_mouse relX=-4
_mouse relX=-1
_mouse relX=-6
_mouse relX=-2
_mouse relX=25
_mouse relX=1
_mouse relX=1
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-1
_mouse relX=-1
_mouse relX=2
_mouse relX=-3
_mouse relX=-3
_mouse relX=0
_mouse relX=-6
_mouse relX=-1
_mouse relX=-5
_mouse relX=-2
_mouse relX=18
_mouse relX=2
_mouse relX=-3
_mouse relX=-3
_mouse relX=-1
_mouse relX=0
_mouse relX=0
_mouse relX=-1
_mouse relX=-4
_mouse relX=8
_mouse relX=4
_mouse relX=-3
_mouse relX=-2
_mouse relX=2
_mouse relX=0
_mouse relX=2
_mouse relX=0
_mouse relX=1
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-1
_mouse relX=-2
_mouse relX=3
_mouse relX=-3
_mouse relX=0
_mouse relX=0
_mouse relX=-3
_mouse relX=4
_mouse relX=2
_mouse relX=-3
_mouse relX=1
_mouse relX=-1
_mouse relX=-4
_mouse relX=-4
_mouse relX=-3
_mouse relX=13
_mouse relX=-1
_mouse relX=0
_mouse relX=0
_mouse relX=-4
_mouse relX=-3
_mouse relX=9
_mouse relX=-6
_mouse relX=3
_mouse relX=-3
_mouse relX=-9
_mouse relX=-3
_mouse relX=15
_mouse relX=-4
_mouse relX=-2
_mouse relX=5
_mouse relX=-5
_mouse relX=0
_mouse relX=-14
_mouse relX=23
_mouse relX=-4
_mouse relX=0
_mouse relX=4
_mouse relX=-5
_mouse relX=-3
_mouse relX=0
_mouse relX=6
_mouse relX=2
_mouse relX=-2
_mouse relX=-3
_mouse relX=2
_mouse relX=-1
_mouse relX=-1
_mouse relX=3
_mouse relX=-5
_mouse relX=-2
_mouse relX=6
_mouse relX=3
Fifth test :
I added a OIS injection to set the apply the cursor position (in an attempt to avoid the back-jumps being interpreted as mouse movements) :
Code: Select all
#ifndef _WIN32
XWarpPointer(TutorialApplication::mainApp->display, None, TutorialApplication::mainApp->root, 0, 0, 0, 0, x, y);
XFlush(TutorialApplication::mainApp->display);
OIS::MouseState ms2=static_cast<OIS::MouseState>(mMouse->getMouseState());
ms2.X.abs=x;
ms2.Y.abs=y;
#endif
There seems to be no effect done :/_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=0
_mouse relX=-1
_mouse relX=-9
_mouse relX=-23
_mouse relX=-32
_mouse relX=42
_mouse relX=0
_mouse relX=-7
_mouse relX=19
_mouse relX=-5
_mouse relX=16
_mouse relX=-7
_mouse relX=5
_mouse relX=-2
_mouse relX=-2
_mouse relX=1
_mouse relX=-3
_mouse relX=4
_mouse relX=-5
_mouse relX=5
_mouse relX=4
_mouse relX=-12
_mouse relX=12
_mouse relX=-14
_mouse relX=0
_mouse relX=3
_mouse relX=7
_mouse relX=-3
_mouse relX=-5
_mouse relX=-9
_mouse relX=-3
_mouse relX=-6
_mouse relX=-7
_mouse relX=33
_mouse relX=-7
_mouse relX=7
_mouse relX=-2
_mouse relX=-8
_mouse relX=0
_mouse relX=-5
_mouse relX=-2
_mouse relX=18
_mouse relX=3
_mouse relX=-5
_mouse relX=4
_mouse relX=-3
_mouse relX=1
_mouse relX=-6
_mouse relX=-5
_mouse relX=9
_mouse relX=4
_mouse relX=1
_mouse relX=-4
_mouse relX=-6
_mouse relX=-1
_mouse relX=11
_mouse relX=-2
_mouse relX=-4
_mouse relX=0
_mouse relX=2
_mouse relX=0
_mouse relX=-3
_mouse relX=-3
_mouse relX=6
_mouse relX=0
_mouse relX=-1
_mouse relX=-2
_mouse relX=1
_mouse relX=0
_mouse relX=-1
_mouse relX=0
_mouse relX=-12
_mouse relX=0
_mouse relX=13
_mouse relX=0
_mouse relX=-10
_mouse relX=-4
_mouse relX=15
_mouse relX=0
_mouse relX=5
_mouse relX=-3
_mouse relX=-2
_mouse relX=-2
_mouse relX=3
_mouse relX=-1
_mouse relX=1
_mouse relX=4
_mouse relX=-7
I guess I could apply a compensation after each mouse position reset to compensate this effect. I'll try that tomorrow...
- Jabberwocky
- OGRE Moderator
- Posts: 2819
- Joined: Mon Mar 05, 2007 11:17 pm
- Location: Canada
- x 218
- Contact:
Re: Mouse capture using OIS
It looks like you're running on linux? (I see "x11_mouse_grab" in your code.)
I've never seen this problem, but I'm running on windows.
It pretty clearly looks like an OIS problem. You might want to try the OIS forums:
http://www.wreckedgames.com/forum/index ... d,6.0.html
I've never seen this problem, but I'm running on windows.
It pretty clearly looks like an OIS problem. You might want to try the OIS forums:
http://www.wreckedgames.com/forum/index ... d,6.0.html
-
- Kobold
- Posts: 32
- Joined: Thu Aug 11, 2011 10:00 pm
Re: Mouse capture using OIS
Yes, I'm using Ubuntu Linux. I actually managed to do what I wanted to do in a very ugly and os-specific way. After each mouse reposition, I set a compensation factor equaling the distance the mouse needed to move to replace in the center. This value is then subtracted to the value given by getMouseState (plus a constant that depends on the display (6px on my computer).
This works pretty well, but is so ugly... I guess I'll ask this on the OIS forums.
Thanks for your help !
This works pretty well, but is so ugly... I guess I'll ask this on the OIS forums.
Thanks for your help !