如何使用SceneKit的unprojectPoint将2D点转换为3D而没有深度值?

时间:2014-06-23 10:15:27

标签: ios 3d scenekit

是否可以使用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方法,但我认为在每次触摸/拖动事件中都不是很好。此外,它也不允许物体移动到飞机外。

我已经尝试了基于已接受的答案here的解决方案,但它没有奏效。对unprojectPoint使用一个深度值,如果在+/- Z方向上拖动对象,则对象不会在手指下停留太长时间,而是会远离它移动它。 我需要让拖动的物体留在手指下,无论它在XZ平面上移动到哪里。

1 个答案:

答案 0 :(得分:2)

首先,您是否真的在xz平面或xy平面中寻找位置?默认情况下,摄像机在-z方向上查看,因此3D场景套件坐标系的x轴和y轴的方向与在2D视图坐标系中的方向相同。 (好吧,默认情况下,y在UIKit中被翻转,但它仍然是垂直轴。)然后xz平面与屏幕平面正交。

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

SceneKit的unprojectPoint的工作方式相同 - 它的z坐标指的是clip space中的深度,并将其映射到场景世界空间中的某个点。

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

然而,考虑使用未投影的矢量是个好主意 - 如果你要做的下一件事就是测试场景几何的交叉点,那么请看hitTest:而不是