5

是否可以使用 SceneKit 的unprojectPoint将 2D 点转换为 3D 而没有深度值?我只需要在 XZ 平面中找到 3D 位置。Y 可以始终为 0 或任何值,因为我没有使用它。

我正在尝试为 iOS 8 Beta 执行此操作。

我对 JavaScript 和 Three.js (WebGL) 有类似的东西,如下所示:

function getMouse3D(x, y) {
    var pos = new THREE.Vector3(0, 0, 0);
    var pMouse = new THREE.Vector3(
        (x / renderer.domElement.width) * 2 - 1,
       -(y / renderer.domElement.height) * 2 + 1,
       1
    );
    //
    projector.unprojectVector(pMouse, camera);

    var cam = camera.position;
    var m = pMouse.y / ( pMouse.y - cam.y );

    pos.x = pMouse.x + ( cam.x - pMouse.x ) * m;
    pos.z = pMouse.z + ( cam.z - pMouse.z ) * m;

    return pos;
};

但我不知道如何将带有 unprojectVector 的部分翻译为 SceneKit。


我想要做的是能够仅在 XZ 平面中拖动对象。垂直轴 Y 将被忽略。

由于对象需要沿平面移动,一种解决方案是使用 hitTest 方法,但我认为对于每个触摸/拖动事件都执行此操作在性能方面不是很好。此外,它也不允许物体移出平面。

我已经尝试了基于此处接受的答案的解决方案,但没有奏效。为 unprojectPoint 使用一个深度值,如果在 +/-Z 方向上拖动对象,则对象不会在手指下停留太久,而是会远离手指。无论拖动的对象在 XZ 平面中的哪个位置移动,我都需要让拖动的对象保持在手指下方。

4

1 回答 1

2

首先,您实际上是在寻找 xz 平面还是 xy 平面中的位置?默认情况下,相机朝 -z 方向看,因此 3D Scene Kit 坐标系的 x 轴和 y 轴与它们在 2D 视图坐标系中的方向相同。(好吧,在 UIKit 中,y 默认是翻转的,但它仍然是垂直轴。)然后 xz 平面与屏幕平面正交。

其次,深度值是从 2D 转换为 3D 的必要部分。我不是three.js 方面的专家,但是通过查看他们的库文档(显然无法链接到),他们unprojectVector仍然需要一个Vector3. 这就是您在pMouse上面的代码中构建的内容 - 一个向量,其 z 和 y 坐标来自 2D 鼠标位置,其 z 坐标为 1。

SceneKit 的unprojectPoint工作方式相同——它获取一个 z 坐标指向剪辑空间深度的点,并将其映射到场景世界空间中的一个点。

如果你的世界空间的方向是你关心的唯一变化是在 x 轴和 y 轴上,你可以传递任何你想要unprojectPoint的 z 值,并忽略你返回的向量中的 z 值。否则,传递-1到远剪裁平面、1近剪裁平面或0中间剪裁平面的映射——z 坐标(在相机空间中)为 的平面0。如果您使用未投影点在场景中定位节点,最好的建议是尝试不同的 z 值(介于 -1 和 1 之间),直到获得所需的行为。

但是,考虑使用非投影向量是一个好主意——如果您接下来要做的事情是测试与场景几何的交叉点,请查看hitTest :。

于 2014-06-23T21:52:49.650 回答