[Swift, ARKit] Migrate from deprecated hitTest to raycastQuery

iOS 14 has been officially released. Along with this, ARKit also moved from 3.5 to 4.0, but it existed in ARSCN View in that.

open func hitTest(_ point: CGPoint, types: ARHitTestResult.ResultType) -> [ARHitTestResult]

Function has been deprecated.

I think the purpose of this function is to get the position of the place traced with your fingertip when moving the 3D object placed in ARSCNView. For example, the code below.

@IBOutlet var scnView: ARSCNView!

override func viewDidLoad() {
    super.viewDidLoad()

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(pan))
    self.scnView.addGestureRecognizer(panGesture)
}

@objc
func pan(_ sender: UIPanGestureRecognizer) {
    //This hitTest is[SCNHitTestResult]Is different from the deprecated function that returns
    guard let node = scnView.hitTest(sender.location(in: scnView), options: nil).first?.node else {
        return
    }
    //This is a deprecated function
    guard let transform = scnView.hitTest(sender.location(in: scnView), types: .existingPlaneUsingExtent).first?.worldTransform else {
        return
    }
    node.setWorldTransform(SCNMatrix4(transform))
}

Depending on the code, there may be some differences, such as switching depending on the state of the sender, or using if let instead of guard.

If you rewrite this into raycastQuery, it will look like the following.

//Variable declaration and viewDidLoad()Is omitted

@objc
func pan(_ sender: UIPanGestureRecognizer) {
    guard let node = scnView.hitTest(sender.location(in: scnView), options: nil).first?.node else {
        return
    }
    //Where I changed
    guard let raycast = scnView.raycastQuery(from: sender.location(in: scnView),
                                                  allowing: .estimatedPlane,
                                                  alignment: .any),
          let result = scnView.session.raycast(raycast).first? else {
        return
    }
    node.setWorldTransform(SCNMatrix4(result.transform))
}

The ARRaycastQuery obtained from the ARSCNView main unit is sent to the ARSCNView session this time, and the [ARRaycastResult] is obtained again from there. Instead of using the tapped part of ARSCNView as it is, you put a session in between.

Since ARRaycastResult itself has not changed, there is no problem with the same usage as when it was acquired by hitTest.

Next, let's check the contents of raycastQuery.

open func raycastQuery(from point: CGPoint, allowing target: ARRaycastQuery.Target, alignment: ARRaycastQuery.TargetAlignment) -> ARRaycastQuery?

The first argument remains the same. Both the second and third arguments are enums in ARRaycastQuery.

Click here for the second argument enum.

public enum Target : Int {
    case existingPlaneGeometry = 0
    case existingPlaneInfinite = 1
    case estimatedPlane = 2
}

It is for determining what is present at the point. If you want a plane with a fixed size, select existingPlaneInfinite, and if you want a rough plan, select estimatedPlane.

Next is the third argument enum.

public enum TargetAlignment : Int {
    case horizontal = 0
    case vertical = 1
    case any = 2
}

This is a list of three options: whether the location is vertical, horizontal, or either.

Both the second argument and the third argument are new, but I think you can think that you can now freely combine them by decomposing the ARHitTestResult.ResultType used in hitTest.

Since hitTest is only deprecated, it can be used, but I would like to change it from time to time.

Recommended Posts

[Swift, ARKit] Migrate from deprecated hitTest to raycastQuery
Migrate from JUnit 4 to JUnit 5
How to migrate from JUnit4 to JUnit5
Migrate from on-premise Pukiwiki to esa.io \ (⁰⊖⁰) /
How to call Swift 5.3 code from Objective-C
Convert from C String pointer to Swift String type
Migrate Ubuntu 18.04 LTS from HDD to smaller SSD
Migrate from Java to Server Side Kotlin + Spring-boot
Migrate from Transport Client to Rest High Level Client
[Swift] Skill map from inexperienced to practical (roadmap)
[Swift] How to play songs from your music library
Generate models from JSON to Swift, PHP, C #, JAVA