如何记录 ARCamera 随着时间的推移的位置和旋转并将其保存到文件中?

2023-12-04

我已经尝试创建一个 ARView 两天多了,它可以随时间记录相机在空间中的位置,然后将其保存到关键帧文件中。基本上,我想创建一个应用程序,让您记录虚拟相机的运动,然后可以在 3D 应用程序中使用,例如Autodesk Maya or Cinema4D驱动相机。首选文件输出是任何可以容纳相机对象并随时间对其进行动画处理的东西(或者也可以是随时间移动的对象,然后我可以将相机作为其父对象)。

这是我的代码,抱歉它有点混乱,我尝试了很多不同的东西...基本上我尝试记录设备位置和旋转,然后将其保存到 MDL 对象,但不知何故它没有动画。我还尝试了多种不同的文件类型(其中一些不支持关键帧动画,所以这没有帮助,但据我了解,Alembic 可以)

import SwiftUI
import ARKit
import RealityKit
import ModelIO

struct ARViewContainer: UIViewRepresentable {
    let session = ARSession()
    let delegate = MySessionDelegate()
    
    func makeUIView(context: Context) -> ARView {
        // Set up the ARView with session
        let arView = ARView(frame: .zero)
        let boxAnchor = try! Experience.loadBox()
        arView.scene.anchors.append(boxAnchor)
        arView.session.delegate = delegate // assign delegate to the session
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {
        // Update the ARView if needed
    }
    
    func startARSession() {
        // Start the ARSession
        let configuration = ARWorldTrackingConfiguration()
        configuration.planeDetection = [.horizontal, .vertical]
        session.run(configuration, options: [])
    }
    
    func stopARSession() {
        // Stop the ARSession
        session.pause()
    }
}

class MySessionDelegate: NSObject, ARSessionDelegate {
    var object: MDLMesh?
    let asset = MDLAsset()
    let cameraTransform = MDLTransform()
    var documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
            // Get the camera position and orientation for the current frame
            let transform = frame.camera.transform
            let rotation = frame.camera.eulerAngles
            let position = transform.columns.3
            let elapsedTime = frame.timestamp
            cameraTransform.setTranslation(position[SIMD3(0,1,2)], forTime: elapsedTime)
            cameraTransform.setRotation(rotation, forTime: elapsedTime)
            print("Camera Transform: \(cameraTransform.matrix)")
    }

}

struct Camera: View {
    var body: some View {
        VStack {
            ARViewContainer().onAppear(perform: ARViewContainer().startARSession)
                .onDisappear(perform: ARViewContainer().stopARSession)
            Button("Export Recording") {
                // Create an MDLAsset with a box representing the camera transform
                let object = MDLMesh(boxWithExtent: .init(0.1, 0.1, 0.1), segments: .init(10, 10, 10), inwardNormals: false, geometryType: .triangles, allocator: nil)
                object.name = "Camera Transform"
                object.transform = MySessionDelegate().cameraTransform
                
                let asset = MDLAsset()
                asset.add(object)
                
                // Export the MDLAsset to a file
                let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
                let fileURL = documentsDirectory.appendingPathComponent("recording.abc")
                try! asset.export(to: fileURL)
            }
        }
        
    }
}

如果有完全不同的方法,也请分享,我先感谢大家的帮助!


每秒记录 60 个 4x4 变换矩阵

写一个4x4 变换矩阵(即存储平移、旋转和缩放的复杂变换)到文本文件,我使用write(to:)实例方法。点击后Record Transform Values按钮,数据立即开始写入toMaya.txt文件。为了方便起见,我将矩阵的所有 16 个值都放在屏幕上(我在 iPad 上测试了这一点,因此请使用屏幕更大的设备)。再次按下该按钮将停止录制。

数据来自嵌套列表 in the toMaya.txt可以使用常规 Python 或 MEL 脚本轻松读取文件。看看嵌套是什么样子的。每一个16 个矩阵值​​在Float type.

enter image description here

[x0,y0,z0,w0]是第一个矩阵列,[x1,y1,z1,w1]是第二个矩阵列,等等。

这是代码:

import SwiftUI
import RealityKit
import Combine

struct ARViewContainer : UIViewRepresentable {
    @Binding var arView: ARView

    func makeUIView(context: Context) -> ARView { return arView }
    func updateUIView(_ view: ARView, context: Context) { }
}

struct ContentView : View {
    
    @State private var arView = ARView(frame: .zero)
    @State private var subs: [AnyCancellable] = []
    @State private var array: [[[Float]]] = [[ [1,0,0,0], [0,1,0,0],
                                               [0,0,1,0], [0,0,0,1] ]]
    @State private var boolean = false
    
    let url = FileManager.default.urls(for: .documentDirectory,
                                        in: .userDomainMask)[0]
                                 .appendingPathComponent("toMaya.txt")
                                 
    var body: some View {
        ZStack {
            ARViewContainer(arView: $arView).ignoresSafeArea()
            VStack {
                Button("Record Transform Values") {
                    boolean.toggle()

                    DispatchQueue.main.async {
                        arView.scene.subscribe(to: SceneEvents.Update.self) { _ in
                                                        
                            let col = arView.cameraTransform.matrix.columns
                            
                            let mtx: [[Float]] = [
                                        [col.0.x, col.0.y, col.0.z, col.0.w],
                                        [col.1.x, col.1.y, col.1.z, col.1.w],
                                        [col.2.x, col.2.y, col.2.z, col.2.w],
                                        [col.3.x, col.3.y, col.3.z, col.3.w]
                            ]
                            if boolean {
                                array.append(mtx)
                            }
                            if let data = try? JSONEncoder().encode(self.array) {

                                guard let str = String(data: data, encoding: .ascii)
                                else { return }
                                
                                do {
                                    if boolean {
                                        try str.write(to: url, atomically: true,
                                                                 encoding: .ascii)
                                    }
                                } catch {
                                    print(error.localizedDescription)
                                }
                                print(url)
                            }
                        }.store(in: &subs)
                    }
                }
                Spacer()
            }
            VStack {
                Spacer()
                Text("\(array.count)").foregroundColor(.white)
            }
            HStack {
                VStack {
                    Text("\(array.last![0][0])").foregroundColor(.white)
                    Text("\(array.last![0][1])").foregroundColor(.white)
                    Text("\(array.last![0][2])").foregroundColor(.white)
                    Text("\(array.last![0][3])").foregroundColor(.white)
                }
                VStack {
                    Text("\(array.last![1][0])").foregroundColor(.white)
                    Text("\(array.last![1][1])").foregroundColor(.white)
                    Text("\(array.last![1][2])").foregroundColor(.white)
                    Text("\(array.last![1][3])").foregroundColor(.white)
                }
                VStack {
                    Text("\(array.last![2][0])").foregroundColor(.white)
                    Text("\(array.last![2][1])").foregroundColor(.white)
                    Text("\(array.last![2][2])").foregroundColor(.white)
                    Text("\(array.last![2][3])").foregroundColor(.white)
                }
                VStack {
                    Text("\(array.last![3][0])").foregroundColor(.white)
                    Text("\(array.last![3][1])").foregroundColor(.white)
                    Text("\(array.last![3][2])").foregroundColor(.white)
                    Text("\(array.last![3][3])").foregroundColor(.white)
                }
            }
        }
    }
}

My toMaya.txt文件在下面等我调试目录:

file:///var/mobile/Containers/Data/Application/7C675F52-C78B-4252-98B5-3EBD37A3F832/Documents/toMaya.txt

之后您可以导出您的toMaya.txt文件到 Mac 使用UIActivityViewController.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何记录 ARCamera 随着时间的推移的位置和旋转并将其保存到文件中? 的相关文章

  • Swift 3 中的 JSON 解析

    有没有人能够找到一种在 Swift 3 中解析 JSON 文件的方法 我已经能够返回数据 但在将数据分解为特定字段时我没有成功 我会发布示例代码 但我已经尝试了很多不同的方法但没有成功 并且没有保存任何代码 我想要解析的基本格式是这样的 提
  • 调用 SwiftUI 中位置 #11、#12 处的额外参数 [重复]

    这个问题在这里已经有答案了 我在 SwiftUI 中的切换开关上不断收到 调用中位置 11 12 处有额外参数 错误 我见过其他人有 调用中的额外参数 错误 但答案似乎没有帮助 另外 我的错误是 位置 11 12 我还没有看到其他人发生这种
  • 以编程方式从底部裁剪图像

    我正在开发自定义相机应用程序 一切进展顺利 但我在从底部裁剪图像时遇到了问题 即 裁剪后的图像与原始图像具有完全相同的宽度 但高度将为原始图像的 1 3 并且必须从底部开始 斯威夫特3解决方案 func cropBottomImage im
  • 具有多个 ViewBuilder 的 SwiftUI 视图

    我有一个视图 表示单元格中的一行 如下所示 这很有效 但三个水平元素 图像 标题 副标题 图像 被硬编码为其各自的类型 我想要一个通用的ThreeItemView这可能需要 3Views任何类型并如图所示排列它们 这将允许我将相同的容器布局
  • iOS 防止计时器 UILabel 在数字变化时“晃动”

    我有一个UILabel它以以下格式显示计时器的输出MM ss SS 分 秒 厘秒 但是随着厘秒宽度的变化 它从左向右 摇动 例如 11 比 33 窄 有什么办法可以减轻这种情况吗 我尝试过将其居中 给它固定的宽度 但它们似乎没有帮助 从iO
  • AWS S3 公共对象与私有对象?

    回到 S3 我的存储桶中有图像的 URL 我将在我的应用程序中呈现这些图像 但它们被设置为私有 当我尝试单击该链接时 它显示 访问被拒绝 当我将链接的设置更改为公共时 它会通过 但是我读到公共访问并不是最安全的事情 所以这本质上是一个由两部
  • 如何将字符串日期转换为 NSDate?

    我想转换字符串 2014 07 15 06 55 14 198000 00 00 to an NSDate在斯威夫特 尝试这个 let dateFormatter NSDateFormatter dateFormatter dateForm
  • 所需框架与静态库

    构建现代框架 https developer apple com videos play wwdc2014 416 says 每个应用程序都有自己的自定义框架副本 https stackoverflow com a 15262463 242
  • 在真实设备上展示测试广告

    这是我的代码 let request GADRequest request testDevices kGADSimulatorID XXXX2F32d69CCA859FFB559D0FEA3CF6483D08A6 adView load r
  • SKNode 上的 runAction 未完成

    我使用 NSOperation 子类来获取串行执行SKAction正如这个问题中所描述的 如何在 Swift 中子类化 NSOperation 以将 SKAction 对象排队以进行串行执行 https stackoverflow com
  • Swift C 回调 - Swift 类指针的 takeUnretainedValue 或 takeRetainedValue

    我有一些UIView or UITableViewCell 里面我有 C 回调 例如 CCallback bridge self observer data gt Void in let mySelf Unmanaged
  • 在 swrevealcontroller 之前实现登录屏幕

    我刚刚开始学习 IOS 开发 我已经按照给定的在线教程成功实现了 SWRevealViewController 一切都按预期工作 然后 我决定添加一个登录屏幕 这将是应用程序运行时用户看到的第一个页面 我采取的步骤如下 将 UIViewCo
  • Swift 闭包作为 AnyObject

    我尝试使用这个方法 class addMethod 在 Obj c 中使用如下 class addMethod self class selector eventHandler imp implementationWithBlock han
  • Swift 3 中是否提供内置内部函数?

    我可以在 Xcode 自动完成弹出窗口中看到各种内置函数 如 builtin popount builtin clz 等 我不确定这些是从哪里获取的 单击命令不会导致快速定义或任何文档 Swift 3 中是否有 builtin 或等效的内部
  • 如何防止 RealmSwift 列表中出现重复项?

    如何防止向列表中添加重复项RealmSwift 我有我的User作为领域对象 但真正的数据源是服务器 只是使用领域在本地缓存用户 当我从服务器获取当前用户数据时 我想确保存储在领域中的用户拥有来自服务器的所有播放列表 以及它们的曲目列表等
  • 迭代 NSOrderedSet

    我正在尝试迭代 NSOrderedSet 的实例 像这样的事情 func myFunc var orderedSet NSOrderedSet array 42 43 44 for n in orderedSet NSLog i n 但是
  • 在另一种语言中使用 dateFormatter [重复]

    这个问题在这里已经有答案了 我正在运行一段返回的代码nil在具有不同语言设置的 iPhone 上运行时 代码示例如下所示 let dateFormatter DateFormatter dateFormatter dateFormat MM
  • UISearchController 保留问题

    我正在尝试使用 UISearchController 但是我遇到了无法解决的保留问题 MainTableview 有两个部分 第1节 基于某些正则表达式过滤数据 第2节 All Data 我将 UISearchController 添加到我
  • 为什么我的 tableView 函数运行了 3 次?

    我有一个 UITableView 并且有执行它所需的方法之一 func tableView tableView UITableView numberOfRowsInSection section Int gt Int println sec
  • ResponseSerializer“无法使用 Swift 3 调用非函数类型“NSHTTPURLResponse”的值?

    我一直在使用以下代码 没有出现任何问题 直到更新到 Xcode 8 beta 6 它类似于这个例子 https github com Alamofire Alamofire generic response object serializa

随机推荐