我使用CATransformLayer构建了一个6面3D骰子,将其用作容器层,将6个变换后的图层抓取成可在空间中旋转的3D对象。 I got the idea from here。它工作得很好,我可以在顶层旋转调用CATransform3DMakeRotation的“骰子”,骰子旋转并运行良好。
下一步是将“子弹物理”插入程序中。我已经工作但是因为我不知道如何从物理世界中的骰子的“子弹物理四元数”方向转换为我可以传递给我的容器CALayer方法的旋转角度。 / p>
以下是我正在做的事情:
1)拨打“子弹物理学”以获得骰子的方向:
// QUATERNION: Get the orientation
btQuaternion quatO = TObject->getOrientation();
2)将四元数转换为euler(很多时间谷歌搜索得到的答案找到了下面复制的方法) qW = quatO.getW(); qX = quatO.getX(); qY = quatO.getY(); qZ = quatO.getZ(); [self quaternionToEuler];
3)将新的euler角度应用于我的CALayer(sCtrl)
[sCtrl rotaX:eX rotaY:eY rotaZ:eZ];
注1:这是用来旋转我的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:这是我发现将四元数转换为euler的方法。
-(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的某些(角度)。
提前多多感谢,
路易斯
答案 0 :(得分:1)
这是一种可怕的方法。你从矩阵开始,将其转换为四元数,将其转换为欧拉角,然后将其转换为矩阵。
而不是getOrientation()
,请致电getCenterOfMassTransform().getBasis()
获取btMatrix3x3
。将其打包到CATransform3D
的左上角,然后用零填充其余部分(m44
除外,该值应为1)。