如何从参考零'获得本地轮换?四元数和全局旋转四元数

时间:2014-07-11 13:26:26

标签: opengl math rotation tracking quaternions

我在连接到飞行器(3D跟踪对象)的屏幕上显示字符。我的目标是根据设备输入移动字符。

我注意到设备的“零”(对应于默认位置)与我的角色的未旋转四元数不对应。移动设备时,我的角色围绕其他轴(可能是世界)移动而不是设备。所以我添加了一个同步函数,当它应该处于默认位置时,它会记录我的设备的四元数旋转,但是现在我不知道如何将这个参考四元数与我从设备接收的实际四元数组合,当它移动时按我的意愿旋转我的角色。

以下是我在OpenGL中使用四元数的方法:

glm::quat rotation = QAccumulative.getQuat(); 
glm::mat4 matrix_rotation = glm::mat4_cast(rotation);
object_transform *= matrix_rotation;
Model *= object_transform;
glm::mat4 MVP = Projection * View * Model;  

如果我用这种方法旋转对象,它可以用键盘和鼠标正常工作:

rotate(float angleX,float angleY,float angleZ) {
  Quaternion worldRotationx( 1.0,0,0, angleZ);   
  Quaternion worldRotationy( 0,1.0,0, angleX);      
  Quaternion worldRotationz( 0,0,1.0, angleY);        
  QAccumulative = worldRotationx * worldRotationy * worldRotationz * QAccumulative;
  QAccumulative.normalise();
}

这是主循环,我从跟踪设备计算数据:

void VRPN_CALLBACK handle_tracker(void* userData, const vrpn_TRACKERCB t ) {
  Vrpn_tracker* current = Vrpn_tracker::current_vrpn_device;
  if (current->calibrating == true) {
    current->reference = Quaternion(t.quat[0],t.quat[1],t.quat[2],t.quat[3]);
    current->reference.normalise();
  } else {
    // translation :
    current->newPosition = sf::Vector3f(t.pos[0],t.pos[1],t.pos[2]);
    current->world->current_object->translate(
      current->newPosition.x - current->oldPosition.x,
      current->newPosition.y - current->oldPosition.y,
      current->newPosition.z - current->oldPosition.z);
    current->oldPosition = current->newPosition;

    // rotation:
    current->newQuat = Quaternion(t.quat[0],t.quat[1],t.quat[2],t.quat[3]);
    current->newQuat.normalise();
    current->world->current_object->QAccumulative = 
      (current->reference.getConjugate() * current->newQuat);
    Quaternion result = current->world->current_object->QAccumulative;
    cout << "result? : " << result.x << result.y << result.z << result.w << endl; 
    // prints something like:
    // x : -0.00207066 y : 0.00186546 z : -0.00165524 w : 0.999995 
    // when position of flystick = default position
  }
}

我做的简单测试检查代码:我在没有移动飞行器的情况下启动程序,(ref四元数被捕获)所以在同步之后,角色应该处于默认位置(不移动),因为我没有触摸了飞杆。

我确实尝试将我的引用乘以收到的四元数,但似乎我的角色正在根据局部轴移动。

如果有人可以了解如何从这两个四元数中获得全局轴上的旋转,那就太棒了。

2 个答案:

答案 0 :(得分:1)

你可以对飞杆进行不同的校准,可能与你期望的相符,但是我建议你仔细阅读有关飞杆的文档,你的答案必须在那里。 如果您正在使用ART跟踪,用户手册的第124页将为您提供帮助。

答案 1 :(得分:0)

更改乘法顺序。如果你先旋转,那么比最后一次旋转要好。

您的问题隐藏的问题,我们不知道您的转换符号。

您的旋转可以从世界变为对象框架或从对象变换为世界。根据符号,精确的转换将是不同的。