查看: 1311|回复: 1

请教关于自定义操作器限制翻转角度的问题?

[复制链接]

该用户从未签到

发表于 2014-8-7 17:27:15 | 显示全部楼层 |阅读模式
本帖最后由 zmajun 于 2014-8-7 17:27 编辑

本人目前在做一个使用OSG的项目,需要使用自定义的操作器,准备基于源码中的的TerrainManipulator做一定修改,查看源码后,操作器之间继承关系为TerrainManipulator->OrbitManipulator->StandardManipulator->CameraManipulator。现在遇到的问题是要控制操作器上下翻转的角度,大致在0~30度
之间,现在的TerrainManipulator操作器可以控制翻转角度在-90~90度之间。涉及到的代码主要如下:
  1. /** Update rotation by yaw and pitch.
  2. *
  3. *  localUp parameter defines either camera's "UP" vector
  4. *  that will be preserved during rotation, or it can be zero (0,0,0) to specify
  5. *  that camera's "UP" vector will be not preserved and free rotation will be made.*/
  6. void StandardManipulator::rotateYawPitch( Quat& rotation, const double yaw, const double pitch,
  7.                                            const Vec3d& localUp )
  8. {
  9.     bool verticalAxisFixed = (localUp != Vec3d( 0.,0.,0. ));

  10.     // fix current rotation
  11.     if( verticalAxisFixed )
  12.         fixVerticalAxis( rotation, localUp, true );

  13.     // rotations
  14.     Quat rotateYaw( -yaw, verticalAxisFixed ? localUp : rotation * Vec3d( 0.,1.,0. ) );
  15.     Quat rotatePitch;
  16.     Quat newRotation;
  17.     Vec3d cameraRight( rotation * Vec3d( 1.,0.,0. ) );

  18.     double my_dy = pitch;
  19.     int i = 0;

  20.     do {

  21.         // rotations
  22.         rotatePitch.makeRotate( my_dy, cameraRight );
  23.         newRotation = rotation * rotateYaw * rotatePitch;

  24.         // update vertical axis
  25.         if( verticalAxisFixed )
  26.             fixVerticalAxis( newRotation, localUp, false );

  27.         // check for viewer's up vector to be more than 90 degrees from "up" axis
  28.         Vec3d newCameraUp = newRotation * Vec3d( 0.,1.,0. );
  29.         if( newCameraUp * localUp >0.)
  30.         {

  31.             // apply new rotation
  32.             rotation = newRotation;
  33.             return;

  34.         }

  35.         my_dy /= 2.;
  36.         if( ++i == 20 )
  37.         {
  38.             rotation = rotation * rotateYaw;
  39.             return;
  40.         }

  41.     } while( true );
  42. }


  43. /** The method corrects the rotation to make impression of fixed up direction.
  44. *  Technically said, it makes the roll component of the rotation equal to zero.
  45. *
  46. *  Up vector is given by CoordinateFrame and it is +z by default.
  47. *  It can be changed by osgGA::CameraManipulator::setCoordinateFrameCallback().
  48. *
  49. *  Eye parameter is user position, rotation is the rotation to be fixed, and
  50. *  disallowFlipOver, when set on true, avoids pitch rotation component to grow
  51. *  over +/- 90 degrees. If this happens and disallowFlipOver is true,
  52. *  manipulator is rotated by 180 degrees. More precisely, roll rotation component is changed by 180 degrees,
  53. *  making pitch once again between -90..+90 degrees limits.
  54. */
  55. void StandardManipulator::fixVerticalAxis( Vec3d& eye, Quat& rotation, bool disallowFlipOver )
  56. {
  57.    CoordinateFrame coordinateFrame = getCoordinateFrame( eye );
  58.    Vec3d localUp = getUpVector( coordinateFrame );

  59.    fixVerticalAxis( rotation, localUp, disallowFlipOver );
  60. }


  61. /** The method corrects the rotation to make impression of fixed up direction.
  62. *  Technically said, it makes the roll component of the rotation equal to zero.
  63. *
  64. *  rotation parameter is the rotation to be fixed.
  65. *  localUp is UP vector and must not be zero length.
  66. *  disallowFlipOver, when set on true, avoids pitch rotation component to grow
  67. *  over +/- 90 degrees. If this happens and disallowFlipOver is true,
  68. *  manipulator is rotated by 180 degrees. More precisely, roll rotation component is changed by 180 degrees,
  69. *  making pitch once again between -90..+90 degrees limits.*/
  70. void StandardManipulator::fixVerticalAxis( Quat& rotation, const Vec3d& localUp, bool disallowFlipOver )
  71. {
  72.     // camera direction vectors
  73.     Vec3d cameraUp = rotation * Vec3d( 0.,1.,0. );
  74.     Vec3d cameraRight = rotation * Vec3d( 1.,0.,0. );
  75.     Vec3d cameraForward = rotation * Vec3d( 0.,0.,-1. );

  76.     // computed directions
  77.     Vec3d newCameraRight1 = cameraForward ^ localUp;
  78.     Vec3d newCameraRight2 = cameraUp ^ localUp;
  79.     Vec3d newCameraRight = (newCameraRight1.length2() > newCameraRight2.length2()) ?
  80.                             newCameraRight1 : newCameraRight2;
  81.     if( newCameraRight * cameraRight < 0. )
  82.         newCameraRight = -newCameraRight;

  83.     // vertical axis correction
  84.     Quat rotationVerticalAxisCorrection;
  85.     rotationVerticalAxisCorrection.makeRotate( cameraRight, newCameraRight );

  86.     // rotate camera
  87.     rotation *= rotationVerticalAxisCorrection;

  88.     if( disallowFlipOver )
  89.     {

  90.         // make viewer's up vector to be always less than 90 degrees from "up" axis
  91.         Vec3d newCameraUp = newCameraRight ^ cameraForward;
  92.         if( newCameraUp * localUp < 0. )
  93.             rotation = Quat( PI, Vec3d( 0.,0.,1. ) ) * rotation;

  94.     }
  95. }
复制代码


上面的代码是在StandardManipulator操作器其中实现,我发现修改代码中if( newCameraUp * localUp > 0. )这句话将0.改为0.87(cos(30)的近似值)后可以将翻转角度限制在-30~30度之间,但是现在不知道如何将其控制在0~30度之间,请大神指点一下。

该用户从未签到

发表于 2014-8-12 17:56:29 | 显示全部楼层
你可以来个&来判断
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表