0
votes

I started out with the template project which you get when you choose ARKit project. As you run the app you can see the ship and view it from any angle.

However, once I allow camera control and tap on the screen or zoom into the ship through panning the ship gets stuck to camera. Now wherever I go with the camera the ship is stuck to the screen.

I went through the Apple Guide and seems like the don't really consider this as unexpected behavior as there is nothing about this behavior.

How to keep the position of the ship fixed after I zoom it or touch the screen?

1
As far as I’m aware allowcameracontrols shouldn’t be used with ARKit but SceneKit :)BlackMirrorz
Hmm.. Interesting. Maybe that's why so many articles I am reading talk about hit testing. Let's see if I can work out with that.Rishab
If you want to manipulate your object e.g rotate and scale post another question and I’d be happy to answer :)BlackMirrorz
I really appreciate your help. But I'd like to rack by brain a little bit more :) If I can't I'll surely be asking a question soon :DRishab
Good philosophy :) try first ask later :)BlackMirrorz

1 Answers

0
votes

Well, looks like allowsCameraControl is not the answer at all. It's good for SceneKit but not for ARKit(maybe it's good for something in AR but I'm not aware of it yet).

In order to zoom into the view a UIPinchGestureRecognizer is required.

    // 1. Find the touch location
    // 2. Perform a hit test
    // 3. From the results take the first result
    // 4. Take the node from that first result and change the scale
    @objc private func handlePan(recognizer: UIPinchGestureRecognizer) {
        if recognizer.state == .changed {
            // 1.
            let location = recognizer.location(in: sceneView)

            // 2.
            let hitTestResults = sceneView.hitTest(location, options: nil)

            // 3.
            if let hitTest = hitTestResults.first {
                let shipNode = hitTest.node

                let newScaleX = Float(recognizer.scale) * shipNode.scale.x
                let newScaleY = Float(recognizer.scale) * shipNode.scale.y
                let newScaleZ = Float(recognizer.scale) * shipNode.scale.z

               // 4.
                shipNode.scale = SCNVector3(newScaleX, newScaleY, newScaleZ)

                recognizer.scale = 1
            }
        }

Regarding #2. I got confused a little with another hitTest method called hitTest(_:types:)

Note from documentation

This method searches for AR anchors and real-world objects detected by the AR session, not SceneKit content displayed in the view. To search for SceneKit objects, use the view's hitTest(_:options:) method instead.

So that method cannot be used if you want to scale a node which is a SceneKit content