Skip to content

Commit e800011

Browse files
committed
Adding tests for surface magnetism gimbal lock
1 parent 3d0bd8c commit e800011

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

Assets/MRTK/Tests/PlayModeTests/SolverTests.cs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,79 @@ public IEnumerator TestSurfaceMagnetism()
219219
Assert.IsTrue(Mathf.Approximately(1.0f, Vector3.Dot(targetTransform.forward.normalized, Vector3.forward)));
220220
}
221221

222+
/// <summary>
223+
/// Test Surface Magnetism against vertical normal and ensure no temporal instability (gimbal lock)
224+
/// </summary>
225+
[UnityTest]
226+
public IEnumerator TestSurfaceMagnetismGimbalLock()
227+
{
228+
Vector3 floorCenter = Vector3.forward * 10.0f + Vector3.up * -2.0f;
229+
230+
// Reset view to origin
231+
MixedRealityPlayspace.PerformTransformation(p =>
232+
{
233+
p.position = Vector3.zero;
234+
p.LookAt(floorCenter);
235+
});
236+
237+
// Build floor to collide against
238+
var floor = GameObject.CreatePrimitive(PrimitiveType.Cube);
239+
floor.transform.localScale = new Vector3(25.0f, 0.2f, 25.0f);
240+
floor.transform.position = floorCenter;
241+
242+
// Give the floor a very small tilt
243+
floor.transform.rotation = Quaternion.Euler(10, 0, 0);
244+
245+
yield return WaitForFrames(2);
246+
247+
// Instantiate our test GameObject with solver.
248+
// Set layer to ignore raycast so solver doesn't raycast itself (i.e BoxCollider)
249+
var testObjects = InstantiateTestSolver<SurfaceMagnetism>();
250+
testObjects.target.layer = LayerMask.NameToLayer("Ignore Raycast");
251+
SurfaceMagnetism surfaceMag = testObjects.solver as SurfaceMagnetism;
252+
253+
var targetTransform = testObjects.target.transform;
254+
var cameraTransform = CameraCache.Main.transform;
255+
256+
yield return WaitForFrames(2);
257+
258+
// Change default orientation mode to surface normal
259+
surfaceMag.CurrentOrientationMode = SurfaceMagnetism.OrientationMode.SurfaceNormal;
260+
surfaceMag.KeepOrientationVertical = false;
261+
262+
yield return WaitForFrames(2);
263+
264+
// Test object should now be facing the floor
265+
Assert.IsTrue(Mathf.Approximately(1.0f, Vector3.Dot(-targetTransform.forward.normalized, floor.transform.up)));
266+
267+
// Cache test object's current right vector
268+
Vector3 rightVector = testObjects.target.transform.right;
269+
270+
floor.transform.Rotate(new Vector3(-20, 0, 0));
271+
yield return WaitForFrames(2);
272+
273+
// Make sure that the target's right vector has not flip-flopped
274+
Assert.IsTrue(Mathf.Sign(targetTransform.transform.right.x) == Mathf.Sign(rightVector.x));
275+
276+
// Do the same, but with KeepOrientationVertical = true
277+
surfaceMag.KeepOrientationVertical = true;
278+
279+
// Cache test object's current right vector
280+
rightVector = testObjects.target.transform.right;
281+
282+
yield return WaitForFrames(2);
283+
284+
// Test object should now have proper upright orientation
285+
Assert.IsTrue(Mathf.Approximately(1.0f, Vector3.Dot(targetTransform.up.normalized, Vector3.up)));
286+
floor.transform.Rotate(new Vector3(20, 0, 0));
287+
yield return WaitForFrames(2);
288+
289+
// Make sure that the target's right vector has not flip-flopped
290+
Assert.IsTrue(Mathf.Sign(targetTransform.transform.right.x) == Mathf.Sign(rightVector.x));
291+
292+
293+
}
294+
222295
/// <summary>
223296
/// Test solver system's ability to change target types at runtime
224297
/// </summary>

0 commit comments

Comments
 (0)