diff options
author | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
---|---|---|
committer | Julian Eisel <julian@blender.org> | 2020-06-05 14:09:31 +0300 |
commit | 920a58d9b6d667894cf166cbbd25e4c2fbd238ea (patch) | |
tree | 7ca5a9da640753b5e070c439ac3bdd14dfad92cf /source/blender/editors/object/object_transform.c | |
parent | c94b6209861ca7cc3985b53474feed7d94c0221a (diff) | |
parent | a1d55bdd530390e58c51abe9707b8d3b0ae3e861 (diff) |
Merge branch 'master' into wm-drag-drop-rewritewm-drag-drop-rewrite
Diffstat (limited to 'source/blender/editors/object/object_transform.c')
-rw-r--r-- | source/blender/editors/object/object_transform.c | 69 |
1 files changed, 50 insertions, 19 deletions
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 28bb28a0298..132b530455e 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -1608,6 +1608,7 @@ struct XFormAxisItem { float rot_mat[3][3]; void *obtfm; float xform_dist; + bool is_z_flip; #ifdef USE_RELATIVE_ROTATION /* use when translating multiple */ @@ -1727,14 +1728,19 @@ static void object_apply_location(Object *ob, const float loc[3]) copy_v3_v3(ob->loc, mat[3]); } -static void object_orient_to_location(Object *ob, +static bool object_orient_to_location(Object *ob, const float rot_orig[3][3], const float axis[3], - const float location[3]) + const float location[3], + const bool z_flip) { float delta[3]; sub_v3_v3v3(delta, ob->obmat[3], location); if (normalize_v3(delta) != 0.0f) { + if (z_flip) { + negate_v3(delta); + } + if (len_squared_v3v3(delta, axis) > FLT_EPSILON) { float delta_rot[3][3]; float final_rot[3][3]; @@ -1744,9 +1750,10 @@ static void object_orient_to_location(Object *ob, object_apply_rotation(ob, final_rot); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM); + return true; } } + return false; } static void object_transform_axis_target_cancel(bContext *C, wmOperator *op) @@ -1840,6 +1847,11 @@ static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, cons for (int i = 0; i < xfd->object_data_len; i++, item++) { item->obtfm = BKE_object_tfm_backup(item->ob); BKE_object_rot_to_mat3(item->ob, item->rot_mat, true); + + /* Detect negative scale matrix. */ + float full_mat3[3][3]; + BKE_object_to_mat3(item->ob, full_mat3); + item->is_z_flip = dot_v3v3(item->rot_mat[2], full_mat3[2]) < 0.0f; } } @@ -1860,8 +1872,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const if (event->type == MOUSEMOVE || is_translate_init) { const ViewDepths *depths = xfd->vc.rv3d->depths; - if (depths && ((unsigned int)event->mval[0] < depths->w) && - ((unsigned int)event->mval[1] < depths->h)) { + if (depths && ((uint)event->mval[0] < depths->w) && ((uint)event->mval[1] < depths->h)) { double depth = (double)ED_view3d_depth_read_cached(&xfd->vc, event->mval); float location_world[3]; if (depth == 1.0f) { @@ -1894,9 +1905,9 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const normal_found = true; /* cheap attempt to smooth normals out a bit! */ - const uint ofs = 2; - for (uint x = -ofs; x <= ofs; x += ofs / 2) { - for (uint y = -ofs; y <= ofs; y += ofs / 2) { + const int ofs = 2; + for (int x = -ofs; x <= ofs; x += ofs / 2) { + for (int y = -ofs; y <= ofs; y += ofs / 2) { if (x != 0 && y != 0) { int mval_ofs[2] = {event->mval[0] + x, event->mval[1] + y}; float n[3]; @@ -1913,7 +1924,7 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const normal_found = true; } - if (normal_found) { + { #ifdef USE_RELATIVE_ROTATION if (is_translate_init && xfd->object_data_len > 1) { float xform_rot_offset_inv_first[3][3]; @@ -1942,16 +1953,26 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const item->xform_dist = len_v3v3(item->ob->obmat[3], location_world); normalize_v3_v3(ob_axis, item->ob->obmat[2]); /* Scale to avoid adding distance when moving between surfaces. */ - float scale = fabsf(dot_v3v3(ob_axis, normal)); - item->xform_dist *= scale; + if (normal_found) { + float scale = fabsf(dot_v3v3(ob_axis, normal)); + item->xform_dist *= scale; + } } float target_normal[3]; - copy_v3_v3(target_normal, normal); + + if (normal_found) { + copy_v3_v3(target_normal, normal); + } + else { + normalize_v3_v3(target_normal, item->ob->obmat[2]); + } #ifdef USE_RELATIVE_ROTATION - if (i != 0) { - mul_m3_v3(item->xform_rot_offset, target_normal); + if (normal_found) { + if (i != 0) { + mul_m3_v3(item->xform_rot_offset, target_normal); + } } #endif { @@ -1965,18 +1986,28 @@ static int object_transform_axis_target_modal(bContext *C, wmOperator *op, const } object_orient_to_location( - item->ob, item->rot_mat, item->rot_mat[2], location_world); + item->ob, item->rot_mat, item->rot_mat[2], location_world, item->is_z_flip); + + DEG_id_tag_update(&item->ob->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); } - copy_v3_v3(xfd->prev.normal, normal); - xfd->prev.is_normal_valid = true; + if (normal_found) { + copy_v3_v3(xfd->prev.normal, normal); + xfd->prev.is_normal_valid = true; + } } } else { struct XFormAxisItem *item = xfd->object_data; for (int i = 0; i < xfd->object_data_len; i++, item++) { - object_orient_to_location(item->ob, item->rot_mat, item->rot_mat[2], location_world); - WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + if (object_orient_to_location(item->ob, + item->rot_mat, + item->rot_mat[2], + location_world, + item->is_z_flip)) { + DEG_id_tag_update(&item->ob->id, ID_RECALC_TRANSFORM); + WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, item->ob); + } } xfd->prev.is_normal_valid = false; } |