使用触摸移动 SceneKit 中的节点
Moving a node in SceneKit using touch
我正在尝试通过触摸移动 SceneKit 中的一个节点。
我在这里使用代码:
我遇到的问题是每次启动 panGesture 时,我触摸的对象都会转到场景的左角以开始移动。从那个位置移动它并释放是可以的,只是在每次开始平移时,对象从左角重置的问题。如果我缩小,它会从这个新缩放级别的一角重置自身。
我的代码是:
func CGPointToSCNVector3(view: SCNView, depth: Float, point: CGPoint) -> SCNVector3 {
let projectedOrigin = view.projectPoint(SCNVector3Make(0, 0, depth))
let locationWithz = SCNVector3Make(Float(point.x), Float(point.y), projectedOrigin.z)
return view.unprojectPoint(locationWithz)
}
func dragObject(sender: UIPanGestureRecognizer){
if(movingNow){
let translation = sender.translationInView(sender.view!)
var result : SCNVector3 = CGPointToSCNVector3(objectView, depth: tappedObjectNode.position.z, point: translation)
tappedObjectNode.position = result
}
else{
let hitResults = objectView.hitTest(sender.locationInView(objectView), options: nil)
if hitResults.count > 0 {
movingNow = true
}
}
if(sender.state == UIGestureRecognizerState.Ended) {
}
}
和
override func viewDidLoad() {
super.viewDidLoad()
let scnView = objectView
scnView.backgroundColor = UIColor.whiteColor()
scnView.autoenablesDefaultLighting = true
scnView.allowsCameraControl = true
我通过这样做在调用 dragObject 之前暂时禁用 allowsCameraControl 的平移功能:
globalPanRecognizer = UIPanGestureRecognizer(target: self,
action:#selector(ViewController.dragObject(_:)))
objectView.addGestureRecognizer(globalPanRecognizer)
这些是第一次调用 CGPointToSCNVector3 时的值:
- tappedObjectNode初始值:SCNVector3(x: 0.100000001, y: 0.100000001, z: 3.0)
- projectedOrigin : SCNVector3(x: 261.613159, y: 285.530396, z: 0.949569583) - 这异常大
- CGPointToSCNVector3 返回的值:SCNVector3(x: 1.03418088, y: 1.9734658, z: 4.64346933)
我玩过 CGPointToSCNVector3 的不同变体,但运气不好。
这种行为的原因是什么?
谢谢,
解决方案是将 sender.translationInView(sender.view!)
更改为 sender.translationInView(self.view!)
Swift 4.1 / Xcode 9.3 / iOS 11.3
// node that you want the user to drag
var tappedObjectNode = SCNNode()
// the SCNView
@IBOutlet weak var sceneView: SCNView!
// the scene
let scene = SCNScene()
//helper
func CGPointToSCNVector3(view: SCNView, depth: Float, point: CGPoint) -> SCNVector3 {
let projectedOrigin = view.projectPoint(SCNVector3Make(0, 0, depth))
let locationWithz = SCNVector3Make(Float(point.x), Float(point.y), projectedOrigin.z)
return view.unprojectPoint(locationWithz)
}
// gesture handler
var movingNow = false
@objc func dragObject(sender: UIPanGestureRecognizer){
if(movingNow){
let translation = sender.translation(in: sender.view!)
var result : SCNVector3 = CGPointToSCNVector3(view: sceneView, depth: tappedObjectNode.position.z, point: translation)
tappedObjectNode.position = result
} else {
// view is the view containing the sceneView
let hitResults = sceneView.hitTest(sender.location(in: view), options: nil)
if hitResults.count > 0 {
movingNow = true
}
}
}
// in viewDidLoad
sceneView.scene = scene
let panner = UIPanGestureRecognizer(target: self, action: #selector(dragObject(sender:)))
sceneView.addGestureRecognizer(panner)
我正在尝试通过触摸移动 SceneKit 中的一个节点。
我在这里使用代码:
我遇到的问题是每次启动 panGesture 时,我触摸的对象都会转到场景的左角以开始移动。从那个位置移动它并释放是可以的,只是在每次开始平移时,对象从左角重置的问题。如果我缩小,它会从这个新缩放级别的一角重置自身。
我的代码是:
func CGPointToSCNVector3(view: SCNView, depth: Float, point: CGPoint) -> SCNVector3 {
let projectedOrigin = view.projectPoint(SCNVector3Make(0, 0, depth))
let locationWithz = SCNVector3Make(Float(point.x), Float(point.y), projectedOrigin.z)
return view.unprojectPoint(locationWithz)
}
func dragObject(sender: UIPanGestureRecognizer){
if(movingNow){
let translation = sender.translationInView(sender.view!)
var result : SCNVector3 = CGPointToSCNVector3(objectView, depth: tappedObjectNode.position.z, point: translation)
tappedObjectNode.position = result
}
else{
let hitResults = objectView.hitTest(sender.locationInView(objectView), options: nil)
if hitResults.count > 0 {
movingNow = true
}
}
if(sender.state == UIGestureRecognizerState.Ended) {
}
}
和
override func viewDidLoad() {
super.viewDidLoad()
let scnView = objectView
scnView.backgroundColor = UIColor.whiteColor()
scnView.autoenablesDefaultLighting = true
scnView.allowsCameraControl = true
我通过这样做在调用 dragObject 之前暂时禁用 allowsCameraControl 的平移功能:
globalPanRecognizer = UIPanGestureRecognizer(target: self,
action:#selector(ViewController.dragObject(_:)))
objectView.addGestureRecognizer(globalPanRecognizer)
这些是第一次调用 CGPointToSCNVector3 时的值:
- tappedObjectNode初始值:SCNVector3(x: 0.100000001, y: 0.100000001, z: 3.0)
- projectedOrigin : SCNVector3(x: 261.613159, y: 285.530396, z: 0.949569583) - 这异常大
- CGPointToSCNVector3 返回的值:SCNVector3(x: 1.03418088, y: 1.9734658, z: 4.64346933)
我玩过 CGPointToSCNVector3 的不同变体,但运气不好。 这种行为的原因是什么? 谢谢,
解决方案是将 sender.translationInView(sender.view!)
更改为 sender.translationInView(self.view!)
Swift 4.1 / Xcode 9.3 / iOS 11.3
// node that you want the user to drag
var tappedObjectNode = SCNNode()
// the SCNView
@IBOutlet weak var sceneView: SCNView!
// the scene
let scene = SCNScene()
//helper
func CGPointToSCNVector3(view: SCNView, depth: Float, point: CGPoint) -> SCNVector3 {
let projectedOrigin = view.projectPoint(SCNVector3Make(0, 0, depth))
let locationWithz = SCNVector3Make(Float(point.x), Float(point.y), projectedOrigin.z)
return view.unprojectPoint(locationWithz)
}
// gesture handler
var movingNow = false
@objc func dragObject(sender: UIPanGestureRecognizer){
if(movingNow){
let translation = sender.translation(in: sender.view!)
var result : SCNVector3 = CGPointToSCNVector3(view: sceneView, depth: tappedObjectNode.position.z, point: translation)
tappedObjectNode.position = result
} else {
// view is the view containing the sceneView
let hitResults = sceneView.hitTest(sender.location(in: view), options: nil)
if hitResults.count > 0 {
movingNow = true
}
}
}
// in viewDidLoad
sceneView.scene = scene
let panner = UIPanGestureRecognizer(target: self, action: #selector(dragObject(sender:)))
sceneView.addGestureRecognizer(panner)