Basic Mouse Movement

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
raistca
Posts: 15
Joined: Sat Mar 26, 2011 5:26 am

Basic Mouse Movement

Post by raistca »

Ok so I'm just getting started with Irrlicht and simultaneously brushing up on rusty C++ skills, so be gentle. Basically what I want to do is render a 3d scene, then allow the user to rotate the camera around the scene by holding down the right mouse button and moving the mouse.

So far I've tried modifying some of the code sample from the mouse movement tutorial unsuccessfully for (I think) a couple reasons:

1st: I don't know if there is a simple way to get a delta between the mouse's former position and current position. This would be really cool!

2nd: I'm not entirely clear how the OnEvent method of IEventReceiver plays out in terms of program flow (is the method called automatically whenever the application receives an event message from windows?)

3rd: Having some trouble getting used to the vector data types (vector3df and i), but this problem may be solved if the 1st is easy.

Thanks for the help guys!

Edit: I should have specified, but if someone has a very simple example of how to implement something like this I would be thrilled!
hendu
Posts: 2600
Joined: Sat Dec 18, 2010 12:53 pm

Post by hendu »

Why not take a look at the Maya camera code (or even enable it for your app)?
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

1st: I don't know if there is a simple way to get a delta between the mouse's former position and current position. This would be really cool!
Doing stuff like this is called making algorithms I think..
3rd: Having some trouble getting used to the vector data types (vector3df and i), but this problem may be solved if the 1st is easy.
the 'i' or 'f' part means what type of vector it is.
'i' means integer, 'f' means float.

And for the second question I don't really know, haven't really looked up for that myself. But you could look at the sources and find that.
Last edited by serengeor on Sat Mar 26, 2011 3:56 pm, edited 1 time in total.
Working on game: Marrbles (Currently stopped).
freetimecoder
Posts: 226
Joined: Fri Aug 22, 2008 8:50 pm
Contact:

Post by freetimecoder »

The IrrlichtDevice calls the OnEvent function of an IEventReceiver. You have to set your custom receiver when creating the device or with the ->setEventReceiver function of the device. Then Irrlicht will call the OnEvent function of this receiver in case something happens. If your receiver has processed the event you return true to let Irrlicht know that no other receiver shall receive this event or false if you could not process the event or want Irrlicht to pass it to the other receivers as well (e.g. to the one of the FPS or Maya Camera).

greetings
raistca
Posts: 15
Joined: Sat Mar 26, 2011 5:26 am

Post by raistca »

thanks everyone, and especially freetime, I believe this was the crux of the issue. I didn't notice that receiver was in the device parameters in the tutorial until you said that. Let me try this out and I'll get back
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

Once again, also for you personally: Read the tutorials. They are exactly for this purpose. Learning about the basics of the engine (and also C++, btw). It helps you and offloads much of the boring stuff from us 8)
raistca
Posts: 15
Joined: Sat Mar 26, 2011 5:26 am

Post by raistca »

if you were to reread some of my posts you would see I made specific mention of having read the tutorials, but thanks for the suggestion!
sephoroph
Posts: 7
Joined: Sat Mar 05, 2011 11:42 pm

Post by sephoroph »

To help solve your first problem:

This is code i have in a function that handles my camera movement using deltaX and deltaY.. It is basicly like first person camera you move your mouse to the right the camera looks to the right

Code: Select all

// static makes sure the variable is the same each time the function is called
// the initlialization here only happens on the first call to the function
static int deltaX = receiver.GetMouseState().Position.X ;	
static int deltaY = receiver.GetMouseState().Position.Y;	
deltaX -= receiver.GetMouseState().Position.X;
deltaY -= receiver.GetMouseState().Position.Y;

vector3df rot = cam->getRotation();

// The speed at which the camera rotates
rot.Y -= deltaX/1.0;
rot.X -= deltaY/1.0;
cam->setRotation(rot);

// This saves the old position of the mouse for the next function call to subtract from
deltaX = receiver.GetMouseState().Position.X ;
deltaY = receiver.GetMouseState().Position.Y ;


code for the receiver

Code: Select all

#include "include.h"
#include <irrlicht.h>

using namespace irr;

using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;


class MyEventReceiver : public IEventReceiver
{
public:
        // We'll create a struct to record info on the mouse state
        struct SMouseState
        {
                core::position2di Position;
                bool LeftButtonDown;
                SMouseState() : LeftButtonDown(false) { }
        } MouseState;

		virtual bool IsKeyDown(EKEY_CODE keyCode) const
		{
			return KeyIsDown[keyCode];
		}

        // This is the one method that we have to implement
        virtual bool OnEvent(const SEvent& event)
        {
				if (event.EventType == irr::EET_KEY_INPUT_EVENT)
					KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;

                // Remember the mouse state
                if (event.EventType == irr::EET_MOUSE_INPUT_EVENT)
                {
                        switch(event.MouseInput.Event)
                        {
                        case EMIE_LMOUSE_PRESSED_DOWN:
                                MouseState.LeftButtonDown = true;
                                break;

                        case EMIE_LMOUSE_LEFT_UP:
                                MouseState.LeftButtonDown = false;
                                break;

                        case EMIE_MOUSE_MOVED:
                                MouseState.Position.X = event.MouseInput.X;
                                MouseState.Position.Y = event.MouseInput.Y;
                                break;
							
							break;
                        default:
                                // We won't use the wheel
                                break;
                        }
                }

                // The state of each connected joystick is sent to us
                // once every run() of the Irrlicht device.  Store the
                // state of the first joystick, ignoring other joysticks.
                // This is currently only supported on Windows and Linux.
                if (event.EventType == irr::EET_JOYSTICK_INPUT_EVENT
                        && event.JoystickEvent.Joystick == 0)
                {
                        JoystickState = event.JoystickEvent;
                }

                return false;
        }

        const SEvent::SJoystickEvent & GetJoystickState(void) const
        {
                return JoystickState;
        }

        const SMouseState & GetMouseState(void) const
        {
                return MouseState;
        }


        MyEventReceiver()
        {
			for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
			KeyIsDown[i] = false;
        }

private:
		bool KeyIsDown[KEY_KEY_CODES_COUNT];
        SEvent::SJoystickEvent JoystickState;
};

raistca
Posts: 15
Joined: Sat Mar 26, 2011 5:26 am

Post by raistca »

thanks seph, I had something similar for the delta, but now I see where I went wrong. However, I can't get this code to actually move the camera with the mouse, and I'm not sure why.

This is my camera:

Code: Select all

scene::ISceneNode * camera = smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
my device:

Code: Select all

IrrlichtDevice *device = createDevice( video::EDT_DIRECT3D9, dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
and the begin scene:

Code: Select all

driver->beginScene(true, true, SColor(255,100,101,140));
Is there a parameter in one of these that might be interfering with what I'm trying to do? Most of the code I have so far is copied from the first tutorial, so nothing really crazy going on.

Edit: Also, for the sake of testing I just dropped your function code into the device->run loop. That should work right?
sephoroph
Posts: 7
Joined: Sat Mar 05, 2011 11:42 pm

Post by sephoroph »

Your going to need this line somewhere in there

Code: Select all

cam->bindTargetAndRotation(true);
if you don't have that the camera trys to focus on a specific object

and yea just dropping the code in should work.. You might be better off initializing the deltas outside the loop and dropping the static then
raistca
Posts: 15
Joined: Sat Mar 26, 2011 5:26 am

Post by raistca »

Ok sweet that did it! Finally something working :) So do you have any ideas of how I could invert that principle (i.e. now the camera rotates from a fixed position looking outward, could I make it move around an object at a fixed distance, always looking at the object?)

Thanks again for the help!
serengeor
Posts: 1712
Joined: Tue Jan 13, 2009 7:34 pm
Location: Lithuania

Post by serengeor »

why is that bind target and rotation function not getting removed, it just gives frustration to those who are not familiar with it. I know its left for compatibility, but still it should get removed since I don't think its actually useful for anything, and just gives problems when not using it.
I think it should be removed at least in next major version.
Working on game: Marrbles (Currently stopped).
sephoroph
Posts: 7
Joined: Sat Mar 05, 2011 11:42 pm

Post by sephoroph »

the function shouldn't be removed imho, but it should be true by default
raistca
Posts: 15
Joined: Sat Mar 26, 2011 5:26 am

Post by raistca »

Ok guys problem solved! Thanks for the help!

Basically my plan was to revolve the camera around the object, changing position and rotation so that it always focused on the same point.

This was silly, however, since it was much easier to simply rotate the scene in front of the camera and leave the camera's position and rotation static.

Then (still using Sephoroph's delta mouse move code) I added a simple conditional to check if the right mouse button was held down so that it would only rotate with the right mouse button.

Yay!
saeid
Posts: 4
Joined: Wed Mar 23, 2011 10:13 pm
Location: tehran , IRAN

Post by saeid »

to rotate your camera around an object you must first create a vector like this:
direction = camera->position - object->position
then rotate this vector(direction) using your deltaX and deltaY and at last calculate your camera position :
newCameraPos = object->position + direction
Post Reply