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_camera.h"
00031
00032 #include <OGRE/OgreCamera.h>
00033 #include <OGRE/OgreSceneManager.h>
00034 #include <OGRE/OgreSceneNode.h>
00035 #include <OGRE/OgreVector3.h>
00036 #include <OGRE/OgreQuaternion.h>
00037
00038 #include <stdint.h>
00039 #include <sstream>
00040
00041 namespace ogre_tools
00042 {
00043
00044 static const float PITCH_LIMIT_LOW = -Ogre::Math::HALF_PI + 0.001;
00045 static const float PITCH_LIMIT_HIGH = Ogre::Math::HALF_PI - 0.001;
00046
00047 FPSCamera::FPSCamera( Ogre::SceneManager* scene_manager )
00048 : CameraBase( scene_manager )
00049 , pitch_(0.0f)
00050 , yaw_(0.0f)
00051 {
00052 }
00053
00054 FPSCamera::~FPSCamera()
00055 {
00056 }
00057
00058 void FPSCamera::relativeNodeChanged()
00059 {
00060 if ( relative_node_ )
00061 {
00062 relative_node_->attachObject( camera_ );
00063 }
00064 }
00065
00066 void FPSCamera::update()
00067 {
00068 Ogre::Matrix3 pitch, yaw;
00069
00070 yaw.FromAxisAngle( Ogre::Vector3::UNIT_Y, Ogre::Radian( yaw_ ) );
00071 pitch.FromAxisAngle( Ogre::Vector3::UNIT_X, Ogre::Radian( pitch_ ) );
00072
00073 camera_->setOrientation( yaw * pitch );
00074 }
00075
00076 void FPSCamera::normalizePitch()
00077 {
00078 if ( pitch_ < PITCH_LIMIT_LOW )
00079 {
00080 pitch_ = PITCH_LIMIT_LOW;
00081 }
00082 else if ( pitch_ > PITCH_LIMIT_HIGH )
00083 {
00084 pitch_ = PITCH_LIMIT_HIGH;
00085 }
00086 }
00087
00088 void FPSCamera::normalizeYaw()
00089 {
00090 yaw_ = fmod( yaw_, Ogre::Math::TWO_PI );
00091
00092 if ( yaw_ < 0.0f )
00093 {
00094 yaw_ = Ogre::Math::TWO_PI + yaw_;
00095 }
00096 }
00097
00098 void FPSCamera::yaw( float angle )
00099 {
00100 yaw_ += angle;
00101
00102 normalizeYaw();
00103
00104 update();
00105 }
00106
00107 void FPSCamera::pitch( float angle )
00108 {
00109 pitch_ += angle;
00110
00111 normalizePitch();
00112
00113 update();
00114 }
00115
00116 void FPSCamera::roll( float angle )
00117 {
00118 }
00119
00120 void FPSCamera::setFrom( CameraBase* camera )
00121 {
00122 CameraBase::setPosition( camera->getPosition() );
00123 CameraBase::setOrientation( camera->getOrientation() );
00124 }
00125
00126 void FPSCamera::setOrientation( float x, float y, float z, float w )
00127 {
00128 Ogre::Quaternion quat( w, x, y, z );
00129 yaw_ = quat.getYaw( false ).valueRadians();
00130 pitch_ = quat.getPitch( false ).valueRadians();
00131
00132 Ogre::Vector3 direction = quat * Ogre::Vector3::NEGATIVE_UNIT_Z;
00133 if ( direction.dotProduct( Ogre::Vector3::NEGATIVE_UNIT_Z ) < 0 )
00134 {
00135 if ( pitch_ > Ogre::Math::HALF_PI )
00136 {
00137 pitch_ = -Ogre::Math::HALF_PI + (pitch_ - Ogre::Math::HALF_PI);
00138 }
00139 else if ( pitch_ < -Ogre::Math::HALF_PI )
00140 {
00141 pitch_ = Ogre::Math::HALF_PI - (-pitch_ - Ogre::Math::HALF_PI);
00142 }
00143
00144 yaw_ = -yaw_;
00145
00146 if ( direction.dotProduct( Ogre::Vector3::UNIT_X ) < 0 )
00147 {
00148 yaw_ -= Ogre::Math::PI;
00149 }
00150 else
00151 {
00152 yaw_ += Ogre::Math::PI;
00153 }
00154 }
00155
00156 normalizePitch();
00157 normalizeYaw();
00158
00159 update();
00160 }
00161
00162 Ogre::Quaternion FPSCamera::getOrientation()
00163 {
00164 return camera_->getOrientation();
00165 }
00166
00167 void FPSCamera::move( float x, float y, float z )
00168 {
00169 Ogre::Vector3 translate( x, y, z );
00170
00171 camera_->setPosition( camera_->getPosition() + getOrientation() * translate );
00172 }
00173
00174 void FPSCamera::setPosition( float x, float y, float z )
00175 {
00176 camera_->setPosition( x, y, z );
00177 }
00178
00179 Ogre::Vector3 FPSCamera::getPosition()
00180 {
00181 return camera_->getPosition();
00182 }
00183
00184 void FPSCamera::lookAt( const Ogre::Vector3& point )
00185 {
00186 camera_->lookAt( point );
00187
00188 CameraBase::setOrientation( camera_->getOrientation() );
00189
00190 update();
00191 }
00192
00193 void FPSCamera::mouseLeftDrag( int diff_x, int diff_y, bool ctrl, bool alt, bool shift )
00194 {
00195 yaw( -diff_x*0.005 );
00196 pitch( -diff_y*0.005 );
00197 }
00198
00199 void FPSCamera::mouseMiddleDrag( int diff_x, int diff_y, bool ctrl, bool alt, bool shift )
00200 {
00201 move( diff_x*0.01, -diff_y*0.01, 0.0f );
00202 }
00203
00204 void FPSCamera::mouseRightDrag( int diff_x, int diff_y, bool ctrl, bool alt, bool shift )
00205 {
00206 move( 0.0f, 0.0f, diff_y*0.1 );
00207 }
00208
00209 void FPSCamera::scrollWheel( int diff, bool ctrl, bool alt, bool shift )
00210 {
00211 move( 0.0f, 0.0f, -diff * 0.01 );
00212 }
00213
00214 void FPSCamera::fromString(const std::string& str)
00215 {
00216 std::istringstream iss(str);
00217
00218 iss >> pitch_;
00219 iss.ignore();
00220 iss >> yaw_;
00221 iss.ignore();
00222
00223 Ogre::Vector3 vec;
00224 iss >> vec.x;
00225 iss.ignore();
00226 iss >> vec.y;
00227 iss.ignore();
00228 iss >> vec.z;
00229 iss.ignore();
00230 camera_->setPosition(vec);
00231
00232 update();
00233 }
00234
00235 std::string FPSCamera::toString()
00236 {
00237 std::ostringstream oss;
00238 oss << pitch_ << " " << yaw_ << " " << camera_->getPosition().x << " " << camera_->getPosition().y << " " << camera_->getPosition().z;
00239
00240 return oss.str();
00241 }
00242
00243 }