Mouse capture using OIS

Problems building or running the engine, queries about how to use features etc.
Post Reply
guillaumequest
Kobold
Posts: 32
Joined: Thu Aug 11, 2011 10:00 pm

Mouse capture using OIS

Post by guillaumequest »

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 :D
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Mouse capture using OIS

Post by Jabberwocky »

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?
Image
guillaumequest
Kobold
Posts: 32
Joined: Thu Aug 11, 2011 10:00 pm

Re: Mouse capture using OIS

Post by guillaumequest »

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.
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Mouse capture using OIS

Post by Jabberwocky »

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:

Code: Select all

		Ogre::OverlayContainer* getCursorContainer() { return mCursor; }
And then you can call these functions to set the cursor position on the returned cursor:

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);
I don't know if that will work or not, but give it a shot.
Image
guillaumequest
Kobold
Posts: 32
Joined: Thu Aug 11, 2011 10:00 pm

Re: Mouse capture using OIS

Post by guillaumequest »

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 ?
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Mouse capture using OIS

Post by Jabberwocky »

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
Image
guillaumequest
Kobold
Posts: 32
Joined: Thu Aug 11, 2011 10:00 pm

Re: Mouse capture using OIS

Post by guillaumequest »

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...
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Mouse capture using OIS

Post by Jabberwocky »

getMouseState is what you're after.
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.
}
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.
Image
guillaumequest
Kobold
Posts: 32
Joined: Thu Aug 11, 2011 10:00 pm

Re: Mouse capture using OIS

Post by guillaumequest »

Here are the results I got. For each test i moved the mouse slowly to the left edge of my screen.

Code: Select all

const OIS::MouseState &ms=mMouse->getMouseState();
std::cout<<"_mouse relX="<<ms.X.rel<<std::endl;
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.
_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")));
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.
_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
Third test :
I put Ogre to fullscreen mode :

Code: Select all

rs->setConfigOption("Full Screen", "Yes");
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 :

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
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) :

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
Results :
_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
There seems to be no effect done :/
I guess I could apply a compensation after each mouse position reset to compensate this effect. I'll try that tomorrow...
User avatar
Jabberwocky
OGRE Moderator
OGRE Moderator
Posts: 2819
Joined: Mon Mar 05, 2007 11:17 pm
Location: Canada
x 218
Contact:

Re: Mouse capture using OIS

Post by Jabberwocky »

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
Image
guillaumequest
Kobold
Posts: 32
Joined: Thu Aug 11, 2011 10:00 pm

Re: Mouse capture using OIS

Post by guillaumequest »

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 !
Post Reply