2012-03-04 2 views
0

Я построил 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.

спасибо заранее,

Луис

ответ

1

Это ужасный подход. Вы начинаете с матрицы, превращая ее в кватернион, превращая это в углы Эйлера, а затем превращая их в матрицу.

Вместо getOrientation() позвоните по номеру getCenterOfMassTransform().getBasis(), чтобы получить btMatrix3x3. Упакуйте его в верхний левый угол CATransform3D и заполните остальные нулями (кроме m44, который должен быть 1).

+0

Уфф, спасибо вам большое за разъяснение. Я подробно изучу все это и, очевидно, попробую вашу рекомендацию. Я вернусь и опубликую результаты. Еще раз спасибо, Luis –

+0

Привет @Ahruman, я создаю ответ, комментируя ваш, мне нужно опубликовать новый код. –

Смежные вопросы