From 8d163d597652aec1f2ca926ba978447dd8476619 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 22 Jan 2020 02:51:01 +1100 Subject: Docs: describe turn-table gimble lock mitigation --- source/blender/editors/space_view3d/view3d_edit.c | 27 ++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'source/blender/editors/space_view3d/view3d_edit.c') diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 3dcde401216..a4714249da2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -758,7 +758,32 @@ static void viewrotate_apply(ViewOpsData *vod, const int event_xy[2]) quat_to_mat3(m, vod->curr.viewquat); invert_m3_m3(m_inv, m); - /* avoid gimble lock */ + /* Avoid Gimble Lock + * + * Even though turn-table mode is in use, this can occur when the user exits the camera view + * or when aligning the view to a rotated object. + * + * We have gimble lock when the user's view is rotated +/- 90 degrees along the view axis. + * In this case the vertical rotation is the same as the sideways turntable motion. + * Making it impossible to get out of the gimble locked state without resetting the view. + * + * The logic below lets the user exit out of this state without any abrupt 'fix' + * which would be disorienting. + * + * This works by blending two horizons: + * - Rotated-horizon: `cross_v3_v3v3(xaxis, zvec_global, m_inv[2])` + * When only this is used, this turntable rotation works - but it's side-ways + * (as if the entire turn-table has been placed on it's side) + * While there is no gimble lock, it's also awkward to use. + * - Un-rotated-horizon: `m_inv[0]` + * When only this is used, the turntable rotation can have gimbal lock. + * + * The solution used here is to blend between these two values, + * so the severity of the gimbal lock is used to blend the rotated horizon. + * Blending isn't essential, it just makes the transition smoother. + * + * This allows sideways turn-table rotation on a Z axis that isn't world-space Z, + * While up-down turntable rotation eventually corrects gimble lock. */ #if 1 if (len_squared_v3v3(zvec_global, m_inv[2]) > 0.001f) { float fac; -- cgit v1.2.3