如何在 SparkAR Studio 98 中将跟踪平面上的对象定向到相机?

How can I orient an object on a tracked plane towards the camera in SparkAR Studio 98?

我正在寻找一种方法,通过 SparkAR Studio 98 中的脚本将跟踪平面上的场景对象定向到相机。 这听起来微不足道,但我很难找到相机的世界位置,然后从中生成一个旋转,我可以将其应用于看着相机的物体。

我让它在跟踪的平面层次结构中工作,这样一个对象就会一直看着另一个对象,但是由于相机位于该层次结构和坐标系之外,所以它对我没有帮助。

一如既往,我一直在为 SparkAR API 的反应性而苦苦挣扎,而且事情分布在多个坐标系上,而且很难在网上快速找到信息过时的。 我的代码如下所示:

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);
})();

为了说明reader的概念,我设置了这个场景:

一旦跟踪到底层平面,“S”就会出现。然后它与被跟踪的飞机一起留在原地。 然后它应该总是向 camera/device/user 旋转。 谢谢!

什么有效

浪费了一个周末,放弃十分钟后,我终于找到了方法。实际的解决方案非常简单,post 让我很痛苦,但就这样吧。

使用脚本,我只是将 objectToOrient 的旋转绑定到相机的旋转。就是这样。

const S = require('Scene');
const R = require('Reactive');
const D = require('Diagnostics');

// Enter look-at-target and object that needs to look at the target here
const objectName = 'lookAtObject';
const pivotName = 'pivot';
const targetName = 'Camera';
// const targetName = 'target';

(async function () {
    D.log("Filter activated");

    const [object, pivot, target] = await Promise.all([
        S.root.findFirst(objectName),
        S.root.findFirst(pivotName),
        S.root.findFirst(targetName)])
        .catch((error) => D.log(error.message));

    const deviceTransform = target.worldTransform;
    const pivotTransform = pivot.worldTransform;

    object.transform.rotation = deviceTransform.rotation;
    object.transform.position = pivotTransform.position;

    D.log("End of Log");
})();

删除我的两页旧代码后,我也尝试使用补丁复制它,但是将 DeviceMotion 补丁插入对象的 3D 旋转实际上会在我的 android phone。也许补丁中的旋转和设备实际生成的旋转不一致,我对这个话题的评论很感兴趣。

什么不起作用

我以为我通过 angular 计算和世界变换解决了问题,就像我之前 post 在这里说的那样,但它实际上没有用,我不得不又浪费了两天的生命在此基础上,使用手动计算的矢量、四元数之间的角度或 SparkAR 提供的 lookAt 的所有变体来解决我的计算中的问题。

在我了解到 DeviceMotion-module 的过程中,我希望它能解决我无法将相机的更新 world-position 更新到我的场景中的问题。我想使用这个位置来计算两个向量之间的 angular 差异,然后将对象旋转该角度。与大多数解决方案一样,这在编辑器中运行得很好,但在我的 phone 上却不行。 不幸的是,它不会在场景中更新一次。经过一些调试后,我发现 DeviceMotion.worldTransform 实际上只包含一个旋转,但在访问其位置坐标时不会抛出错误。 我发现使用这个包非常令人沮丧。

其实还有一个简单的方法,就是lookAt方法。它的工作原理似乎有点不同——它总是将对象旋转到世界中的相机位置 space,而不是将相机旋转绑定到对象旋转。

const Scene = require('Scene');

(async function () {

    const camera = await Scene.root.findFirst('Camera');
    const tracker = await Scene.root.findFirst('planeTracker');
    const plane = await Scene.root.findFirst('plane');

    // Get the camera world space position
    const cameraPositionSignal = tracker.worldTransform.inverse().applyToPoint(camera.worldTransform.position);

    // Apply the rotation of the relative transform between plane tracker and camera world position
    plane.transform.rotation = tracker.transform.lookAt(cameraPositionSignal).rotation;

    // Bring object back to the plane tracker origin
    plane.worldTransform.position = tracker.worldTransform.position;

})();

可能是 lookAt 方法在 Spark AR Studio 98 处于活动状态时无法正常工作。这适用于当前最新的 120 版本。