2017-11-06 1 views
0

Ziel: Erstellen Sie eine dritte Person-Ansicht mit OpenSceneGraph (OSG), die das Steuern eines Modells enthält. Das Modell ist mit WASD und der Maus beweglich. Während auf die rechte Maustaste geklickt wird, sollte sich die Kamera UND die Ansicht ändern. Die Richtung des Modells und der Kamera sollte gleich sein, während die rechte Maustaste gedrückt gehalten wird.OpenSceneGraph: 3. Person View

Ich habe schon eine Weile daran gearbeitet und bin in der Lage, die Richtung des Modells und der Kamera gleichzeitig zu ändern, aber ich kann die Kamera nur so einstellen, dass sie von oben nach unten zeigt. Ich möchte, dass die Kamera die Welt auch in anderen Winkeln darstellt (0 - 90 Grad von der Weltebene).

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); 
} 

Ich bin immer noch sehr neu in der Verwendung von OSG. Ich lese die Bücher und arbeite die Tutorials durch. Ich habe auch gesucht, wie ich tun könnte, was ich möchte, aber ich war nicht erfolgreich. Ich wäre für jede Hilfe dankbar. Wenn ich Code-Snippets von anderen Teilen meiner neuen Anwendung bereitstellen kann, lassen Sie mich bitte wissen, was Sie sehen möchten.

Antwort

0

Ich bekam das gewünschte Ergebnis mit einer relativ einfachen Implementierung des NodeTrackManipulators. Ich habe gerade etwas über die Mausbearbeitung geschrieben und es passt zu meinen Bedürfnissen.

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; 
} 
Verwandte Themen