in code/cpp/tools/scene_annotation_tool/main.cpp [2521:2629]
bool mouse_move(igl::opengl::glfw::Viewer& viewer, int mouse_x, int mouse_y) {
int width_window, height_window;
glfwGetFramebufferSize(viewer.window, &width_window, &height_window);
if (g_mouse_rotation || g_mouse_translation || g_mouse_drawing) {
g_mouse_prev_x = g_mouse_curr_x;
g_mouse_prev_y = g_mouse_curr_y;
g_mouse_curr_x = mouse_x;
g_mouse_curr_y = mouse_y;
if (g_mouse_ignore_counter > 0) {
g_mouse_ignore_counter--;
}
}
if (g_mouse_prev_x >= 0 && g_mouse_prev_x < width_window && g_mouse_prev_y >= 0 && g_mouse_prev_y < height_window &&
g_mouse_curr_x >= 0 && g_mouse_curr_x < width_window && g_mouse_curr_y >= 0 && g_mouse_curr_y < height_window &&
g_mouse_ignore_counter == 0) {
if (g_mouse_rotation) {
auto p_x_curr = ((2.0*g_mouse_curr_x) / width_window) - 1.0;
auto p_x_prev = ((2.0*g_mouse_prev_x) / width_window) - 1.0;
auto p_y_curr = ((2.0*g_mouse_curr_y) / height_window) - 1.0;
auto p_y_prev = ((2.0*g_mouse_prev_y) / height_window) - 1.0;
Eigen::Vector3f camera_eye_curr_;
Eigen::Vector3f camera_rotation_axis_;
Eigen::Vector3f camera_eye_next_;
// horizontal rotation
auto theta_curr = std::acos(std::min(std::max(p_x_curr,-1.0),1.0));
auto theta_prev = std::acos(std::min(std::max(p_x_prev,-1.0),1.0));
auto theta_delta = theta_curr - theta_prev;
camera_eye_curr_ = viewer.core().camera_eye - viewer.core().camera_center;
camera_rotation_axis_ = Eigen::Vector3f::UnitZ();
camera_eye_next_ = Eigen::AngleAxisf(theta_delta, camera_rotation_axis_).toRotationMatrix()*camera_eye_curr_;
viewer.core().camera_eye = viewer.core().camera_center + camera_eye_next_;
// vertical rotation
camera_eye_curr_ = viewer.core().camera_eye - viewer.core().camera_center;
Eigen::Vector3f camera_eye_curr_norm = camera_eye_curr_ / camera_eye_curr_.norm();
auto gamma = std::acos(std::min(std::max(camera_eye_curr_norm.dot(Eigen::Vector3f::UnitZ()),-1.0f),1.0f)); // angle between center-to-eye and up
auto alpha_curr = std::acos(std::min(std::max(p_y_curr,-1.0),1.0));
auto alpha_prev = std::acos(std::min(std::max(p_y_prev,-1.0),1.0));
auto alpha_delta = alpha_curr - alpha_prev;
auto eps = 1.0*(igl::PI/180.0); // maintain minimum angle between center-to-eye and poles
auto alpha_delta_ = 0.0;
if (alpha_delta < 0.0) {
alpha_delta_ = std::min(std::max(alpha_delta, eps-gamma), 0.0); // always keep eye least eps away from north pole, most of the time this term is alpha_delta
}
if (alpha_delta > 0.0) {
alpha_delta_ = std::min(std::max(alpha_delta, 0.0), igl::PI-gamma-eps); // always keep eye at least eps away from south pole, most of the time this term is alpha_delta
}
camera_rotation_axis_ = camera_eye_curr_.cross(Eigen::Vector3f::UnitZ()) / camera_eye_curr_.cross(Eigen::Vector3f::UnitZ()).norm();
camera_eye_next_ = Eigen::AngleAxisf(-alpha_delta_, camera_rotation_axis_).toRotationMatrix()*camera_eye_curr_;
viewer.core().camera_eye = viewer.core().camera_center + camera_eye_next_;
}
if (g_mouse_translation) {
Eigen::Vector3f camera_look_at_dir;
Eigen::Vector3f camera_right_dir;
Eigen::Vector3f camera_up_dir;
float camera_look_at_dist;
auto fov_y = viewer.core().camera_view_angle * (igl::PI/180.0);
auto fov_x = 2.0 * std::atan(width_window * std::tan(fov_y/2.0) / height_window);
// horizontal translation
camera_look_at_dir = (viewer.core().camera_center - viewer.core().camera_eye) / (viewer.core().camera_center - viewer.core().camera_eye).norm();
camera_right_dir = camera_look_at_dir.cross(Eigen::Vector3f::UnitZ()) / camera_look_at_dir.cross(Eigen::Vector3f::UnitZ()).norm();
camera_look_at_dist = (viewer.core().camera_center - viewer.core().camera_eye).norm();
auto mouse_delta_x = g_mouse_curr_x - g_mouse_prev_x;
auto delta_x = -(mouse_delta_x / (width_window/2.0))*std::tan(fov_x/2.0)*camera_look_at_dist;
auto delta_x_ = delta_x;
viewer.core().camera_eye = viewer.core().camera_eye + delta_x_*camera_right_dir;
viewer.core().camera_center = viewer.core().camera_center + delta_x_*camera_right_dir;
// vertical translation
camera_look_at_dir = (viewer.core().camera_center - viewer.core().camera_eye) / (viewer.core().camera_center - viewer.core().camera_eye).norm();
camera_right_dir = camera_look_at_dir.cross(Eigen::Vector3f::UnitZ()) / camera_look_at_dir.cross(Eigen::Vector3f::UnitZ()).norm();
camera_up_dir = -(camera_look_at_dir.cross(camera_right_dir) / camera_look_at_dir.cross(camera_right_dir).norm());
camera_look_at_dist = (viewer.core().camera_center - viewer.core().camera_eye).norm();
auto mouse_delta_y = g_mouse_curr_y - g_mouse_prev_y;
auto delta_y = (mouse_delta_y / (height_window/2.0))*std::tan(fov_y/2.0)*camera_look_at_dist;
auto delta_y_ = delta_y;
viewer.core().camera_eye = viewer.core().camera_eye + delta_y_*camera_up_dir;
viewer.core().camera_center = viewer.core().camera_center + delta_y_*camera_up_dir;
}
if (g_mouse_drawing) {
if (mouse_x >= 0 && mouse_x < width_window && mouse_y >= 0 && mouse_y < height_window) {
g_mouse_drawing_positions.push_back({mouse_x, mouse_y});
}
}
}
return true;
}