3DView: Use "real" angle for viewport roll
Since its introduction in {rB5c569d227b64}, the view roll was based on horizontal movement only. Using a "real" angle not only feels more natural but also has the benefit of getting more precission the further away from the center you are (just like regular rotation, brush/stencil rotation etc.). A similar thing has already been implemented in the Grease Pencil Tools Addon, now make the blender standard roll the same. Since this is not using the transform system, we are still lacking a line in the viewport (this could be added but since this is always based on the center of the view we dont necessarily need this), as well as the additional Shift-extra-precission behavior. Fixes T89883 Maniphest Tasks: T89883 Differential Revision: https://developer.blender.org/D12582
This commit is contained in:
parent
8dcddbcc07
commit
69893ef27c
Notes:
blender-bot
2023-02-14 05:53:42 +01:00
Referenced by commit 2a0db195c9
, Fix viewport roll working wrong
Referenced by issue #96299, Rolling the viewport always use last selection as pivot point
Referenced by issue #89883, Bug? Inconsistency? Viewport roll use horizontal move instead angle
|
@ -38,6 +38,7 @@
|
|||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_dial_2d.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
@ -210,6 +211,9 @@ typedef struct ViewOpsData {
|
|||
* If we want the value before running the operator, add a separate member.
|
||||
*/
|
||||
char persp;
|
||||
|
||||
/** Used for roll */
|
||||
Dial *dial;
|
||||
} init;
|
||||
|
||||
/** Previous state (previous modal event handled). */
|
||||
|
@ -577,6 +581,10 @@ static void viewops_data_free(bContext *C, wmOperator *op)
|
|||
WM_event_remove_timer(CTX_wm_manager(C), vod->timer->win, vod->timer);
|
||||
}
|
||||
|
||||
if (vod->init.dial) {
|
||||
MEM_SAFE_FREE(vod->init.dial);
|
||||
}
|
||||
|
||||
MEM_freeN(vod);
|
||||
op->customdata = NULL;
|
||||
}
|
||||
|
@ -4352,18 +4360,9 @@ static void view_roll_angle(
|
|||
rv3d->view = RV3D_VIEW_USER;
|
||||
}
|
||||
|
||||
static void viewroll_apply(ViewOpsData *vod, int x, int UNUSED(y))
|
||||
static void viewroll_apply(ViewOpsData *vod, int x, int y)
|
||||
{
|
||||
float angle = 0.0;
|
||||
|
||||
{
|
||||
float len1, len2, tot;
|
||||
|
||||
tot = vod->region->winrct.xmax - vod->region->winrct.xmin;
|
||||
len1 = (vod->region->winrct.xmax - x) / tot;
|
||||
len2 = (vod->region->winrct.xmax - vod->init.event_xy[0]) / tot;
|
||||
angle = (len1 - len2) * (float)M_PI * 4.0f;
|
||||
}
|
||||
float angle = BLI_dial_angle(vod->init.dial, (const float[2]){x, y});
|
||||
|
||||
if (angle != 0.0f) {
|
||||
view_roll_angle(vod->region, vod->rv3d->viewquat, vod->init.quat, vod->init.mousevec, angle);
|
||||
|
@ -4517,6 +4516,10 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
viewops_data_alloc(C, op);
|
||||
viewops_data_create(C, op, event, viewops_flag_from_prefs());
|
||||
vod = op->customdata;
|
||||
vod->init.dial = BLI_dial_init(
|
||||
(const float[2]){(vod->region->winrct.xmax - vod->region->winrct.xmin) / 2,
|
||||
(vod->region->winrct.ymax - vod->region->winrct.ymin) / 2},
|
||||
FLT_EPSILON);
|
||||
|
||||
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->region);
|
||||
|
||||
|
|
Loading…
Reference in New Issue