Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "fps_view_controller.h"
00031 #include "rviz/viewport_mouse_event.h"
00032 #include "rviz/visualization_manager.h"
00033
00034 #include <OGRE/OgreCamera.h>
00035 #include <OGRE/OgreSceneManager.h>
00036 #include <OGRE/OgreSceneNode.h>
00037 #include <OGRE/OgreVector3.h>
00038 #include <OGRE/OgreQuaternion.h>
00039 #include <OGRE/OgreViewport.h>
00040
00041 #include <ogre_tools/shape.h>
00042
00043 #include <stdint.h>
00044 #include <sstream>
00045
00046 namespace rviz
00047 {
00048
00049 static const Ogre::Quaternion ROBOT_TO_CAMERA_ROTATION =
00050 Ogre::Quaternion( Ogre::Radian( -Ogre::Math::HALF_PI ), Ogre::Vector3::UNIT_Y ) *
00051 Ogre::Quaternion( Ogre::Radian( -Ogre::Math::HALF_PI ), Ogre::Vector3::UNIT_Z );
00052
00053 static const float PITCH_LIMIT_LOW = -Ogre::Math::HALF_PI + 0.001;
00054 static const float PITCH_LIMIT_HIGH = Ogre::Math::HALF_PI - 0.001;
00055
00056 FPSViewController::FPSViewController(VisualizationManager* manager, const std::string& name, Ogre::SceneNode* target_scene_node)
00057 : ViewController(manager, name, target_scene_node)
00058 , yaw_(0.0f)
00059 , pitch_(0.0f)
00060 {
00061 }
00062
00063 FPSViewController::~FPSViewController()
00064 {
00065 }
00066
00067 void FPSViewController::handleMouseEvent(ViewportMouseEvent& event)
00068 {
00069 bool moved = false;
00070 if( event.type == QEvent::MouseMove )
00071 {
00072 int32_t diff_x = event.x - event.last_x;
00073 int32_t diff_y = event.y - event.last_y;
00074
00075 if( event.left() && !event.shift() )
00076 {
00077 yaw( -diff_x*0.005 );
00078 pitch( diff_y*0.005 );
00079 }
00080 else if( event.middle() || ( event.shift() && event.left() ))
00081 {
00082 move( diff_x*0.01, -diff_y*0.01, 0.0f );
00083 }
00084 else if( event.right() )
00085 {
00086 move( 0.0f, 0.0f, diff_y*0.1 );
00087 }
00088
00089 moved = true;
00090 }
00091
00092 if ( event.wheel_delta != 0 )
00093 {
00094 int diff = event.wheel_delta;
00095 move( 0.0f, 0.0f, -diff * 0.01 );
00096
00097 moved = true;
00098 }
00099
00100 if (moved)
00101 {
00102 manager_->queueRender();
00103 }
00104 }
00105
00106 void FPSViewController::setYawPitchFromCamera()
00107 {
00108 Ogre::Quaternion quat = camera_->getOrientation() * ROBOT_TO_CAMERA_ROTATION.Inverse();
00109 yaw_ = quat.getRoll( false ).valueRadians();
00110 pitch_ = quat.getYaw( false ).valueRadians();
00111
00112 Ogre::Vector3 direction = quat * Ogre::Vector3::NEGATIVE_UNIT_Z;
00113
00114 if ( direction.dotProduct( Ogre::Vector3::NEGATIVE_UNIT_Z ) < 0 )
00115 {
00116 if ( pitch_ > Ogre::Math::HALF_PI )
00117 {
00118 pitch_ -= Ogre::Math::PI;
00119 }
00120 else if ( pitch_ < -Ogre::Math::HALF_PI )
00121 {
00122 pitch_ += Ogre::Math::PI;
00123 }
00124
00125 yaw_ = -yaw_;
00126
00127 if ( direction.dotProduct( Ogre::Vector3::UNIT_X ) < 0 )
00128 {
00129 yaw_ -= Ogre::Math::PI;
00130 }
00131 else
00132 {
00133 yaw_ += Ogre::Math::PI;
00134 }
00135 }
00136
00137 normalizePitch();
00138 normalizeYaw();
00139 }
00140
00141 void FPSViewController::onActivate()
00142 {
00143 if (camera_->getProjectionType() == Ogre::PT_ORTHOGRAPHIC)
00144 {
00145 camera_->setProjectionType(Ogre::PT_PERSPECTIVE);
00146 }
00147 else
00148 {
00149 setYawPitchFromCamera();
00150 }
00151 }
00152
00153 void FPSViewController::onDeactivate()
00154 {
00155 }
00156
00157 void FPSViewController::onUpdate(float dt, float ros_dt)
00158 {
00159 updateCamera();
00160 }
00161
00162 void FPSViewController::lookAt( const Ogre::Vector3& point )
00163 {
00164 camera_->lookAt( point );
00165 setYawPitchFromCamera();
00166 }
00167
00168 void FPSViewController::onTargetFrameChanged(const Ogre::Vector3& old_reference_position, const Ogre::Quaternion& old_reference_orientation)
00169 {
00170 camera_->setPosition( camera_->getPosition() + old_reference_position - reference_position_ );
00171 }
00172
00173 void FPSViewController::normalizePitch()
00174 {
00175 if ( pitch_ < PITCH_LIMIT_LOW )
00176 {
00177 pitch_ = PITCH_LIMIT_LOW;
00178 }
00179 else if ( pitch_ > PITCH_LIMIT_HIGH )
00180 {
00181 pitch_ = PITCH_LIMIT_HIGH;
00182 }
00183 }
00184
00185 void FPSViewController::normalizeYaw()
00186 {
00187 yaw_ = fmod( yaw_, Ogre::Math::TWO_PI );
00188
00189 if ( yaw_ < 0.0f )
00190 {
00191 yaw_ = Ogre::Math::TWO_PI + yaw_;
00192 }
00193 }
00194
00195 void FPSViewController::updateCamera()
00196 {
00197 Ogre::Quaternion pitch, yaw;
00198
00199 yaw.FromAngleAxis( Ogre::Radian( yaw_ ), Ogre::Vector3::UNIT_Z );
00200 pitch.FromAngleAxis( Ogre::Radian( pitch_ ), Ogre::Vector3::UNIT_Y );
00201
00202 camera_->setOrientation( yaw * pitch * ROBOT_TO_CAMERA_ROTATION );
00203 }
00204
00205 void FPSViewController::yaw( float angle )
00206 {
00207 yaw_ += angle;
00208
00209 normalizeYaw();
00210 }
00211
00212 void FPSViewController::pitch( float angle )
00213 {
00214 pitch_ += angle;
00215
00216 normalizePitch();
00217 }
00218
00219 void FPSViewController::move( float x, float y, float z )
00220 {
00221 Ogre::Vector3 translate( x, y, z );
00222 camera_->setPosition( camera_->getPosition() + camera_->getOrientation() * translate );
00223 }
00224
00225 void FPSViewController::fromString(const std::string& str)
00226 {
00227 std::istringstream iss(str);
00228
00229 iss >> pitch_;
00230 iss.ignore();
00231 iss >> yaw_;
00232 iss.ignore();
00233
00234 Ogre::Vector3 vec;
00235 iss >> vec.x;
00236 iss.ignore();
00237 iss >> vec.y;
00238 iss.ignore();
00239 iss >> vec.z;
00240 iss.ignore();
00241 camera_->setPosition(vec);
00242 }
00243
00244 std::string FPSViewController::toString()
00245 {
00246 std::ostringstream oss;
00247 oss << pitch_ << " " << yaw_ << " " << camera_->getPosition().x << " " << camera_->getPosition().y << " " << camera_->getPosition().z;
00248
00249 return oss.str();
00250 }
00251
00252
00253 }