Using MRTK 2 in Unity 2021 LTS, I'm trying to display a 3D object positioned relative to a QR code on a Hololens 2. The goal is to "scan" the QR code lying flat on a table and have the object displayed a few centimeters behind it aligned to its rotation. Due to physics joints on the object, I can't simply move the object to match the position and orientation of the scanned QR code, I have to instead move the "camera" (more precisely the MRTK playspace which is a parent of the camera GameObject).
To do so, I tried the following, where anchor is a child transform of the tracked QR code transform with a position offset:
MixedRealityPlayspace.Position -= anchor.position;
MixedRealityPlayspace.RotateAround(Vector3.zero, Vector3.up, anchor.rotation.eulerAngles.y);
This sort of works, the 3D object (at world position (0, 0, 0)) appears in the correct location but the rotation is always a little off, sometimes barely noticeable, other times up to ~30 degrees off. The two lines are run once 1 second after the QR code is detected, but the rotation mismatch is too great to be due to tracking inaccuracy at that one point in time I feel. I don't know how I can apply the transformations continuously.
The QR code tracking I use is based on this MRTK QR Code sample for Unity, modified slightly by multiplying the detected QR code rotation by Quaternion.Euler(90, 90, 90)
in SpatialGraphNodeTracker.cs to get a y-up orientation for the detected code. The position and orientation of the code is correct, i.e. a visualization object placed there lines up in both position and orientation with the real-world code before and after moving the playspace.
I tried looking into the World Locking Tools, but couldn't find helpful information for this use case and got the impression that it is more targeted at large-scale AR experiences with multiple anchors.
How can I reposition the playspace so that my 3D object positioned relative to the tracked QR code is perfectly (as well as tracking permits) aligned?
When I don't move the transform "manually", but use a temporary transform with parenting like in this snippet, the rotation is correct:
var tempTransform = new GameObject().transform;
tempTransform.parent = anchor; // anchor is parented to the detected QR Code transform with a position offset
tempTransform.localPosition = Vector3.zero;
tempTransform.localRotation = Quaternion.identity;
tempTransform.parent = null;
playspaceTransform.parent = tempTransform;
tempTransform.position = Vector3.zero;
tempTransform.rotation = Quaternion.identity;