+ // determine where camera should be
+ double actual_dist = cam_dist;
+ if (shown_creature) {
+ cam_tgt_focus = shown_creature->GetSituation().Position();
+ cam_tgt_up = glm::normalize(cam_tgt_focus);
+ actual_dist += shown_creature->Size();
+ } else if (shown_body) {
+ cam_tgt_focus = glm::dvec3(0.0);
+ cam_tgt_up = glm::dvec3(0.0, 1.0, 0.0);
+ actual_dist += shown_body->Radius();
+ }
+
+ glm::dvec3 dir(0.0, 0.0, -actual_dist);
+ glm::dvec3 ref_dir(glm::normalize(glm::cross(cam_tgt_up, glm::dvec3(-cam_tgt_up.z, cam_tgt_up.x, cam_tgt_up.y))));
+ dir =
+ glm::dmat3(ref_dir, cam_tgt_up, glm::cross(ref_dir, cam_tgt_up))
+ * glm::dmat3(glm::eulerAngleYX(-cam_orient.y, -cam_orient.x))
+ * dir;
+ cam_tgt_up = glm::rotate(cam_tgt_up, cam_orient.z, glm::normalize(-dir));
+ cam_tgt_pos = cam_tgt_focus - dir;
+
+ // approach target location
+ glm::dvec3 cam_pos_diff(cam_tgt_pos - cam_pos);
+ if (glm::length2(cam_pos_diff) > 0.000001) {
+ cam_pos += cam_pos_diff * 0.25;
+ } else {
+ cam_pos = cam_tgt_pos;
+ }
+
+ glm::dvec3 cam_focus_diff(cam_tgt_focus - cam_focus);
+ if (glm::length2(cam_focus_diff) > 0.000001) {
+ cam_focus += cam_focus_diff * 0.25;