0
\$\begingroup\$

I try to make a spherical billboard that follow the camera's direction. But, the result that I got is model get distorted or event twisted. If I'm using only a yaw/pitch quaternion per time, it works perfectly(but I got cylinder billboard instead, which I didn't want).

The sheep is player. The black circle is the objects that I want spherical billboard effect. The result.

Here is the implementation.

void updateRotation(glm::vec3 cameraPosition, glm::vec3 playerPosition) {
    glm::quat yaw_quat(1.0f, 0.0f, 0.0f, 0.0f), pitch_quat(1.0f, 0.0f, 0.0f, 0.0f);
    
    //calculate yaw
    glm::vec3 toProject(0.0f, 0.0f, 0.0f);
    toProject = cameraPosition - playerPosition;
    toProject.y = 0.0f;
    
    glm::vec3 normailizedToProject = glm::normalize(toProject);
    glm::vec3 normailizedObjLookAt(0.0f, 0.0f, 1.0f);
    
    glm::vec3 upAxis = glm::cross(normailizedObjLookAt, normailizedToProject);
    glm::vec3 normalizedUpAxis = glm::normalize(upAxis);
    float dotProduct = glm::dot(normailizedObjLookAt, normailizedToProject);
    if ((dotProduct < 0.99990f) && (dotProduct > -0.9999f)) {
        yaw_quat = glm::angleAxis(acos(dotProduct), normalizedUpAxis);
    }
    
    //calculate pitch
    toProject = glm::vec3(0.0f, 0.0f, 0.0f);
    toProject = cameraPosition - playerPosition;
    
    normailizedToProject = glm::normalize(toProject);
    dotProduct = glm::dot(normailizedObjLookAt, normailizedToProject);
    if ((dotProduct < 0.99990f) && (dotProduct > -0.9999f)) {
        if(normailizedToProject.y < 0.0f) {
            pitch_quat = glm::angleAxis(acos(dotProduct), glm::vec3(1.0f, 0.0f, 0.0f));
        }
        else {
            pitch_quat = glm::angleAxis(acos(dotProduct), glm::vec3(-1.0f, 0.0f, 0.0f));
        }
    }
glm::quat rotationQuat = glm::normalize(yaw_quat * pitch_quat);
}
\$\endgroup\$

0

You must log in to answer this question.

Browse other questions tagged .