【发布时间】:2020-02-16 05:34:36
【问题描述】:
我正在尝试使用三个 JS 制作一个看起来像这样的 blender-esk 方向视图:
我的计划是让相机旋转并旋转 3 个矢量点(代表图片中的 X、Y 和 Z 气泡)。然后,一旦我有了这些点,我就可以使用 X 和 Y 坐标在画布上绘制圆圈并绘制线以将它们连接到中心。然后我可以使用 Z 方向来确定应该在什么之上绘制什么。
目前我正在使用第二个 three.js 场景来可视化这些 X、Y 和 Z 点的位置,因为我尝试了不同的方法来旋转顶点组以使其与相机的方向匹配。我在这部分苦苦挣扎,我尝试了很多没用的方法。
这是我目前所在位置的 JS Fiddle:
https://jsfiddle.net/j9mcL0x4/4/ (在 Brave 中不加载,但在 Chrome 中有效)
当您平移相机时,它会移动第二个场景中的 3 个立方体,但我无法让它正确旋转。
X、Y 和 Z 点由一组 Vector3 表示:
this.ref = [
[new THREE.Vector3(1,0,0), 0xFF0000],
[new THREE.Vector3(0,1,0), 0x00FF00],
[new THREE.Vector3(0,0,1), 0x0000FF],
]
然后我创建每个立方体并将其添加到一个组中:
this.group = new THREE.Group();
for(var pos of this.ref) {
var geometry = new THREE.BoxGeometry(.25,.25,.25);
var material = new THREE.MeshBasicMaterial({
color: pos[1]
});
var cube = new THREE.Mesh(geometry, material);
cube.position.copy(pos[0]);
this.group.add(cube);
}
this.scene.add(this.group);
然后在我的动画函数中,我试图计算组的旋转,使其与主视图的方向相同:
var quaternion = new THREE.Quaternion();
camera.getWorldQuaternion( quaternion );
let rotation = new THREE.Euler();
rotation.setFromQuaternion(quaternion);
var dir = new THREE.Vector3();
dir.subVectors( camera.position, controls.target ).normalize();
orientationHelper.group.rotation.set(dir.x, dir.y, dir.z);
orientationHelper.animate();
我所拥有的是完全错误的,但这是我尝试过的一些事情:
- 计算相机前方的一个点,然后使用 lookAt 函数使小组朝那个方向看
- 我正在使用轨道控制,它有一个相机聚焦的目标。我试过减去相机位置向量和目标向量来获得观察方向,但这没有用(目前在 jsfiddle 中)
- 我试过只使用相机局部旋转(并尝试否定它)
注意 我可以在第二个场景中旋转相机以匹配主视图中的相机,但我真的想自己旋转矢量。这样我就可以将这些点投影到基本画布上以绘制 6 个圆圈和 3 条线。我觉得这会比尝试在 3d 中使用 sprite 容易得多,而且三个 JS 在不为其创建矩形网格的情况下无法轻松绘制粗线。
以下是我希望输出的一些示例:
更新
Rabbid76 解决了这个问题,如果有人有兴趣在他们的项目中使用 Blender 风格的方位立方体,您可以在这里找到完整的源代码:
https://github.com/jrj2211/three-orientation-gizmo/
或者用 npm 下载:
【问题讨论】:
-
太棒了。感谢分享
-
很棒的作品,感谢分享。
-
谢谢!我还添加了一个 npm 链接,以防你使用 nodejs 并想使用它
标签: javascript vector three.js quaternions coordinate-transformation