如何在Three.js json场景中使用四元数旋转

发布于 2025-01-07 19:42:55 字数 1493 浏览 0 评论 0原文

我正在研究 L 系统解释器,我使用四元数作为旋转的内部表示。我需要将结果导出到 ThreeJs JavaScript 场景,我发现 json 场景是实现此目的的最佳方法。

我在 https://github 上找到了一个场景示例。 com/mrdoob/third.js/blob/master/examples/scenes/test_scene.js 但没有任何关于四元数旋转的内容。

所以我使用了 http://thirdjs.org/io/s/quaternion 的帮助并发现, THREE.Object3D 具有属性 quaternionuseQuaternion 但它似乎不起作用,场景加载器引发错误(可能是因为缺少“旋转”属性,请参见编辑在最后):

"obj": {
    ...
    "quaternion": [0.38268343236509,0,0,0.923879532511287],
    "useQuaternion": true
}

我也尝试将四元数转换为欧拉角,但它对我不起作用,可能是因为角度应用的其他顺序(我假设顺序为 Y、Z、X)。在上面的示例中,四元数表示绕 Z 轴(俯仰)旋转 135 度,转换为欧拉角 [pi,pi,pi/4],但在场景中显示不正确。

下图显示了每个块在 Z 轴上比其他块多旋转 11 度。轴为 X(红色)、Y(绿色)和 Z(蓝色)。由于四元数到欧几里得的转换不正确,上半部分旋转不正确(我使用此页面进行实现:http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/)。

问题说明
编辑:经过进一步检查,场景加载器引发的错误是因为对象上缺少“旋转”属性。以下输出不会引发错误并且场景已加载,但它是错误的(与所示图像相同),因为四元数旋转被忽略。

"obj": {
    ...
    "rotation": [3.14159265358979,3.14159265358979,0.785398163397449],
    "quaternion": [0.38268343236509,0,0,0.923879532511287],
    "useQuaternion": true
}

I am working on L-system interpreter and I use quaternion as internal representation of rotation. I need to export result to ThreeJs JavaScript scene and I found json scene as the best way how to do that.

I found one example of scene on https://github.com/mrdoob/three.js/blob/master/examples/scenes/test_scene.js but there is nothing about quaternion rotations.

So I used help at http://threejs.org/io/s/quaternion and found, that THREE.Object3D has properties quaternion and useQuaternion but It seems to do not work, the error is raised by scene loader (probably because of missing "rotation" attribute, see EDIT at the end):

"obj": {
    ...
    "quaternion": [0.38268343236509,0,0,0.923879532511287],
    "useQuaternion": true
}

I've also tried to convert quaternion to Euler angles but It wont work for me, probably because of other order of applying of angles (I assume order Y, Z, X). In the above example, quaternion is representing rotation about the Z axis (pitch) by 135 degrees which is converted to Euler angles [pi,pi,pi/4] but it is displayed not correct in the scene.

Following picture shows blocks each rotated by 11 deg more than other by Z axis. Axes are X(red), Y(green) and Z (blue). The upper half is rotated incorrectly due to incorrect conversion quaternion to Euclid (I used this page for implementation: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/ ).

ilustration of the problem

EDIT: After further examination the error raised by scene loader is because of missing "rotation" attribute on object. Following output do not throw error and scene is loaded but it is wrong (in the same way as shown image) because quaternion rotations are ignored.

"obj": {
    ...
    "rotation": [3.14159265358979,3.14159265358979,0.785398163397449],
    "quaternion": [0.38268343236509,0,0,0.923879532511287],
    "useQuaternion": true
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

似梦非梦 2025-01-14 19:42:55

我想我解决了我的问题。这不是我问题的直接答案,只是我如何解决这个问题。

问题出在场景加载器中,它不适用于四元数旋转。我重写了场景生成脚本,直接在JS中生成场景。

var mesh = new THREE.Mesh(geometry, material);
... set position & scale ...
mesh.rotation.x = 3.141;
mesh.rotation.y = 3.141;
mesh.rotation.z = 0.785;
mesh.updateMatrix();
scene.add(mesh);

然后我发现 THREE.Object3D 上的魔术属性 eulerOrder 默认设置为“XYZ”,这导致了我的问题(有问题的附图),我的四元数-欧拉转换是为“YZX”设计的,所以我改变了它。

mesh.eulerOrder = 'YZX';

就是这样。我没有时间尝试场景加载器,但如果可以使用场景加载器设置 eulerOrder 属性,那么它将解决我的问题的第二部分。

最好的方法是直接在场景定义中设置四元数,但可能需要更改场景加载器本身。

I think I solved my problem. This is not direct answer to my question, just how I workaround that.

Problem is in scene loader, which does not work with quaternion rotations. I rewritten scene generation script to generate scene directly in JS.

var mesh = new THREE.Mesh(geometry, material);
... set position & scale ...
mesh.rotation.x = 3.141;
mesh.rotation.y = 3.141;
mesh.rotation.z = 0.785;
mesh.updateMatrix();
scene.add(mesh);

Then I found magic property eulerOrder on THREE.Object3D which is set to 'XYZ' in default which was causing my problems (attached image in question), my quaternion-euler conversion was designed for 'YZX' so I changed that.

mesh.eulerOrder = 'YZX';

Thats it. I have no time for experimenting with scene loader but IF it is possible to set eulerOrder property with scene loader than it will be sollution to second part of my question.

The best would be setting quaternion directly in scene definition but it will probably require changes in scene loader itself.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文