@@ -388,15 +388,26 @@ private Vector3 RaycastDirection
388388 /// <returns>Quaternion, the orientation to use for the object</returns>
389389 private Quaternion CalculateMagnetismOrientation ( Vector3 direction , Vector3 surfaceNormal )
390390 {
391+
392+ // Compute the up vector of our current working rotation,
393+ // to avoid gimbal lock instability when normal is also pointing upwards.
394+ // This "current" up vector is used in the LookRotation, which causes
395+ // the derived rotation to fit "closest" to the current up vector.
396+ Vector3 currentUpVector = WorkingRotation * Vector3 . up ;
397+
398+ Quaternion trackedReferenceRotation = Quaternion . LookRotation ( - direction , currentUpVector ) ;
399+ Quaternion surfaceReferenceRotation = Quaternion . LookRotation ( - surfaceNormal , currentUpVector ) ;
400+
401+ // If requested, compute FromTo from the current computed Up to global Up,
402+ // and apply to the computed quat; this will ensure object stays globally vertical.
391403 if ( KeepOrientationVertical )
392404 {
393- direction . y = 0 ;
394- surfaceNormal . y = 0 ;
405+ Vector3 trackedReferenceUp = trackedReferenceRotation * Vector3 . up ;
406+ trackedReferenceRotation = Quaternion . FromToRotation ( trackedReferenceUp , Vector3 . up ) * trackedReferenceRotation ;
407+ Vector3 surfaceReferenceUp = surfaceReferenceRotation * Vector3 . up ;
408+ surfaceReferenceRotation = Quaternion . FromToRotation ( surfaceReferenceUp , Vector3 . up ) * surfaceReferenceRotation ;
395409 }
396410
397- var trackedReferenceRotation = Quaternion . LookRotation ( - direction , Vector3 . up ) ;
398- var surfaceReferenceRotation = Quaternion . LookRotation ( - surfaceNormal , Vector3 . up ) ;
399-
400411 switch ( CurrentOrientationMode )
401412 {
402413 case OrientationMode . None :
0 commit comments