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 _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org