簡體   English   中英

Swift:使用scenekit中的projectPoint隨時間獲取並保存更新的SCNNode

[英]Swift: Obtain and save the updated SCNNode over time using projectPoint in scenekit

我正在嘗試使用projectPoint在 scenekit 中獲取更新的 SCNNode 的 2D 信息並保存它們。

根據 ignotusverum 的建議,我可以將 SCNNode 保存到按鈕中的路徑中。

     var lastPosition: CGPoint?
     func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
            guard anchor == currentFaceAnchor,
                let contentNode = selectedContentController.contentNode,
                contentNode.parent == node
                else { return }
            for (index, vertex) in vertices.enumerated() {
            let vertex = sceneView.projectPoint(node.convertPosition(SCNVector3(vertex), to: nil))
            let xVertex = CGFloat(vertex.x)
            let yVertex = CGFloat(vertex.y)
            Position = CGPoint(x: xVertex, y: yVertex)
           }
            selectedContentController.session = sceneView?.session
            selectedContentController.sceneView = sceneView
            selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)
        }

通過開始按鈕開始保存:

    private var fpsTimer = Timer()
    private var currentCaptureFrame = 0
    @IBAction private func startPressed() {
        currentCaptureFrame = 0 //inital capture frame
        fpsTimer = Timer.scheduledTimer(withTimeInterval: 1/fps, repeats: true, block: {(timer) -> Void in self.recordData()})
    }

通過單擊停止按鈕保存它們:

@IBAction private func stopPressed() {
    do {
        fpsTimer.invalidate() //turn off the timer
        let capturedData = captureData.map{$0.stringRepresentation}.joined(separator:"\(lastPosition)>")
        let dir: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! as URL
        let url = dir.appendingPathComponent("testing.txt")
        try capturedData.appendLineToURL(fileURL: url as URL)
    }
    catch {
        print("Could not write to file")
    }
}

到目前為止,在保存點的情況下工作正常。 問題是在保存的數據中,我意識到數據只保存了 x 和 y 頂點的一幀。 例如:

[(411.0618591308594, 534.4215087890625), (410.7286071777344, 544.9381713867188), (411.5425720214844, 522.1063232421875), (412.0340881347656, 512.1854248046875),... 

[(411.0618591308594, 534.4215087890625), (410.7286071777344, 544.9381713867188), (411.5425720214844, 522.1063232421875), (412.0340881347656, 512.1854248046875)

從單擊開始按鈕到停止按鈕的那一刻起,數據以一幀而不是我想要保存的時間重復。

我的問題是從我單擊開始按鈕到停止按鈕的那一刻起,如何隨着時間的推移保存更新的 SCNNode?

提前致謝!

SceneKit 每幀只調用一次此方法。 如果你在渲染器中做一些事情,你必須“完成它”然后離開,否則它會對 FPS 產生影響。

如果您需要移動或檢查大量循環內容,您可以使用計時器單獨執行這些工作,這樣您就可以對其進行一些控制。 您仍然可以保持您的 FPS 並在計時器中中斷循環或分塊工作。 如果你這樣做,只要確保你把定時器放在主線程中。

您還可以查看:node.presentation,即:屬性反映了由當前影響節點的任何飛行動畫確定的臨時值。

如果我正確理解您的問題,您希望在每次更新時保存頂點位置,跟蹤所有以前的更新以及最近的更新。 為了做到這一點,您只需要將 append 新的頂點 position 數組添加到保存數據的全局數組中。

 var savedPositions = [CGPoint]()
 var beginSaving = false

 func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
        guard anchor == currentFaceAnchor,
            let contentNode = selectedContentController.contentNode,
            contentNode.parent == node
            else { return }
        for vertex in vertices {
            let projectedPoint = sceneView.projectPoint(node.convertPosition(SCNVector3(vertex), to: nil))
            if beginSaving {
               savedPositions.append(CGPoint(x: projectedPoint.x, y: projectedPoint.y))
            }
        }
        selectedContentController.session = sceneView?.session
        selectedContentController.sceneView = sceneView
        selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)
}

@IBAction private func startPressed() {
    beginSaving = true
}

@IBAction private func stopPressed() {
    beginSaving = false
    ....//do whatever with your array of saved positions
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM