I am looking for a way to orient a sceneobject on a tracked plane towards the camera via scripting in SparkAR Studio 98. This sounds trivial, but I am having a very hard time finding the world position of the camera, and then from that generating a rotation that I can apply to the object looking at the camera.
I got it to work WITHIN the tracked plane hierarchy, so that one object would always look at the other, but as the camera is living outside of that hierarchy and coordinate system, it doesn't help me.
I am, as always, struggeling with the reactive nature of the SparkAR API, as well as the fact that things are spread out over several coordinate systems and information is hard to find on the net and quickly outdated. My code looks like this:
const Scene = require('Scene');
const R = require('Reactive');
export const Diagnostics = require('Diagnostics');
(async function () {
Diagnostics.log("Filter activated");
const objectToOrient = await Scene.root.findFirst('object');
const objectParent= await Scene.root.findFirst('objectParent');
const target = await Scene.root.findFirst('target');
const lookAtPt = R.point(
target.worldTransform.x,
target.worldTransform.y,
target.worldTransform.z);
const lookAtTransform = objectParent.transform.lookAt(lookAtPt);
})();
To illustrate the concept for the reader, I have set up this scene:
The "S" appears, as soon as the underlying plane is tracked. It then stays in place, along with the tracked plane. It should then always rotate towards the camera/device/user. Thank you!
WHAT WORKED
Having wasted a weekend, and ten minutes after giving up, I finally found out how to do it. The actual solution is so simple that it pains me to post it, but here it goes.
Using script, I just bound the rotation of the
objectToOrient
to the rotation of the camera. That's it.After deleting two pages of my old code, I also tried to replicate this using patches, but plugging the DeviceMotion patch into the 3D rotation of the object actually produces different and counterintuitive behaviour on my android phone. Maybe the rotation in the patch and the one actually generated by the device don't line up, I'd be very interested in comments on this topic.
WHAT DIDN'T WORK
After having thought I solved the problem through angular calculations and world transforms like I posted here before, it actually wasn't working and I had to waste another two days of my life on this, troubleshooting and looking for problems in my calculations using either manually calculated angles between vectors, quaternions or all variations of
lookAt
that SparkAR offers.On the way I learned about the DeviceMotion-module, which I hoped would fix the problem that I couldn't get an updated world-position of the camera into my scene. I wanted to use this position to calculate the angular difference between two vectors, and then from that rotate the object by that angle. Like most of the solutions, this worked perfectly in the editor, but not on my phone. Unfortunately it wouldn't update once in the scene. After some debugging I found out that DeviceMotion.worldTransform ACTUALLY ONLY CONTAINS A ROTATION, but doesn't throw an error when its positional coordinates are accessed. I find this package EXCESSIVELY frustrating to work with.