Index: source/blender/editors/space_view3d/view3d_ops.c =================================================================== --- source/blender/editors/space_view3d/view3d_ops.c (revision 57888) +++ source/blender/editors/space_view3d/view3d_ops.c (working copy) @@ -138,6 +138,7 @@ WM_operatortype_append(VIEW3D_OT_view_all); WM_operatortype_append(VIEW3D_OT_viewnumpad); WM_operatortype_append(VIEW3D_OT_view_orbit); + WM_operatortype_append(VIEW3D_OT_view_roll); WM_operatortype_append(VIEW3D_OT_view_pan); WM_operatortype_append(VIEW3D_OT_view_persportho); WM_operatortype_append(VIEW3D_OT_background_image_add); @@ -274,7 +275,9 @@ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD4, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD6, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", PAD8, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANUP); - + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", PAD6, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANRIGHT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "type", V3D_VIEW_PANLEFT); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_pan", WHEELUPMOUSE, KM_PRESS, KM_SHIFT, 0)->ptr, "type", V3D_VIEW_PANUP); @@ -285,6 +288,9 @@ RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELUPMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPUP); RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_orbit", WHEELDOWNMOUSE, KM_PRESS, KM_SHIFT | KM_ALT, 0)->ptr, "type", V3D_VIEW_STEPDOWN); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELUPMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPLEFT); + RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_roll", WHEELDOWNMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0)->ptr, "type", V3D_VIEW_STEPRIGHT); + /* active aligned, replaces '*' key in 2.4x */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, KM_SHIFT, 0); RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_FRONT); Index: source/blender/editors/space_view3d/view3d_intern.h =================================================================== --- source/blender/editors/space_view3d/view3d_intern.h (revision 57888) +++ source/blender/editors/space_view3d/view3d_intern.h (working copy) @@ -94,6 +94,7 @@ void VIEW3D_OT_background_image_add(struct wmOperatorType *ot); void VIEW3D_OT_background_image_remove(struct wmOperatorType *ot); void VIEW3D_OT_view_orbit(struct wmOperatorType *ot); +void VIEW3D_OT_view_roll(struct wmOperatorType *ot); void VIEW3D_OT_clip_border(struct wmOperatorType *ot); void VIEW3D_OT_cursor3d(struct wmOperatorType *ot); void VIEW3D_OT_manipulator(struct wmOperatorType *ot); Index: source/blender/editors/space_view3d/view3d_edit.c =================================================================== --- source/blender/editors/space_view3d/view3d_edit.c (revision 57888) +++ source/blender/editors/space_view3d/view3d_edit.c (working copy) @@ -3499,6 +3499,67 @@ ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); } +static EnumPropertyItem prop_view_roll_items[] = { + {V3D_VIEW_STEPLEFT, "ROLLLEFT", 0, "Roll Left", "Roll the view around to the Left"}, + {V3D_VIEW_STEPRIGHT, "ROLLRIGHT", 0, "Roll Right", "Roll the view around to the Right"}, + {0, NULL, 0, NULL, NULL} +}; + +static int viewroll_exec(bContext *C, wmOperator *op) +{ + View3D *v3d; + ARegion *ar; + RegionView3D *rv3d; + + /* ED call also checks view is not locked */ + if (ED_view3d_context_user_region(C, &v3d, &ar)) { + rv3d = ar->regiondata; + if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { + int orbitdir = RNA_enum_get(op->ptr, "type"); + float quat_mul[4]; + float quat_new[4]; + + if (ELEM(orbitdir, V3D_VIEW_STEPLEFT, V3D_VIEW_STEPRIGHT)) { + float angle = DEG2RADF((float)U.pad_rot_angle); + + if (orbitdir == V3D_VIEW_STEPRIGHT) { + angle = -angle; + } + + /* camera axis */ + axis_angle_to_quat(quat_mul, rv3d->viewinv[2], angle); + } + + mul_qt_qtqt(quat_new, rv3d->viewquat, quat_mul); + rv3d->view = RV3D_VIEW_USER; + + view3d_smooth_view(C, CTX_wm_view3d(C), ar, NULL, NULL, NULL, quat_new, NULL, NULL); + + return OPERATOR_FINISHED; + } + } + + return OPERATOR_CANCELLED; +} + +void VIEW3D_OT_view_roll(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "View Roll"; + ot->description = "Roll the view"; + ot->idname = "VIEW3D_OT_view_roll"; + + /* api callbacks */ + ot->exec = viewroll_exec; + ot->poll = ED_operator_rv3d_user_region_poll; + + /* flags */ + ot->flag = 0; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_roll_items, 0, "Roll", "Direction of View Roll"); +} + static EnumPropertyItem prop_view_pan_items[] = { {V3D_VIEW_PANLEFT, "PANLEFT", 0, "Pan Left", "Pan the view to the Left"}, {V3D_VIEW_PANRIGHT, "PANRIGHT", 0, "Pan Right", "Pan the view to the Right"},