[osg-users] First Person Camera disable inertial rotation
Anatoly Dovzhik
dovzhik.anatoly at gmail.com
Thu Mar 28 06:01:42 PDT 2019
Windows 10 x64
Hi, i'm trying to make a FPS camera. I have found some examples from other sources and now i have camera, that can move by WASD and have its own default looking system. I press right mouse button and rotate camera. But i still have inertial rotating when i release the mouse button. How to disable this feature?
tell me if you need more information.
Here is my FPS controller .cpp file:
Code:
#include "FirstPersonController.h"
bool FirstPersonController::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{
// Still use first person manipulator for camera movements (Inherited class function)
FirstPersonManipulator::handle(ea, aa);
if (!viewer_)
{
return false;
}
// Set the viewer's "eye" position, which is located at the center of the camera.
osg::Vec3d eyePos;
osg::Matrix matrix = viewer_->getCameraManipulator()->getMatrix();
eyePos = matrix.getTrans();
osg::Quat camRotation = matrix.getRotate();
switch(ea.getEventType()) {
case(osgGA::GUIEventAdapter::KEYDOWN):
{
// Movement of the camera correlates with W, A, S, D
switch(ea.getKey())
{
case 'w':
isWPressed = true;
break;
case 'a':
isAPressed = true;
break;
case 's':
isSPressed = true;
break;
case 'd':
isDPressed = true;
break;
default:
break;
}
break;
}
case(osgGA::GUIEventAdapter::KEYUP):
{
switch(ea.getKey())
{
case 'w':
isWPressed = false;
tempMov_.set(0, 0, 0);
break;
case 'a':
isAPressed = false;
tempMov_.set(0, 0, 0);
break;
case 's':
isSPressed = false;
tempMov_.set(0, 0, 0);
break;
case 'd':
isDPressed = false;
tempMov_.set(0, 0, 0);
break;
default:
break;
}
break;
}
}
doTranslate();
eyePos += camRotation * tempMov_;
matrix.setTrans(eyePos);
// Check [mainTimer.time % (time divisor) == 0]
if (mainTimer_.time_s() >= maxTick_)
{
viewer_->getCameraManipulator()->setByMatrix(matrix);
maxTick_ += inputTimeInterval_;
}
return false;
}
bool FirstPersonController::performMovement()
{
// return if less then two events have been added
if( _ga_t0.get() == NULL || _ga_t1.get() == NULL )
{
return false;
}
// get delta time, throw warning if error with delta time
double eventTimeDelta = _ga_t0->getTime() - _ga_t1->getTime();
if( eventTimeDelta < 0. )
{
OSG_WARN << "Manipulator warning: eventTimeDelta = " << eventTimeDelta << std::endl;
eventTimeDelta = 0.;
}
// get deltaX and deltaY
float dx = _ga_t0->getXnormalized() - _ga_t1->getXnormalized();
float dy = _ga_t0->getYnormalized() - _ga_t1->getYnormalized();
// return if there is no movement.
if( dx == 0.0 && dy == 0.0 )
{
return false;
}
// call appropriate methods
unsigned int buttonMask = _ga_t1->getButtonMask();
if( buttonMask == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
{
// return performMovementLeftMouseButton( eventTimeDelta, dx, dy );
osg::CoordinateFrame coordinateFrame = getCoordinateFrame( _eye );
osg::Vec3d localUp = getUpVector( coordinateFrame );
myRotateYawPitch( _rotation, dx, dy, localUp );
// rotateYawPitch( _rotation, dx, dy, localUp );
return true;
}
else if( buttonMask == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON ||
buttonMask == (osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON | osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) )
{
//return performMovementMiddleMouseButton( eventTimeDelta, dx, dy );
}
else if( buttonMask == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON )
{
//return performMovementRightMouseButton( eventTimeDelta, dx, dy );
}
return false;
}
void FirstPersonController::doTranslate() {
if(isWPressed){
tempMov_.z() = -moveSpeed_;
}
if(isAPressed){
tempMov_.x() = -moveSpeed_;
}
if(isSPressed){
tempMov_.z() = moveSpeed_;
}
if(isDPressed){
tempMov_.x() = moveSpeed_;
}
}
void FirstPersonController::myRotateYawPitch( osg::Quat& rotation, const double yaw, const double pitch, const osg::Vec3d& localUp )
{
bool verticalAxisFixed = (localUp != osg::Vec3d( 0.,0.,0. ));
// fix current rotation
if( verticalAxisFixed ){
fixVerticalAxis( rotation, localUp, true );
}
// rotations
osg::Quat rotateYaw( -yaw, verticalAxisFixed ? localUp : rotation * osg::Vec3d( 0.,1.,0. ) );
osg::Quat rotatePitch;
osg::Quat newRotation;
osg::Vec3d cameraRight( rotation * osg::Vec3d( 1.,0.,0. ) );
double my_dy = pitch;
int i = 0;
do {
// rotations
rotatePitch.makeRotate( my_dy, cameraRight );
newRotation = rotation * rotateYaw * rotatePitch;
my_dy = 0;
// update vertical axis
if( verticalAxisFixed ){
fixVerticalAxis( newRotation, localUp, false );
}
// check for viewer's up vector to be more than 90 degrees from "up" axis
osg::Vec3d newCameraUp = newRotation * osg::Vec3d( 0.,1.,0. );
if( newCameraUp * localUp > 0. )
{
// apply new rotation
rotation = newRotation;
return;
}
my_dy /= 2.;
if( ++i == 20 )
{
rotation = rotation * rotateYaw;
return;
}
} while( true );
}
With hopes.
Anatoly[/code]
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=75741#75741
More information about the osg-users
mailing list