Как переместить и повернуть дочерний SCNode родительского узла с помощью ARKit и Gesture Recognizer относительно положения камеры - PullRequest
0 голосов
/ 13 мая 2019

Я работаю над приложением для iOS на основе AR, используя ARKit (SceneKit). Для этого я использовал образец кода Apple https://developer.apple.com/documentation/arkit/handling_3d_interaction_and_ui_controls_in_augmented_reality. С его помощью я могу перемещать или вращать весь виртуальный объект.

Но я хочу выбрать и переместить / повернуть дочерний узел в виртуальном объекте с помощью пальца пользователя, аналогично тому, как мы перемещаем / вращаем сам весь виртуальный объект.

Мне пришлось удалить класс VirtualObject, который был потомком SCNReferenceNode, потому что мне нужно работать с SCNNode. Поэтому я объединил всю логику в VirtualObjectInteraction.

Код Apple прекрасно работает с перемещением всего объекта .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
    }
}
...