[osg-users] First Person Camera disable inertial rotation

Anatoly Dovzhik dovzhik.anatoly at gmail.com
Thu Mar 28 06:01:42 PDT 2019


Windows 10 x64

Hi, i'm trying to make a FPS camera. I have found some examples from other sources and now i have camera, that can move by WASD and have its own default looking system. I press right mouse button and rotate camera. But i still have inertial rotating when i release the mouse button. How to disable this feature? 

tell me if you need more information.
Here is my FPS controller .cpp file:



Code:
#include "FirstPersonController.h"

bool FirstPersonController::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{

    // Still use first person manipulator for camera movements (Inherited class function)
    FirstPersonManipulator::handle(ea, aa);

    if (!viewer_)
    {
        return false;
    }

    // Set the viewer's "eye" position, which is located at the center of the camera.
    osg::Vec3d eyePos;
    osg::Matrix matrix = viewer_->getCameraManipulator()->getMatrix();

    eyePos = matrix.getTrans();

    osg::Quat camRotation = matrix.getRotate();

    switch(ea.getEventType()) {
    case(osgGA::GUIEventAdapter::KEYDOWN):
    {
        // Movement of the camera correlates with W, A, S, D
        switch(ea.getKey())
        {
        case 'w':
            isWPressed = true;
            break;
        case 'a':
            isAPressed = true;
            break;
        case 's':
            isSPressed = true;
            break;
        case 'd':
            isDPressed = true;
            break;
        default:
            break;
        }

        break;
    }

    case(osgGA::GUIEventAdapter::KEYUP):
    {
        switch(ea.getKey())
        {
        case 'w':
            isWPressed = false;
            tempMov_.set(0, 0, 0);
            break;
        case 'a':
            isAPressed = false;
            tempMov_.set(0, 0, 0);
            break;
        case 's':
            isSPressed = false;
            tempMov_.set(0, 0, 0);
            break;
        case 'd':
            isDPressed = false;
            tempMov_.set(0, 0, 0);
            break;
        default:
            break;
        }
        break;
    }

    }

    doTranslate();
    eyePos += camRotation * tempMov_;
    matrix.setTrans(eyePos);

    // Check [mainTimer.time % (time divisor) == 0]
    if (mainTimer_.time_s() >= maxTick_)
    {
        viewer_->getCameraManipulator()->setByMatrix(matrix);
        maxTick_ += inputTimeInterval_;
    }


    return false;
}

bool FirstPersonController::performMovement()
{
    // return if less then two events have been added
    if( _ga_t0.get() == NULL || _ga_t1.get() == NULL )
    {
        return false;
    }

    // get delta time, throw warning if error with delta time
    double eventTimeDelta = _ga_t0->getTime() - _ga_t1->getTime();
    if( eventTimeDelta < 0. )
    {
        OSG_WARN << "Manipulator warning: eventTimeDelta = " << eventTimeDelta << std::endl;
        eventTimeDelta = 0.;
    }

    // get deltaX and deltaY
    float dx = _ga_t0->getXnormalized() - _ga_t1->getXnormalized();
    float dy = _ga_t0->getYnormalized() - _ga_t1->getYnormalized();

    // return if there is no movement.
    if( dx == 0.0 && dy == 0.0 )
    {
        return false;
    }

    // call appropriate methods
    unsigned int buttonMask = _ga_t1->getButtonMask();
    if( buttonMask == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
    {

//      return performMovementLeftMouseButton( eventTimeDelta, dx, dy );
        osg::CoordinateFrame coordinateFrame = getCoordinateFrame( _eye );
        osg::Vec3d localUp = getUpVector( coordinateFrame );
        myRotateYawPitch( _rotation, dx, dy, localUp );
//        rotateYawPitch( _rotation, dx, dy, localUp );

        return true;
    }
    else if( buttonMask == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
             buttonMask == (osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON | osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) )
    {
        //return performMovementMiddleMouseButton( eventTimeDelta, dx, dy );
    }
    else if( buttonMask == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
    {
        //return performMovementRightMouseButton( eventTimeDelta, dx, dy );
    }

    return false;
}


void FirstPersonController::doTranslate() {

    if(isWPressed){
        tempMov_.z() = -moveSpeed_;
    }
    if(isAPressed){
        tempMov_.x() = -moveSpeed_;
    }
    if(isSPressed){
        tempMov_.z() = moveSpeed_;
    }
    if(isDPressed){
        tempMov_.x() = moveSpeed_;
    }
}



void FirstPersonController::myRotateYawPitch( osg::Quat& rotation, const double yaw, const double pitch, const osg::Vec3d& localUp )
{
    bool verticalAxisFixed = (localUp != osg::Vec3d( 0.,0.,0. ));

    // fix current rotation
    if( verticalAxisFixed ){
        fixVerticalAxis( rotation, localUp, true );
    }

    // rotations
    osg::Quat rotateYaw( -yaw, verticalAxisFixed ? localUp : rotation * osg::Vec3d( 0.,1.,0. ) );
    osg::Quat rotatePitch;
    osg::Quat newRotation;
    osg::Vec3d cameraRight( rotation * osg::Vec3d( 1.,0.,0. ) );

    double my_dy = pitch;
    int i = 0;

    do {

        // rotations
        rotatePitch.makeRotate( my_dy, cameraRight );
        newRotation = rotation * rotateYaw * rotatePitch;

        my_dy = 0;


        // update vertical axis
        if( verticalAxisFixed ){
            fixVerticalAxis( newRotation, localUp, false );
        }

        // check for viewer's up vector to be more than 90 degrees from "up" axis
        osg::Vec3d newCameraUp = newRotation * osg::Vec3d( 0.,1.,0. );
        if( newCameraUp * localUp > 0. )
        {
            // apply new rotation
            rotation = newRotation;
            return;
        }

        my_dy /= 2.;
        if( ++i == 20 )
        {
            rotation = rotation * rotateYaw;
            return;
        }

    } while( true );
}




With hopes. 
Anatoly[/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75741#75741







More information about the osg-users mailing list