1

Goal: Create a third person view using OpenSceneGraph (OSG) which includes controlling a model. The model is movable using WASD and the mouse. While the right mouse button is clicked, the camera AND the view should change. The direction of the model and camera should be the same while the right mouse button is held down.

I've been working on this for little while now and I am able to change the direction of the model and the camera at the same time, but I am only able to get the camera to show a top down view. I would like for the camera to also render the world at other angles ( 0 - 90 degrees from the world plane ).

bool EventHandlerMouse::performMovementRightMouseButton( 
    const double eventTimeDelta, 
    const double dx, 
    const double dy
) {

// Read in the mouse movement to determine if the user is turning left 
// or right. Then set the bool attribute of this->_screen_model to true
// for the direction that the user is moving and then sets the other to
// false. The else statement turns them both off.
if      ( dx < -0.01 ) { 
    this->_screen_model->turn_left();
    this->_screen_model->stop_turn_right();
}
else if ( dx >  0.01 ) {
    this->_screen_model->turn_right();
    this->_screen_model->stop_turn_left();
}
else {
    this->_screen_model->stop_turn_right();
    this->_screen_model->stop_turn_left();
}

// Get the model's orientation. Orientation is a float between 0.0 and
// 360.0 representing the models orientation. 0.0 and 360.0 are true 
// north.
float local_o = this->_screen_model->get_orientation();

// Create the OSG variable to hold the camera manipulator's current and 
// future rotation.
osg::Quat rotation, new_rotation;
osg::Vec3d eye;

// Retrieve the camera's current rotation and eye.
this->getTransformation( eye, rotation );

// Retrieve the camera's rotation matrix.
osg::Matrixd rotation_matrix;
rotation.get( rotation_matrix );

new_rotation = rotation_matrix.getRotate();

// I don't really know what makeRotate does. I couldn't find good
// documentation. From what I'm seeing, it takes the current attitude
// ( rotation ) and changes it to what you have specified. I think this 
// is where my problem/solution will be. Here, I set the angle to the
// orientation of the model. I am then setting that angle to the z axis in
// the Vec3d. I think that this is what is giving me the top down view,
// but it does turn with the model. I don't know how I can change this so
// that it gives a view that would be at an over the shoulder type of
// angle similar to a typical 3rd person view.
new_rotation.makeRotate( 
    osg::DegreesToRadians( local_o ), Vec3d( 0.0, 0.0, 1.0 )
    );

// Setting the camera's eye and rotation to the newly calculated
// perspective.
this->setTransformation( eye, new_rotation );
}

I'm still very new to using OSG. I am reading the books and working through the tutorials. I have also been searching for how to do what I would like, but I have not been successful. I would be grateful for any assistance. If I can provide code snippets from any other part of my fledgling application, please let me know what you want to see.

Jay
  • 27
  • 7

1 Answers1

1

I ended up getting the desired result with a fairly simple implementation of the NodeTrackManipulator. I just over wrote some of the mouse handling and it fits my needs.

event_handler_mouse.hpp

#ifndef EVENT_HANDLER_MOUSE_H
#define EVENT_HANDLER_MOUSE_H

#include <osgGA/GUIEventHandler>
#include <osgGA/NodeTrackerManipulator>
#include <osgViewer/View>
#include <iostream>

#include "../headers/client_obj_char.hpp"

using std::cout;
using std::endl;


class EventHandlerMouse : public osgGA::NodeTrackerManipulator {
    public:
        virtual bool performMovementLeftMouseButton(
            const double eventTimeDelta, 
            const double dx, 
            const double dy 
            );

        virtual bool performMovementRightMouseButton(
                const double eventTimeDelta, 
                const double dx, 
                const double dy
            );

        virtual bool performMovementMiddleMouseButton(
                const double eventTimeDelta, 
                const double dx, 
                const double dy 
            );

        EventHandlerMouse( ClientObjChar* sm ) :
            _client_char( sm ),
            _distance( 1.0 )
            {}
protected:
        virtual ~EventHandlerMouse() {}

        osg::Vec3      _center;
        double         _distance;
        ClientObjChar* _client_char;

        osg::observer_ptr<osg::Node> _target;
};


#endif

event_handler_mouse.cpp

#include "../headers/event_handler_mouse.hpp"


bool EventHandlerMouse::performMovementLeftMouseButton( 
        const double eventTimeDelta, 
        const double dx, 
        const double dy
    ) {

    rotateWithFixedVertical( dx, dy );
    return true;
}

bool EventHandlerMouse::performMovementRightMouseButton( 
        const double eventTimeDelta, 
        const double dx, 
        const double dy
    ) {
    if ( true ) {
        if      ( dx < -0.01 ) { 
            this->_client_char->turn_left();
            this->_client_char->stop_turn_right();
        }
        else if ( dx >  0.01 ) {
            this->_client_char->turn_right();
            this->_client_char->stop_turn_left();
        }
        else {
            this->_client_char->stop_turn_right();
            this->_client_char->stop_turn_left();
        }
    }
    return true;
}


bool EventHandlerMouse::performMovementMiddleMouseButton(
        const double eventTimeDelta, 
        const double dx, 
        const double dy 
    ) {
    return false;
}
Jay
  • 27
  • 7