flickering, double vision with raycast on iPadOS 15.0

In ARKit+RealityKit I do a raycast from the ARView's center, then create an AnchorEntity at the result and add a target ModelEntity (a flattened cube) to the AnchorEntity.

guard let result = session.raycast(query).first else { return }
let newAnchor = AnchorEntity(raycastResult: result)
newAnchor.addChild(placementTargetEntity)
arView.scene.addAnchor(newAnchor)

I repeat this for each frame update via the ARSessionDelegate session(_:didUpdate:), removing the previous AnchorEntity first.

I use this as a target to let the user know where the full model will be placed when they tap the screen.

This works find under iOS 14, but I get strange results with iPadOS 15 - two different placements are created on different screen updates, offset from each other and slightly rotated from each other.

Has anyone else had issues with raycast() or creating an AnchorEntity from the result?

Is the use of session(_:didUpdate:) via ARSessionDelegate to update virtual content considered bad style now? (I noticed in the WWDC21 they used a different mechanism to update their virtual content.)

(If any Apple engineers read this, I filed a feedback with sample code and video of the issue at FB9535616)

Answered by Todd2 in 685381022

Found a work around.

I replaced

let newAnchor = AnchorEntity(raycastResult: result)

with

let newAnchor = AnchorEntity(world: result.worldTransform)

and I get expected results in both iOS 14.7 and iPadOS 15.

I don't know why I get different behaviors between iOS 14 and iPadOS 15 with the with the old style of getting an AnchorEntity, AnchorEntity(raycastResult: result), but consistent behaviors across iOS 14 and iPadOS 15 with the second approach, AnchorEntity(world: result.worldTransform).

I'll leave this marked an unsolved for a day or two hoping someone can suggest why the two initializers create different results on the two OSes.

Accepted Answer

Found a work around.

I replaced

let newAnchor = AnchorEntity(raycastResult: result)

with

let newAnchor = AnchorEntity(world: result.worldTransform)

and I get expected results in both iOS 14.7 and iPadOS 15.

I don't know why I get different behaviors between iOS 14 and iPadOS 15 with the with the old style of getting an AnchorEntity, AnchorEntity(raycastResult: result), but consistent behaviors across iOS 14 and iPadOS 15 with the second approach, AnchorEntity(world: result.worldTransform).

I'll leave this marked an unsolved for a day or two hoping someone can suggest why the two initializers create different results on the two OSes.

Just as a general comment – I think instead of creating a new anchor on every frame explicitly there is also a reanchor method on AnchorEntity that you could use (set preservingWorldTransform to false).

Yes, please try what Arthur mentioned above. You could also look at the tracked ray cast API. Also, your feedback item has been sent to the ARKit team for review.

Thanks guys!

If anyone runs across this post in the future, this is the change I made to use reanchor().

I don't know about performance improvements, but for me the code reads cleaner.

if let anchorEntity = self.placementAnchorEntity {
    // Update position of existing AnchorEntity
    anchorEntity.reanchor(.world(transform: result.worldTransform), preservingWorldTransform: false)
    return
}
// First time through, so create placementAnchorEntity and add to scene

I'm glad you were able to unblock yourself! It looks like the team is investigating this as a bug, so hopefully it'll get resolved.

flickering, double vision with raycast on iPadOS 15.0
 
 
Q