Перетаскивание SCNNode в ARKit Использование SceneKit
У меня есть простой SCNNode в ARKit, и я пытаюсь перетащить его туда, куда я двигал пальцем по телефону. Вот мой код.
@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)
}
}
Проблема в том, что перетаскивание происходит очень медленно и не является гладким.
Ответы
Ответ 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 on a virtual object
if let objectNode = virtualObject(at: position) {
// virtualObject(at searches for root node if it 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
У меня была аналогичная проблема. В то время как вы должны использовать совет Джона в комментариях и использовать правильные состояния жесты (Начал, Изменен, Закончен), я думаю, проблема может заключаться в том, что вы захватываете hitResult.node, когда вы должны захватывать родительский элемент node, или даже родительский родитель и т.д. У меня была эта проблема, и я решил ее исправить, перейдя на родительские уровни, пока весь объект не будет выбран, а не его часть.
Ответ 3
Была такая же проблема. Использование 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()
}