当要旋转的对象的父对象有旋转时如何使用 SparkAR 的 LookAt
How to use SparkAR's LookAt when parents of the object to rotate have a rotation
在 SparkAR 中,我想要一个元素(称为 toRotate
),它总是看着相机,类似于已经问过的(但接受的解决方案对我和我来说并不令人满意没有足够的声誉来回答它的评论)。
要注意的是该元素处于无法修改的层次结构中:顺序必须 绝对 为 root->planeTracker->parent->toRotate
,如 this screenshot 所示(似乎好像我没有足够的声誉来嵌入图像)。
通过使用 lookAt
函数(感谢 this github repo 我知道我必须创建一个 toRotateDuplicate
同级 toRotate
并且具有相同的本地位置,然后使用它的转换代替)我可以让它在编辑器中工作得很好但是一旦我在设备上尝试它我的 toRotate
有一个奇怪的旋转..
经过一些测试,我可以看出问题出在以下事实:planeTracker
仅在编辑器上的旋转等于 Quaternion.Identity,而在设备上该值有所不同。
如果用一个空节点替换 planeTracker
并对其应用非身份旋转,即使在编辑器上我们也会遇到“奇怪的旋转”问题。
也证明了这一点。
这是我的代码:
const Scene = require("Scene");
const Reactive = require("Reactive");
const find = e => Scene.root.findFirst(e);
(async function () {
const toRotate = await find('toRotate');
const toRotateDuplicate = await find('toRotateDuplicate');
const camera = await find('Camera');
toRotate.worldTransform.rotation = toRotateDuplicate.worldTransform.lookAt(camera.worldTransform.position).rotation;
})();
因为我正在使用世界变换,所以我不应该有关于旋转的问题,对吗?
那我该怎么办?
请注意接受的解决方案 对我不起作用:如果相机正在注视对象的中心,则对象只会注视相机,而且如果我不移动相机旋转它我可以看到该对象没有更新其旋转以继续查看相机。
我找到了一个“hacky”解决方案:
为我们的 toRotate
创建另一个名为 cameraDuplicate
的兄弟姐妹,它反映了 Camera
对象的 worldPosition.. 由于 lookAt
逻辑中所有使用的转换现在都在同一层级,我可以使用局部变换而不是世界变换 ^^'
这是更新后的代码:
const Scene = require("Scene");
const Reactive = require("Reactive");
const find = e => Scene.root.findFirst(e);
(async function () {
const toRotate = await find('toRotate');
const toRotateDuplicate = await find('toRotateDuplicate');
const camera = await find('Camera');
const cameraDuplicate = await find('cameraDuplicate');
cameraDuplicate.worldTransform.position = camera.worldTransform.position;
toRotate.transform.rotation = toRotateDuplicate.transform.lookAt(cameraDuplicate.transform.position).rotation;
})();
我不太喜欢它,因为:它意味着创建第二个兄弟姐妹(好像一个还不够)并且没有澄清我的轮换问题,只是避免了它..所以请提供你的解决方案如果没有我那么老套,我会接受它:)
在 SparkAR 中,我想要一个元素(称为 toRotate
),它总是看着相机,类似于已经问过的
要注意的是该元素处于无法修改的层次结构中:顺序必须 绝对 为 root->planeTracker->parent->toRotate
,如 this screenshot 所示(似乎好像我没有足够的声誉来嵌入图像)。
通过使用 lookAt
函数(感谢 this github repo 我知道我必须创建一个 toRotateDuplicate
同级 toRotate
并且具有相同的本地位置,然后使用它的转换代替)我可以让它在编辑器中工作得很好但是一旦我在设备上尝试它我的 toRotate
有一个奇怪的旋转..
经过一些测试,我可以看出问题出在以下事实:planeTracker
仅在编辑器上的旋转等于 Quaternion.Identity,而在设备上该值有所不同。
如果用一个空节点替换 planeTracker
并对其应用非身份旋转,即使在编辑器上我们也会遇到“奇怪的旋转”问题。
这是我的代码:
const Scene = require("Scene");
const Reactive = require("Reactive");
const find = e => Scene.root.findFirst(e);
(async function () {
const toRotate = await find('toRotate');
const toRotateDuplicate = await find('toRotateDuplicate');
const camera = await find('Camera');
toRotate.worldTransform.rotation = toRotateDuplicate.worldTransform.lookAt(camera.worldTransform.position).rotation;
})();
因为我正在使用世界变换,所以我不应该有关于旋转的问题,对吗?
那我该怎么办?
请注意接受的解决方案
我找到了一个“hacky”解决方案:
为我们的 toRotate
创建另一个名为 cameraDuplicate
的兄弟姐妹,它反映了 Camera
对象的 worldPosition.. 由于 lookAt
逻辑中所有使用的转换现在都在同一层级,我可以使用局部变换而不是世界变换 ^^'
这是更新后的代码:
const Scene = require("Scene");
const Reactive = require("Reactive");
const find = e => Scene.root.findFirst(e);
(async function () {
const toRotate = await find('toRotate');
const toRotateDuplicate = await find('toRotateDuplicate');
const camera = await find('Camera');
const cameraDuplicate = await find('cameraDuplicate');
cameraDuplicate.worldTransform.position = camera.worldTransform.position;
toRotate.transform.rotation = toRotateDuplicate.transform.lookAt(cameraDuplicate.transform.position).rotation;
})();
我不太喜欢它,因为:它意味着创建第二个兄弟姐妹(好像一个还不够)并且没有澄清我的轮换问题,只是避免了它..所以请提供你的解决方案如果没有我那么老套,我会接受它:)