Mouse rotation

Problems building or running the engine, queries about how to use features etc.
User avatar
marco1475
Kobold
Posts: 27
Joined: Mon Nov 08, 2004 8:30 pm
Location: Hagenberg, Austria

Mouse rotation

Post by marco1475 »

Hi y'all!

I have the following problem - I am trying to implement a mouse rotation in my application where I rotate the camera around an object (mouseButton1 pressed = rotate, mouseButton2 pressed = pan).

I looked at and studied the "Lights, Camera, Action" tutorial (http://www.ogre3d.org/docs/Tutorials/3_ ... otion.html) where something similar is being discussed. However, there are several differences to my application:
- I am not using ExampleApplication and ExampleFrameListener - I have written my own application class and I am actually trying to rotate the camera in it's own listener
- I try to rotate the camera using the mouse - the rotation should be dependent on the mouse movement (move mouse left -> rotate left until the button is released, etc. - you get the picture)

Now here's my problem:
I have the mRotatingNode attached to the object I want to rotate around and mCamera attached to mRotatingNode, just like in the tutorial. When I call:

Code: Select all

mRotatingNode->rotate(Vector3::UNIT_Y, (Radian)1.0*evt.timeSinceLastFrame);
... it all works perfectly, constantly rotating around the object. However, when I exchange the "1.0" with the mRotX variable that is set in the processUnbufferedMouseInput() method, nothing happens.

I came to the conclusion that it is because the getMouseRelativeX() method never returns anything else besides 0.0. So my program is not tracking the mouse movement. The question is why? What do I need to start, include, etc. in the constructor, so the program will track my mouse?

And now for the code ;).

First, my class is derived only from FrameListener:

Code: Select all

class PAnalyzerMouseListener : public FrameListener
Do I need anything else?

This is my constructor:

Code: Select all

PAnalyzerMouseListener::PAnalyzerMouseListener(RenderWindow* window, Camera* camera, SceneNode* centralNode) {
    mWindow = window;
    mCamera = camera;

    mCentralNode = centralNode;

    mTranslateVector = Vector3::ZERO;
    mRotX = 0.0;
    mRotY = 0.0;

    // create a node to act as the central rotation point
    mRotatingNode = static_cast<SceneNode*>(mCentralNode->createChild());
    mRotatingNode->attachObject(mCamera);

    mCamera->moveRelative(Vector3(0.0, 0.0, 200.0));
    mCamera->lookAt(0.0, 0.0, 0.0);

    mEventProcessor = new EventProcessor();
    mEventProcessor->initialise(mWindow);
    OverlayManager::getSingleton().createCursorOverlay();

    mInputReader = mEventProcessor->getInputReader();
    mInputReader->setBufferedInput(false, true);

    mEventProcessor->startProcessingEvents();
}
Is anything missing? Do I need anything else?

Now for the processUnbufferedMouseInput() method:

Code: Select all

bool PAnalyzerMouseListener::processUnbufferedMouseInput(const FrameEvent& evt) {
    if (mInputReader->getMouseButton(0)) {
        mRotX = Degree(-mInputReader->getMouseRelativeX()*0.13);
        mRotY = Degree(-mInputReader->getMouseRelativeY()*0.13);
    }
    else if (mInputReader->getMouseButton(1)) {
        mTranslateVector.x += mInputReader->getMouseRelativeX() * 0.13;
        mTranslateVector.y -= mInputReader->getMouseRelativeY() * 0.13;
    }

    return true;
}
I tried already changing the 0.13 to 100 and 1000 to increase the rotation (in case it is to small to be seen), leaving it out ... nothing changed. However, when I set mRotX here to 1.0, it works (it rotates continuerly again).

And last is the frameStarted() method:

Code: Select all

bool PAnalyzerMouseListener::frameStarted(const FrameEvent &evt) {
    mInputReader->capture();

    GuiContainer* cursor = OverlayManager::getSingleton().getCursorGui();
    cursor->setMaterialName("Cursor/default");
    cursor->setDimensions(32.0/mWindow->getHeight(), 32.0/mWindow->getWidth());
    cursor->show();

    processUnbufferedMouseInput(evt);

    mRotatingNode->rotate(Vector3::UNIT_Y, mRotX*evt.timeSinceLastFrame);

    return true;
}
So, there you go. What did I leave out? Something's missing. Why doesn't Ogre track my mouse movement? Lastly, here's how the frame listener is called in my *App.cpp:

Code: Select all

mMouseListener = new PAnalyzerMouseListener(mWindow, mCamera, mBoxNode);
mRoot->addFrameListener(mMouseListener);
If anyone can help, please do so! =)
marco1475
User avatar
haffax
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4823
Joined: Fri Jun 18, 2004 1:40 pm
Location: Berlin, Germany
x 8

Post by haffax »

Did you try it with unbuffered mouse input?

in the constructor:

Code: Select all

mInputReader->setBufferedInput(false, false); 
team-pantheon programmer
creators of Rastullahs Lockenpracht
User avatar
marco1475
Kobold
Posts: 27
Joined: Mon Nov 08, 2004 8:30 pm
Location: Hagenberg, Austria

Post by marco1475 »

tanis wrote:Did you try it with unbuffered mouse input?
I did - now in my code all it did was that I couldn't move the mouse pointer. That is strange, right?

What I also did was try to implement the mouse movement in the SpaceApp from the above mentioned tutorial ... with the same results. So even when I am using the ExampleApp and ExampleFrameListener I cannot get the mouse position. So the problem won't be in my frame listener but only in the constructor, frameStarted() and processUnbufferedMouseInput() methods.
marco1475
User avatar
marco1475
Kobold
Posts: 27
Joined: Mon Nov 08, 2004 8:30 pm
Location: Hagenberg, Austria

Post by marco1475 »

Ok, here's a little update:

I managed to get the rotation working, but I think it is an (ugly) workaround and would appreciate it if someone could explain to me, if the buffered/immerdiate mouse input is supposed to be working this way or not.

So, here's how I solved the problem:

The interesting part I noticed (thx to tanis) was that once I turned off the buffered input via

Code: Select all

mInputReader->setBufferedInput(false, false);
... I was able to rotate the object, but my mouse pointer was stationary. Meaning the movements were tracked and passed onto the object that was then being rotated when I pressed the mouse button and moved the mouse, but I couldn't move the cursor on screen even if the mouse button was released.

It came down to this: bufferedInput on -> I can move the mouse pointer but it isn't being tracked; bufferedInput off -> I cannot move the mouse pointer but the mouse movement is being tracked.

So I developed a workaround where I set the bufferedInput to true in the constructor so I can freely move the mouse pointer and when I press a mouse button, I turn the bufferedInput off, so the mouse is tracked and the object rotated:

Code: Select all

bool PAnalyzerMouseListener::processMouseInput(const FrameEvent& evt) {
    if (mInputReader->getMouseButton(0) || mInputReader->getMouseButton(1)) {
        mInputReader->setBufferedInput(false, false);

        if (mInputReader->getMouseButton(0)) {
            mReset = false;
            mRotX = -(mInputReader->getMouseRelativeX());
            mRotY = -(mInputReader->getMouseRelativeY());
        }
        else {
            mReset = true;
        }
    }
    else {
        mInputReader->setBufferedInput(false, true);
    }

    return true;
}
So basically it works, but this cannot be how the mouse input modes were supposed to be used, is it? I mean it has to be possible to track the mouse pointer when I click and drag the mouse in just the buffered mode without the need to switch to immediate mode, right?

Thx for any advice you can give me ...
marco1475
User avatar
haffax
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 4823
Joined: Fri Jun 18, 2004 1:40 pm
Location: Berlin, Germany
x 8

Post by haffax »

Well I don't know what is the best way to handle this problem, but your solution is the one most projects I know off work with. Our project uses the switching between buffered and unbuffered too.
Another way would be to not let Ogre handle the input at all but this is unknown territory for me.
team-pantheon programmer
creators of Rastullahs Lockenpracht