Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2020-08-02 11:08:46 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-08-02 11:10:07 +0300
commitf349a53c0815b7b6e5f7b432b10a4eeebe266341 (patch)
tree8e6c39419b0559766e1acddab1562f7fe7a5d31b /source/blender/editors/space_view3d/view3d_camera_control.c
parent70d7805fa901d9678db3557f6e81877b6b94128a (diff)
Fix T78691: Fly/Walk navigation ignores object channel locks
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_camera_control.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_camera_control.c64
1 files changed, 58 insertions, 6 deletions
diff --git a/source/blender/editors/space_view3d/view3d_camera_control.c b/source/blender/editors/space_view3d/view3d_camera_control.c
index 7e63d650409..1d5b33e7b90 100644
--- a/source/blender/editors/space_view3d/view3d_camera_control.c
+++ b/source/blender/editors/space_view3d/view3d_camera_control.c
@@ -198,6 +198,56 @@ struct View3DCameraControl *ED_view3d_cameracontrol_acquire(Depsgraph *depsgraph
}
/**
+ * A version of #BKE_object_apply_mat4 that respects #Object.protectflag,
+ * applying the locking back to the view to avoid the view.
+ * This is needed so the view doesn't get out of sync with the object,
+ * causing visible jittering when in fly/walk mode for e.g.
+ *
+ * \note This could be exposed as an API option, as we might not want the view
+ * to be constrained by the thing it's controlling.
+ */
+static bool object_apply_mat4_with_protect(Object *ob,
+ const float obmat[4][4],
+ const bool use_parent,
+ /* Only use when applying lock. */
+ RegionView3D *rv3d,
+ const float view_mat[4][4])
+{
+ const bool use_protect = (ob->protectflag != 0);
+ bool view_changed = false;
+
+ ObjectTfmProtectedChannels obtfm;
+ if (use_protect) {
+ BKE_object_tfm_protected_backup(ob, &obtfm);
+ }
+
+ BKE_object_apply_mat4(ob, obmat, true, use_parent);
+
+ if (use_protect) {
+ float obmat_noprotect[4][4], obmat_protect[4][4];
+
+ BKE_object_to_mat4(ob, obmat_noprotect);
+ BKE_object_tfm_protected_restore(ob, &obtfm, ob->protectflag);
+ BKE_object_to_mat4(ob, obmat_protect);
+
+ if (!equals_m4m4(obmat_noprotect, obmat_protect)) {
+ /* Apply the lock protection back to the view, without this the view
+ * keeps moving, ignoring the object locking, causing jittering in some cases. */
+ float diff_mat[4][4];
+ float view_mat_protect[4][4];
+ float obmat_noprotect_inv[4][4];
+ invert_m4_m4(obmat_noprotect_inv, obmat_noprotect);
+ mul_m4_m4m4(diff_mat, obmat_protect, obmat_noprotect_inv);
+
+ mul_m4_m4m4(view_mat_protect, diff_mat, view_mat);
+ ED_view3d_from_m4(view_mat_protect, rv3d->ofs, rv3d->viewquat, &rv3d->dist);
+ view_changed = true;
+ }
+ }
+ return view_changed;
+}
+
+/**
* Updates cameras from the ``rv3d`` values, optionally auto-keyframing.
*/
void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
@@ -216,21 +266,25 @@ void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
ID *id_key;
+ float view_mat[4][4];
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+
/* transform the parent or the camera? */
if (vctrl->root_parent) {
Object *ob_update;
- float view_mat[4][4];
float prev_view_imat[4][4];
float diff_mat[4][4];
float parent_mat[4][4];
invert_m4_m4(prev_view_imat, vctrl->view_mat_prev);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
mul_m4_m4m4(diff_mat, view_mat, prev_view_imat);
mul_m4_m4m4(parent_mat, diff_mat, vctrl->root_parent->obmat);
- BKE_object_apply_mat4(vctrl->root_parent, parent_mat, true, false);
+ if (object_apply_mat4_with_protect(vctrl->root_parent, parent_mat, false, rv3d, view_mat)) {
+ /* Calculate again since the view locking changes the matrix. */
+ ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
+ }
ob_update = v3d->camera->parent;
while (ob_update) {
@@ -243,18 +297,16 @@ void ED_view3d_cameracontrol_update(View3DCameraControl *vctrl,
id_key = &vctrl->root_parent->id;
}
else {
- float view_mat[4][4];
float scale_mat[4][4];
float scale_back[3];
/* even though we handle the scale matrix, this still changes over time */
copy_v3_v3(scale_back, v3d->camera->scale);
- ED_view3d_to_m4(view_mat, rv3d->ofs, rv3d->viewquat, rv3d->dist);
size_to_mat4(scale_mat, v3d->camera->scale);
mul_m4_m4m4(view_mat, view_mat, scale_mat);
- BKE_object_apply_mat4(v3d->camera, view_mat, true, true);
+ object_apply_mat4_with_protect(v3d->camera, view_mat, true, rv3d, view_mat);
DEG_id_tag_update(&v3d->camera->id, ID_RECALC_TRANSFORM);