For reference, code of a working orbiting camera.
1.) Initialize camera vectors on setup:
m_target is the position of the ball, translated to for example 0/0/0
m_position is the initial camera position, set to for example m_target - vec3{0,0,5}
glm::vec3 direction{ m_target - m_position };
m_distance = glm::length( m_target - m_position );
m_yaw = glm::degres( std::atan2( -direction.x, direction.z ) );
m_pitch = glm::degrees( std::atan2( direction.y, std::sqrt( ( direction.x * direction.x) + ( direction.y * direction.y ) ) ) );
I use degrees because intuitive and makes more sense on display.
2.) In your render loop, after having processed input:
float yaw{ -glm::radians( m_yaw ) };
float pitch{ -glm::radians( m_pitch ) };
// Calculate the camera position on the sphere around the target
m_position = glm::dvec3{ m_distance * std::sin( yaw ) * std::cos( pitch ),
m_distance * std::sin( pitch ),
-m_distance * std::cos( yaw ) * std::cos( pitch ) };
// Normalization not necessarily needed here. But later when buidling the frustum.
m_front = glm::normalize( m_target - m_position );
// conversion to float because precision isn't needed here
m_viewMatrix = glm::lookAt( glm::vec3{ m_position }, glm::vec3{ m_target }, m_up );
// Also re-calculate the right vector. Normalize for later use
m_right = glm::normalize( glm::cross( m_front, m_up ) );
m_projectionViewMatrix = m_perspectiveProjectionMatrix * m_viewMatrix;
Code for an orbiting camera. Projection matrix is only calculated when viewport or near/far planes change.
If you want to change the distance for example with the mouse wheel, you must recalc it in the loop. You will want to use pitch and yaw from the ball, so that the camera is following it. Also, maybe you will want to limit camera movement to the y/z plane, which should be trivial now that you have read the linear algebra things ?
No guarantee ;-).
Edit: looks like you have deleted the video and thus invalidated my post. The camera in the video was still freely turning and not locked to the ball.