예제 #1
0
    Quaternion Quaternion::RotationBetween(Vector3 aStart, Vector3 aEnd)
    {
        glm::vec3 start = glm::normalize(aStart.Raw());
        glm::vec3 end = glm::normalize(aEnd.Raw());

        float cosTheta = glm::dot(start, end);
        glm::vec3 rotationAxis;

        if (cosTheta < -1 + 0.001f)
        {
            rotationAxis = glm::cross(Vector3::Forward(), start);
            if (glm::length2(rotationAxis) < 0.01f)
            {
                rotationAxis = glm::cross(Vector3::Right(), start);
            }
            rotationAxis = glm::normalize(rotationAxis);
            return glm::angleAxis(180.0f, rotationAxis);
        }
        rotationAxis = glm::cross(start, end);

        float s = glm::sqrt( (1 + cosTheta) * 2.0f);
        float invs = 1 / s;

        return glm::quat(s * 0.5f, rotationAxis.x * invs, rotationAxis.y * invs, rotationAxis.z * invs);
    }
예제 #2
0
    Quaternion Quaternion::LookRotation(const Vector3 & aLookDirection, const Vector3 & aDesiredUp)
    {
        glm::quat quat1 = RotationBetween(Vector3::Forward(), aLookDirection).Raw();

        glm::vec3 desiredUp = aDesiredUp.Raw();
        glm::vec3 right = glm::cross(aLookDirection, desiredUp);
        desiredUp = glm::cross(right, aLookDirection);

        glm::vec3 newUp = quat1 * Vector3::Up().Raw();
        glm::quat quat2 = RotationBetween(newUp, desiredUp);
        return quat2 * quat1;
    }