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 float PITCH_LIMIT_LOW = -Ogre::Math::HALF_PI + 0.001;
00050 static const float PITCH_LIMIT_HIGH = Ogre::Math::HALF_PI - 0.001;
00051
00052 FPSViewController::FPSViewController(VisualizationManager* manager, const std::string& name)
00053 : ViewController(manager, name)
00054 , yaw_(0.0f)
00055 , pitch_(0.0f)
00056 {
00057 }
00058
00059 FPSViewController::~FPSViewController()
00060 {
00061 }
00062
00063 void FPSViewController::handleMouseEvent(ViewportMouseEvent& event)
00064 {
00065 bool moved = false;
00066 if ( event.event.Dragging() )
00067 {
00068 int32_t diff_x = event.event.GetX() - event.last_x;
00069 int32_t diff_y = event.event.GetY() - event.last_y;
00070
00071 if ( event.event.LeftIsDown() )
00072 {
00073 yaw( -diff_x*0.005 );
00074 pitch( -diff_y*0.005 );
00075 }
00076 else if ( event.event.MiddleIsDown() )
00077 {
00078 move( diff_x*0.01, -diff_y*0.01, 0.0f );
00079 }
00080 else if ( event.event.RightIsDown() )
00081 {
00082 move( 0.0f, 0.0f, diff_y*0.1 );
00083 }
00084
00085 moved = true;
00086 }
00087
00088 if ( event.event.GetWheelRotation() != 0 )
00089 {
00090 int diff = event.event.GetWheelRotation();
00091 move( 0.0f, 0.0f, -diff * 0.01 );
00092
00093 moved = true;
00094 }
00095
00096 if (moved)
00097 {
00098 manager_->queueRender();
00099 }
00100 }
00101
00102 void FPSViewController::setOrientation(const Ogre::Quaternion& orientation)
00103 {
00104 Ogre::Quaternion quat = orientation;
00105 yaw_ = quat.getYaw( false ).valueRadians();
00106 pitch_ = quat.getPitch( false ).valueRadians();
00107
00108 Ogre::Vector3 direction = quat * Ogre::Vector3::NEGATIVE_UNIT_Z;
00109 if ( direction.dotProduct( Ogre::Vector3::NEGATIVE_UNIT_Z ) < 0 )
00110 {
00111 if ( pitch_ > Ogre::Math::HALF_PI )
00112 {
00113 pitch_ = -Ogre::Math::HALF_PI + (pitch_ - Ogre::Math::HALF_PI);
00114 }
00115 else if ( pitch_ < -Ogre::Math::HALF_PI )
00116 {
00117 pitch_ = Ogre::Math::HALF_PI - (-pitch_ - Ogre::Math::HALF_PI);
00118 }
00119
00120 yaw_ = -yaw_;
00121
00122 if ( direction.dotProduct( Ogre::Vector3::UNIT_X ) < 0 )
00123 {
00124 yaw_ -= Ogre::Math::PI;
00125 }
00126 else
00127 {
00128 yaw_ += Ogre::Math::PI;
00129 }
00130 }
00131
00132 normalizePitch();
00133 normalizeYaw();
00134 }
00135
00136 void FPSViewController::onActivate()
00137 {
00138 if (camera_->getProjectionType() == Ogre::PT_ORTHOGRAPHIC)
00139 {
00140 camera_->setProjectionType(Ogre::PT_PERSPECTIVE);
00141 }
00142 else
00143 {
00144 setOrientation(camera_->getOrientation());
00145 }
00146
00147 reference_node_->attachObject(camera_);
00148 }
00149
00150 void FPSViewController::onDeactivate()
00151 {
00152 reference_node_->detachObject(camera_);
00153 }
00154
00155 void FPSViewController::onUpdate(float dt, float ros_dt)
00156 {
00157 updateCamera();
00158 }
00159
00160 void FPSViewController::lookAt( const Ogre::Vector3& point )
00161 {
00162 camera_->lookAt( point );
00163 setOrientation( camera_->getOrientation() );
00164 }
00165
00166 void FPSViewController::onReferenceFrameChanged(const Ogre::Vector3& old_reference_position, const Ogre::Quaternion& old_reference_orientation)
00167 {
00168 lookAt(reference_node_->getPosition());
00169 }
00170
00171 void FPSViewController::normalizePitch()
00172 {
00173 if ( pitch_ < PITCH_LIMIT_LOW )
00174 {
00175 pitch_ = PITCH_LIMIT_LOW;
00176 }
00177 else if ( pitch_ > PITCH_LIMIT_HIGH )
00178 {
00179 pitch_ = PITCH_LIMIT_HIGH;
00180 }
00181 }
00182
00183 void FPSViewController::normalizeYaw()
00184 {
00185 yaw_ = fmod( yaw_, Ogre::Math::TWO_PI );
00186
00187 if ( yaw_ < 0.0f )
00188 {
00189 yaw_ = Ogre::Math::TWO_PI + yaw_;
00190 }
00191 }
00192
00193 void FPSViewController::updateCamera()
00194 {
00195 Ogre::Matrix3 pitch, yaw;
00196
00197 yaw.FromAxisAngle( Ogre::Vector3::UNIT_Y, Ogre::Radian( yaw_ ) );
00198 pitch.FromAxisAngle( Ogre::Vector3::UNIT_X, Ogre::Radian( pitch_ ) );
00199
00200 camera_->setOrientation( yaw * pitch );
00201 }
00202
00203 void FPSViewController::yaw( float angle )
00204 {
00205 yaw_ += angle;
00206
00207 normalizeYaw();
00208 }
00209
00210 void FPSViewController::pitch( float angle )
00211 {
00212 pitch_ += angle;
00213
00214 normalizePitch();
00215 }
00216
00217 void FPSViewController::move( float x, float y, float z )
00218 {
00219 Ogre::Vector3 translate( x, y, z );
00220 camera_->setPosition( camera_->getPosition() + camera_->getOrientation() * translate );
00221 }
00222
00223 void FPSViewController::fromString(const std::string& str)
00224 {
00225 std::istringstream iss(str);
00226
00227 iss >> pitch_;
00228 iss.ignore();
00229 iss >> yaw_;
00230 iss.ignore();
00231
00232 Ogre::Vector3 vec;
00233 iss >> vec.x;
00234 iss.ignore();
00235 iss >> vec.y;
00236 iss.ignore();
00237 iss >> vec.z;
00238 iss.ignore();
00239 camera_->setPosition(vec);
00240 }
00241
00242 std::string FPSViewController::toString()
00243 {
00244 std::ostringstream oss;
00245 oss << pitch_ << " " << yaw_ << " " << camera_->getPosition().x << " " << camera_->getPosition().y << " " << camera_->getPosition().z;
00246
00247 return oss.str();
00248 }
00249
00250
00251 }