Search code examples
c++quaternionsglm-math

quaternion inverts vector


I'm using glm::quaternions to rotate a vector around a certain axis. But the vector inverts the axis everytime it is called.

Here is my code to rotate my object around the side axis:

void PlayerController::rotateForward(float angle) {
    angle = (angle*M_PI) / 180.0f;
    fquat rot = fquat(angle, playerObject->getVecSide());
    normalize(rot);
    vec4 newUpVec = rot * vec4(playerObject->getVecUp(), 1.0f);
    normalize(newUpVec);
    vec3 upVec3 = normalize(vec3(newUpVec.x ,newUpVec.y, newUpVec.z));

    playerObject->setVecUp(upVec3);
    playerObject->setVecForward(-normalize(cross(playerObject->getVecUp(), playerObject->getVecSide())));
    vec3 newPlayerPos = currentPlanet->getPosition() + (playerObject->getVecUp() * radius);
    playerObject->setPosition(newPlayerPos);
}

everytime I call this method, my up vector is turned around the axis, but also inverted. I can work around this by using:

    vec4 newUpVec = rot * -vec4(playerObject->getVecUp(), 1.0f);

but this is more like treating symptoms instead of finding the cause. Maybe someone around here can help me in understanding what the quaternion does here.


Solution

  • well here is the answer, the quaternion initialization was wrong...

    these lines were missing:

    rotateAround = rotateAround * sinf(angle/2.0f);
    angle = cosf(angle/2.0f);
    

    so the correct version of the method looks like this:

    vec3 GameObjectRotator::rotateVector(float angle, vec3 toRotate, vec3 rotateAround) {
        angle = (angle*M_PI) / 180.0f;
    
        rotateAround = rotateAround * sinf(angle/2.0f);
        angle = cosf(angle/2.0f);
    
        fquat rot = fquat(angle, rotateAround);
        normalize(rot);
        vec4 rotated =  rot * vec4(toRotate, 1.0f);
        normalize(rotated);
        return normalize(vec3(rotated));
    }
    

    (the class has gone through quite a bit refactoring since the first version, but the idea should be clear anyways)