: Documentation : Interaction Tutorials

Introduction

This tutorial demonstrates how to include keyboard input in an osgART application. Here we will use keyboard controls to interact with an object in the scene (a car model loaded from file).

Setup

As before we add the event handlers to the OSG Viewer, and set up the Scene node. Here we will track one marker. We add the 3D car model into the scene using the same process as in earlier tutorials.

osg::ref_ptr<osg::MatrixTransform> mt = scene->addTrackedTransform("single;data/artoolkit2/patt.hiro;80;0;0");
osg::ref_ptr<osg::MatrixTransform> driveCar = new osg::MatrixTransform();
driveCar->addChild(osgDB::readNodeFile("media/models/car.ive"));
mt->addChild(driveCar.get());

We also add an additional handler - MyKeyboardEventHandler - using our driveCar MatrixTransform object in parameter. We will define next what the Event Handler do.

viewer.addEventHandler(new MyKeyboardEventHandler(driveCar)); // Our handler

KeyboardEventHandler

To handle both keyboard and mouse events in OSG, we need to define a subclass of osgGA::GUIEventHandler, and override the handle() method with custom code. We also need to make aware the Event Handler of the object we want to modify: we pass then the osg::MatrixTransform in argument (in our case the driveCar defined previously).

The code is as follows:

class MyKeyboardEventHandler : public osgGA::GUIEventHandler {

protected:
    osg::MatrixTransform* _driveCar;

public:
    MyKeyboardEventHandler(osg::MatrixTransform* drivecar) : osgGA::GUIEventHandler() {_driveCar=drivecar; }


    /**
        OVERRIDE THE HANDLE METHOD:
        The handle() method should return true if the event has been dealt with
        and we do not wish it to be handled by any other handler we may also have
        defined. Whether you return true or false depends on the behaviour you
        want - here we have no other handlers defined so return true.
    **/
    virtual bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa,
                        osg::Object* obj, osg::NodeVisitor* nv) {

        switch (ea.getEventType()) {


            /** KEY EVENTS:
                Key events have an associated key and event names.
                In this example, we are interested in keys up/down/right/left arrow
                and space bar.
                If we detect a press then we modify the transformation matrix
                of the local transform node. **/
            case osgGA::GUIEventAdapter::KEYDOWN: {

                switch (ea.getKey()) {

                    case osgGA::GUIEventAdapter::KEY_Up: // Move forward 5mm
                        _driveCar->preMult(osg::Matrix::translate(0, -5, 0));
                        return true;

                    case osgGA::GUIEventAdapter::KEY_Down: // Move back 5mm
                        _driveCar->preMult(osg::Matrix::translate(0, 5, 0));
                        return true;

                    case osgGA::GUIEventAdapter::KEY_Left: // Rotate 10 degrees left
                        _driveCar->preMult(osg::Matrix::rotate(osg::DegreesToRadians(10.0f),
                                                       osg::Z_AXIS));
                        return true;

                    case osgGA::GUIEventAdapter::KEY_Right: // Rotate 10 degrees right
                        _driveCar->preMult(osg::Matrix::rotate(osg::DegreesToRadians(-10.0f),
                                                       osg::Z_AXIS));
                        return true;

                    case ' ': // Reset the transformation
                        _driveCar->setMatrix(osg::Matrix::identity());
                        return true;
                }

                   default: return false;
            }


        }
    }
};

KeyboardInputScreenshot.jpg KeyboardInputGraph.png