View3D: remove orbit snapping LUT, allow to snap axis but not roll
This commit is contained in:
@@ -311,6 +311,7 @@ struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval
|
||||
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
|
||||
void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
|
||||
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
|
||||
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
|
||||
char ED_view3d_lock_view_from_index(int index);
|
||||
bool ED_view3d_lock(struct RegionView3D *rv3d);
|
||||
|
||||
|
||||
@@ -695,56 +695,6 @@ static void viewops_data_free(bContext *C, wmOperator *op)
|
||||
|
||||
/* ************************** viewrotate **********************************/
|
||||
|
||||
#define COS45 0.7071068
|
||||
#define SIN45 COS45
|
||||
|
||||
#define NUM_SNAP_QUATS 39
|
||||
|
||||
static const float snapquats[NUM_SNAP_QUATS][5] = {
|
||||
/*{q0, q1, q3, q4, view}*/
|
||||
{COS45, -SIN45, 0.0, 0.0, RV3D_VIEW_FRONT},
|
||||
{0.0, 0.0, -SIN45, -SIN45, RV3D_VIEW_BACK},
|
||||
{1.0, 0.0, 0.0, 0.0, RV3D_VIEW_TOP},
|
||||
{0.0, -1.0, 0.0, 0.0, RV3D_VIEW_BOTTOM},
|
||||
{0.5, -0.5, -0.5, -0.5, RV3D_VIEW_RIGHT},
|
||||
{0.5, -0.5, 0.5, 0.5, RV3D_VIEW_LEFT},
|
||||
|
||||
/* some more 45 deg snaps */
|
||||
{ 0.6532815, -0.6532815, 0.2705981, 0.2705981, 0},
|
||||
{ 0.9238795, 0.0, 0.0, 0.3826834, 0},
|
||||
{ 0.0, -0.9238795, 0.3826834, 0.0, 0},
|
||||
{ 0.3535534, -0.8535534, 0.3535534, 0.1464466, 0},
|
||||
{ 0.8535534, -0.3535534, 0.1464466, 0.3535534, 0},
|
||||
{ 0.4999999, -0.4999999, 0.5, 0.5, 0},
|
||||
{ 0.2705980, -0.6532815, 0.6532815, 0.2705980, 0},
|
||||
{ 0.6532815, -0.2705980, 0.2705980, 0.6532815, 0},
|
||||
{ 0.2705978, -0.2705980, 0.6532814, 0.6532814, 0},
|
||||
{ 0.3826834, 0.0, 0.0, 0.9238794, 0},
|
||||
{ 0.0, -0.3826834, 0.9238794, 0.0, 0},
|
||||
{ 0.1464466, -0.3535534, 0.8535534, 0.3535534, 0},
|
||||
{ 0.3535534, -0.1464466, 0.3535534, 0.8535534, 0},
|
||||
{ 0.0, 0.0, 0.9238794, 0.3826834, 0},
|
||||
{-0.0, 0.0, 0.3826834, 0.9238794, 0},
|
||||
{-0.2705980, 0.2705980, 0.6532813, 0.6532813, 0},
|
||||
{-0.3826834, 0.0, 0.0, 0.9238794, 0},
|
||||
{ 0.0, 0.3826834, 0.9238794, 0.0, 0},
|
||||
{-0.1464466, 0.3535534, 0.8535533, 0.3535533, 0},
|
||||
{-0.3535534, 0.1464466, 0.3535533, 0.8535533, 0},
|
||||
{-0.4999999, 0.4999999, 0.4999999, 0.4999999, 0},
|
||||
{-0.2705980, 0.6532815, 0.6532814, 0.2705980, 0},
|
||||
{-0.6532815, 0.2705980, 0.2705980, 0.6532814, 0},
|
||||
{-0.6532813, 0.6532813, 0.2705979, 0.2705979, 0},
|
||||
{-0.9238793, 0.0, 0.0, 0.3826833, 0},
|
||||
{ 0.0, 0.9238793, 0.3826833, 0.0, 0},
|
||||
{-0.3535533, 0.8535533, 0.3535533, 0.1464466, 0},
|
||||
{-0.8535533, 0.3535533, 0.1464466, 0.3535533, 0},
|
||||
{-0.3826833, 0.9238794, 0.0, 0.0, 0},
|
||||
{-0.9238794, 0.3826833, 0.0, 0.0, 0},
|
||||
{-COS45, 0.0, 0.0, SIN45, 0},
|
||||
{ COS45, 0.0, 0.0, SIN45, 0},
|
||||
{ 0.0, 0.0, 0.0, 1.0, 0}
|
||||
};
|
||||
|
||||
enum {
|
||||
VIEW_PASS = 0,
|
||||
VIEW_APPLY,
|
||||
@@ -818,6 +768,108 @@ static void viewrotate_apply_dyn_ofs(ViewOpsData *vod, const float viewquat[4])
|
||||
}
|
||||
}
|
||||
|
||||
static void viewrotate_apply_snap(ViewOpsData *vod)
|
||||
{
|
||||
const float axis_limit = DEG2RADF(45 / 3);
|
||||
|
||||
RegionView3D *rv3d = vod->rv3d;
|
||||
|
||||
float viewquat_inv[4];
|
||||
float zaxis[3] = {0, 0, 1};
|
||||
float zaxis_best[3];
|
||||
int x, y, z;
|
||||
bool found = false;
|
||||
|
||||
invert_qt_qt(viewquat_inv, vod->viewquat);
|
||||
|
||||
mul_qt_v3(viewquat_inv, zaxis);
|
||||
normalize_v3(zaxis);
|
||||
|
||||
|
||||
for (x = -1; x < 2; x++) {
|
||||
for (y = -1; y < 2; y++) {
|
||||
for (z = -1; z < 2; z++) {
|
||||
if (x || y || z) {
|
||||
float zaxis_test[3] = {x, y, z};
|
||||
|
||||
normalize_v3(zaxis_test);
|
||||
|
||||
if (angle_normalized_v3v3(zaxis_test, zaxis) < axis_limit) {
|
||||
copy_v3_v3(zaxis_best, zaxis_test);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
|
||||
/* find the best roll */
|
||||
float quat_roll[4], quat_final[4], quat_best[4], quat_snap[4];
|
||||
float viewquat_align[4]; /* viewquat aligned to zaxis_best */
|
||||
float viewquat_align_inv[4]; /* viewquat aligned to zaxis_best */
|
||||
float best_angle = axis_limit;
|
||||
int j;
|
||||
|
||||
/* viewquat_align is the original viewquat aligned to the snapped axis
|
||||
* for testing roll */
|
||||
rotation_between_vecs_to_quat(viewquat_align, zaxis_best, zaxis);
|
||||
normalize_qt(viewquat_align);
|
||||
mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align);
|
||||
normalize_qt(viewquat_align);
|
||||
invert_qt_qt(viewquat_align_inv, viewquat_align);
|
||||
|
||||
vec_to_quat(quat_snap, zaxis_best, OB_NEGZ, OB_POSY);
|
||||
invert_qt(quat_snap);
|
||||
normalize_qt(quat_snap);
|
||||
|
||||
/* check if we can find the roll */
|
||||
found = false;
|
||||
|
||||
/* find best roll */
|
||||
for (j = 0; j < 8; j++) {
|
||||
float angle;
|
||||
float xaxis1[3] = {1, 0, 0};
|
||||
float xaxis2[3] = {1, 0, 0};
|
||||
float quat_final_inv[4];
|
||||
|
||||
axis_angle_to_quat(quat_roll, zaxis_best, (float)j * DEG2RADF(45.0f));
|
||||
normalize_qt(quat_roll);
|
||||
|
||||
mul_qt_qtqt(quat_final, quat_snap, quat_roll);
|
||||
normalize_qt(quat_final);
|
||||
|
||||
/* compare 2 vector angles to find the least roll */
|
||||
invert_qt_qt(quat_final_inv, quat_final);
|
||||
mul_qt_v3(viewquat_align_inv, xaxis1);
|
||||
mul_qt_v3(quat_final_inv, xaxis2);
|
||||
angle = angle_v3v3(xaxis1, xaxis2);
|
||||
|
||||
if (angle <= best_angle) {
|
||||
found = true;
|
||||
best_angle = angle;
|
||||
copy_qt_qt(quat_best, quat_final);
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
/* lock 'quat_best' to an axis view if we can */
|
||||
rv3d->view = ED_view3d_quat_to_axis_view(quat_best, 0.01f);
|
||||
if (rv3d->view != RV3D_VIEW_USER) {
|
||||
ED_view3d_quat_from_axis_view(rv3d->view, quat_best);
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_qt_qt(quat_best, viewquat_align);
|
||||
}
|
||||
|
||||
copy_qt_qt(rv3d->viewquat, quat_best);
|
||||
|
||||
viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
|
||||
}
|
||||
}
|
||||
|
||||
static void viewrotate_apply(ViewOpsData *vod, int x, int y)
|
||||
{
|
||||
RegionView3D *rv3d = vod->rv3d;
|
||||
@@ -916,72 +968,7 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
|
||||
/* check for view snap,
|
||||
* note: don't apply snap to vod->viewquat so the view wont jam up */
|
||||
if (vod->axis_snap) {
|
||||
int i;
|
||||
float viewquat_inv[4];
|
||||
float zaxis[3] = {0, 0, 1};
|
||||
invert_qt_qt(viewquat_inv, vod->viewquat);
|
||||
|
||||
mul_qt_v3(viewquat_inv, zaxis);
|
||||
|
||||
for (i = 0; i < NUM_SNAP_QUATS; i++) {
|
||||
|
||||
float view = (int)snapquats[i][4];
|
||||
float viewquat_inv_test[4];
|
||||
float zaxis_test[3] = {0, 0, 1};
|
||||
|
||||
invert_qt_qt(viewquat_inv_test, snapquats[i]);
|
||||
mul_qt_v3(viewquat_inv_test, zaxis_test);
|
||||
|
||||
if (angle_v3v3(zaxis_test, zaxis) < DEG2RADF(45 / 3)) {
|
||||
/* find the best roll */
|
||||
float quat_roll[4], quat_final[4], quat_best[4];
|
||||
float viewquat_align[4]; /* viewquat aligned to zaxis_test */
|
||||
float viewquat_align_inv[4]; /* viewquat aligned to zaxis_test */
|
||||
float best_angle = FLT_MAX;
|
||||
int j;
|
||||
|
||||
/* viewquat_align is the original viewquat aligned to the snapped axis
|
||||
* for testing roll */
|
||||
rotation_between_vecs_to_quat(viewquat_align, zaxis_test, zaxis);
|
||||
normalize_qt(viewquat_align);
|
||||
mul_qt_qtqt(viewquat_align, vod->viewquat, viewquat_align);
|
||||
normalize_qt(viewquat_align);
|
||||
invert_qt_qt(viewquat_align_inv, viewquat_align);
|
||||
|
||||
/* find best roll */
|
||||
for (j = 0; j < 8; j++) {
|
||||
float angle;
|
||||
float xaxis1[3] = {1, 0, 0};
|
||||
float xaxis2[3] = {1, 0, 0};
|
||||
float quat_final_inv[4];
|
||||
|
||||
axis_angle_to_quat(quat_roll, zaxis_test, (float)j * DEG2RADF(45.0f));
|
||||
normalize_qt(quat_roll);
|
||||
|
||||
mul_qt_qtqt(quat_final, snapquats[i], quat_roll);
|
||||
normalize_qt(quat_final);
|
||||
|
||||
/* compare 2 vector angles to find the least roll */
|
||||
invert_qt_qt(quat_final_inv, quat_final);
|
||||
mul_qt_v3(viewquat_align_inv, xaxis1);
|
||||
mul_qt_v3(quat_final_inv, xaxis2);
|
||||
angle = angle_v3v3(xaxis1, xaxis2);
|
||||
|
||||
if (angle <= best_angle) {
|
||||
best_angle = angle;
|
||||
copy_qt_qt(quat_best, quat_final);
|
||||
if (j) view = 0; /* view grid assumes certain up axis */
|
||||
}
|
||||
}
|
||||
|
||||
copy_qt_qt(rv3d->viewquat, quat_best);
|
||||
rv3d->view = view; /* if we snap to a rolled camera the grid is invalid */
|
||||
|
||||
viewrotate_apply_dyn_ofs(vod, rv3d->viewquat);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
viewrotate_apply_snap(vod);
|
||||
}
|
||||
vod->oldx = x;
|
||||
vod->oldy = y;
|
||||
|
||||
@@ -831,39 +831,40 @@ static void obmat_to_viewmat(RegionView3D *rv3d, Object *ob)
|
||||
mat3_to_quat(rv3d->viewquat, tmat);
|
||||
}
|
||||
|
||||
static float view3d_quat_axis[6][4] = {
|
||||
{M_SQRT1_2, -M_SQRT1_2, 0.0f, 0.0f}, /* RV3D_VIEW_FRONT */
|
||||
{0.0f, 0.0f, -M_SQRT1_2, -M_SQRT1_2}, /* RV3D_VIEW_BACK */
|
||||
{0.5f, -0.5f, 0.5f, 0.5f}, /* RV3D_VIEW_LEFT */
|
||||
{0.5f, -0.5f, -0.5f, -0.5f}, /* RV3D_VIEW_RIGHT */
|
||||
{1.0f, 0.0f, 0.0f, 0.0f}, /* RV3D_VIEW_TOP */
|
||||
{0.0f, -1.0f, 0.0f, 0.0f}, /* RV3D_VIEW_BOTTOM */
|
||||
};
|
||||
|
||||
|
||||
bool ED_view3d_quat_from_axis_view(const char view, float quat[4])
|
||||
{
|
||||
if (RV3D_VIEW_IS_AXIS(view)) {
|
||||
copy_qt_qt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon)
|
||||
{
|
||||
/* quat values are all unit length */
|
||||
|
||||
switch (view) {
|
||||
case RV3D_VIEW_BOTTOM:
|
||||
copy_v4_fl4(quat, 0.0, -1.0, 0.0, 0.0);
|
||||
break;
|
||||
char view;
|
||||
|
||||
case RV3D_VIEW_BACK:
|
||||
copy_v4_fl4(quat, 0.0, 0.0, -M_SQRT1_2, -M_SQRT1_2);
|
||||
break;
|
||||
|
||||
case RV3D_VIEW_LEFT:
|
||||
copy_v4_fl4(quat, 0.5, -0.5, 0.5, 0.5);
|
||||
break;
|
||||
|
||||
case RV3D_VIEW_TOP:
|
||||
copy_v4_fl4(quat, 1.0, 0.0, 0.0, 0.0);
|
||||
break;
|
||||
|
||||
case RV3D_VIEW_FRONT:
|
||||
copy_v4_fl4(quat, M_SQRT1_2, -M_SQRT1_2, 0.0, 0.0);
|
||||
break;
|
||||
|
||||
case RV3D_VIEW_RIGHT:
|
||||
copy_v4_fl4(quat, 0.5, -0.5, -0.5, -0.5);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
for (view = RV3D_VIEW_FRONT; view <= RV3D_VIEW_BOTTOM; view++) {
|
||||
if (angle_qtqt(quat, view3d_quat_axis[view - RV3D_VIEW_FRONT]) < epsilon) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return RV3D_VIEW_USER;
|
||||
}
|
||||
|
||||
char ED_view3d_lock_view_from_index(int index)
|
||||
|
||||
Reference in New Issue
Block a user