📄 navigate.c
字号:
view_translate_z(sr, cam, gf_mulfix(dy, trans_scale)); } else { view_orbit_x(sr, cam, -gf_mulfix(GF_PI, dx)); view_orbit_y(sr, cam, gf_mulfix(GF_PI, dy)); } break; case GF_NAVIGATE_GAME: view_pan_x(sr, cam, -dx); view_pan_y(sr, cam, dy); break; } sr->grab_x = x; sr->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(sr, cam, gf_mulfix(key_pan, ev->mouse.wheel_pos)); break; case GF_NAVIGATE_VR: view_zoom(sr, 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 (is_pixel_metrics) { view_translate_z(sr, cam, gf_mulfix(trans_scale, ev->mouse.wheel_pos) * ((keys & GF_KEY_MOD_SHIFT) ? 4 : 1)); } else { view_translate_z(sr, cam, ev->mouse.wheel_pos * ((keys & GF_KEY_MOD_SHIFT) ? 4 : 1)); } break; } return 1; case GF_EVENT_MOUSEUP: if (ev->mouse.button==GF_MOUSE_LEFT) sr->nav_is_grabbed = 0; break; case GF_EVENT_KEYDOWN: switch (ev->key.key_code) { case GF_KEY_BACKSPACE: gf_sr_reset_graphics(sr->compositor); return 1; case GF_KEY_C: sr->collide_mode = sr->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_sr_invalidate(sr->compositor, NULL); return 1; } break; case GF_KEY_HOME: if (!sr->nav_is_grabbed) R3D_ResetCamera(sr); break; case GF_KEY_END: if (cam->navigate_mode==GF_NAVIGATE_GAME) { cam->navigate_mode = GF_NAVIGATE_WALK; sr->nav_is_grabbed = 0; return 1; } break; case GF_KEY_LEFT: key_inv = -1; case GF_KEY_RIGHT: switch (cam->navigate_mode) { case GF_NAVIGATE_SLIDE: if (keys & GF_KEY_MOD_CTRL) view_pan_x(sr, cam, key_inv * key_pan); else view_translate_x(sr, cam, key_inv * key_trans); break; case GF_NAVIGATE_EXAMINE: if (keys & GF_KEY_MOD_CTRL) view_roll(sr, cam, gf_mulfix(dx, trans_scale)); else view_exam_x(sr, cam, -key_inv * key_exam); break; case GF_NAVIGATE_ORBIT: if (keys & GF_KEY_MOD_CTRL) view_translate_x(sr, cam, key_inv * key_trans); else view_orbit_x(sr, cam, -key_inv * key_exam); break; case GF_NAVIGATE_GAME: view_translate_x(sr, cam, key_inv * key_trans); break; case GF_NAVIGATE_VR: view_pan_x(sr, cam, -key_inv * key_pan); break; /*walk/fly/pan*/ default: if (keys & GF_KEY_MOD_CTRL) view_translate_x(sr, cam, key_inv * key_trans); else view_pan_x(sr, 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) return 0; switch (cam->navigate_mode) { case GF_NAVIGATE_SLIDE: if (keys & GF_KEY_MOD_CTRL) view_translate_z(sr, cam, key_inv * key_trans); else view_translate_y(sr, cam, key_inv * key_trans); break; case GF_NAVIGATE_EXAMINE: if (keys & GF_KEY_MOD_CTRL) view_translate_z(sr, cam, key_inv * key_trans); else view_exam_y(sr, cam, -key_inv * key_exam); break; case GF_NAVIGATE_ORBIT: if (keys & GF_KEY_MOD_CTRL) view_translate_y(sr, cam, key_inv * key_trans); else view_orbit_y(sr, cam, -key_inv * key_exam); break; case GF_NAVIGATE_PAN: if (keys & GF_KEY_MOD_CTRL) view_translate_y(sr, cam, key_inv * key_trans); else view_pan_y(sr, cam, key_inv * key_pan); break; case GF_NAVIGATE_GAME: view_translate_z(sr, cam, key_inv * key_trans); break; case GF_NAVIGATE_VR: if (keys & GF_KEY_MOD_CTRL) view_zoom(sr, cam, key_inv * key_pan); else view_pan_y(sr, cam, key_inv * key_pan); break; /*walk/fly*/ default: if (keys & GF_KEY_MOD_CTRL) view_pan_y(sr, cam, key_inv * key_pan); else view_translate_z(sr, cam, key_inv * key_trans); break; } return 1; case GF_KEY_PAGEDOWN: if (keys & GF_KEY_MOD_CTRL) { view_zoom(sr, cam, FIX_ONE/10); return 1; } break; case GF_KEY_PAGEUP: if (keys & GF_KEY_MOD_CTRL) { view_zoom(sr, cam, -FIX_ONE/10); return 1; } break; } break; } return 0;}static void VS_SetZoom2D(VisualSurface *surf, Fixed zoom) { Fixed ratio; if (zoom <= 0) zoom = FIX_ONE/1000; if (zoom != surf->camera.zoom) { ratio = zoom/surf->camera.zoom; surf->camera.trans.x = gf_mulfix(surf->camera.trans.x, ratio); surf->camera.trans.y = gf_mulfix(surf->camera.trans.y, ratio); surf->camera.zoom = zoom; } camera_changed(surf->render, &surf->camera);}/*let's try to keep the same behaviour as the 2D renderer*/static Bool VS_HandleEvents2D(VisualSurface *surf, GF_Event *ev){ Fixed x, y, dx, dy, key_trans, key_rot; s32 key_inv; Bool is_pixel_metrics = gf_sg_use_pixel_metrics(surf->render->compositor->scene); u32 keys = surf->render->compositor->key_states; if (!surf->camera.navigate_mode) return 0; x = y = 0; /*renorm between -1, 1*/ if (ev->type<=GF_EVENT_MOUSEWHEEL) { x = INT2FIX(ev->mouse.x); y = INT2FIX(ev->mouse.y); } else { if (!(keys & GF_KEY_MOD_ALT) && (!surf->camera.navigate_mode || !(surf->camera.navigation_flags & NAV_ANY)) ) return 0; } dx = x - surf->render->grab_x; dy = y - surf->render->grab_y; if (!is_pixel_metrics) { dx /= surf->width; dy /= surf->height; } key_inv = 1; key_trans = INT2FIX(2); key_rot = FIX_ONE/10; if (keys & GF_KEY_MOD_SHIFT) { dx *= 4; dy *= 4; key_rot *= 4; key_trans*=4; } if (!is_pixel_metrics) { key_trans /= surf->width;} switch (ev->type) { case GF_EVENT_MOUSEDOWN: /*left*/ if (ev->mouse.button==GF_MOUSE_LEFT) { surf->render->grab_x = x; surf->render->grab_y = y; surf->render->nav_is_grabbed = 1; return 0; } break; case GF_EVENT_MOUSEUP: if (ev->mouse.button==GF_MOUSE_LEFT) { surf->render->nav_is_grabbed = 0; return 0; } break; case GF_EVENT_MOUSEMOVE: if (!surf->render->nav_is_grabbed) return 0; switch (surf->camera.navigate_mode) { case GF_NAVIGATE_SLIDE: if (keys & GF_KEY_MOD_CTRL) { Fixed new_zoom = surf->camera.zoom; if (new_zoom > FIX_ONE) new_zoom += dy/20; else new_zoom += dy/80; VS_SetZoom2D(surf, new_zoom); } else { surf->camera.trans.x += dx; surf->camera.trans.y += dy; VS_SetZoom2D(surf, surf->camera.zoom); } break; case GF_NAVIGATE_EXAMINE: surf->camera.rot.y += gf_mulfix(GF_PI, dx) / surf->width; surf->camera.rot.x += gf_mulfix(GF_PI, dy) / surf->height; camera_changed(surf->render, &surf->camera); break; } surf->render->grab_x = x; surf->render->grab_y = y; return 1; case GF_EVENT_KEYDOWN: switch (ev->key.key_code) { case GF_KEY_BACKSPACE: gf_sr_reset_graphics(surf->render->compositor); return 1; case GF_KEY_HOME: if (!surf->render->nav_is_grabbed) R3D_ResetCamera(surf->render); return 1; case GF_KEY_LEFT: key_inv = -1; case GF_KEY_RIGHT: if (surf->camera.navigate_mode == GF_NAVIGATE_SLIDE) surf->camera.trans.x += key_inv*key_trans; else surf->camera.rot.y -= key_inv * key_rot; camera_changed(surf->render, &surf->camera); return 1; case GF_KEY_DOWN: key_inv = -1; case GF_KEY_UP: if (surf->camera.navigate_mode == GF_NAVIGATE_SLIDE) { if (keys & GF_KEY_MOD_CTRL) { Fixed new_zoom = surf->camera.zoom; if (new_zoom > FIX_ONE) new_zoom += key_inv*FIX_ONE/10; else new_zoom += key_inv*FIX_ONE/20; VS_SetZoom2D(surf, new_zoom); } else { surf->camera.trans.y += key_inv*key_trans; camera_changed(surf->render, &surf->camera); } } else { surf->camera.rot.x += key_rot; camera_changed(surf->render, &surf->camera); } return 1; } break; } return 0;}Bool R3D_HandleUserEvent(Render3D *sr, GF_Event *ev){ if (sr->root_is_3D || sr->active_layer) { return R3D_HandleEvents3D(sr, ev); } else { return VS_HandleEvents2D(sr->surface, ev); }}void VS_ViewpointChange(RenderEffect3D *eff, GF_Node *vp, Bool animate_change, Fixed fieldOfView, SFVec3f position, SFRotation orientation, SFVec3f local_center){ Fixed dist; SFVec3f d; /*update znear&zfar*/ eff->camera->z_near = eff->camera->avatar_size.x / 20; if (eff->camera->z_near<=0) eff->camera->z_near = FIX_ONE/100; eff->camera->z_far = eff->camera->visibility; if (eff->camera->z_far<=0) { eff->camera->z_far = INT2FIX(1000); /*use the current graph pm settings, NOT the viewpoint one*/#ifdef GPAC_FIXED_POINT if (eff->is_pixel_metrics) eff->camera->z_far = FIX_MAX/40;#else if (eff->is_pixel_metrics) eff->camera->z_far = gf_mulfix(eff->camera->z_far , eff->min_hsize);#endif } if (vp) { /*now check if vp is in pixel metrics. If not then: - either it's in the main scene, there's nothing to do - or it's in an inline, and the inline has been scaled if main scene is in pm: nothing to do*/ if (0 && gf_sg_use_pixel_metrics(gf_node_get_graph(vp))) { GF_Matrix mx; gf_mx_init(mx); gf_mx_add_scale(&mx, eff->min_hsize, eff->min_hsize, eff->min_hsize); gf_mx_apply_vec(&mx, &position); gf_mx_apply_vec(&mx, &local_center); } } /*default VP setup - this is undocumented in the spec. Default VP pos is (0, 0, 10) but not really nice in pixel metrics. We set z so that we see just the whole surface*/ else if (eff->is_pixel_metrics) { position.z = gf_divfix(eff->camera->width, 2*gf_tan(fieldOfView/2) ); } gf_vec_diff(d, position, local_center); dist = gf_vec_len(d); if (!dist || (dist<eff->camera->z_near) || (dist > eff->camera->z_far)) { if (dist > eff->camera->z_far) eff->camera->z_far = 2*dist; dist = 10 * eff->camera->avatar_size.x; if ((dist<eff->camera->z_near) || (dist > eff->camera->z_far)) dist = (eff->camera->avatar_size.x + eff->camera->z_far) / 5; } eff->camera->vp_dist = dist; eff->camera->vp_position = position; eff->camera->vp_orientation = orientation; eff->camera->vp_fov = fieldOfView; eff->camera->examine_center = local_center; camera_reset_viewpoint(eff->camera, animate_change); gf_sr_invalidate(eff->surface->render->compositor, NULL);}void R3D_ResetCamera(Render3D *sr){ GF_Camera *cam; if (sr->active_layer) { cam = l3d_get_camera(sr->active_layer); } else { cam = &sr->surface->camera; } camera_reset_viewpoint(cam, 1); gf_sr_invalidate(sr->compositor, NULL);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -