|
本帖最后由 zmajun 于 2014-8-7 17:27 编辑
本人目前在做一个使用OSG的项目,需要使用自定义的操作器,准备基于源码中的的TerrainManipulator做一定修改,查看源码后,操作器之间继承关系为TerrainManipulator->OrbitManipulator->StandardManipulator->CameraManipulator。现在遇到的问题是要控制操作器上下翻转的角度,大致在0~30度
之间,现在的TerrainManipulator操作器可以控制翻转角度在-90~90度之间。涉及到的代码主要如下:
- /** Update rotation by yaw and pitch.
- *
- * localUp parameter defines either camera's "UP" vector
- * that will be preserved during rotation, or it can be zero (0,0,0) to specify
- * that camera's "UP" vector will be not preserved and free rotation will be made.*/
- void StandardManipulator::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 );
- }
- /** The method corrects the rotation to make impression of fixed up direction.
- * Technically said, it makes the roll component of the rotation equal to zero.
- *
- * Up vector is given by CoordinateFrame and it is +z by default.
- * It can be changed by osgGA::CameraManipulator::setCoordinateFrameCallback().
- *
- * Eye parameter is user position, rotation is the rotation to be fixed, and
- * disallowFlipOver, when set on true, avoids pitch rotation component to grow
- * over +/- 90 degrees. If this happens and disallowFlipOver is true,
- * manipulator is rotated by 180 degrees. More precisely, roll rotation component is changed by 180 degrees,
- * making pitch once again between -90..+90 degrees limits.
- */
- void StandardManipulator::fixVerticalAxis( Vec3d& eye, Quat& rotation, bool disallowFlipOver )
- {
- CoordinateFrame coordinateFrame = getCoordinateFrame( eye );
- Vec3d localUp = getUpVector( coordinateFrame );
- fixVerticalAxis( rotation, localUp, disallowFlipOver );
- }
- /** The method corrects the rotation to make impression of fixed up direction.
- * Technically said, it makes the roll component of the rotation equal to zero.
- *
- * rotation parameter is the rotation to be fixed.
- * localUp is UP vector and must not be zero length.
- * disallowFlipOver, when set on true, avoids pitch rotation component to grow
- * over +/- 90 degrees. If this happens and disallowFlipOver is true,
- * manipulator is rotated by 180 degrees. More precisely, roll rotation component is changed by 180 degrees,
- * making pitch once again between -90..+90 degrees limits.*/
- void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp, bool disallowFlipOver )
- {
- // camera direction vectors
- Vec3d cameraUp = rotation * Vec3d( 0.,1.,0. );
- Vec3d cameraRight = rotation * Vec3d( 1.,0.,0. );
- Vec3d cameraForward = rotation * Vec3d( 0.,0.,-1. );
- // computed directions
- Vec3d newCameraRight1 = cameraForward ^ localUp;
- Vec3d newCameraRight2 = cameraUp ^ localUp;
- Vec3d newCameraRight = (newCameraRight1.length2() > newCameraRight2.length2()) ?
- newCameraRight1 : newCameraRight2;
- if( newCameraRight * cameraRight < 0. )
- newCameraRight = -newCameraRight;
- // vertical axis correction
- Quat rotationVerticalAxisCorrection;
- rotationVerticalAxisCorrection.makeRotate( cameraRight, newCameraRight );
- // rotate camera
- rotation *= rotationVerticalAxisCorrection;
- if( disallowFlipOver )
- {
- // make viewer's up vector to be always less than 90 degrees from "up" axis
- Vec3d newCameraUp = newCameraRight ^ cameraForward;
- if( newCameraUp * localUp < 0. )
- rotation = Quat( PI, Vec3d( 0.,0.,1. ) ) * rotation;
- }
- }
复制代码
上面的代码是在StandardManipulator操作器其中实现,我发现修改代码中if( newCameraUp * localUp > 0. )这句话将0.改为0.87(cos(30)的近似值)后可以将翻转角度限制在-30~30度之间,但是现在不知道如何将其控制在0~30度之间,请大神指点一下。
|
|