Я работаю над приложением для 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
}
}