int viewglut_point(viewglut *P, int x, int y) { double v[3]; assert(P); /* Convert the mouse position to a pointer vector. */ pointer(P, x, y, (P->state == st_zoom), v); /* Apply the new pointer vector. */ switch (P->state) { case st_look: view_look(P->V, v); break; case st_roll: view_roll(P->V, v); break; case st_zoom: view_zoom(P->V, v); break; default: return 0; } glutPostRedisplay(); return 1; }
static Bool compositor_handle_navigation_3d(GF_Compositor *compositor, GF_Event *ev) { Fixed x, y, trans_scale; Fixed dx, dy, key_trans, key_pan, key_exam; s32 key_inv; u32 keys; #ifdef SCALE_NAV Bool is_pixel_metrics; #endif GF_Camera *cam; Fixed zoom = compositor->zoom; cam = NULL; #ifndef GPAC_DISABLE_VRML if (compositor->active_layer) { cam = compositor_layer3d_get_camera(compositor->active_layer); #ifdef SCALE_NAV is_pixel_metrics = gf_sg_use_pixel_metrics(gf_node_get_graph(compositor->active_layer)); #endif } #endif if (!cam) { cam = &compositor->visual->camera; assert(compositor); assert(compositor->scene); #ifdef SCALE_NAV is_pixel_metrics = compositor->traverse_state->pixel_metrics; #endif } if (!cam || (cam->navigate_mode==GF_NAVIGATE_NONE)) return 0; keys = compositor->key_states; if (!cam->navigate_mode && !(keys & GF_KEY_MOD_ALT) ) return 0; x = y = 0; /*renorm between -1, 1*/ if (ev->type<=GF_EVENT_MOUSEWHEEL) { x = gf_divfix( INT2FIX(ev->mouse.x - (s32) compositor->visual->width/2), INT2FIX(compositor->visual->width)); y = gf_divfix( INT2FIX(ev->mouse.y - (s32) compositor->visual->height/2), INT2FIX(compositor->visual->height)); } dx = (x - compositor->grab_x); dy = (compositor->grab_y - y); #ifdef SCALE_NAV trans_scale = is_pixel_metrics ? cam->width/2 : INT2FIX(10); key_trans = is_pixel_metrics ? INT2FIX(10) : cam->avatar_size.x; #else trans_scale = cam->width/20; key_trans = cam->avatar_size.x/2; //if default VP is quite far from center use larger dz/dy moves if (cam->vp_dist>100) trans_scale *= 10; #endif if (cam->world_bbox.is_set && (key_trans*5 > cam->world_bbox.radius)) { key_trans = cam->world_bbox.radius / 100; } key_pan = FIX_ONE/25; key_exam = FIX_ONE/20; key_inv = 1; if (keys & GF_KEY_MOD_SHIFT) { dx *= 4; dy *= 4; key_pan *= 4; key_exam *= 4; key_trans*=4; } switch (ev->type) { case GF_EVENT_MOUSEDOWN: /*left*/ if (ev->mouse.button==GF_MOUSE_LEFT) { compositor->grab_x = x; compositor->grab_y = y; compositor->navigation_state = 1; /*change vp and examine center to current location*/ if ((keys & GF_KEY_MOD_CTRL) && compositor->hit_square_dist) { cam->vp_position = cam->position; cam->vp_orientation = camera_get_orientation(cam->position, cam->target, cam->up); cam->vp_fov = cam->fieldOfView; cam->examine_center = compositor->hit_world_point; camera_changed(compositor, cam); return 1; } } /*right*/ else if (ev->mouse.button==GF_MOUSE_RIGHT) { if (compositor->navigation_state && (cam->navigate_mode==GF_NAVIGATE_WALK)) { camera_jump(cam); gf_sc_invalidate(compositor, NULL); return 1; } else if (keys & GF_KEY_MOD_CTRL) gf_sc_fit_world_to_screen(compositor); } break; /* note: shortcuts are mostly the same as blaxxun contact, I don't feel like remembering 2 sets...*/ case GF_EVENT_MOUSEMOVE: if (!compositor->navigation_state) { if (cam->navigate_mode==GF_NAVIGATE_GAME) { /*init mode*/ compositor->grab_x = x; compositor->grab_y = y; compositor->navigation_state = 1; } return 0; } compositor->navigation_state++; switch (cam->navigate_mode) { /*FIXME- we'll likely need a "step" value for walk at some point*/ case GF_NAVIGATE_WALK: case GF_NAVIGATE_FLY: view_pan_x(compositor, cam, -dx); if (keys & GF_KEY_MOD_CTRL) view_pan_y(compositor, cam, dy); else view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale)); break; case GF_NAVIGATE_VR: view_pan_x(compositor, cam, -dx); if (keys & GF_KEY_MOD_CTRL) view_zoom(compositor, cam, dy); else view_pan_y(compositor, cam, dy); break; case GF_NAVIGATE_PAN: view_pan_x(compositor, cam, -dx); if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale)); else view_pan_y(compositor, cam, dy); break; case GF_NAVIGATE_SLIDE: view_translate_x(compositor, cam, gf_mulfix(dx, trans_scale)); if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale)); else view_translate_y(compositor, cam, gf_mulfix(dy, trans_scale)); break; case GF_NAVIGATE_EXAMINE: if (keys & GF_KEY_MOD_CTRL) { view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale)); view_roll(compositor, cam, gf_mulfix(dx, trans_scale)); } else { if (ABS(dx) > ABS(dy)) { view_exam_x(compositor, cam, -gf_mulfix(GF_PI, dx)); } else { view_exam_y(compositor, cam, gf_mulfix(GF_PI, dy)); } } break; case GF_NAVIGATE_ORBIT: if (keys & GF_KEY_MOD_CTRL) { view_translate_z(compositor, cam, gf_mulfix(dy, trans_scale)); } else { view_orbit_x(compositor, cam, -gf_mulfix(GF_PI, dx)); view_orbit_y(compositor, cam, gf_mulfix(GF_PI, dy)); } break; case GF_NAVIGATE_GAME: view_pan_x(compositor, cam, -dx); view_pan_y(compositor, cam, dy); break; } compositor->grab_x = x; compositor->grab_y = y; return 1; case GF_EVENT_MOUSEWHEEL: switch (cam->navigate_mode) { /*FIXME- we'll likely need a "step" value for walk at some point*/ case GF_NAVIGATE_WALK: case GF_NAVIGATE_FLY: view_pan_y(compositor, cam, gf_mulfix(key_pan, ev->mouse.wheel_pos)); break; case GF_NAVIGATE_VR: view_zoom(compositor, cam, gf_mulfix(key_pan, ev->mouse.wheel_pos)); break; case GF_NAVIGATE_SLIDE: case GF_NAVIGATE_EXAMINE: case GF_NAVIGATE_ORBIT: case GF_NAVIGATE_PAN: if (cam->is_3D) { view_translate_z(compositor, cam, gf_mulfix(trans_scale, ev->mouse.wheel_pos) * ((keys & GF_KEY_MOD_SHIFT) ? 4 : 1)); } else { nav_set_zoom_trans_2d(compositor->visual, zoom + INT2FIX(ev->mouse.wheel_pos)/10, 0, 0); } } return 1; case GF_EVENT_MOUSEUP: if (ev->mouse.button==GF_MOUSE_LEFT) compositor->navigation_state = 0; break; case GF_EVENT_KEYDOWN: switch (ev->key.key_code) { case GF_KEY_BACKSPACE: gf_sc_reset_graphics(compositor); return 1; case GF_KEY_C: compositor->collide_mode = compositor->collide_mode ? GF_COLLISION_NONE : GF_COLLISION_DISPLACEMENT; return 1; case GF_KEY_J: if (cam->navigate_mode==GF_NAVIGATE_WALK) { camera_jump(cam); gf_sc_invalidate(compositor, NULL); return 1; } break; case GF_KEY_HOME: if (!compositor->navigation_state) { compositor->visual->camera.start_zoom = compositor->zoom; compositor->zoom = FIX_ONE; compositor->interoccular_offset = 0; compositor->focus_distance = 0; compositor->interoccular_offset = 0; compositor->focus_distance = 0; compositor_3d_reset_camera(compositor); } break; case GF_KEY_END: if (cam->navigate_mode==GF_NAVIGATE_GAME) { cam->navigate_mode = GF_NAVIGATE_WALK; compositor->navigation_state = 0; return 1; } break; case GF_KEY_LEFT: key_inv = -1; case GF_KEY_RIGHT: if (keys & GF_KEY_MOD_ALT) { if ( (keys & GF_KEY_MOD_SHIFT) && (compositor->visual->nb_views > 1) ) { /*+ or - 10 cm*/ compositor->focus_distance += INT2FIX(key_inv); cam->flags |= CAM_IS_DIRTY; fprintf(stderr, "AutoStereo view distance %f - focus %f\n", FIX2FLT(compositor->video_out->view_distance)/100, FIX2FLT(compositor->focus_distance)/100); gf_sc_invalidate(compositor, NULL); return 1; } return 0; } switch (cam->navigate_mode) { case GF_NAVIGATE_SLIDE: if (keys & GF_KEY_MOD_CTRL) view_pan_x(compositor, cam, key_inv * key_pan); else view_translate_x(compositor, cam, key_inv * key_trans); break; case GF_NAVIGATE_EXAMINE: if (keys & GF_KEY_MOD_CTRL) view_roll(compositor, cam, gf_mulfix(dx, trans_scale)); else view_exam_x(compositor, cam, -key_inv * key_exam); break; case GF_NAVIGATE_ORBIT: if (keys & GF_KEY_MOD_CTRL) view_translate_x(compositor, cam, key_inv * key_trans); else view_orbit_x(compositor, cam, -key_inv * key_exam); break; case GF_NAVIGATE_GAME: view_translate_x(compositor, cam, key_inv * key_trans); break; case GF_NAVIGATE_VR: view_pan_x(compositor, cam, -key_inv * key_pan); break; /*walk/fly/pan*/ default: if (keys & GF_KEY_MOD_CTRL) view_translate_x(compositor, cam, key_inv * key_trans); else view_pan_x(compositor, cam, -key_inv * key_pan); break; } return 1; case GF_KEY_DOWN: key_inv = -1; case GF_KEY_UP: if (keys & GF_KEY_MOD_ALT) { if ( (keys & GF_KEY_MOD_SHIFT) && (compositor->visual->nb_views > 1) ) { compositor->interoccular_offset += FLT2FIX(0.5) * key_inv; fprintf(stderr, "AutoStereo interoccular distance %f\n", FIX2FLT(compositor->interoccular_distance + compositor->interoccular_offset)); cam->flags |= CAM_IS_DIRTY; gf_sc_invalidate(compositor, NULL); return 1; } return 0; } switch (cam->navigate_mode) { case GF_NAVIGATE_SLIDE: if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, key_inv * key_trans); else view_translate_y(compositor, cam, key_inv * key_trans); break; case GF_NAVIGATE_EXAMINE: if (keys & GF_KEY_MOD_CTRL) view_translate_z(compositor, cam, key_inv * key_trans); else view_exam_y(compositor, cam, -key_inv * key_exam); break; case GF_NAVIGATE_ORBIT: if (keys & GF_KEY_MOD_CTRL) view_translate_y(compositor, cam, key_inv * key_trans); else view_orbit_y(compositor, cam, -key_inv * key_exam); break; case GF_NAVIGATE_PAN: if (keys & GF_KEY_MOD_CTRL) view_translate_y(compositor, cam, key_inv * key_trans); else view_pan_y(compositor, cam, key_inv * key_pan); break; case GF_NAVIGATE_GAME: view_translate_z(compositor, cam, key_inv * key_trans); break; case GF_NAVIGATE_VR: if (keys & GF_KEY_MOD_CTRL) view_zoom(compositor, cam, key_inv * key_pan); else view_pan_y(compositor, cam, key_inv * key_pan); break; /*walk/fly*/ default: if (keys & GF_KEY_MOD_CTRL) view_pan_y(compositor, cam, key_inv * key_pan); else view_translate_z(compositor, cam, key_inv * key_trans); break; } return 1; case GF_KEY_PAGEDOWN: if (keys & GF_KEY_MOD_CTRL) { view_zoom(compositor, cam, FIX_ONE/10); return 1; } break; case GF_KEY_PAGEUP: if (keys & GF_KEY_MOD_CTRL) { view_zoom(compositor, cam, -FIX_ONE/10); return 1; } break; } break; } return 0; }