$search
00001 /* 00002 * Copyright (c) 2008, Willow Garage, Inc. 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions are met: 00007 * 00008 * * Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * * Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * * Neither the name of the Willow Garage, Inc. nor the names of its 00014 * contributors may be used to endorse or promote products derived from 00015 * this software without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00018 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 00021 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00022 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00023 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00024 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00025 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00026 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00027 * POSSIBILITY OF SUCH DAMAGE. 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 } // namespace ogre_tools