Page 1 of 1

How to get the Mouse wheel value?

Posted: Tue Apr 12, 2005 4:38 pm
by steveybop
I am trying to implement a zoom function in my FPS style camera. in my event reciever i check to see if the event is a mouse and mouse wheel event, but i cant figure out how to get the f32 Wheel value that is in the EMIE_MOUSE_WHEEL event

here is the code im using:

Code: Select all

else if(event.EventType == irr::EET_MOUSE_INPUT_EVENT && event.MouseInput.Event == EMIE_MOUSE_WHEEL)
    {    
        //THIS LINE IS NOT WORKING 
if(event.EventType.EET_MOUSE_INPUT_EVENT.EMIE_MOUSE_WHEEL.Wheel<0)
         {
          cam->setFOV((PI/3.5f)*2.0f); //set camera zooming in  
          }
          else
          {
              cam->setFOV((PI/3.5f)/2.0f); //set camera zooming out
          }
    }
Ive tried all different combinations of this line, form just 'Wheel<0' to the whole thing

Code: Select all

event.EventType.EET_MOUSE_INPUT_EVENT.EMIE_MOUSE_WHEEL.Wheel<0

Posted: Tue Apr 12, 2005 4:55 pm
by Fraza
WHOA! I don't think the constants are class members! Here's what you're after

event.MouseInput.Wheel

it either = 1 or -1, judging by your code you know that.

Also, a little bit of advice, you should have a minimum and maximum amount of zooming in and out. (I have made a camera mode with mouse wheel for zoom as well).

Also, I don't see how that will zoom in and out. PI / 3.5 * or / 2???? These are constant values.... You want something more like

fCameraDistance *= or /= fMultiplyer;

I think.

Posted: Tue Apr 12, 2005 5:03 pm
by steveybop
thanks, thats working now. Question though, min and max? when i roll the mouse wheel forward it zooms once by 2 then thats it, it checks if Wheel > 0, if so it zooms, how did you get it to zoom that much over again? :oops: I didnt really put loads of thought into this, just saw setFOV() method and thought COOL!! Zoom function...hmmmmm

Posted: Tue Apr 12, 2005 6:28 pm
by Fraza
here is the basic idea. I will include something about angles aswell :wink:

Code: Select all

#include <irrlicht.h>
#include <iostream.h>

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

#pragma comment(lib, "Irrlicht.lib")

//Globals
//Variables
float fAngleX = 0, fAngleY = 0, fCameraDistance = 100, fLookAtX = 0, fLookAtY = 0, fLookAtZ = 0;
IrrlichtDevice* Device = NULL;
ICameraSceneNode* Camera = NULL;
position2d<f32> MousePos;

//Classes
class EventHandler : public IEventReceiver
{
    //Forgive my indentation for classes, I have only been learning C++ for a couple of months.
    public:
        virtual bool OnEvent(SEvent event)
        {
            switch(event.EventType)
            {
                case EET_MOUSE_INPUT_EVENT:
                {
                    switch(event.MouseInput.Event)
                    {
                        case EMIE_MOUSE_WHEEL:
                        {
                            float fMultiplyer = 1;
                            fMultiplyer += event.MouseInput.Wheel/10;
                            fCameraDistance *= fMultiplyer;
                            //here you can have an if statement involving fCameraDistance that will change fCameraDistance if it is bigger than 100 to 100 etc.
                        }
                        break;
                    }
                }
                break;
                case EET_KEY_INPUT_EVENT:
                {
                    switch(event.KeyInput.Key)
                    {
                        case KEY_NUMPAD8: //Move "Forwards"
                            fLookAtX--;
                        break;
                        case KEY_NUMPAD2: //Move "Backwards"
                            fLookAtX++;
                        break;
                        case KEY_NUMPAD4: //Move "Left"
                            fLookAtZ--;
                        break;
                        case KEY_NUMPAD6: //Move "Right"
                            fLookAtZ++;
                        break;
                        case KEY_NUMPAD9: //Move "Up"
                            fLookAtY++;
                        break;
                        case KEY_NUMPAD1: //Move "Down"
                            fLookAtY--;
                        break;
                        case KEY_KEY_Q: //Quit
                            Device->closeDevice();
                        break;
                    }
                }
                break;
            }
            return false;
        }
};

//Function Prototypes
void DrawCamera(float fLookX, float fLookY, float fLookZ, float fAX, float fAY, float fDist);

int main()
{
    EventHandler MyReceiver;
    Device = createDevice(EDT_OPENGL, dimension2d<s32>(1024, 768), 32, true, false, false, &MyReceiver);
    IVideoDriver* Driver = Device->getVideoDriver();
    ISceneManager* SceneManager = Device->getSceneManager();
    Camera = SceneManager->addCameraSceneNode(0, vector3df(0, 0, 0), vector3df(0, 0, 0));
    SceneManager->addTestSceneNode();
    DrawCamera(fLookAtX, fLookAtY, fLookAtZ, fAngleX, fAngleY, fCameraDistance);
    while(Device->run())
    {
        Driver->beginScene(true, true, SColor(255, 255, 255, 200));
        SceneManager->drawAll();
        Driver->endScene();
        DrawCamera(fLookAtX, fLookAtY, fLookAtZ, fAngleX, fAngleY, fCameraDistance);
        //I will implement here a basic camera that will move when the mouse is at the edge of the screen. My tests showed that the relative mouse pos is not infact 1.0 at the end of the screen. Perhaps this could be changed by niko? (awesome job though!)
        MousePos = Device->getCursorControl()->getRelativePosition();
        if(MousePos.X >= 0.99)
            fAngleX += 0.1;
        if(MousePos.Y >= 0.99)
            fAngleY += 0.1;
        if(!MousePos.X)
            fAngleX -= 0.1;
        if(!MousePos.Y)
            fAngleY -= 0.1;
        if(fAngleX >= 360)
            fAngleX -= 360;
        if(fAngleX <= 0)
            fAngleX += 360;
        if(fAngleY > 89)
            fAngleY = 89;
        if(fAngleY < -89)
            fAngleY = -89;
    }
    return 0;
}

//Function Definitions
void DrawCamera(float fLookX, float fLookY, float fLookZ, float fAX, float fAY, float fDist)
{
    vector3df CameraPos = Camera->getPosition(), CameraTarget = Camera->getTarget();
    float fX = CameraPos.X, fY = CameraPos.Y, fZ = CameraPos.Z, fXZDistance;
    fXZDistance = fDist*cos(PI*(fAngleY/180));
    fY = fDist*sin(PI*(fAY/180));
    fX = cos(PI*(fAX/180))*fXZDistance;
    fZ = sin(PI*(fAX/180))*fXZDistance;
    fX += fLookX;
    fY += fLookY;
    fZ += fLookZ;
    CameraPos.X = fX;
    CameraPos.Y = fY;
    CameraPos.Z = fZ;
    Camera->setPosition(CameraPos);
    CameraTarget.X = fLookX;
    CameraTarget.Y = fLookY;
    CameraTarget.Z = fLookZ;
    Camera->setTarget(CameraTarget);
    //OK, very inefficient procedure, I would change it if anyone wants me to do a game quality camera.
}
well... there it is. My camera I made for you :D

The controls are, mouse to the edge of the screen rotates the view. numpad keys, 8 and 2 forward and back, 4 and 6 left and right and 1 and 9 up and down.

Have a try with just the code, there's a test scene node there for you.

Posted: Tue Apr 12, 2005 7:33 pm
by Fraza
Hope this helps... p.s. Remember to put the DLL into the folder before compilation, I forgot to and I took about 10 mins to remember to!

Note : moving forward backward etc is NOT relative to camera orientation. I may write something about this at a later date.

Posted: Tue Apr 12, 2005 7:51 pm
by Guest
[quote="Fraza"] //OK, very inefficient procedure, I would change it if anyone wants me to do a game quality camera.
[quote]

If it is not a bother, that would be great. :D

Posted: Tue Apr 12, 2005 8:01 pm
by Fraza
I'll sort out the movement first, as in you won't have moving forward, backward, left and right based on the world X and Z.


Hmm... It seems by changing the movement to be independant of the X and Z i am merely making the camera very like the FPS camera. So I will just update the function then continue working with this camera.

Posted: Tue Apr 12, 2005 10:09 pm
by Fraza
Here is a fairly decent version:

Code: Select all

void DrawCamera(float fLookX, float fLookY, float fLookZ, float fAX, float fAY, float fDist)
{
    vector3df CameraPos = Camera->getPosition(), CameraTarget = Camera->getTarget();
    float fXZDistance;
    fXZDistance = fDist*cos(PI*(fAngleY/180));
    CameraPos.Y = fDist*sin(PI*(fAY/180))+fLookY;
    CameraPos.X = cos(PI*(fAX/180))*fXZDistance+fLookX;
    CameraPos.Z = sin(PI*(fAX/180))*fXZDistance+fLookZ;
    Camera->setPosition(CameraPos);
    CameraTarget.X = fLookX;
    CameraTarget.Y = fLookY;
    CameraTarget.Z = fLookZ;
    Camera->setTarget(CameraTarget);
    //Still inneficient to an extent, recalculation of angles if they are the same as they were last time. Also, a commercial game would probably use assembly language for such a highly used procedure
}

Posted: Wed Apr 13, 2005 7:51 am
by arras
dont know if it helps but here is code of my event receiver I use for geting mouse and key input:

Code: Select all

#include <irrlicht.h>

bool keys[irr::KEY_KEY_CODES_COUNT];
bool mouseLeft;
bool mouseRight;
bool mouseMiddle;
irr::s32 mouseX;
irr::s32 mouseY;
irr::f32 mouseWheel; 
        
class MyEventReceiver : public IEventReceiver
{
public: 
    virtual bool OnEvent(SEvent event)
    {
        if(event.EventType == irr::EET_MOUSE_INPUT_EVENT)
        {
            if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
                mouseLeft = true;
            if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
                mouseRight = true;
            if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN)
                mouseMiddle = true;
            
            if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
                mouseLeft = false;
            if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
                mouseRight = false;
            if(event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP)
                mouseMiddle = false;
            
            if(event.MouseInput.Event == EMIE_MOUSE_MOVED)
            {
                mouseX = event.MouseInput.X;
                mouseY = event.MouseInput.Y;
            }
            if(event.MouseInput.Event == EMIE_MOUSE_WHEEL)
                mouseWheel += event.MouseInput.Wheel;
            return true;
        }

        if(event.EventType == irr::EET_KEY_INPUT_EVENT)
        {
            keys[event.KeyInput.Key] = event.KeyInput.PressedDown;
            return true;
        }
        
        return false;
    }	
};
As you can see I firsth declare global variables where I store input so I can use it later anywhere in program ...for example like this, using function I call each loop:

Code: Select all

void control(irr::IrrlichtDevice* device, SCamera *camera, SShip *ship = NULL)
{
    irr::core::dimension2d<irr::s32>screen;
    switch(camera->getMode())
    {
        case 0:
            screen = device->getVideoDriver()->getScreenSize();
            screen.Height = screen.Height / 2;
            screen.Width = screen.Width / 2;
            if(mouseX != screen.Width)
            {
                irr::f32 i = mouseX-screen.Width;
                i = i / 2;
                camera->turnAroundW(i);
                mouseX = screen.Width;
            }
            if(mouseY != screen.Height)
            {
                irr::f32 i = mouseY-screen.Height;
                i = i / 2;
                camera->turnAroundH(i);
                mouseY = screen.Height;
            }
            device->getCursorControl()->setPosition(screen.Width+1, screen.Height+1);
            break;
        case 1:
            break;
    }
    
    if(keys[irr::KEY_F1])
    {
        camera->setMode(0);
        irr::core::dimension2d<irr::s32>screen = device->getVideoDriver()->getScreenSize();
        screen.Height = screen.Height / 2;
        screen.Width = screen.Width / 2;
        device->getCursorControl()->setPosition(screen.Width+1, screen.Height+1);
    }
    if(keys[irr::KEY_F2])
    {
        camera->setMode(1);
    }    

    if(ship)
    {
        // direction control
        if(keys[irr::KEY_LEFT])
        {
            ship->turnLeft();
        }
        if(keys[irr::KEY_RIGHT])
        {
            ship->turnRight();
        }

        // engine control
        if(keys[irr::KEY_KEY_W])
        {
            ship->thrustForward(0.1f);
        }
        if(keys[irr::KEY_KEY_S])
        {
            ship->thrustBack(0.1f);
        }
    }    
}

Posted: Wed Apr 13, 2005 9:00 pm
by Fraza
arras wrote:

Code: Select all

            if(event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
                mouseLeft = true;
            if(event.MouseInput.Event == EMIE_RMOUSE_PRESSED_DOWN)
                mouseRight = true;
            if(event.MouseInput.Event == EMIE_MMOUSE_PRESSED_DOWN)
                mouseMiddle = true;
           
            if(event.MouseInput.Event == EMIE_LMOUSE_LEFT_UP)
                mouseLeft = false;
            if(event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP)
                mouseRight = false;
            if(event.MouseInput.Event == EMIE_MMOUSE_LEFT_UP)
                mouseMiddle = false;
You could use this instead :

Code: Select all

            mouseLeft = event.MouseInput.Event-EMIE_LMOUSE_LEFT_UP;
            mouseRight = event.MouseInput.Event-EMIE_RMOUSE_LEFT_UP;
            mouseMiddle = event.MouseInput.Event-EMIE_MMOUSE_LEFT_UP;
(not tested... i am only guessing the constants are integers).