如何使用ARKit和Gesture Recognizer相对于摄像机位置移动和旋转父节点的子SCNode

时间:2019-05-13 04:20:01

标签: swift arkit pan scnnode

我正在使用ARKit(SceneKit)开发基于AR的iOS应用。我使用Apple示例代码https://developer.apple.com/documentation/arkit/handling_3d_interaction_and_ui_controls_in_augmented_reality作为基础。使用此工具,我可以移动或旋转整个虚拟对象。

但是我想使用用户手指在虚拟对象中选择和移动/旋转子节点,类似于我们移动/旋转整个虚拟对象本身的方式。

我必须删除SCNReferenceNode的子级VirtualObject类,因为我需要使用SCNNode。所以我在VirtualObjectInteraction中结合了所有逻辑。

Apples代码可以相对于相机位置移动所有.scn对象,从而完美发挥作用。但是在我的情况下,当我尝试移动this.scn对象的子节点时,只有当我在它前面时,它才起作用。但是,当我尝试从另一侧移动对象时,它无法正常工作。当我从左向右移动手指时,它正在沿相反的方向移动SCNode。

请帮助,我几天都无法解决这个问题。

这是我平移手势的代码

@objc
func didPan(_ gesture: ThresholdPanGesture) {

    switch gesture.state {
    case .began:
        if let object = objectInteracting(with: gesture, in: sceneView) {
            trackedObject = object
        }

    case .changed where gesture.isThresholdExceeded:
        guard let object = trackedObject else { return }
        let translation = gesture.translation(in: sceneView)

        if ARTourVC.isSceneObjectPlacement {
            //this code work only if you in front of selected child node
            object.position = SCNVector3Make(object.position.x + Float(translation.x * 0.01 * CGFloat(object.scale.x)), object.position.y, object.position.z + Float(translation.y * 0.01 * CGFloat(object.scale.z)))
        }
        else {
            //This code work perfect for all .scn object
            let currentPosition = currentTrackingPosition ?? CGPoint(sceneView.projectPoint(object.position))
            currentTrackingPosition = CGPoint(x: currentPosition.x + translation.x, y: currentPosition.y + translation.y)
        }

        gesture.setTranslation(.zero, in: sceneView)

    case .changed:
        break

    case .ended:
        guard let existingTrackedObject = trackedObject else { break }
        sceneView.addOrUpdateAnchor(for: existingTrackedObject)
        fallthrough

    default:
        currentTrackingPosition = nil
        trackedObject = nil
    }
}

0 个答案:

没有答案