[英]Dragging SCNNode in ARKit Using SceneKit
我在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)
}
}
问题是阻力很慢而且不平滑。
我像这样处理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
}
}
}
我遇到了类似的问题。 虽然您应该在评论中使用John的建议并使用平移手势状态正确(开始,更改,结束),但我认为问题可能是您在抓住节点的父节点时抓住了hitResult.node,或者甚至父母的父母等...我已经遇到了这个问题并最终通过上升父级来修复它,直到整个对象被选中而不是它的一部分。
有同样的问题。 使用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()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.