Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_view3d/view3d_walk.c
| Show All 34 Lines | |||||
| #include "BLI_blenlib.h" | #include "BLI_blenlib.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_report.h" | #include "BKE_report.h" | ||||
| #include "BLT_translation.h" | #include "BLT_translation.h" | ||||
| #include "RNA_access.h" | |||||
| #include "RNA_define.h" | |||||
| #include "RNA_types.h" | |||||
| #include "BIF_gl.h" | #include "BIF_gl.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "ED_space_api.h" | #include "ED_space_api.h" | ||||
| Show All 37 Lines | enum { | ||||
| WALK_MODAL_JUMP, | WALK_MODAL_JUMP, | ||||
| WALK_MODAL_JUMP_STOP, | WALK_MODAL_JUMP_STOP, | ||||
| WALK_MODAL_TELEPORT, | WALK_MODAL_TELEPORT, | ||||
| WALK_MODAL_TOGGLE, | WALK_MODAL_TOGGLE, | ||||
| WALK_MODAL_ACCELERATE, | WALK_MODAL_ACCELERATE, | ||||
| WALK_MODAL_DECELERATE, | WALK_MODAL_DECELERATE, | ||||
| }; | }; | ||||
| enum { | typedef enum { | ||||
| WALK_BIT_FORWARD = 1 << 0, | WALK_BIT_FORWARD = 1 << 0, | ||||
| WALK_BIT_BACKWARD = 1 << 1, | WALK_BIT_BACKWARD = 1 << 1, | ||||
| WALK_BIT_LEFT = 1 << 2, | WALK_BIT_LEFT = 1 << 2, | ||||
| WALK_BIT_RIGHT = 1 << 3, | WALK_BIT_RIGHT = 1 << 3, | ||||
| WALK_BIT_UP = 1 << 4, | WALK_BIT_UP = 1 << 4, | ||||
| WALK_BIT_DOWN = 1 << 5, | WALK_BIT_DOWN = 1 << 5, | ||||
| }; | } eWalkDirectionFlag; | ||||
| typedef enum eWalkTeleportState { | typedef enum eWalkTeleportState { | ||||
| WALK_TELEPORT_STATE_OFF = 0, | WALK_TELEPORT_STATE_OFF = 0, | ||||
| WALK_TELEPORT_STATE_ON, | WALK_TELEPORT_STATE_ON, | ||||
| } eWalkTeleportState; | } eWalkTeleportState; | ||||
| typedef enum eWalkMethod { | typedef enum eWalkMethod { | ||||
| WALK_MODE_FREE = 0, | WALK_MODE_FREE = 0, | ||||
| WALK_MODE_GRAVITY, | WALK_MODE_GRAVITY, | ||||
| } eWalkMethod; | } eWalkMethod; | ||||
| typedef enum eWalkGravityState { | typedef enum eWalkGravityState { | ||||
| WALK_GRAVITY_STATE_OFF = 0, | WALK_GRAVITY_STATE_OFF = 0, | ||||
| WALK_GRAVITY_STATE_JUMP, | WALK_GRAVITY_STATE_JUMP, | ||||
| WALK_GRAVITY_STATE_START, | WALK_GRAVITY_STATE_START, | ||||
| WALK_GRAVITY_STATE_ON, | WALK_GRAVITY_STATE_ON, | ||||
| } eWalkGravityState; | } eWalkGravityState; | ||||
| typedef enum eWalkMouseMode { | |||||
| WALK_MOUSE_LOOKAROUND = 0, | |||||
| WALK_MOUSE_MOVEHORIZONTAL, | |||||
| WALK_MOUSE_MOVEVERTICAL, | |||||
| WALK_MOUSE_NULL, | |||||
| } eWalkMouseMode; | |||||
| /* called in transform_ops.c, on each regeneration of keymaps */ | /* called in transform_ops.c, on each regeneration of keymaps */ | ||||
| void walk_modal_keymap(wmKeyConfig *keyconf) | void walk_modal_keymap(wmKeyConfig *keyconf) | ||||
| { | { | ||||
| static EnumPropertyItem modal_items[] = { | static EnumPropertyItem modal_items[] = { | ||||
| {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, | {WALK_MODAL_CANCEL, "CANCEL", 0, "Cancel", ""}, | ||||
| {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, | {WALK_MODAL_CONFIRM, "CONFIRM", 0, "Confirm", ""}, | ||||
| {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, | {WALK_MODAL_ACCELERATE, "ACCELERATE", 0, "Accelerate", ""}, | ||||
| ▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | typedef struct WalkInfo { | ||||
| ARegion *ar; | ARegion *ar; | ||||
| Scene *scene; | Scene *scene; | ||||
| wmTimer *timer; /* needed for redraws */ | wmTimer *timer; /* needed for redraws */ | ||||
| short state; | short state; | ||||
| bool redraw; | bool redraw; | ||||
| int init_mval[2]; /* initial 2D mouse values */ | |||||
| int prev_mval[2]; /* previous 2D mouse values */ | int prev_mval[2]; /* previous 2D mouse values */ | ||||
| int center_mval[2]; /* center mouse values */ | int center_mval[2]; /* center mouse values */ | ||||
| int moffset[2]; | int moffset[2]; | ||||
| wmNDOFMotionData *ndof; /* latest 3D mouse values */ | wmNDOFMotionData *ndof; /* latest 3D mouse values */ | ||||
| /* walk state state */ | /* walk state state */ | ||||
| float base_speed; /* the base speed without run/slow down modifications */ | float base_speed; /* the base speed without run/slow down modifications */ | ||||
| float speed; /* the speed the view is moving per redraw */ | float speed; /* the speed the view is moving per redraw */ | ||||
| float grid; /* world scale 1.0 default */ | float grid; /* world scale 1.0 default */ | ||||
| /* compare between last state */ | /* compare between last state */ | ||||
| double time_lastdraw; /* time between draws */ | double time_lastdraw; /* time between draws */ | ||||
| void *draw_handle_pixel; | void *draw_handle_pixel; | ||||
| /* use for some lag */ | /* use for some lag */ | ||||
| float dvec_prev[3]; /* old for some lag */ | float dvec_prev[3]; /* old for some lag */ | ||||
| /* walk/fly */ | /* walk/fly */ | ||||
| eWalkMethod navigation_mode; | eWalkMethod navigation_mode; | ||||
| eWalkMouseMode mouse_mode; | |||||
| bool use_mouse; | |||||
| /* teleport */ | /* teleport */ | ||||
| WalkTeleport teleport; | WalkTeleport teleport; | ||||
| /* look speed factor - user preferences */ | /* look speed factor - user preferences */ | ||||
| float mouse_speed; | float mouse_speed; | ||||
| /* speed adjustments */ | /* speed adjustments */ | ||||
| bool is_fast; | bool is_fast; | ||||
| ▲ Show 20 Lines • Show All 109 Lines • ▼ Show 20 Lines | if (mode == WALK_MODE_FREE) { | ||||
| walk->navigation_mode = WALK_MODE_FREE; | walk->navigation_mode = WALK_MODE_FREE; | ||||
| walk->gravity_state = WALK_GRAVITY_STATE_OFF; | walk->gravity_state = WALK_GRAVITY_STATE_OFF; | ||||
| } | } | ||||
| else { /* WALK_MODE_GRAVITY */ | else { /* WALK_MODE_GRAVITY */ | ||||
| walk->navigation_mode = WALK_MODE_GRAVITY; | walk->navigation_mode = WALK_MODE_GRAVITY; | ||||
| walk->gravity_state = WALK_GRAVITY_STATE_START; | walk->gravity_state = WALK_GRAVITY_STATE_START; | ||||
| } | } | ||||
| if (walk->use_mouse) { | |||||
| walk_update_header(C, op, walk); | walk_update_header(C, op, walk); | ||||
| } | } | ||||
| } | |||||
| /** | /** | ||||
| * \param r_distance Distance to the hit point | * \param r_distance Distance to the hit point | ||||
| */ | */ | ||||
| static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance) | static bool walk_floor_distance_get(bContext *C, RegionView3D *rv3d, WalkInfo *walk, const float dvec[3], float *r_distance) | ||||
| { | { | ||||
| float dummy_dist_px = 0; | float dummy_dist_px = 0; | ||||
| float ray_normal[3] = {0, 0, -1}; /* down */ | float ray_normal[3] = {0, 0, -1}; /* down */ | ||||
| ▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | enum { | ||||
| WALK_CANCEL = 1, | WALK_CANCEL = 1, | ||||
| WALK_CONFIRM = 2, | WALK_CONFIRM = 2, | ||||
| }; | }; | ||||
| /* keep the previous speed until user changes userpreferences */ | /* keep the previous speed until user changes userpreferences */ | ||||
| static float base_speed = -1.f; | static float base_speed = -1.f; | ||||
| static float userdef_speed = -1.f; | static float userdef_speed = -1.f; | ||||
| static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op) | static bool initWalkInfo(bContext *C, WalkInfo *walk, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| wmWindow *win = CTX_wm_window(C); | wmWindow *win = CTX_wm_window(C); | ||||
| walk->rv3d = CTX_wm_region_view3d(C); | walk->rv3d = CTX_wm_region_view3d(C); | ||||
| walk->v3d = CTX_wm_view3d(C); | walk->v3d = CTX_wm_view3d(C); | ||||
| walk->ar = CTX_wm_region(C); | walk->ar = CTX_wm_region(C); | ||||
| walk->scene = CTX_data_scene(C); | walk->scene = CTX_data_scene(C); | ||||
| Show All 28 Lines | if (fabsf(U.walk_navigation.walk_speed - userdef_speed) > 0.1f) { | ||||
| userdef_speed = U.walk_navigation.walk_speed; | userdef_speed = U.walk_navigation.walk_speed; | ||||
| } | } | ||||
| walk->speed = 0.0f; | walk->speed = 0.0f; | ||||
| walk->is_fast = false; | walk->is_fast = false; | ||||
| walk->is_slow = false; | walk->is_slow = false; | ||||
| walk->grid = 1.f / walk->scene->unit.scale_length; | walk->grid = 1.f / walk->scene->unit.scale_length; | ||||
| walk->mouse_mode = RNA_enum_get(op->ptr, "mouse_mode"); | |||||
| walk->use_mouse = walk->mouse_mode != WALK_MOUSE_NULL; | |||||
| /* user preference settings */ | /* user preference settings */ | ||||
| walk->teleport.duration = U.walk_navigation.teleport_time; | walk->teleport.duration = U.walk_navigation.teleport_time; | ||||
| walk->mouse_speed = U.walk_navigation.mouse_speed; | walk->mouse_speed = U.walk_navigation.mouse_speed; | ||||
| if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) | if ((U.walk_navigation.flag & USER_WALK_GRAVITY)) | ||||
| walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY); | walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY); | ||||
| else | else | ||||
| walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE); | walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE); | ||||
| Show All 28 Lines | #endif | ||||
| zero_v3(walk->dvec_prev); | zero_v3(walk->dvec_prev); | ||||
| walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); | walk->timer = WM_event_add_timer(CTX_wm_manager(C), win, TIMER, 0.01f); | ||||
| walk->ndof = NULL; | walk->ndof = NULL; | ||||
| walk->time_lastdraw = PIL_check_seconds_timer(); | walk->time_lastdraw = PIL_check_seconds_timer(); | ||||
| walk->draw_handle_pixel = ED_region_draw_cb_activate(walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL); | walk->draw_handle_pixel = NULL; | ||||
| walk->rv3d->rflag |= RV3D_NAVIGATING; | walk->rv3d->rflag |= RV3D_NAVIGATING; | ||||
| walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( | walk->v3d_camera_control = ED_view3d_cameracontrol_acquire( | ||||
| walk->scene, walk->v3d, walk->rv3d, | walk->scene, walk->v3d, walk->rv3d, | ||||
| (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); | (U.uiflag & USER_CAM_LOCK_NO_PARENT) == 0); | ||||
| /* center the mouse */ | /* center the mouse */ | ||||
| walk->center_mval[0] = walk->ar->winx * 0.5f; | walk->center_mval[0] = walk->ar->winx * 0.5f; | ||||
| walk->center_mval[1] = walk->ar->winy * 0.5f; | walk->center_mval[1] = walk->ar->winy * 0.5f; | ||||
| copy_v2_v2_int(walk->prev_mval, walk->center_mval); | copy_v2_v2_int(walk->prev_mval, walk->center_mval); | ||||
| /* store the initial mouse positions */ | |||||
| walk->init_mval[0] = event->x; | |||||
| walk->init_mval[1] = event->y; | |||||
| if (walk->use_mouse) { | |||||
| walk->draw_handle_pixel = ED_region_draw_cb_activate(walk->ar->type, drawWalkPixel, walk, REGION_DRAW_POST_PIXEL); | |||||
| WM_cursor_warp(win, | WM_cursor_warp(win, | ||||
| walk->ar->winrct.xmin + walk->center_mval[0], | walk->ar->winrct.xmin + walk->center_mval[0], | ||||
| walk->ar->winrct.ymin + walk->center_mval[1]); | walk->ar->winrct.ymin + walk->center_mval[1]); | ||||
| /* remove the mouse cursor temporarily */ | /* remove the mouse cursor temporarily */ | ||||
| WM_cursor_modal_set(win, CURSOR_NONE); | WM_cursor_modal_set(win, CURSOR_NONE); | ||||
| } | |||||
| return 1; | return true; | ||||
| } | } | ||||
| static int walkEnd(bContext *C, WalkInfo *walk) | static int walkEnd(bContext *C, WalkInfo *walk) | ||||
| { | { | ||||
| wmWindow *win; | wmWindow *win; | ||||
| RegionView3D *rv3d; | RegionView3D *rv3d; | ||||
| if (walk->state == WALK_RUNNING) | if ((walk->use_mouse == false) && (walk->active_directions == 0)) { | ||||
| walk->state = WALK_CONFIRM; | |||||
| } | |||||
| else if (walk->state == WALK_RUNNING) { | |||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | |||||
| #ifdef NDOF_WALK_DEBUG | #ifdef NDOF_WALK_DEBUG | ||||
| puts("\n-- walk end --"); | puts("\n-- walk end --"); | ||||
| #endif | #endif | ||||
| win = CTX_wm_window(C); | win = CTX_wm_window(C); | ||||
| rv3d = walk->rv3d; | rv3d = walk->rv3d; | ||||
| WM_event_remove_timer(CTX_wm_manager(C), win, walk->timer); | |||||
| ED_region_draw_cb_exit(walk->ar->type, walk->draw_handle_pixel); | |||||
| ED_view3d_cameracontrol_release(walk->v3d_camera_control, walk->state == WALK_CANCEL); | ED_view3d_cameracontrol_release(walk->v3d_camera_control, walk->state == WALK_CANCEL); | ||||
| rv3d->rflag &= ~RV3D_NAVIGATING; | rv3d->rflag &= ~RV3D_NAVIGATING; | ||||
| if (walk->ndof) | if (walk->ndof) | ||||
| MEM_freeN(walk->ndof); | MEM_freeN(walk->ndof); | ||||
| /* restore the cursor */ | WM_event_remove_timer(CTX_wm_manager(C), win, walk->timer); | ||||
| WM_cursor_modal_restore(win); | |||||
| #ifdef USE_TABLET_SUPPORT | #ifdef USE_TABLET_SUPPORT | ||||
| if (walk->is_cursor_absolute == false) | if ((walk->is_cursor_absolute == false) && | ||||
| (walk->use_mouse)) | |||||
| #endif | #endif | ||||
| { | { | ||||
| /* center the mouse */ | ED_region_draw_cb_exit(walk->ar->type, walk->draw_handle_pixel); | ||||
| WM_cursor_warp( | |||||
| win, | /* restore the cursor */ | ||||
| walk->ar->winrct.xmin + walk->center_mval[0], | WM_cursor_modal_restore(win); | ||||
| walk->ar->winrct.ymin + walk->center_mval[1]); | |||||
| /* restore the mouse position */ | |||||
| WM_cursor_warp(win, walk->init_mval[0], walk->init_mval[1]); | |||||
| } | } | ||||
| if (walk->state == WALK_CONFIRM) { | if (walk->state == WALK_CONFIRM) { | ||||
| MEM_freeN(walk); | MEM_freeN(walk); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| MEM_freeN(walk); | MEM_freeN(walk); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| static bool wm_event_is_last_mousemove(const wmEvent *event) | static bool wm_event_is_last_mousemove(const wmEvent *event) | ||||
| { | { | ||||
| while ((event = event->next)) { | while ((event = event->next)) { | ||||
| if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { | if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE, MOUSEPAN)) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| return true; | return true; | ||||
| } | } | ||||
| static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent *event) | static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent *event) | ||||
| { | { | ||||
| if (event->type == TIMER && event->customdata == walk->timer) { | if (event->type == TIMER && event->customdata == walk->timer) { | ||||
| walk->redraw = true; | walk->redraw = true; | ||||
| } | } | ||||
| else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { | |||||
| #ifdef USE_TABLET_SUPPORT | |||||
| if (walk->is_cursor_first) { | |||||
| /* wait until we get the 'warp' event */ | |||||
| if ((walk->center_mval[0] == event->mval[0]) && | |||||
| (walk->center_mval[1] == event->mval[1])) | |||||
| { | |||||
| walk->is_cursor_first = false; | |||||
| } | |||||
| else { | |||||
| /* note, its possible the system isn't giving us the warp event | |||||
| * ideally we shouldn't have to worry about this, see: T45361 */ | |||||
| wmWindow *win = CTX_wm_window(C); | |||||
| WM_cursor_warp(win, | |||||
| walk->ar->winrct.xmin + walk->center_mval[0], | |||||
| walk->ar->winrct.ymin + walk->center_mval[1]); | |||||
| } | |||||
| return; | |||||
| } | |||||
| if ((walk->is_cursor_absolute == false) && WM_event_is_absolute(event)) { | |||||
| walk->is_cursor_absolute = true; | |||||
| copy_v2_v2_int(walk->prev_mval, event->mval); | |||||
| copy_v2_v2_int(walk->center_mval, event->mval); | |||||
| /* without this we can't turn 180d */ | |||||
| CLAMP_MIN(walk->mouse_speed, 4.0f); | |||||
| } | |||||
| #endif /* USE_TABLET_SUPPORT */ | |||||
| walk->moffset[0] += event->mval[0] - walk->prev_mval[0]; | |||||
| walk->moffset[1] += event->mval[1] - walk->prev_mval[1]; | |||||
| copy_v2_v2_int(walk->prev_mval, event->mval); | |||||
| if ((walk->center_mval[0] != event->mval[0]) || | |||||
| (walk->center_mval[1] != event->mval[1])) | |||||
| { | |||||
| walk->redraw = true; | |||||
| #ifdef USE_TABLET_SUPPORT | |||||
| if (walk->is_cursor_absolute) { | |||||
| /* pass */ | |||||
| } | |||||
| else | |||||
| #endif | |||||
| if (wm_event_is_last_mousemove(event)) { | |||||
| wmWindow *win = CTX_wm_window(C); | |||||
| #ifdef __APPLE__ | |||||
| if ((abs(walk->prev_mval[0] - walk->center_mval[0]) > walk->center_mval[0] / 2) || | |||||
| (abs(walk->prev_mval[1] - walk->center_mval[1]) > walk->center_mval[1] / 2)) | |||||
| #endif | |||||
| { | |||||
| WM_cursor_warp(win, | |||||
| walk->ar->winrct.xmin + walk->center_mval[0], | |||||
| walk->ar->winrct.ymin + walk->center_mval[1]); | |||||
| copy_v2_v2_int(walk->prev_mval, walk->center_mval); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| else if (event->type == NDOF_MOTION) { | |||||
| /* do these automagically get delivered? yes. */ | |||||
| // puts("ndof motion detected in walk mode!"); | |||||
| // static const char *tag_name = "3D mouse position"; | |||||
| const wmNDOFMotionData *incoming_ndof = event->customdata; | |||||
| switch (incoming_ndof->progress) { | |||||
| case P_STARTING: | |||||
| /* start keeping track of 3D mouse position */ | |||||
| #ifdef NDOF_WALK_DEBUG | |||||
| puts("start keeping track of 3D mouse position"); | |||||
| #endif | |||||
| /* fall-through */ | |||||
| case P_IN_PROGRESS: | |||||
| /* update 3D mouse position */ | |||||
| #ifdef NDOF_WALK_DEBUG | |||||
| putchar('.'); fflush(stdout); | |||||
| #endif | |||||
| if (walk->ndof == NULL) { | |||||
| // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name); | |||||
| walk->ndof = MEM_dupallocN(incoming_ndof); | |||||
| // walk->ndof = malloc(sizeof(wmNDOFMotionData)); | |||||
| } | |||||
| else { | |||||
| memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData)); | |||||
| } | |||||
| break; | |||||
| case P_FINISHING: | |||||
| /* stop keeping track of 3D mouse position */ | |||||
| #ifdef NDOF_WALK_DEBUG | |||||
| puts("stop keeping track of 3D mouse position"); | |||||
| #endif | |||||
| if (walk->ndof) { | |||||
| MEM_freeN(walk->ndof); | |||||
| // free(walk->ndof); | |||||
| walk->ndof = NULL; | |||||
| } | |||||
| /* update the time else the view will jump when 2D mouse/timer resume */ | |||||
| walk->time_lastdraw = PIL_check_seconds_timer(); | |||||
| break; | |||||
| default: | |||||
| break; /* should always be one of the above 3 */ | |||||
| } | |||||
| } | |||||
| /* handle modal keymap first */ | /* handle modal keymap first */ | ||||
| else if (event->type == EVT_MODAL_MAP) { | else if (event->type == EVT_MODAL_MAP) { | ||||
| switch (event->val) { | switch (event->val) { | ||||
| case WALK_MODAL_CANCEL: | case WALK_MODAL_CANCEL: | ||||
| walk->state = WALK_CANCEL; | walk->state = WALK_CANCEL; | ||||
| break; | break; | ||||
| case WALK_MODAL_CONFIRM: | case WALK_MODAL_CONFIRM: | ||||
| walk->state = WALK_CONFIRM; | walk->state = WALK_CONFIRM; | ||||
| ▲ Show 20 Lines • Show All 145 Lines • ▼ Show 20 Lines | #undef JUMP_SPEED_MIN | ||||
| walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE); | walk_navigation_mode_set(C, op, walk, WALK_MODE_FREE); | ||||
| } | } | ||||
| else { /* WALK_MODE_FREE */ | else { /* WALK_MODE_FREE */ | ||||
| walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY); | walk_navigation_mode_set(C, op, walk, WALK_MODE_GRAVITY); | ||||
| } | } | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE, MOUSEPAN)) { | |||||
| int xy[2], prevxy[2]; | |||||
| #ifdef USE_TABLET_SUPPORT | |||||
| if (walk->is_cursor_first) { | |||||
| /* wait until we get the 'warp' event */ | |||||
| if ((walk->center_mval[0] == event->mval[0]) && | |||||
| (walk->center_mval[1] == event->mval[1])) | |||||
| { | |||||
| walk->is_cursor_first = false; | |||||
| } | |||||
| else { | |||||
| /* note, its possible the system isn't giving us the warp event | |||||
| * ideally we shouldn't have to worry about this, see: T45361 */ | |||||
| wmWindow *win = CTX_wm_window(C); | |||||
| WM_cursor_warp(win, | |||||
| walk->ar->winrct.xmin + walk->center_mval[0], | |||||
| walk->ar->winrct.ymin + walk->center_mval[1]); | |||||
| } | |||||
| return; | |||||
| } | |||||
| if ((walk->is_cursor_absolute == false) && WM_event_is_absolute(event)) { | |||||
| walk->is_cursor_absolute = true; | |||||
| copy_v2_v2_int(walk->prev_mval, event->mval); | |||||
| copy_v2_v2_int(walk->center_mval, event->mval); | |||||
| /* without this we can't turn 180d */ | |||||
| CLAMP_MIN(walk->mouse_speed, 4.0f); | |||||
| } | |||||
| #endif /* USE_TABLET_SUPPORT */ | |||||
| xy[0] = event->x; | |||||
| xy[1] = event->y; | |||||
| prevxy[0] = event->prevx; | |||||
| prevxy[1] = event->prevy; | |||||
| if ((event->type == MOUSEPAN) && U.uiflag2 & USER_TRACKPAD_NATURAL) { | |||||
| negate_v2_int(xy); | |||||
| negate_v2_int(prevxy); | |||||
| } | |||||
| walk->moffset[0] += xy[0] - prevxy[0]; | |||||
| walk->moffset[1] += xy[1] - prevxy[1]; | |||||
| copy_v2_v2_int(walk->prev_mval, xy); | |||||
| if ((walk->center_mval[0] != event->mval[0]) || | |||||
| (walk->center_mval[1] != event->mval[1])) | |||||
| { | |||||
| walk->redraw = true; | |||||
| #ifdef USE_TABLET_SUPPORT | |||||
| if (walk->is_cursor_absolute) { | |||||
| /* pass */ | |||||
| } | |||||
| else | |||||
| #endif | |||||
| if (wm_event_is_last_mousemove(event) && walk->use_mouse) { | |||||
| wmWindow *win = CTX_wm_window(C); | |||||
| #ifdef __APPLE__ | |||||
| if ((abs(walk->prev_mval[0] - walk->center_mval[0]) > walk->center_mval[0] / 2) || | |||||
| (abs(walk->prev_mval[1] - walk->center_mval[1]) > walk->center_mval[1] / 2)) | |||||
| #endif | |||||
| { | |||||
| WM_cursor_warp(win, | |||||
| walk->ar->winrct.xmin + walk->center_mval[0], | |||||
| walk->ar->winrct.ymin + walk->center_mval[1]); | |||||
| copy_v2_v2_int(walk->prev_mval, walk->center_mval); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| else if (event->type == NDOF_MOTION) { | |||||
| /* do these automagically get delivered? yes. */ | |||||
| // puts("ndof motion detected in walk mode!"); | |||||
| // static const char *tag_name = "3D mouse position"; | |||||
| const wmNDOFMotionData *incoming_ndof = event->customdata; | |||||
| switch (incoming_ndof->progress) { | |||||
| case P_STARTING: | |||||
| /* start keeping track of 3D mouse position */ | |||||
| #ifdef NDOF_WALK_DEBUG | |||||
| puts("start keeping track of 3D mouse position"); | |||||
| #endif | |||||
| /* fall-through */ | |||||
| case P_IN_PROGRESS: | |||||
| /* update 3D mouse position */ | |||||
| #ifdef NDOF_WALK_DEBUG | |||||
| putchar('.'); fflush(stdout); | |||||
| #endif | |||||
| if (walk->ndof == NULL) { | |||||
| // walk->ndof = MEM_mallocN(sizeof(wmNDOFMotionData), tag_name); | |||||
| walk->ndof = MEM_dupallocN(incoming_ndof); | |||||
| // walk->ndof = malloc(sizeof(wmNDOFMotionData)); | |||||
| } | |||||
| else { | |||||
| memcpy(walk->ndof, incoming_ndof, sizeof(wmNDOFMotionData)); | |||||
| } | |||||
| break; | |||||
| case P_FINISHING: | |||||
| /* stop keeping track of 3D mouse position */ | |||||
| #ifdef NDOF_WALK_DEBUG | |||||
| puts("stop keeping track of 3D mouse position"); | |||||
| #endif | |||||
| if (walk->ndof) { | |||||
| MEM_freeN(walk->ndof); | |||||
| // free(walk->ndof); | |||||
| walk->ndof = NULL; | |||||
| } | |||||
| /* update the time else the view will jump when 2D mouse/timer resume */ | |||||
| walk->time_lastdraw = PIL_check_seconds_timer(); | |||||
| break; | |||||
| default: | |||||
| break; /* should always be one of the above 3 */ | |||||
| } | |||||
| } | |||||
| } | } | ||||
| static void walkMoveCamera(bContext *C, WalkInfo *walk, | static void walkMoveCamera(bContext *C, WalkInfo *walk, | ||||
| const bool do_rotate, const bool do_translate) | const bool do_rotate, const bool do_translate) | ||||
| { | { | ||||
| ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate); | ED_view3d_cameracontrol_update(walk->v3d_camera_control, true, C, do_rotate, do_translate); | ||||
| } | } | ||||
| static float getFreeFallDistance(const float gravity, const float time) | static float getFreeFallDistance(const float gravity, const float time) | ||||
| { | { | ||||
| return gravity * (time * time) * 0.5f; | return gravity * (time * time) * 0.5f; | ||||
| } | } | ||||
| static float getVelocityZeroTime(const float gravity, const float velocity) | static float getVelocityZeroTime(const float gravity, const float velocity) | ||||
| { | { | ||||
| return velocity / gravity; | return velocity / gravity; | ||||
| } | } | ||||
| static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk) | |||||
| { | |||||
| #define WALK_ROTATE_FAC 2.2f /* more is faster */ | #define WALK_ROTATE_FAC 2.2f /* more is faster */ | ||||
| #define WALK_TOP_LIMIT DEG2RADF(85.0f) | #define WALK_TOP_LIMIT DEG2RADF(85.0f) | ||||
| #define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f) | #define WALK_BOTTOM_LIMIT DEG2RADF(-80.0f) | ||||
| #define WALK_MOVE_SPEED base_speed | #define WALK_MOVE_SPEED base_speed | ||||
| #define WALK_BOOST_FACTOR ((void)0, walk->speed_factor) | #define WALK_BOOST_FACTOR ((void)0, walk->speed_factor) | ||||
| /* rotate about the Y axis- look left/right */ | |||||
| static void walk_mouse_rotate_horizontal(ARegion *ar, RegionView3D *rv3d, const float mouse_speed, int moffset[2], float r_mat[3][3], float r_upvec[3]) | |||||
| { | |||||
| float x; | |||||
| float tmp_quat[4]; | |||||
| /* if we're upside down invert the moffset */ | |||||
| copy_v3_fl3(r_upvec, 0.0f, 1.0f, 0.0f); | |||||
| mul_m3_v3(r_mat, r_upvec); | |||||
| if (r_upvec[2] < 0.0f) | |||||
| moffset[0] = -moffset[0]; | |||||
| /* relative offset */ | |||||
| x = (float) moffset[0] / ar->winx; | |||||
| /* speed factor */ | |||||
| x *= WALK_ROTATE_FAC; | |||||
| /* user adjustement factor */ | |||||
| x *= mouse_speed; | |||||
| copy_v3_fl3(r_upvec, 0.0f, 0.0f, 1.0f); | |||||
| /* Rotate about the relative up vec */ | |||||
| axis_angle_normalized_to_quat(tmp_quat, r_upvec, x); | |||||
| mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); | |||||
| } | |||||
| /* rotate about the X axis- look up/down */ | |||||
| static void walk_mouse_rotate_vertical(ARegion *ar, RegionView3D *rv3d, const float mouse_speed, int moffset[2], float r_mat[3][3], float r_upvec[3]) | |||||
| { | |||||
| float angle, y; | |||||
| float tmp_quat[4]; | |||||
| /* relative offset */ | |||||
| y = (float) moffset[1] / ar->winy; | |||||
| /* speed factor */ | |||||
| y *= WALK_ROTATE_FAC; | |||||
| /* user adjustement factor */ | |||||
| y *= mouse_speed; | |||||
| /* clamp the angle limits */ | |||||
| /* it ranges from 90.0f to -90.0f */ | |||||
| angle = -asinf(rv3d->viewmat[2][2]); | |||||
| if (angle > WALK_TOP_LIMIT && y > 0.0f) | |||||
| y = 0.0f; | |||||
| else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) | |||||
| y = 0.0f; | |||||
| copy_v3_fl3(r_upvec, 1.0f, 0.0f, 0.0f); | |||||
| mul_m3_v3(r_mat, r_upvec); | |||||
| /* Rotate about the relative up vec */ | |||||
| axis_angle_to_quat(tmp_quat, r_upvec, -y); | |||||
| mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); | |||||
| } | |||||
| static void walk_forward(float mat[3][3], const float speed, | |||||
| const bool is_world_forward, float r_dvec[3]) | |||||
| { | |||||
| float dvec_tmp[3] = {0.0f, 0.0f, speed}; | |||||
| mul_m3_v3(mat, dvec_tmp); | |||||
| if (is_world_forward) | |||||
| dvec_tmp[2] = 0.0f; | |||||
| normalize_v3(dvec_tmp); | |||||
| mul_v3_fl(dvec_tmp, fabsf(speed)); | |||||
| add_v3_v3(r_dvec, dvec_tmp); | |||||
| } | |||||
| static void walk_sideways(const float viewinvmat[4][4], const float speed, float r_dvec[3]) | |||||
| { | |||||
| float dvec_tmp[3] = {viewinvmat[0][0], | |||||
| viewinvmat[0][1], | |||||
| 0.0f}; | |||||
| normalize_v3(dvec_tmp); | |||||
| mul_v3_fl(dvec_tmp, speed); | |||||
| add_v3_v3(r_dvec, dvec_tmp); | |||||
| } | |||||
| static void walk_updown(const float speed, float r_dvec[3]) | |||||
| { | |||||
| float dvec_tmp[3] = {0.0f, 0.0f, speed}; | |||||
| add_v3_v3(r_dvec, dvec_tmp); | |||||
| } | |||||
| static void walk_mouse_move(WalkInfo *walk, float mat[3][3], const eWalkDirectionFlag direction, const float time_redraw, float r_dvec[3]) | |||||
| { | |||||
| const float speed = walk->speed * time_redraw; | |||||
| switch (direction) { | |||||
| case WALK_BIT_UP: | |||||
| walk_updown(-speed, r_dvec); | |||||
| break; | |||||
| case WALK_BIT_DOWN: | |||||
| walk_updown(speed, r_dvec); | |||||
| break; | |||||
| case WALK_BIT_LEFT: | |||||
| walk_sideways(walk->rv3d->viewinv, speed, r_dvec); | |||||
| break; | |||||
| case WALK_BIT_RIGHT: | |||||
| walk_sideways(walk->rv3d->viewinv, -speed, r_dvec); | |||||
| break; | |||||
| case WALK_BIT_FORWARD: | |||||
| walk_forward(mat, speed, true, r_dvec); | |||||
| break; | |||||
| case WALK_BIT_BACKWARD: | |||||
| walk_forward(mat, -speed, true, r_dvec); | |||||
| break; | |||||
| default: | |||||
| break; | |||||
| } | |||||
| } | |||||
| static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk) | |||||
| { | |||||
| /* walk mode - Ctrl+Shift+F | /* walk mode - Ctrl+Shift+F | ||||
| * a walk loop where the user can move move the view as if they are in a walk game | * a walk loop where the user can move move the view as if they are in a walk game | ||||
| */ | */ | ||||
| RegionView3D *rv3d = walk->rv3d; | RegionView3D *rv3d = walk->rv3d; | ||||
| ARegion *ar = walk->ar; | ARegion *ar = walk->ar; | ||||
| float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */ | float mat[3][3]; /* 3x3 copy of the view matrix so we can move along the view axis */ | ||||
| float dvec[3] = {0.0f, 0.0f, 0.0f}; /* this is the direction that's added to the view offset per redraw */ | float dvec[3] = {0.0f, 0.0f, 0.0f}; /* this is the direction that's added to the view offset per redraw */ | ||||
| /* Camera Uprighting variables */ | /* Camera Uprighting variables */ | ||||
| float upvec[3] = {0.0f, 0.0f, 0.0f}; /* stores the view's up vector */ | float upvec[3] = {0.0f, 0.0f, 0.0f}; /* stores the view's up vector */ | ||||
| int moffset[2]; /* mouse offset from the views center */ | int moffset[2]; /* mouse offset from the views center */ | ||||
| float tmp_quat[4]; /* used for rotating the view */ | |||||
| #ifdef NDOF_WALK_DEBUG | #ifdef NDOF_WALK_DEBUG | ||||
| { | { | ||||
| static unsigned int iteration = 1; | static unsigned int iteration = 1; | ||||
| printf("walk timer %d\n", iteration++); | printf("walk timer %d\n", iteration++); | ||||
| } | } | ||||
| #endif | #endif | ||||
| Show All 37 Lines | #endif | ||||
| walk->speed *= WALK_BOOST_FACTOR; | walk->speed *= WALK_BOOST_FACTOR; | ||||
| } | } | ||||
| else if (walk->is_slow) { | else if (walk->is_slow) { | ||||
| walk->speed *= 1.0f / WALK_BOOST_FACTOR; | walk->speed *= 1.0f / WALK_BOOST_FACTOR; | ||||
| } | } | ||||
| copy_m3_m4(mat, rv3d->viewinv); | copy_m3_m4(mat, rv3d->viewinv); | ||||
| switch (walk->mouse_mode) { | |||||
| case WALK_MOUSE_NULL: | |||||
| { | { | ||||
| /* rotate about the X axis- look up/down */ | /* used when we enter the operator with an arrow key directly */ | ||||
| if (moffset[1]) { | break; | ||||
| float angle; | |||||
| float y; | |||||
| /* relative offset */ | |||||
| y = (float) moffset[1] / ar->winy; | |||||
| /* speed factor */ | |||||
| y *= WALK_ROTATE_FAC; | |||||
| /* user adjustement factor */ | |||||
| y *= walk->mouse_speed; | |||||
| /* clamp the angle limits */ | |||||
| /* it ranges from 90.0f to -90.0f */ | |||||
| angle = -asinf(rv3d->viewmat[2][2]); | |||||
| if (angle > WALK_TOP_LIMIT && y > 0.0f) | |||||
| y = 0.0f; | |||||
| else if (angle < WALK_BOTTOM_LIMIT && y < 0.0f) | |||||
| y = 0.0f; | |||||
| copy_v3_fl3(upvec, 1.0f, 0.0f, 0.0f); | |||||
| mul_m3_v3(mat, upvec); | |||||
| /* Rotate about the relative up vec */ | |||||
| axis_angle_to_quat(tmp_quat, upvec, -y); | |||||
| mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); | |||||
| } | } | ||||
| case WALK_MOUSE_MOVEHORIZONTAL: | |||||
| { | |||||
| if (moffset[0]) | |||||
| walk_mouse_rotate_horizontal(ar, rv3d, walk->mouse_speed, moffset, mat, upvec); | |||||
| /* rotate about the Y axis- look left/right */ | if (moffset[1] > 0) | ||||
| if (moffset[0]) { | walk_mouse_move(walk, mat, WALK_BIT_FORWARD, time_redraw, dvec); | ||||
| float x; | else if (moffset[1] < 0) | ||||
| walk_mouse_move(walk, mat, WALK_BIT_BACKWARD, time_redraw, dvec); | |||||
| /* if we're upside down invert the moffset */ | |||||
| copy_v3_fl3(upvec, 0.0f, 1.0f, 0.0f); | |||||
| mul_m3_v3(mat, upvec); | |||||
| if (upvec[2] < 0.0f) | |||||
| moffset[0] = -moffset[0]; | |||||
| /* relative offset */ | break; | ||||
| x = (float) moffset[0] / ar->winx; | } | ||||
| case WALK_MOUSE_MOVEVERTICAL: | |||||
| { | |||||
| /* if we both movements at the same time the effect is too unstable */ | |||||
| const bool is_vertical = (abs(moffset[1]) - abs(moffset[0])) > 0; | |||||
| /* speed factor */ | if (is_vertical) { | ||||
| x *= WALK_ROTATE_FAC; | if (moffset[1] > 0) | ||||
| walk_mouse_move(walk, mat, WALK_BIT_UP, time_redraw, dvec); | |||||
| else if (moffset[1] < 0) | |||||
| walk_mouse_move(walk, mat, WALK_BIT_DOWN, time_redraw, dvec); | |||||
| } | |||||
| else { | |||||
| if (moffset[0] > 0) | |||||
| walk_mouse_move(walk, mat, WALK_BIT_RIGHT, time_redraw, dvec); | |||||
| else if (moffset[0] < 0) | |||||
| walk_mouse_move(walk, mat, WALK_BIT_LEFT, time_redraw, dvec); | |||||
| } | |||||
| /* user adjustement factor */ | break; | ||||
| x *= walk->mouse_speed; | } | ||||
| case WALK_MOUSE_LOOKAROUND: | |||||
| default: | |||||
| { | |||||
| if (moffset[1]) | |||||
| walk_mouse_rotate_vertical(ar, rv3d, walk->mouse_speed, moffset, mat, upvec); | |||||
| copy_v3_fl3(upvec, 0.0f, 0.0f, 1.0f); | if (moffset[0]) | ||||
| walk_mouse_rotate_horizontal(ar, rv3d, walk->mouse_speed, moffset, mat, upvec); | |||||
| /* Rotate about the relative up vec */ | break; | ||||
| axis_angle_normalized_to_quat(tmp_quat, upvec, x); | |||||
| mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, tmp_quat); | |||||
| } | } | ||||
| } | } | ||||
| /* WASD - 'move' translation code */ | /* WASD - 'move' translation code */ | ||||
| if ((walk->active_directions) && | if ((walk->active_directions) && | ||||
| (walk->gravity_state == WALK_GRAVITY_STATE_OFF)) | (walk->gravity_state == WALK_GRAVITY_STATE_OFF)) | ||||
| { | { | ||||
| short direction; | |||||
| zero_v3(dvec); | zero_v3(dvec); | ||||
| /* XOR */ | |||||
| if ((walk->active_directions & WALK_BIT_FORWARD) || | if ((walk->active_directions & WALK_BIT_FORWARD) || | ||||
| (walk->active_directions & WALK_BIT_BACKWARD)) | (walk->active_directions & WALK_BIT_BACKWARD)) | ||||
| { | { | ||||
| if ((walk->active_directions & WALK_BIT_FORWARD) && | |||||
| direction = 0; | (walk->active_directions & WALK_BIT_BACKWARD)) | ||||
| { | |||||
| if ((walk->active_directions & WALK_BIT_FORWARD)) | } | ||||
| direction += 1; | else if ((walk->active_directions & WALK_BIT_FORWARD)) { | ||||
| walk_forward(mat, 1.0f, (walk->navigation_mode == WALK_MODE_GRAVITY), dvec); | |||||
| if ((walk->active_directions & WALK_BIT_BACKWARD)) | } | ||||
| direction -= 1; | else { /* WALK_BIT_BACKWARD */ | ||||
| walk_forward(mat, -1.0f, (walk->navigation_mode == WALK_MODE_GRAVITY), dvec); | |||||
| copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction); | |||||
| mul_m3_v3(mat, dvec_tmp); | |||||
| if (walk->navigation_mode == WALK_MODE_GRAVITY) { | |||||
| dvec_tmp[2] = 0.0f; | |||||
| } | } | ||||
| normalize_v3(dvec_tmp); | |||||
| add_v3_v3(dvec, dvec_tmp); | |||||
| } | } | ||||
| /* XOR */ | |||||
| if ((walk->active_directions & WALK_BIT_LEFT) || | if ((walk->active_directions & WALK_BIT_LEFT) || | ||||
| (walk->active_directions & WALK_BIT_RIGHT)) | (walk->active_directions & WALK_BIT_RIGHT)) | ||||
| { | { | ||||
| if ((walk->active_directions & WALK_BIT_LEFT) && | |||||
| direction = 0; | (walk->active_directions & WALK_BIT_RIGHT)) | ||||
| { | |||||
| if ((walk->active_directions & WALK_BIT_LEFT)) | } | ||||
| direction += 1; | else if ((walk->active_directions & WALK_BIT_LEFT)) { | ||||
| walk_sideways(rv3d->viewinv, 1.0f, dvec); | |||||
| if ((walk->active_directions & WALK_BIT_RIGHT)) | } | ||||
| direction -= 1; | else { /* WALK_BIT_RIGHT */ | ||||
| walk_sideways(rv3d->viewinv, -1.0f, dvec); | |||||
| dvec_tmp[0] = direction * rv3d->viewinv[0][0]; | } | ||||
| dvec_tmp[1] = direction * rv3d->viewinv[0][1]; | |||||
| dvec_tmp[2] = 0.0f; | |||||
| normalize_v3(dvec_tmp); | |||||
| add_v3_v3(dvec, dvec_tmp); | |||||
| } | } | ||||
| /* XOR */ | |||||
| if ((walk->active_directions & WALK_BIT_UP) || | if ((walk->active_directions & WALK_BIT_UP) || | ||||
| (walk->active_directions & WALK_BIT_DOWN)) | (walk->active_directions & WALK_BIT_DOWN)) | ||||
| { | { | ||||
| if ((walk->active_directions & WALK_BIT_UP) && | |||||
| if (walk->navigation_mode == WALK_MODE_FREE) { | (walk->active_directions & WALK_BIT_DOWN)) | ||||
| { | |||||
| direction = 0; | } | ||||
| else if (walk->navigation_mode == WALK_MODE_FREE) { | |||||
| if ((walk->active_directions & WALK_BIT_UP)) | if ((walk->active_directions & WALK_BIT_UP)) { | ||||
| direction -= 1; | walk_updown(-1.0f, dvec); | ||||
| } | |||||
| if ((walk->active_directions & WALK_BIT_DOWN)) | else { /* WALK_BIT_DOWN */ | ||||
| direction = 1; | walk_updown(1.0f, dvec); | ||||
| } | |||||
| copy_v3_fl3(dvec_tmp, 0.0f, 0.0f, direction); | |||||
| add_v3_v3(dvec, dvec_tmp); | |||||
| } | } | ||||
| } | } | ||||
| /* apply movement */ | /* apply movement */ | ||||
| mul_v3_fl(dvec, walk->speed * time_redraw); | mul_v3_fl(dvec, walk->speed * time_redraw); | ||||
| } | } | ||||
| /* stick to the floor */ | /* stick to the floor */ | ||||
| ▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | else { | ||||
| /* we're not redrawing but we need to update the time else the view will jump */ | /* we're not redrawing but we need to update the time else the view will jump */ | ||||
| walk->time_lastdraw = PIL_check_seconds_timer(); | walk->time_lastdraw = PIL_check_seconds_timer(); | ||||
| } | } | ||||
| /* end drawing */ | /* end drawing */ | ||||
| copy_v3_v3(walk->dvec_prev, dvec); | copy_v3_v3(walk->dvec_prev, dvec); | ||||
| } | } | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| #undef WALK_ROTATE_FAC | |||||
| #undef WALK_ZUP_CORRECT_FAC | #undef WALK_ZUP_CORRECT_FAC | ||||
| #undef WALK_ZUP_CORRECT_ACCEL | #undef WALK_ZUP_CORRECT_ACCEL | ||||
| #undef WALK_SMOOTH_FAC | #undef WALK_SMOOTH_FAC | ||||
| } | |||||
| #undef WALK_ROTATE_FAC | |||||
| #undef WALK_TOP_LIMIT | #undef WALK_TOP_LIMIT | ||||
| #undef WALK_BOTTOM_LIMIT | #undef WALK_BOTTOM_LIMIT | ||||
| #undef WALK_MOVE_SPEED | #undef WALK_MOVE_SPEED | ||||
| #undef WALK_BOOST_FACTOR | #undef WALK_BOOST_FACTOR | ||||
| } | |||||
| static void walkApply_ndof(bContext *C, WalkInfo *walk) | static void walkApply_ndof(bContext *C, WalkInfo *walk) | ||||
| { | { | ||||
| Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control); | Object *lock_ob = ED_view3d_cameracontrol_object_get(walk->v3d_camera_control); | ||||
| bool has_translate, has_rotate; | bool has_translate, has_rotate; | ||||
| view3d_ndof_fly(walk->ndof, | view3d_ndof_fly(walk->ndof, | ||||
| walk->v3d, walk->rv3d, | walk->v3d, walk->rv3d, | ||||
| Show All 17 Lines | static int walk_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| if (rv3d->viewlock & RV3D_LOCKED) | if (rv3d->viewlock & RV3D_LOCKED) | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation"); | walk = MEM_callocN(sizeof(WalkInfo), "NavigationWalkOperation"); | ||||
| op->customdata = walk; | op->customdata = walk; | ||||
| if (initWalkInfo(C, walk, op) == false) { | if (initWalkInfo(C, walk, op, event) == false) { | ||||
| MEM_freeN(op->customdata); | MEM_freeN(op->customdata); | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| walkEvent(C, op, walk, event); | walkEvent(C, op, walk, event); | ||||
| if (walk->use_mouse == false) | |||||
| walk->active_directions = RNA_enum_get(op->ptr, "initial_direction"); | |||||
| WM_event_add_modal_handler(C, op); | WM_event_add_modal_handler(C, op); | ||||
| return OPERATOR_RUNNING_MODAL; | return OPERATOR_RUNNING_MODAL; | ||||
| } | } | ||||
| static void walk_cancel(bContext *C, wmOperator *op) | static void walk_cancel(bContext *C, wmOperator *op) | ||||
| { | { | ||||
| WalkInfo *walk = op->customdata; | WalkInfo *walk = op->customdata; | ||||
| ▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | static int walk_modal(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| } | } | ||||
| if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) | if (ELEM(exit_code, OPERATOR_FINISHED, OPERATOR_CANCELLED)) | ||||
| ED_area_headerprint(CTX_wm_area(C), NULL); | ED_area_headerprint(CTX_wm_area(C), NULL); | ||||
| return exit_code; | return exit_code; | ||||
| } | } | ||||
| static EnumPropertyItem walk_navigation_mouse_mode_items[] = { | |||||
| {WALK_MOUSE_LOOKAROUND, "LOOK_AROUND", 0, "Look Around", "Rotates the viewport camera"}, | |||||
| {WALK_MOUSE_MOVEHORIZONTAL, "MOVE_HORIZONTAL", 0, "Move Horizontally", "Moves the camera forward and backward and rotates left and right"}, | |||||
| {WALK_MOUSE_MOVEVERTICAL, "MOVE_VERTICAL", 0, "Move Vertically", "Moves the camera up and down or left and right"}, | |||||
| {WALK_MOUSE_NULL, "NONE", 0, "None", "Mouse movement is not considered"}, | |||||
| {0, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| static EnumPropertyItem walk_navigation_initial_direction_items[] = { | |||||
| {0, "NONE", 0, "None", ""}, | |||||
| {WALK_BIT_FORWARD, "MOVE_FORWARD", 0, "Move Forward", ""}, | |||||
| {WALK_BIT_BACKWARD, "MOVE_BACKWARD", 0, "Move Backward", ""}, | |||||
| {WALK_BIT_LEFT, "MOVE_LEFT", 0, "Move Left", ""}, | |||||
| {WALK_BIT_RIGHT, "MOVE_RIGHT", 0, "Move Right", ""}, | |||||
| {WALK_BIT_UP, "MOVE_UP", 0, "Move Up", ""}, | |||||
| {WALK_BIT_DOWN, "MOVE_DOWN", 0, "Move Down", ""}, | |||||
| {0, NULL, 0, NULL, NULL} | |||||
| }; | |||||
| void VIEW3D_OT_walk(wmOperatorType *ot) | void VIEW3D_OT_walk(wmOperatorType *ot) | ||||
| { | { | ||||
| PropertyRNA *prop; | |||||
| /* identifiers */ | /* identifiers */ | ||||
| ot->name = "Walk Navigation"; | ot->name = "Walk Navigation"; | ||||
| ot->description = "Interactively walk around the scene"; | ot->description = "Interactively walk around the scene"; | ||||
| ot->idname = "VIEW3D_OT_walk"; | ot->idname = "VIEW3D_OT_walk"; | ||||
| /* api callbacks */ | /* api callbacks */ | ||||
| ot->invoke = walk_invoke; | ot->invoke = walk_invoke; | ||||
| ot->cancel = walk_cancel; | ot->cancel = walk_cancel; | ||||
| ot->modal = walk_modal; | ot->modal = walk_modal; | ||||
| ot->poll = ED_operator_view3d_active; | ot->poll = ED_operator_view3d_active; | ||||
| /* flags */ | /* flags */ | ||||
| ot->flag = OPTYPE_BLOCKING; | ot->flag = OPTYPE_BLOCKING; | ||||
| prop = RNA_def_enum(ot->srna, "mouse_mode", walk_navigation_mouse_mode_items, WALK_MOUSE_LOOKAROUND, "Mouse Mode", ""); | |||||
| RNA_def_property_flag(prop, PROP_SKIP_SAVE); | |||||
| prop = RNA_def_enum(ot->srna, "initial_direction", walk_navigation_initial_direction_items, 0, "Initial Direction", ""); | |||||
| RNA_def_property_flag(prop, PROP_SKIP_SAVE); | |||||
| } | } | ||||