Maya camera reworked

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
Neirdan
Posts: 39
Joined: Tue Aug 14, 2012 10:29 pm

Maya camera reworked

Post by Neirdan »

My own version of the maya camera scene node.
Translation code is highly inspired (as in "copy/paste") from the original one.
Instead of using a camera without parent, to simplify the rotation and translation, the camera is child of an empty node.
It might be improved, but it's doing the basic function of a Maya camera without having to tweak the "official" one.

LMB or Up Down Left Right arrow keys = rotate
RMB or ZQSD (AZERTY keyboard) = translate
MW or LMB+RMB = zoom in/out (left/right axis)

Code: Select all

 
//global vars
irr::scene::ICameraSceneNode *camera;
irr::scene::ISceneNode *camTarget;
 
//Event receiver
class MyEventReceiver : public irr::IEventReceiver {
    private:
        SAppContext & Context;
 
        struct mouseData {
            int X;
            int Y;
            irr::f32 wheel;
        };
        struct mouseData mousePos;
        struct mouseData mouseLastPos;
        core::vector3df camTargetPos;
        core::vector3df camTargetRot;
        bool leftButton;
        bool rightButton;
 
    public:
        bool KeyIsDown[irr::KEY_KEY_CODES_COUNT];
        core::vector3df cameraPos;
        f32 cameraDistance;
 
    MyEventReceiver(SAppContext & context) : Context(context) {
        for (irr::u32 i=0; i<irr::KEY_KEY_CODES_COUNT; ++i){
            KeyIsDown[i] = false;
        }
        leftButton=false;
        rightButton=false;
    }
 
    virtual bool OnEvent(const irr::SEvent& event) {
        //KEYBOARD
        if (event.EventType == irr::EET_KEY_INPUT_EVENT) {
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
            //KeyboardProcess();
        }
        //MOUSE
        if (event.EventType == irr::EET_MOUSE_INPUT_EVENT) {
            if (event.MouseInput.Event == irr::EMIE_MOUSE_MOVED) {
                mousePos.X=event.MouseInput.X;
                mousePos.Y=event.MouseInput.Y;
            }
            if (event.MouseInput.Event == irr::EMIE_MOUSE_WHEEL) {
                mousePos.wheel+=event.MouseInput.Wheel;
                //MouseWheelProcess();
            }
            if (event.MouseInput.Event == irr::EMIE_LMOUSE_PRESSED_DOWN) {
                leftButton=true;
                mouseLastPos=mousePos;
            }
            if (event.MouseInput.Event == irr::EMIE_LMOUSE_LEFT_UP) {
                leftButton=false;
            }
            if (event.MouseInput.Event == irr::EMIE_RMOUSE_PRESSED_DOWN) {
                rightButton=true;
                mouseLastPos=mousePos;
            }
            if (event.MouseInput.Event == irr::EMIE_RMOUSE_LEFT_UP) {
                rightButton=false;
            }
        }
        return false;
    }
 
    virtual bool IsKeyDown(irr::EKEY_CODE keyCode) const {
        return KeyIsDown[keyCode];
    }
 
    void AllProcess() {
        KeyboardProcess();
        MouseProcess();
        MouseWheelProcess();
    }
 
    void KeyboardProcess() {
        if(IsKeyDown(irr::KEY_UP)) {
            camTargetRot=camTarget->getRotation();
            camTargetRot.X+=0.01;
            if (camTargetRot.X>89.9) {
                camTargetRot.X=89.9;
            }
            camTarget->setRotation(camTargetRot);
        }
        if(IsKeyDown(irr::KEY_DOWN)) {
            camTargetRot=camTarget->getRotation();
            camTargetRot.X-=0.01;
            if (camTargetRot.X<-89.9) {
                camTargetRot.X=-89.9;
            }
            camTarget->setRotation(camTargetRot);
        }
        if(IsKeyDown(irr::KEY_LEFT)) {
            camTargetRot=camTarget->getRotation();
            camTargetRot.Y+=0.01;
            camTarget->setRotation(camTargetRot);
        }
        if(IsKeyDown(irr::KEY_RIGHT)) {
            camTargetRot=camTarget->getRotation();
            camTargetRot.Y-=0.01;
            camTarget->setRotation(camTargetRot);
        }
        if (IsKeyDown(irr::KEY_KEY_Q)) {
            translateCenter(-0.1,0);
        }
        if (IsKeyDown(irr::KEY_KEY_D)) {
            translateCenter(0.1,0);
        }
        if (IsKeyDown(irr::KEY_KEY_Z)) {
            translateCenter(0,-0.1);
        }
        if (IsKeyDown(irr::KEY_KEY_S)) {
            translateCenter(0,0.1);
        }
    }
 
    void MouseProcess() {
        if (leftButton) {
            if (rightButton) {
                //zoom
                zoom((mouseLastPos.X-mousePos.X)*0.05);
                mouseLastPos=mousePos;
            } else {
                //rotate
                camTargetRot=camTarget->getRotation();
                camTargetRot.X+=(mouseLastPos.Y-mousePos.Y)*0.1;
                if (camTargetRot.X<-89.0) {
                    camTargetRot.X=-89.0;
                } else if (camTargetRot.X>89.0) {
                    camTargetRot.X=89.0;
                }
                camTargetRot.Y+=(mouseLastPos.X-mousePos.X)*0.1;
                camTarget->setRotation(camTargetRot);
                mouseLastPos=mousePos;
            }
        }
        if (rightButton & !leftButton) {
            if ((mousePos.X!=mouseLastPos.X) || (mousePos.Y!=mouseLastPos.Y))
            translateCenter((mousePos.X-mouseLastPos.X)*0.1,(mousePos.Y-mouseLastPos.Y)*0.1);
            mouseLastPos=mousePos;
        }
    }
 
    void MouseWheelProcess() {
        if (mousePos.wheel!=0) {
            zoom(mousePos.wheel*(-1));
            mousePos.wheel=0;
        }
    }
 
    void zoom(irr::f32 zoomValue) {
        cameraPos = camera->getPosition();
        cameraDistance = cameraPos.getLength()+1.0f*zoomValue;
 
        if (cameraDistance<1.0f) {
            cameraDistance=1.0f;
        }
        if (cameraDistance>100.0f) {
            cameraDistance=100.0f;
        }
        //std::cout << cameraDistance << std::endl;
 
        cameraPos.setLength(cameraDistance);
        camera->setPosition(cameraPos);
        camera->setTarget(camTarget->getPosition());
    }
 
    void translateCenter(irr::f32 X, irr::f32 Y) {
        core::vector3df upVector(camera->getUpVector());
        core::vector3df target = camera->getTarget();
        core::vector3df pos = camera->getAbsolutePosition();
 
        core::vector3df tvectX = pos - target;
        tvectX = tvectX.crossProduct(upVector);
        tvectX.normalize();
 
        const SViewFrustum* const va = camera->getViewFrustum();
        core::vector3df tvectY = (va->getFarLeftDown() - va->getFarRightDown());
        tvectY = tvectY.crossProduct(upVector.Y > 0 ? pos - target : target - pos);
        tvectY.normalize();
 
        camTargetPos=camTarget->getPosition();
        camTargetPos+=tvectX*X+tvectY*Y;
        camTarget->setPosition(camTargetPos);
        camera->setTarget(camTarget->getPosition());
    }
};
 
//Inside main
MyEventReceiver receiver();
 
    //camera target
    camTarget=sceneManager->addEmptySceneNode(0);
    camTarget->setPosition(irr::core::vector3df(0.0f,0.0f,0.0f));
 
    /* CAMERA */
    camera=sceneManager->addCameraSceneNode(camTarget,core::vector3df(0.0f,0.0f,-(100.0f)),camTarget->getPosition());
 
//Inside run loop
receiver.AllProcess();
 
Post Reply