2012-04-03 10 views
1

Das Problem ist, wenn ich meine Kamera zum Beispiel die z-Achse hinunter und Pitch dies funktioniert gut, aber nachdem ich die Tonhöhe beendet und möchte auf dieser neuen Achse zu gieren beginnt es für einige zu rollen unbekannter Grund = s.Kamera im opengl funktioniert nicht

void FrustumCamera::xAxisRotation(float angle) 
{ 
// angle = angle * (double)degToRad; 
    Vector3<float> x = m_orientation.getXAxis(); 
    Vector3<float> y = m_orientation.getYAxis(); 
    Vector3<float> z = m_orientation.getZAxis(); 

    y.rotateAroundAxis(x,angle); 
    x = m_orientation.getXAxis(); 
    z.rotateAroundAxis(x,angle); 

    m_orientation.setYAxis(y); 
    m_orientation.setZAxis(z); 

} 
void FrustumCamera::yAxisRotation(float angle) 
{ 
// angle = angle * (double)degToRad; 

    Vector3<float> x = m_orientation.getXAxis(); 
    Vector3<float> y = m_orientation.getYAxis(); 
    Vector3<float> z = m_orientation.getZAxis(); 

    x.rotateAroundAxis(y,angle); 
    y = m_orientation.getYAxis(); 
    z.rotateAroundAxis(y,angle); 

    m_orientation.setXAxis(x); 
    m_orientation.setZAxis(z); 
} 
void FrustumCamera::zAxisRotation(float angle) 
{ 
    Vector3<float> x = m_orientation.getXAxis(); 
    Vector3<float> y = m_orientation.getYAxis(); 
    Vector3<float> z = m_orientation.getZAxis(); 

    x.rotateAroundAxis(z,angle); 
    z = m_orientation.getYAxis(); 
    y.rotateAroundAxis(z,angle); 

    m_orientation.setXAxis(x); 
    m_orientation.setYAxis(y); 
} 

template <class Type> 
void Vector3<Type>::rotateAroundAxis(Vector3<Type> axis, const float angle) 
{ 
    float radians = static_cast<Type>(angle * degToRad); 
    Type sinAngle = static_cast<Type>(sin(radians)); 
    Type cosAngle = 0.0; 

    if (angle == 90 || angle == -90) 
     cosAngle = 0.0; 
    else 
     cosAngle = cos(radians); 

    normalise(axis); // normalise the axis 

    Type oneMinusCos = 1 - cosAngle;  // (1 - cos(theta)) 

    // construct the rotation matrix 
    Type tempMatrix[3][3]; 
    tempMatrix[0][0] = (axis.x * axis.x) * oneMinusCos + cosAngle; 
    tempMatrix[0][1] = (axis.x * axis.y) * oneMinusCos + axis.z * sinAngle; 
    tempMatrix[0][2] = (axis.x * axis.z) * oneMinusCos - axis.y * sinAngle; 
    tempMatrix[1][0] = (axis.x * axis.y) * oneMinusCos - axis.z * sinAngle; 
    tempMatrix[1][1] = (axis.y * axis.y) * oneMinusCos + cosAngle; 
    tempMatrix[1][2] = (axis.y * axis.z) * oneMinusCos + axis.x * sinAngle; 
    tempMatrix[2][0] = (axis.x * axis.z) * oneMinusCos + axis.y * sinAngle; 
    tempMatrix[2][1] = (axis.y * axis.z) * oneMinusCos - axis.x * sinAngle; 
    tempMatrix[2][2] = (axis.z * axis.z) * oneMinusCos + cosAngle; 

    Vector3<Type> temp(*this); 
    Vector3<Type> result; 

    result.x = (temp.x * tempMatrix[0][0]) + (temp.y * tempMatrix[1][0]) + (temp.z * tempMatrix[2][0]); 
    result.y = (temp.x * tempMatrix[0][1]) + (temp.y * tempMatrix[1][1]) + (temp.z * tempMatrix[2][1]); 
    result.z = (temp.x * tempMatrix[0][2]) + (temp.y * tempMatrix[1][2]) + (temp.z * tempMatrix[2][2]); 

    *this = result; 
} 

void OpenGLRenderer::startDraw(unsigned long mask) 
{ 
    //sortBuffer();          // sort draw queue 
    clearBuffers(mask);         // clear buffers 
    loadIdentity(); 
    glTranslatef(-1*m_frustumCamera->getViewMatrix().getTranslationAxis().x,-1*m_frustumCamera->getViewMatrix().getTranslationAxis().y,-1*m_frustumCamera->getViewMatrix().getTranslationAxis().z); 
    glMultMatrixf(m_frustumCamera->getViewMatrix().getMatrix()); 
    glTranslatef(m_frustumCamera->getViewMatrix().getTranslationAxis().x,m_frustumCamera->getViewMatrix().getTranslationAxis().y,m_frustumCamera->getViewMatrix().getTranslationAxis().z);// load identity 

    // 

    // push matrix stack 
    matrixStackPush();           
} 

Antwort

3

Sie Gimbal Lock erleben werden könnten; Dies kann passieren, wenn Sie den ganzen Weg nach oben oder unten gehen, so dass Ihr Blickvektor parallel zu Ihrem Aufwärtsvektor wird. In diesem Fall ist ein Gieren dasselbe wie ein Rollen.

Dies kann ein Nachteil der Konstruktion von Rotationen stückweise über Euler-Winkel sein. Vielleicht möchten Sie in Quaternionen schauen. (Beachten Sie, dass Sie nicht mit Euler-Winkeln rotieren können; sie sind nur eine Repräsentation für die Rotation (Sie müssen sie in Matrix oder Quats umwandeln), aber die Art, wie Sie sie angehen, ist eine Art "Euler-Winkel".

Die Stärke der Matrixmultiplikation besteht darin, dass jede Sequenz mehrerer Rotationen als eine einzige Rotationsmatrix dargestellt (und verkettet) werden kann. Was Sie tun müssen, ist etwas wie folgt:

void Transformable::yaw(float angle) 
{ 
    float4x4 rot; // temp rotation matrix 
    float3 translate(&_transform._41); // save our translation 
    float3 up(&_transform._21); // y axis 

    // build the rotation matrix for rotation around y 
    MatrixRotationAxis(&rot, &up, angle); 

    // multiply our transform by the rotation matrix 
    // note that order of multiplication matters and depends on 
    // if your matrices are column-major or row-major 
    MatrixMultiply(&_transform, &_transform, &rot); 

    // write back our original translation 
    memcpy(&_transform._41, &translate, sizeof(float3)); 

    // might want to reorthogonalise every now and then 
    // to make sure basis vectors are orthonormal 
    // or you will probably get matrix creep after a few operations 
} 

anstatt zu versuchen, einen Basisvektor auf einmal zu drehen. In diesem Fall wäre _transform eine 4x4 homogene Matrix, die die Transformationsmatrix darstellt. (Rotation und Übersetzung). Die topleft 3x3-Submatrix ist einfach die Basisvektoren des Orientierungsraums.

+0

Doesnt Matrizen vermeiden Gimbal Lock Tho? Ich bin sehr fokussiert, weil ich meine neuen Matrix-Achsen umdrehen lasse? Kannst du eine bessere Erklärung geben, wie ich es beheben würde? –

+0

'x.rotateAroundAxis (z, Winkel);' ist eine Euler-Winkel-Rotation und keine Rotation über eine Matrix. Sie müssen Ihre Matrix mit einer Rotationsmatrix multiplizieren, um eine kardanische Sperre zu vermeiden. –

+0

Vielen Dank, dies löste das Problem, das ich jetzt hatte, um zu versuchen, dieses andere zu lösen :( –