我正在尝试从 CGPoint 获取 SCNVector3。我正在使用手势识别器来获取触摸的位置(作为 CGPoint)。
问题是,当我进行测试时,触摸并不总是会击中某些东西,因为并不总是有物体被触摸。 (触摸一个空的地方,将你的船移动到那个空的地方)。
我发现的其他堆栈溢出问题使用 SCNHitTestResult 来获取worldCoordinates
但这对我不起作用。
有谁知道如何找到这个?鉴于我当然知道 z 坐标。移动的船舶始终以 z 位置为 1 移动。
我需要世界坐标才能使用将 SCNNode 移动到具有 CGPoint 的触摸点的操作。谢谢!
那么,您想将视图空间中的点转换为场景空间中的点吗?当然,问题在于场景空间具有第三维,而视图空间则没有。您使用SCNView
(或其他渲染器)方法projectPoint and unprojectPoint在 3D 场景空间和……也是 3D 视图空间之间进行转换?是的 - 屏幕像素点的二维,以及归一化深度的一维:对于近剪裁平面上的点,z 坐标为 0,对于远剪裁平面上的点,z 坐标为 1。
无论如何,您有一个有用的约束,因为您希望将视图空间点映射到特定平面上(z=1
)在场景空间中。如果场景空间的方向使得所述平面与视图方向正交,即相机直接指向 +z 或 -z 方向,则您将获得更有用的约束。
如果要将视图空间点映射到特定的场景空间深度,则需要知道该平面的视图空间深度是多少。使用projectPoint
为了那个原因:
SCNVector3 projectedPlaneCenter = [view projectPoint:planeNode.position];
float projectedDepth = projectedPlaneCenter.z;
现在,抓住它,每当您需要将触摸位置映射到该平面上时,您就可以使用它:
CGPoint vp = [recognizer locationInView:view];
SCNVector3 vpWithDepth = SCNVector3Make(vp.x, vp.y, projectedDepth);
SCNVector3 scenePoint = [view unprojectPoint:vpWithDepth];
如果你的场景的 z 轴不平行于相机,那就有点困难了——你必须弄清楚你的场景在哪里z=1
平面对于您处理的任何视空间点都是独立的。在这种情况下,您可能会发现添加不可见的更容易SCNPlane
到您的场景并使用hitTest
/worldCoordinates
方法来定位该平面上的点。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)