[osg-users] [customizing manipulator] problem with delta mouse pos
Julien Valentin
julienvalentin51 at gmail.com
Tue Apr 24 17:52:54 PDT 2018
Here's the code,
Code:
class myFirstPersonManipulator : public osgGA::FirstPersonManipulator{
public:
osg::ref_ptr<osgGA::GUIEventAdapter> myMouseEvent;
myFirstPersonManipulator():osgGA::FirstPersonManipulator(){
setAllowThrow(false);
setVerticalAxisFixed(true);
setAcceleration(0);
this->setHomePosition(osg::Vec3(0,-0.2,0.5),osg::Vec3(0.0,0,0.0),osg::Vec3(1,0,0));
flushMouseEventStack();
myMouseEvent=new osgGA::GUIEventAdapter();
myMouseEvent->setEventType(osgGA::GUIEventAdapter::MOVE);
myMouseEvent->setButton(osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON);
myMouseEvent->setTime(00);
_ga_t1=myMouseEvent.get();
//addMouseEvent( *new osgGA::GUIEventAdapter);
//this->setPosition(osg::Vec3(0,0,0));
}
protected:
//bool performMovementLeftMouseButton( const double /*eventTimeDelta*/, const double dx, const double dy )
//{ // world up vector
// osg::CoordinateFrame coordinateFrame = getCoordinateFrame( _eye ); osg::Vec3d localUp = getUpVector( coordinateFrame );
// rotateYawPitch( _rotation, dx*100, dy*100, localUp );//hack rotation x100
// return true;
//}
virtual bool handle( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us ){
/* switch(ea.getEventType())
{*/
//case(osgGA::GUIEventAdapter::KEYDOWN):
switch( ea.getEventType() )
{
case osgGA::GUIEventAdapter::MOVE:
//mouse event
//move the mouse away from window borders (100,100) may be good enoug
//but viewport center is more accurate
//addMouseEvent( ea );
if(!_ga_t0.valid()) _ga_t0 = &ea;
myMouseEvent->setTime(_ga_t0->getTime());
myMouseEvent->setXmin(_ga_t0->getXmin());
myMouseEvent->setXmax(_ga_t0->getXmax());
myMouseEvent->setYmin(_ga_t0->getYmin());
myMouseEvent->setYmax(_ga_t0->getYmax());
dynamic_cast<osgViewer::View*>(&us)->requestWarpPointer( 0.5*(_ga_t0->getXmax()-_ga_t0->getXmin()),0.5*(_ga_t0->getYmax()-_ga_t0->getYmin()));
// dynamic_cast<osgViewer::GraphicsWindow*>(us.asView()->getCamera()->getGraphicsContext())->requestWarpPointer( 0.5*(_ga_t0->getXmax()-_ga_t0->getXmin()),0.5*(_ga_t0->getYmax()-_ga_t0->getYmin()));
_ga_t1=myMouseEvent;
// _ga_t1 = _ga_t0;
_ga_t0 = &ea;
if( performMovement() )
us.requestRedraw();
//dynamic_cast<osgViewer::GraphicsWindow*>(us.asView()->getCamera()->getGraphicsContext())->requestWarpPointer(100,100);
default:
//check 4 keyboard event
switch(ea.getKey())
{
case osgGA::GUIEventAdapter::KEY_Up :
moveForward(1);
break;
case osgGA::GUIEventAdapter::KEY_Down :
moveForward(-1);
break;
case osgGA::GUIEventAdapter::KEY_Left :
moveRight(-1);
break;
case osgGA::GUIEventAdapter::KEY_Right :
moveRight(1);
break;
default:
break;
}
/* default:
}*/
return true;
//return osgGA::FirstPersonManipulator::handle(ea,us);
}
}
virtual bool handleMousePush( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
{
if( performMovement() )
us.requestRedraw();
// us.requestContinuousUpdate( false );
_thrown = false;
return true;
}
/// Handles GUIEventAdapter::RELEASE event.
virtual bool handleMouseRelease( const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& us )
{
if( ea.getButtonMask() == 0 )
{
double timeSinceLastRecordEvent = _ga_t0.valid() ? (ea.getTime() - _ga_t0->getTime()) : DBL_MAX;
/* if( timeSinceLastRecordEvent > 0.02 )
flushMouseEventStack();*/
if( isMouseMoving() )
{
if( performMovement() && _allowThrow )
{
us.requestRedraw();
us.requestContinuousUpdate( true );
_thrown = true;
}
return true;
}
}
// dynamic_cast<osgViewer::View*>(&us)->requestWarpPointer(0,0);
//flushMouseEventStack();
//addMouseEvent( ea );
if( performMovement() )
us.requestRedraw();
// us.requestContinuousUpdate( false );
_thrown = false;
return true;
}
/// Make movement step of manipulator. Returns true if any movement was made.
bool performMovement()
{
// return if less then two events have been added
if( _ga_t0.get() == NULL || _ga_t1.get() == NULL )
return false;
// get 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_ga_t0
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. && dy == 0. )
return false;
// call appropriate methods
unsigned int buttonMask = _ga_t1->getButtonMask();
unsigned int modKeyMask = _ga_t1->getModKeyMask();
if( buttonMask == osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON )
{
return performMovementLeftMouseButton( eventTimeDelta, dx, dy );
}
else if( ( buttonMask == osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON ) ||
( buttonMask == osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON && modKeyMask & osgGA::GUIEventAdapter::MODKEY_CTRL ) ||
( 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 );
}else{
// world up vector
CoordinateFrame coordinateFrame = getCoordinateFrame( _eye );
Vec3d localUp = Vec3d(0,1,0);//getUpVector( coordinateFrame );
RotateYawPitch( _rotation, dx, dy, localUp );
return true;
}
// return performMovementLeftMouseButton( eventTimeDelta, dx, dy );
return false;
}
static void RotateYawPitch( Quat& rotation, const double yaw, const double pitch,
const Vec3d& localUp )
{
bool verticalAxisFixed = (localUp != Vec3d( 0.,0.,0. ));
// fix current rotation
if( verticalAxisFixed )
fixVerticalAxis( rotation, localUp, true );
// rotations
Quat rotateYaw( -yaw, verticalAxisFixed ? localUp : rotation * Vec3d( 0.,1.,0. ) );
Quat rotatePitch;
Quat newRotation;
Vec3d cameraRight( rotation * Vec3d( 1.,0.,0. ) );
double my_dy = pitch;
int i = 0;
do {
// rotations
rotatePitch.makeRotate( my_dy, cameraRight );
newRotation = rotation * rotateYaw * rotatePitch;
// update vertical axis
if( verticalAxisFixed )
fixVerticalAxis( newRotation, localUp, false );
// check for viewer's up vector to be more than 90 degrees from "up" axis
Vec3d newCameraUp = newRotation * 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 );
}
};
Hope it helps to diagnose the problem....
Thanks,
mp3butcher wrote:
> ok, i misinterpreted eventqueue::mouseWarped which in fact is not an event..
> so no there's nothin strange in how it's manage and my problem comes from somewhere elsewhere..
>
> So I'll try to be concise
> -I derive my manip from FirstPersonManipulator
> -i override handle and performMovement:
> in handle I store only last evt time and warpmousepointer to window center
> in performaction i remove from dx dy substraction of lastevt.getXnormalized() (as it's in theory 0,0 after warprequest) and pass dx,dy to FirstPersonManipulator::performMovementLeftMouseButton
>
> It seams to work for small mouse moves but when I make larger mouse movement i get lost. It look like the where numerical drift in the transformation from normalized screen to Euler Angle...or something..
>
> I can post the code but if someone already experience the problem it would be welcome
> Edit:
> Is the loop in StandardManipulator::rotateYawPitch refer to some exp mapping.I really dont understand
> Cheers
>
>
> robertosfield wrote:
> > Hi Julian,
> >
> > On 23 April 2018 at 20:13, Julien Valentin <> wrote:
> >
> > > I'm beginning the implementation of my own StandardManipulator
> > > and would like to make a classic fps controller.
> > > So mouse must stay centered all delta mouse pos be captured
> > > However I found out that requestWarpPointer posts a wrapMouse event both in Viewer and GraphicWindows implementations.
> > > it leads to duplication of the event (which is not so bad) but more dramatic, it prevent to recenter mouse without trigger an osgevent.
> > > Is it a desired behavior?
> > >
> >
> > Yes. If the mouse moves you want objects that depend upon mouse
> > position to wake up to the fact that it's moved using an event.
> >
> > I can't work out what the problem you are having.
> >
> > Robert.
> > _______________________________________________
> > osg-users mailing list
> >
> > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
> >
> > ------------------
> > Post generated by Mail2Forum
>
------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=73503#73503
More information about the osg-users
mailing list