你如何在ARKit中得到重点

时间:2017-07-25 05:06:03

标签: swift scenekit arkit

在ARKit中,如果您触摸屏幕上的某个点,您是否可以确定该点距离此点1米处的位置?

目前您似乎检测到了一个生命值

if let hit = sceneView.hitTest(touchLocation, types:.featurePoint).first {
  …
}

或者您从屏幕中心转换:

var translation = matrix_identity_float4x4
translation.columns.3.z = -1
let transform = simd_mul(currentFrame.camera.transform, translation)

我要找的是距离触摸位置1米。

更新:我根据建议进行了更改。

func getDirection(for point: CGPoint, in view: SCNView) -> SCNVector3 {
    let farPoint  = view.unprojectPoint(SCNVector3(Float(point.x), Float(point.y), 1))
    let nearPoint = view.unprojectPoint(SCNVector3(Float(point.x), Float(point.y), 0))

    return SCNVector3(farPoint.x - nearPoint.x, farPoint.y - nearPoint.y, farPoint.z - nearPoint.z)
}

func getCameraPosition() -> SCNVector3 {
    let transform = sceneView.session.currentFrame?.camera.transform
    let pos = MDLTransform(matrix:transform!)
    return SCNVector3(pos.translation.x, pos.translation.y, pos.translation.z)
}

然后在接触中我改为:

if let touchLocation = touches.first?.location(in:sceneView) {
  …
  let node = SCNNode(geometry: geometry)
  let pos = getCameraPosition()
  let dir = getDirection(for: touchLocation, in: sceneView).normalized
  node.position = SCNVector3(pos.x + dir.x, pos.y + dir.y, pos.z + dir.z)
}

基于评论中的规范化扩展。我现在可以看到SCNNode了!只是没有手指指向的位置,大幅度偏离。

2 个答案:

答案 0 :(得分:4)

当您点击屏幕时,您基本上是指定方向。在3D空间中,您可以从两个点获得方向。查看this question以获取可能的解决方案。

当你有方向时需要将其标准化(使其长度为1米)并将其添加到当前相机位置。

要规范化矢量,您可以使用这些扩展名

extension SCNVector3 {
    /// Returns the length of the vector
    var length: Float {
        return sqrt(self.x * self.x + self.y * self.y + self.z * self.z)
    }
    var normalized: SCNVector3 {
        let length = self.length
        return SCNVector3(self.x/length, self.y/length, self.z/length)
    }
}

编辑:

这对我来说很好用:

func getCameraPosition(in view: ARSCNView) -> SCNVector3? {
    guard let lastFrame = view.session.currentFrame else {
        return nil
    }

    let position = lastFrame.camera.transform * float4(x: 0, y: 0, z: 0, w: 1)
    let camera: SCNVector3 = SCNVector3(position.x, position.y, position.z)

    return camera
}

答案 1 :(得分:0)

您是否在询问如何找到从相机到真实世界表面的距离?

在这种情况下,您需要一个匹配测试,就像您问题中的第一个代码段一样。 ARHitTestResult提供distance属性,可以为您提供您正在寻找的内容。

如果您正在询问如何计算距离相机正好1米的点(无论是否存在真实世界表面),而是与屏幕上的特定点对齐,而不是沿着相机的中心线... { {3}}是您可以开始调查的一条途径。另一种方法是使用命中测试来找到一个表面,然后将得到的矢量缩放到1米长。