ARKit-调用func渲染器(_渲染器:SCNSceneRenderer,didAdd节点:SCNNode,锚点:ARAnchor)时,如何解决屏幕冻结问题

时间:2019-07-02 09:01:01

标签: swift arkit

我正在iPhone 7上设置ARKit-App,并且在检测到第一个(三分之一)ARImageAnchor时面临屏幕冻结的问题。要将SCNNodes引入UIView,我正在ARSCNViewDelegate中使用func renderer-didAdd方法。为了在不同ARReferenceImages的逻辑(对于所有场景几乎相等)之间进行切换,我使用了switch-case语句。此外,我将DispatchQueue.main.async-Statement用于多线程目的。在三个不同的.scn-Scenes中提供3D内容(请参见代码)。

此问题的奇怪之处在于,屏幕在加载第一个场景(仅一个对象)时会冻结一小段时间,但是在加载场景2和3(包含多个更复杂的对象)时会平稳运行。

为解决此问题,我已经尝试将DispatchQueue语句移到不同的位置-似乎不影响冻结。另外,我查看了统计信息,发现CPU在冻结到100%忙于从屏幕1渲染3D内容。

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    //
        if let imageAnchor = anchor as? ARImageAnchor {
            DispatchQueue.main.async {
            let name = imageAnchor.referenceImage.name!
            switch name {

            // Adding 3D Content associated with Marker A to positionImageAnchorA
            case "Trigger_A":   print ("Anchor A Deteced") //Debug
                                let boxNode = createImageOverlayNode(for: imageAnchor, DisScene: self.DisassemblySceneA)
                                self.positionImageAnchorA = boxNode
                                self.disStateCounter = 1
                                self.MarkerTracked.append(ARMarker(name: name, node: self.positionImageAnchorA)) // Information for Marker.isTracked?
                                self.MarkerADetected = true
                                node.addChildNode(self.positionImageAnchorA!)
                                return
            // Adding 3D Content associated with Marker B to positionImageAnchorB
            case "Trigger_B":   print ("Anchor B Deteced") //Debug
                                self.MarkerBDetected = true
                                self.MarkerTracked.append(ARMarker(name: name, node: self.positionImageAnchorB)) // Information for Marker.isTracked?
                                let boxNode = createImageOverlayNode(for: imageAnchor, DisScene: self.DisassemblySceneB)
                                self.positionImageAnchorB = boxNode
                                node.addChildNode(self.positionImageAnchorB!)
                                return

            // Adding 3D Content associated with Marker C to PositionImageAnchorC
            case "Trigger_C":   print ("Anchor C detected") // Debug
                                self.MarkerCDetected = true
                                self.MarkerTracked.append(ARMarker(name: name, node: self.positionImageAnchorC)) // Information for Marker.isTracked?
                                let boxNode = createImageOverlayNode(for: imageAnchor, DisScene: self.DisassemblySceneC)
                                self.positionImageAnchorC = boxNode
                                node.addChildNode(self.positionImageAnchorC!)
                                return
            // Default closing statement
            default: return

            }
        }
    }
}

/////////////////////////////////////////////////////////////////////
If interested in the logic createImageOverlayNode - please see below:
/////////////////////////////////////////////////////////////////////

func createImageOverlayNode(for anchor: ARImageAnchor, DisScene: SCNNode) -> SCNNode? {

// Creating green box for visualization of Tracking of AR Reference Image
    let box = SCNBox(width: anchor.referenceImage.physicalSize.width, height: 0.001, length: anchor.referenceImage.physicalSize.height, chamferRadius: 0)
    if let material = box.firstMaterial {
        material.diffuse.contents = UIColor.green
        material.transparency = 0.3
    }
    let boxNode = SCNNode(geometry: box)
    boxNode.name = "AR_Marker_B"

// Creating rootNode (Position of ARAnchor)
let rootNode = SCNNode()
rootNode.addChildNode(boxNode)

// Creating plane for showing 2D Text for spring removal and position in correctly
let planeForSpringNode = createTextOutputForSpringRemoval(anchor: anchor)
planeForSpringNode.name = "SpringRemoval"
planeForSpringNode.eulerAngles.x = -.pi / 2
planeForSpringNode.position = SCNVector3 (-0.06,0.016,0.016)

// Creating plane for showing 2D Arrow and position it correctly
let planeBoldNode = createBoldPlane()
planeBoldNode.name = "BoldRemoval"
planeBoldNode.eulerAngles.x = -.pi / 2

// Adding 3D Content to rootNode (Position of AR Anchor)
if DisScene.name == Optional("Scene_A") {
            rootNode.addChildNode(DisScene)
            return rootNode
}
else if DisScene.name == Optional("Scene_B") {

        // Adding 3D Content constructed via code (in here)
        rootNode.addChildNode(planeForSpringNode)
        rootNode.addChildNode(planeBoldNode)

        // Adding all ChildNodes of DisScene as ChildNodes of "boxnode"
        DisScene.childNodes.forEach{ element in
            addChildNodes(destinationNode: rootNode, sourceNode: element)
            print (element)
        }


        // Hiding all ChildNodes of "boxnode" -> Unhide in ARSCNDelegate when needed
        rootNode.childNodes.forEach{ element in
            hideSCNNodeWithMarkerPlane(inputNode: element)
            }

        // Positioning constructed planes to SCNNodes Coordinates
        let positionFederhalterLang = rootNode.childNode(withName: "Federhalter_lang", recursively: false)!.position
        let positionSpring = rootNode.childNode(withName: "Feder", recursively: false)!.position
        rootNode.childNode(withName: "BoldRemoval", recursively: false)!.position = positionFederhalterLang
        rootNode.childNode(withName: "SpringRemoval", recursively: false)!.position = addTwoVectors(first: positionSpring,second: SCNVector3(0,0,-0.01))

        // Hide green box for AR Reference Image again
        rootNode.childNode(withName: boxNode.name!, recursively: false)!.isHidden = true

        return rootNode
    }

else if DisScene.name == Optional("Scene_C"){

    // Adding all ChildNodes of DisScene as ChildNodes of "boxnode"
    DisScene.childNodes.forEach{ element in
        addChildNodes(destinationNode: rootNode, sourceNode: element)
    }
    // Hiding all ChildNodes of "boxnode" -> Unhide in ARSCNDelegate when needed
    rootNode.childNodes.forEach{ element in
        hideSCNNodeWithMarkerPlane(inputNode: element)
    }
    // Hide green box for AR Reference Image again
    rootNode.childNode(withName: boxNode.name!, recursively: false)!.isHidden = true

    return rootNode
}
return nil
}

0 个答案:

没有答案