【问题标题】:Dragging SCNNode in ARKit Using SceneKit使用 SceneKit 在 ARKit 中拖动 SCNNode
【发布时间】:2017-11-27 12:23:39
【问题描述】:

我在 ARKit 中有一个简单的 SCNNode,我试图将它拖动到我在手机上移动手指的任何地方。这是我的代码。

 @objc func pan(recognizer :UIGestureRecognizer) {

        guard let currentFrame = self.sceneView.session.currentFrame else {
            return
        }

        var translation = matrix_identity_float4x4
        translation.columns.3.z = -1.5

        let sceneView = recognizer.view as! ARSCNView
        let touchLocation = recognizer.location(in: sceneView)

        let hitTestResult = sceneView.hitTest(touchLocation, options: [:])

        if !hitTestResult.isEmpty {

            print("hit result")

            guard let hitResult = hitTestResult.first else {
                return
            }

            let node = hitResult.node

            node.simdTransform = matrix_multiply(currentFrame.camera.transform, translation)
        }
    }

问题是拖很慢而且不流畅。

【问题讨论】:

标签: ios scenekit arkit


【解决方案1】:

我像这样使用 PanGesture 处理翻译。除以 700 是为了平滑和调整运动速度,我通过反复试验达到了这个值,您可以尝试一下

@objc func onTranslate(_ sender: UIPanGestureRecognizer) {
    let position = sender.location(in: scnView)
    let state = sender.state

    if (state == .failed || state == .cancelled) {
        return
    }

    if (state == .began) {
        // Check it's on a virtual object
        if let objectNode = virtualObject(at: position) {
            // virtualObject(at searches for root node if it's a subnode
            targetNode = objectNode
            latestTranslatePos = position
        }

    }
    else if let _ = targetNode {

        // Translate virtual object
        let deltaX = Float(position.x - latestTranslatePos!.x)/700
        let deltaY = Float(position.y - latestTranslatePos!.y)/700

        targetNode!.localTranslate(by: SCNVector3Make(deltaX, 0.0, deltaY))

        latestTranslatePos = position

        if (state == .ended) {
            targetNode = nil
        }
    }
}

【讨论】:

  • 这适用于 2 轴,但是当我使用 UIRotationGestureRecognizer 用手指旋转对象然后尝试移动它时,它无法正常工作。当我从左向右移动手指时,它正在向相反方向移动 SCNode。有没有办法通过手指移动正确移动 SCNode 而与旋转无关?
  • 嗨@yaali。我只是在这里猜测,但也许如果你使用一些改变父节点或世界原点的位置的东西,你可以更正它而不是localTranslate:by。也许worldPositionposition
  • @leandrodemarco:你能帮我理解什么是“virtualObject(at: position)”吗?
  • virtualObject 这是什么
【解决方案2】:

有同样的问题。使用SCNTransaction 对我有用。

@objc private func handlePan(_ gesture: UIPanGestureRecognizer) {
    [...]

    SCNTransaction.begin()
    SCNTransaction.animationDuration = 0
    imagePlane.position.x = hitTestResult.localCoordinates.x
    imagePlane.position.y = hitTestResult.localCoordinates.y
    SCNTransaction.commit()
}

【讨论】:

    【解决方案3】:

    我遇到了类似的问题。虽然您应该在 cmets 中使用 John 的建议并使用正确的平移手势状态(开始、更改、结束),但我认为问题可能是您在应该抓取节点的父节点时抓取了 hitResult.node,或者甚至是父母的父母等等......我遇到了这个问题并最终通过提高父母级别来解决它,直到选择整个对象而不是它的一部分。

    【讨论】:

      猜你喜欢
      • 2018-09-01
      • 2018-01-12
      • 2019-01-30
      • 2018-05-18
      • 2018-08-03
      • 2018-08-04
      • 2016-03-25
      • 1970-01-01
      • 2018-01-02
      相关资源
      最近更新 更多