ARSCNView freezes when adding 14 ARAnchor subclass

2019-08-27 10:57发布

问题:

I have next code:

    guard let feauturePoint = frame.hitTest(normalizedPoint, types: .featurePoint).first?.worldTransform else {
        return
    }
    let anchor = MyAnchorSubclass(transform: feauturePoint, plus: someAdditionalInfo)
    arSession.add(anchor: anchor)

This function creates and adds object of my subclass of ARAnchor. Then...

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let anchor = anchor as? MyAnchorSubclass else { return }
        anchors.append(anchor)
        /* then goes some my logic with adding SCNNode */
    }

... after anchor was rendered, I'm adding my SCNNode there. But, when I'm using anchors.append(anchor), where anchors is [MyAnchorSubclass], scene freezes right after 14 added anchors. If I'm not saving anchor in array, scene view does not freezes.

Does anyone know what is it? iOS 11 Beta bug or some kind of limitations?

UPDATE

Last, what happens - is renderer(_:didUpdate:for:) being called and after it scene view freezes and few [Technique] World tracking performance is being affected by resource constraints [0] messages appears in log.

UPDATE 1

Interesting fact: after app goes to the background and returns back, sessionWasInterrupted(:) and sessionInterruptionEnded(:) being called, even though scene view was freezed before.

回答1:

Ok, your issue is, you don’t want to be maintaining your own array of the anchors. You want to be maintaining an array of the identifiers (UUID) of each anchor. In Apple docs:

Anchors are considered equal based on their identifier property.

Reason being, ARKit calls init(anchor:) on a background thread to copy instances of your anchor class from each ARFrame to the next. In storing an array of each ARAnchor you are only holding-on to one set of instances of those anchors in time, that would otherwise have been discarded by ARKit.

With your array of UUIDs of the anchors, if you need to reference one, iterate through the anchors in the session for the current ARFrame, searching for the UUID of the one you need to do something with.

You could use something along the lines of:

func anchorForID(_ anchorID: UUID) -> ARAnchor? {

    return session?.currentFrame?.anchors.first(where: { $0.identifier == anchorID })

}


回答2:

Does anyone know what is it? iOS 11 Beta bug or some kind of limitations?

Please implement the callback session(_:didFailWithError:) so you can see what ARError is returned when your ARSession fails—causing your screen to freeze.


NB. if you receive the Code=200 "World tracking failed." I would very much like to know, because I'm diagnosing that over here.