Я построил 3D-кубики с 6 гранями, используя CATransformLayer, используя его как контейнерный слой, захватив 6 преобразованных слоев в 3D-объект, который может вращаться в пространстве. I got the idea from here. Он работает хорошо, и я могу вращать «кости», вызывающие CATransform3DMakeRotation на верхнем слое, кости вращаются и работают хорошо.Преобразование из кватерниона физики пули в угол для использования с CATransform3DMakeRotation
Следующий шаг состоял в том, чтобы ввести «пулевую физику» в программу. Я работаю, но я застрял, потому что я не знаю, как преобразовать из «кватернионной физики» пулевую физику «кости» в физическом мире в углы поворота, которые я могу передать моему методу CALayer контейнера.
Вот что я делаю:
1) Призыв к «физике пули», чтобы получить ориентацию кости:
// QUATERNION: Get the orientation
btQuaternion quatO = TObject->getOrientation();
2) Преобразовать кватернион Эйлер (много времени googling для ответа нашел способ, скопированный ниже, чтобы сделать это) 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: это метод использует, чтобы повернуть мою 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
}
}
В итоге, моя цель: представлять "Bullet Physics" BOX (кости) в моей программе, используя (не OpenGL) CALayer в. Для этого я использую CATransformLayer в качестве контейнера из 6 преобразованных слоев в 3D-объект.
- Результаты я получаю сейчас не хорошо, графические кости вращается, но, очевидно, неправильно ... так что я делаю что-то совершенно неправильно здесь ...
вопрос: Учитывая, что I может получить «ориентацию или поворот» BOX в мире физики пули, как я могу преобразовать возвращаемый кватернион в нечто (углы), используемые с CATransform3DMakeRotation.
спасибо заранее,
Луис
Уфф, спасибо вам большое за разъяснение. Я подробно изучу все это и, очевидно, попробую вашу рекомендацию. Я вернусь и опубликую результаты. Еще раз спасибо, Luis –
Привет @Ahruman, я создаю ответ, комментируя ваш, мне нужно опубликовать новый код. –