/* this function is called when the mouse buttons are clicked or un-clicked */ void glfw_mouse_click_callback ( GLFWwindow* window, int button, int action, int mods ) { // Note: could query if window has lost focus here if (GLFW_PRESS == action) { double xpos, ypos; glfwGetCursorPos (g_window, &xpos, &ypos); // work out ray vec3 ray_wor = get_ray_from_mouse ((float)xpos, (float)ypos); // check ray against all spheres in scene int closest_sphere_clicked = -1; float closest_intersection = 0.0f; for (int i = 0; i < NUM_SPHERES; i++) { float t_dist = 0.0f; if (ray_sphere ( cam_pos, ray_wor, sphere_pos_wor[i], sphere_radius, &t_dist )) { // if more than one sphere is in path of ray, only use the closest one if (-1 == closest_sphere_clicked || t_dist < closest_intersection) { closest_sphere_clicked = i; closest_intersection = t_dist; } } } // endfor g_selected_sphere = closest_sphere_clicked; printf ("sphere %i was clicked\n", closest_sphere_clicked); } }
BOOL linesegment_sphere(const LLVector3 &point_a, const LLVector3 &point_b, const LLVector3 &sphere_center, F32 sphere_radius, LLVector3 &intersection, LLVector3 &intersection_normal) { LLVector3 ray_direction = point_b - point_a; F32 segment_length = ray_direction.normVec(); if (ray_sphere(point_a, ray_direction, sphere_center, sphere_radius, intersection, intersection_normal)) { if (segment_length >= (point_a - intersection).magVec()) { return TRUE; } } return FALSE; }