【问题标题】:Get SCNVector3 from CGPoint从 CGPoint 获取 SCNVector3
【发布时间】:2015-01-06 01:44:29
【问题描述】:

我正在尝试从 CGPoint 获取 SCNVector3。我正在使用手势识别器来获取触摸的位置(作为 CGPoint)。

问题是,当我进行测试时,触摸并不总是碰到某些东西,因为并不总是有物体被触摸。 (触摸空白处可将您的飞船移动到该空白处)。

我发现的其他 Stack Overflow 问题使用 SCNHitTestResult 来获取 worldCoordinates,但这对我不起作用。

有人知道怎么找到吗?鉴于我当然知道 z 坐标。移动的船总是以 z 位置 1 移动。

我需要 worldCoordinates 才能使用将 SCNNode 移动到具有 CGPoint 的接触点的操作。谢谢!

【问题讨论】:

  • 你说的是this the answer吗?阅读那里的行之间,你会找到一个解决方案。或者等几分钟,我会在这里完成更具体的答案。

标签: objective-c xcode scenekit


【解决方案1】:

那么,您想将视图空间中的一个点变成场景空间中的一个点吗?当然,要注意的是场景空间有三维,而视图空间没有。您使用SCNView(或其他渲染器)方法projectPointunprojectPoint 在3D 场景空间和......也是3D 的视图空间之间进行转换?是的 - 屏幕 pixels 点的二维和标准化深度之一:z 坐标对于近裁剪平面上的点为 0,对于远裁剪平面上的点为 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 方法来定位该平面上的点会更容易。

【讨论】:

  • is that scene space has a third dimension and scene space doesn't => 第二个scene space 应该是view space 对吧?
猜你喜欢
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
  • 2015-08-14
  • 1970-01-01
  • 2012-05-20
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
相关资源
最近更新 更多