Não é possível limitar o ângulo de inclinação da câmera entre [-90º, 90º] no OpenGL usando vetores!

Estou tendo um grande problema ao limitar o ângulo de inclinação da câmera (entre -90º e 90º) com o código abaixo. Este é um acompanhamento de atéessa questã.

O problema, ao que parece, é que a câmera gira mais que -90º ou mais que + 90º e, quando isso acontecer, estarei olhando para baixo (ou para cima), mas a visão girou 180º em torno do eixo Y.

Exemplo: estou voltado para o norte, olhando para o horizonte e começo a olhar para baixo até não poder mais descer (limitado pelo código abaixo). Então começo a olhar para cima e voltarei para o sul.

void Camera::Rotate(Vector3D angle) {
    angle = angle * CAMERA_ROTATION_SPEED;

    accumPitchAngle += angle.x;

    if(accumPitchAngle > 90.0f) {
        angle.x = 90.0f - (accumPitchAngle - angle.x);
        accumPitchAngle = 90.0f;
    }

    if(accumPitchAngle < -90.0f) {
        angle.x = -90.0f - (accumPitchAngle - angle.x);
        accumPitchAngle = -90.0f;
    }

    // Rotate along the WORLD_SKY_VECTOR axis (yaw/heading rotation)
    // WORLD_SKY_VECTOR = (0.0f, 1.0f, 0.0f)
    if(angle.y != 0.0f) {
        Reference = RotateArbitraryAxis(Reference, WORLD_SKY_VECTOR, angle.y);
        RightVector = Vector3D::CrossProduct(Reference, WORLD_SKY_VECTOR);
        UpVector = Vector3D::CrossProduct(RightVector, Reference);
    }

    // Rotate along the x axis (pitch rotation)
    if(angle.x != 0.0f) {
        Reference = RotateArbitraryAxis(Reference, RightVector, angle.x);
        UpVector = Vector3D::CrossProduct(RightVector, Reference);
    }

    // Makes sure all vectors are perpendicular all the time
    Reference.Normalize();
    RightVector = Vector3D::CrossProduct(Reference, UpVector);
    RightVector.Normalize();
    UpVector = Vector3D::CrossProduct(RightVector, Reference);
    UpVector.Normalize();
}

Vector3D Camera::RotateArbitraryAxis(const Vector3D v, Vector3D u, double angle) {
    Vector3D result;

    u.Normalize();

    double scalar = Vector3D::DotProduct(v, u);
    double c = cos(Math::DegreesToRadians(angle));
    double s = sin(Math::DegreesToRadians(angle));
    double a = 1.0f - c;

    result.x = u.x * scalar * a + (v.x * c) + ((-u.z * v.y) + (u.y * v.z)) * s;
    result.y = u.y * scalar * a + (v.y * c) + (( u.z * v.x) - (u.x * v.z)) * s;
    result.z = u.z * scalar * a + (v.z * c) + ((-u.y * v.x) + (u.x * v.y)) * s;

    return result;
}

O problema provavelmente está noif(angle.y != 0.0f), se eu comentar esse bloco de código, o problema não exist Tem algo a ver comWORLD_SKY_VECTOR, mas esse código é assim para permitir que eu gire o cabeçalho e mantenha a câmera nivelada. Se eu usasse oUpVector em vez disso, problema resolvido. Mas isso só é bom para um simulador de vôo. Preciso manter o horizonte nivelado. Essa é a razão por trás deWORLD_SKY_VECTOR. Mas parece que essa é a causa da "troca lateral" quando aponto a câmera diretamente para baix

Conforme solicitado em um comentário abaixo ... Isto é para uma câmera de primeira pessoa (e terceira pessoa, mas ainda não comecei a implementar essa parte) e quando olho para baixo, -90º (ou para cima, + 90º) e quando o ângulo vai de -89º a -91º (ou de + 89º a + 91º), quero que a câmera impeça isso e não ultrapasse o limite de -90º e + 90º. Quando atingir esse limite, preciso que a câmera seja capaz de voltar (para cima se estiver a -90º ou para baixo se estiver a + 90º). No momento, isso só funciona algumas vezes; outras vezes, eu vou estar olhando para o outro lado, e não para o que estava olhando inicialment

questionAnswers(3)

yourAnswerToTheQuestion