2012-03-04 54 views
0

我已经使用CATransformLayer构建了一个6面3D骰子,将它用作容器图层,将6个变形图层转换为可以在空间中旋转的3D对象。 I got the idea from here。它运行良好,我可以旋转“骰子”在顶层上调用CATransform3DMakeRotation,骰子旋转并运行良好。从子弹物理四元数转换为与CATransform3DMakeRotation一起使用的角度

下一步是在程序中插入“子弹物理”。我已经工作了,但是我被卡住了,因为我不知道如何从其物理世界中的“子弹物理学”四元数'方向'转换成旋转角度,我可以传递给我的容器CALayer方法。

下面是我在做什么:

1)调用“Bullet物理”获得骰子的方向:

// QUATERNION: Get the orientation 
btQuaternion quatO = TObject->getOrientation(); 

2)转换的四元数欧拉(大量的时间谷歌搜索答案发现一个方法复制下面这样做) qW = quatO.getW(); qX = quatO.getX(); qY = quatO.getY(); qZ = quatO.getZ(); [self quaternionToEuler];

3)应用新的欧拉角到我的CALayer(SCTRL)

[sCtrl rotaX:eX rotaY:eY rotaZ:eZ]; 

注1:这是方法“M采用旋转我的CALayer

- (CATransform3D) rotaX:(CGFloat) anguloX rotaY:(CGFloat) anguloY rotaZ:(CGFloat) anguloZ 
{   
    CATransform3D rX; 
    CATransform3D rY; 
    CATransform3D rZ; 
    CATransform3D ret; 

    // Apply all the rotations in order (x, y, z) 
    rX = CATransform3DMakeRotation([self gradosARadianes:(anguloX)], 1.0f, 0.0f, 0.0f); 
    ret = CATransform3DConcat(baseTransform, rX); 
    rY = CATransform3DMakeRotation([self gradosARadianes:(anguloY)], 0.0f, 1.0f, 0.0f); 
    ret = CATransform3DConcat(rX, rY); 
    rZ = CATransform3DMakeRotation([self gradosARadianes:(anguloZ)], 0.0f, 0.0f, 1.0f); 
    ret = CATransform3DConcat(rY, rZ); 


    // Store finished result for next time start from there... 
    baseTransform = ret; 

    return ret; 
} 

注2:这是我的方法我发现将四元数转换为欧拉。

-(void) quaternionToEuler 
{ 
    float matrix[3][3]; 
    float cx,sx; 
    float cy,sy,yr; 
    float cz,sz; 
    matrix[0][0] = 1.0f - 2.0f * (qY * qY + qZ * qZ); 
    matrix[0][1] = (2.0f * qX * qY) - (2.0f * qW * qZ); 
    matrix[1][0] = 2.0f * (qX * qY + qW * qZ); 
    matrix[1][1] = 1.0f - (2.0f * qX * qX) - (2.0f * qZ * qZ); 
    matrix[2][0] = 2.0f * (qX * qZ - qW * qY); 
    matrix[2][1] = 2.0f * (qY * qZ + qW * qX); 
    matrix[2][2] = 1.0f - 2.0f * (qX * qX - qY * qY); 


    sy = -matrix[2][0]; 
    cy = sqrt(1 - (sy * sy)); 
    yr = (float)atan2(sy,cy); 
    eY = (yr * 180.0f)/(float)M_PI; 

    if (sy != 1.0f && sy != -1.0f) 
    { 
     cx = matrix[2][2]/cy; 
     sx = matrix[2][1]/cy; 
     eX = ((float)atan2(sx,cx) * 180.0f)/(float)M_PI; // RAD TO DEG 

     cz = matrix[0][0]/cy; 
     sz = matrix[1][0]/cy; 
     eZ = ((float)atan2(sz,cz) * 180.0f)/(float)M_PI; // RAD TO DEG 
    } 
    else 
    { 
     cx = matrix[1][1]; 
     sx = -matrix[1][2]; 
     eX = ((float)atan2(sx,cx) * 180.0f)/(float)M_PI; // RAD TO DEG 

     cz = 1.0f; 
     sz = 0.0f; 
     eZ = ((float)atan2(sz,cz) * 180.0f)/(float)M_PI; // RAD TO DEG 
    }  
} 

总之,我的目标是:在我的程序中使用CALayer(不是OpenGL)表示一个“子弹物理”BOX(骰子)。为了让我使用CATransformLayer作为6个转换图层到3D对象的容器。

- 现在我得到的结果并不好,图形骰子旋转,但显然不正确......所以我做的东西完全错在这里...

的问题是:考虑到我可以在子弹物理世界中获得BOX的“方向或旋转”,我可以如何将返回的四元数转换为CATransform3DMakeRotation可用的某些(角度)。

非常感谢提前,

路易斯

回答

1

这是一个可怕的做法。你从一个矩阵开始,把它变成一个四元数,把它变成欧拉角,然后把它们变成一个矩阵。

而不是getOrientation(),请致电getCenterOfMassTransform().getBasis()得到btMatrix3x3。将其装入CATransform3D的左上角,并用零填充其余部分(m44,应该是1)。

+0

你好,非常感谢你的澄清。我会深入研究这一切,明显地尝试你的建议。我会返回并发布结果。再次感谢,Luis – 2012-03-06 06:35:35

+0

嗨@Ahruman,我正在创建一个评论你的答案,我需要发布新代码。 – 2012-03-10 07:47:57