Nicoara Talpes
Nicoara Talpes

Reputation: 720

Moving a node in SceneKit using touch

I am trying to move a node in SceneKit by touch. I am using the code here: Move a specific node in SceneKit using touch

The issue that I am having is that every time I start a panGesture, the object I touch goes to the left corner of the scene to start the move. Moving it from that position and releasing are ok, just the issue that at every start of panning, the object resets from the left corner. If I zoom out, it resets itself from the corner of this new zoom level.

My code is:

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) {
    }
}

and

override func viewDidLoad() {
    super.viewDidLoad()
    let scnView = objectView
    scnView.backgroundColor = UIColor.whiteColor()
    scnView.autoenablesDefaultLighting = true
    scnView.allowsCameraControl = true

i am temporarily disabling the allowsCameraControl's panning functions before dragObject is called by doing this:

globalPanRecognizer = UIPanGestureRecognizer(target: self, 
    action:#selector(ViewController.dragObject(_:)))
objectView.addGestureRecognizer(globalPanRecognizer)

These are the values inside the first call to CGPointToSCNVector3 :

I have played with different variations of CGPointToSCNVector3 but no luck. What is the cause of this behavior? Thanks,

Upvotes: 6

Views: 5193

Answers (2)

Nicoara Talpes
Nicoara Talpes

Reputation: 720

The solution was to change sender.translationInView(sender.view!) to sender.translationInView(self.view!)

Upvotes: 4

drewster
drewster

Reputation: 6090

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)

Upvotes: 0

Related Questions