Swift:使用scenekit 中的projectPoint 随时间获取并保存更新的SCNNode [英] Swift: Obtain and save the updated SCNNode over time using projectPoint in scenekit

查看:32
本文介绍了Swift:使用scenekit 中的projectPoint 随时间获取并保存更新的SCNNode的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 projectPoint 来获取 Scenekit 中更新的 SCNNode 的二维信息并保存它们.

根据 ignotusverum 的建议,我可以将 SCNNode 保存到按钮中的路径中.

 var lastPosition: CGPoint?func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {守卫锚== currentFaceAnchor,让 contentNode = selectedContentController.contentNode,contentNode.parent == 节点否则{返回}for (index, vertex) in vertices.enumerated() {让顶点 = sceneView.projectPoint(node.convertPosition(SCNVector3(vertex), to: nil))让 xVertex = CGFloat(vertex.x)让 yVertex = CGFloat(vertex.y)位置 = CGPoint(x: xVertex, y: yVertex)}selectedContentController.session = sceneView?.sessionselectedContentController.sceneView = 场景视图selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)}


通过开始按钮开始保存:

 private var fpsTimer = Timer()私有变量 currentCaptureFrame = 0@IBAction 私有 func startPressed() {currentCaptureFrame = 0//初始捕获帧fpsTimer = Timer.scheduledTimer(withTimeInterval: 1/fps, repeats: true, block: {(timer) -> Void in self.recordData()})}


通过单击停止按钮保存它们:

@IBAction private func stopPressed() {做 {fpsTimer.invalidate()//关闭定时器let captureData = captureData.map{$0.stringRepresentation}.joined(separator:"\(lastPosition)>")让 dir: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last!作为网址让 url = dir.appendingPathComponent(testing.txt")尝试 captureData.appendLineToURL(fileURL: url as URL)}抓住 {打印(无法写入文件")}}

到目前为止,保存的点数工作正常.问题是在保存的数据中,我意识到数据只保存了 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?

提前致谢!

解决方案

如果我正确理解您的问题,您希望在每次更新顶点位置时保存它们,跟踪所有以前的更新以及最近的更新.为此,您只需将新的顶点位置数组附加到具有保存数据的全局数组中.

 var savedPositions = [CGPoint]()var beginSaving = falsefunc renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {守卫锚== currentFaceAnchor,让 contentNode = selectedContentController.contentNode,contentNode.parent == 节点否则{返回}对于顶点中的顶点{让projectedPoint = sceneView.projectPoint(node.convertPosition(SCNVector3(vertex), to: nil))如果开始保存{savedPositions.append(CGPoint(x:projectedPoint.x,y:projectedPoint.y))}}selectedContentController.session = sceneView?.sessionselectedContentController.sceneView = 场景视图selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)}@IBAction 私有 func startPressed() {开始保存 = 真}@IBAction 私有 func stopPressed() {开始保存 = 假....//对您保存的位置数组做任何事情}

I am trying to use projectPoint to get the 2D information of the updated SCNNode in scenekit and save them.

Based on ignotusverum's suggestion, I am able to save the SCNNode in to a path in a button.

     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)
        }


Started saving via a start button:

    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()})
    }


Saved them via a stop button clicks:

@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")
    }
}

So far works fine with the points being saved. The problem is that in the saved data, I realized the data is only saving one frame of the x and y vertices. For example:

[(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)

The data is repeating with one frame rather than the period I want to save from the moment when I click start button to stop button.

My question is how to save the updated SCNNode over time from the moment when I click start button to stop button?

Thanks in advance!

解决方案

If I understand your question correctly you want to save the vertex positions each time they are updated, keeping track of all previous updates as well as the most recent one. In order to do this you simply need to append the new vertex position array to the global array with saved data.

 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
}

这篇关于Swift:使用scenekit 中的projectPoint 随时间获取并保存更新的SCNNode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆