首页 文章

使用 SceneKit 在 ARKit 中拖动 SCNNode

提问于
浏览
11

我在 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)
        }
    }

问题是阻力很慢而且不平滑。

3 回答

  • 0

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

  • 0

    有同样的问题。使用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()
    }
    
  • 4

    我像这样处理 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
            }
        }
    }
    

相关问题