@@ -388,15 +388,26 @@ private Vector3 RaycastDirection
388
388
/// <returns>Quaternion, the orientation to use for the object</returns>
389
389
private Quaternion CalculateMagnetismOrientation ( Vector3 direction , Vector3 surfaceNormal )
390
390
{
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.
391
403
if ( KeepOrientationVertical )
392
404
{
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 ;
395
409
}
396
410
397
- var trackedReferenceRotation = Quaternion . LookRotation ( - direction , Vector3 . up ) ;
398
- var surfaceReferenceRotation = Quaternion . LookRotation ( - surfaceNormal , Vector3 . up ) ;
399
-
400
411
switch ( CurrentOrientationMode )
401
412
{
402
413
case OrientationMode . None :
0 commit comments