[
  {
    "path": ".gitignore",
    "content": "## User settings\nxcuserdata/\n\n## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)\n*.xcscmblueprint\n*.xccheckout\n\n## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)\nbuild/\nDerivedData/\n*.moved-aside\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\n\n## Obj-C/Swift specific\n*.hmap\n\n## App packaging\n*.ipa\n*.dSYM.zip\n*.dSYM\n\n## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n#\n# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.\n# Packages/\n# Package.pins\n# Package.resolved\n# *.xcodeproj\n#\n# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata\n# hence it is not needed unless you have added a package configuration file to your project\n# .swiftpm\n\n.build/\n\n# CocoaPods\n#\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n#\n# Pods/\n#\n# Add this line if you want to avoid checking in source code from the Xcode workspace\n# *.xcworkspace\n\n# Carthage\n#\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\nCarthage/Build/\n\n# Accio dependency management\nDependencies/\n.accio/\n\n# fastlane\n#\n# It is recommended to not store the screenshots in the git repo.\n# Instead, use fastlane to re-generate the screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/#source-control\n\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots/**/*.png\nfastlane/test_output\n\n# Code Injection\n#\n# After new code Injection tools there's a generated folder /iOSInjectionProject\n# https://github.com/johnno1962/injectionforxcode\n\niOSInjectionProject/"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.2.0\nmessage: \"If you use this software, please cite it as below.\"\nauthors:\n- family-names: \"Abou-Chakra\"\n  given-names: \"Jad\"\n  orcid: \"https://orcid.org/0000-0002-9122-3132\"\ntitle: \"NeRFCapture: A tool for streaming posed images\"\nversion: 1.0.0\nurl: \"https://github.com/jc211/NeRFCapture\""
  },
  {
    "path": "LICENCE",
    "content": "MIT License\n\nCopyright (c) 2023 Jad Abou-Chakra \n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "NeRFCapture/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport UIKit\nimport SwiftUI\n\n@main\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n    var window: UIWindow?\n    var view: ContentView?\n    \n    var appSettings = AppSettings()\n    var datasetWriter = DatasetWriter()\n    var ddsWriter = DDSWriter()\n\n    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {\n\n        // Create the SwiftUI view that provides the window contents.\n        let viewModel = ARViewModel(datasetWriter: datasetWriter, ddsWriter: ddsWriter)\n        let contentView = ContentView(viewModel: viewModel)\n\n        // Use a UIHostingController as window root view controller.\n        let window = UIWindow(frame: UIScreen.main.bounds)\n        window.rootViewController = UIHostingController(rootView: contentView)\n        self.window = window\n        self.view = contentView\n        window.makeKeyAndVisible()\n        return true\n    }\n\n    func applicationWillResignActive(_ application: UIApplication) {\n        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.\n        datasetWriter.clean()\n        saveSettings()\n    }\n\n    func applicationDidEnterBackground(_ application: UIApplication) {\n        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n        datasetWriter.clean()\n        saveSettings()\n    }\n\n    func applicationWillEnterForeground(_ application: UIApplication) {\n        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.\n    }\n    \n\n    func applicationDidBecomeActive(_ application: UIApplication) {\n        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n    }\n    \n    \n    func saveSettings() {\n        let encoder = JSONEncoder()\n        if let data = try? encoder.encode(appSettings) {\n            UserDefaults.standard.set(data, forKey: \"appSettings\")\n        }\n    }\n    \n    func loadSettings() {\n        if let data = UserDefaults.standard.data(forKey: \"appSettings\") {\n            do {\n                let decoder = JSONDecoder()\n                appSettings = try decoder.decode(AppSettings.self, from: data)\n            } catch {\n                appSettings = AppSettings()\n            }\n        }\n    }\n\n\n}\n\n"
  },
  {
    "path": "NeRFCapture/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"color\" : {\n        \"color-space\" : \"srgb\",\n        \"components\" : {\n          \"alpha\" : \"1.000\",\n          \"blue\" : \"0xB0\",\n          \"green\" : \"0x11\",\n          \"red\" : \"0xAC\"\n        }\n      },\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "NeRFCapture/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"Icon-40.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"Icon-60.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"Icon-29.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"1x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"Icon-58.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"Icon-87.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"Icon-80.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"Icon-120.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"Icon-57.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"1x\",\n      \"size\" : \"57x57\"\n    },\n    {\n      \"filename\" : \"Icon-114.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"57x57\"\n    },\n    {\n      \"filename\" : \"Icon-120 1.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"2x\",\n      \"size\" : \"60x60\"\n    },\n    {\n      \"filename\" : \"Icon-180.png\",\n      \"idiom\" : \"iphone\",\n      \"scale\" : \"3x\",\n      \"size\" : \"60x60\"\n    },\n    {\n      \"filename\" : \"Icon-20.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"Icon-40 2.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"20x20\"\n    },\n    {\n      \"filename\" : \"Icon-29 1.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"Icon-58 1.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"29x29\"\n    },\n    {\n      \"filename\" : \"Icon-40 1.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"Icon-80 1.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"40x40\"\n    },\n    {\n      \"filename\" : \"Icon-76.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"1x\",\n      \"size\" : \"76x76\"\n    },\n    {\n      \"filename\" : \"Icon-152.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"76x76\"\n    },\n    {\n      \"filename\" : \"Icon-167.png\",\n      \"idiom\" : \"ipad\",\n      \"scale\" : \"2x\",\n      \"size\" : \"83.5x83.5\"\n    },\n    {\n      \"filename\" : \"Icon-1024.png\",\n      \"idiom\" : \"ios-marketing\",\n      \"scale\" : \"1x\",\n      \"size\" : \"1024x1024\"\n    },\n    {\n      \"filename\" : \"Icon-16.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"16x16\"\n    },\n    {\n      \"filename\" : \"Icon-32.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"32x32\"\n    },\n    {\n      \"filename\" : \"Icon-128.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"128x128\"\n    },\n    {\n      \"filename\" : \"Icon-256.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"256x256\"\n    },\n    {\n      \"filename\" : \"Icon-512.png\",\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\",\n      \"size\" : \"512x512\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "NeRFCapture/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "NeRFCapture/Assets.xcassets/NeRFCaptureSplash.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"NeRFCaptureSplash 2.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"filename\" : \"NeRFCaptureSplash 1.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"filename\" : \"NeRFCaptureSplash.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "NeRFCapture/DDSModel/NeRFCaptureData.c",
    "content": "/****************************************************************\n\n  Generated by Eclipse Cyclone DDS IDL to C Translator\n  File name: NeRFCaptureData.c\n  Cyclone DDS: V0.11.0\n\n*****************************************************************/\n#include \"NeRFCaptureData.h\"\n\nstatic const uint32_t NeRFCaptureData_NeRFCaptureFrame_ops [] =\n{\n  /* NeRFCaptureFrame */\n  DDS_OP_ADR | DDS_OP_FLAG_KEY | DDS_OP_FLAG_MU | DDS_OP_TYPE_4BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, id),\n  DDS_OP_ADR | DDS_OP_TYPE_8BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, timestamp),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, fl_x),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, fl_y),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, cx),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, cy),\n  DDS_OP_ADR | DDS_OP_TYPE_ARR | DDS_OP_SUBTYPE_4BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, transform_matrix), 16u,\n  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, width),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, height),\n  DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, image),\n  DDS_OP_ADR | DDS_OP_TYPE_BLN, offsetof (NeRFCaptureData_NeRFCaptureFrame, has_depth),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, depth_width),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, depth_height),\n  DDS_OP_ADR | DDS_OP_TYPE_4BY | DDS_OP_FLAG_FP, offsetof (NeRFCaptureData_NeRFCaptureFrame, depth_scale),\n  DDS_OP_ADR | DDS_OP_TYPE_SEQ | DDS_OP_SUBTYPE_1BY, offsetof (NeRFCaptureData_NeRFCaptureFrame, depth_image),\n  DDS_OP_RTS,\n  \n  /* key: id */\n  DDS_OP_KOF | 1, 0u /* order: 0 */\n};\n\nstatic const dds_key_descriptor_t NeRFCaptureData_NeRFCaptureFrame_keys[1] =\n{\n  { \"id\", 32, 0 }\n};\n\n/* Type Information:\n  [MINIMAL 58c15e051fee500969361b5dfc44] (#deps: 0)\n  [COMPLETE 29f4d038609e4e7e64774dbdf9fc] (#deps: 0)\n*/\n#define TYPE_INFO_CDR_NeRFCaptureData_NeRFCaptureFrame (unsigned char []){ \\\n  0x60, 0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x40, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, \\\n  0x14, 0x00, 0x00, 0x00, 0xf1, 0x58, 0xc1, 0x5e, 0x05, 0x1f, 0xee, 0x50, 0x09, 0x69, 0x36, 0x1b, \\\n  0x5d, 0xfc, 0x44, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \\\n  0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x40, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, \\\n  0x14, 0x00, 0x00, 0x00, 0xf2, 0x29, 0xf4, 0xd0, 0x38, 0x60, 0x9e, 0x4e, 0x7e, 0x64, 0x77, 0x4d, \\\n  0xbd, 0xf9, 0xfc, 0x00, 0xf2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, \\\n  0x00, 0x00, 0x00, 0x00\\\n}\n#define TYPE_INFO_CDR_SZ_NeRFCaptureData_NeRFCaptureFrame 100u\n#define TYPE_MAP_CDR_NeRFCaptureData_NeRFCaptureFrame (unsigned char []){ \\\n  0x30, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf1, 0x58, 0xc1, 0x5e, 0x05, 0x1f, 0xee, 0x50, \\\n  0x09, 0x69, 0x36, 0x1b, 0x5d, 0xfc, 0x44, 0x00, 0x18, 0x01, 0x00, 0x00, 0xf1, 0x51, 0x01, 0x00, \\\n  0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x07, 0xb8, 0x0b, 0xb7, 0x74, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0xd7, 0xe6, 0xd5, 0x5b, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0xb1, 0xf0, 0x2e, 0x42, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x0f, 0xe4, 0xcf, 0x54, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x0b, 0xdf, 0xf8, 0x09, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x47, 0x1c, 0x1f, 0x3f, 0x00, \\\n  0x16, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \\\n  0x01, 0x00, 0x00, 0x00, 0x10, 0x09, 0x0e, 0x1f, 0x23, 0x7b, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, \\\n  0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0xea, 0xae, 0x26, 0xa6, 0x00, 0x0b, 0x00, 0x00, 0x00, \\\n  0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0xb4, 0x35, 0xe2, 0x27, 0x00, 0x10, 0x00, 0x00, 0x00, \\\n  0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x78, 0x80, 0x5a, 0x22, \\\n  0x0b, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x71, 0x26, 0x29, 0xb6, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0xb4, 0x1f, 0x76, 0xe8, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0xd7, 0x32, 0xcd, 0xd0, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x0e, 0x97, 0xe6, 0xea, 0x00, \\\n  0x10, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, \\\n  0x59, 0xf4, 0x30, 0x3f, 0x06, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf2, 0x29, 0xf4, 0xd0, \\\n  0x38, 0x60, 0x9e, 0x4e, 0x7e, 0x64, 0x77, 0x4d, 0xbd, 0xf9, 0xfc, 0x00, 0xee, 0x01, 0x00, 0x00, \\\n  0xf2, 0x51, 0x01, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, \\\n  0x4e, 0x65, 0x52, 0x46, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x44, 0x61, 0x74, 0x61, 0x3a, \\\n  0x3a, 0x4e, 0x65, 0x52, 0x46, 0x43, 0x61, 0x70, 0x74, 0x75, 0x72, 0x65, 0x46, 0x72, 0x61, 0x6d, \\\n  0x65, 0x00, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, \\\n  0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x07, 0x00, 0x03, 0x00, 0x00, 0x00, 0x69, 0x64, 0x00, 0x00, \\\n  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x00, \\\n  0x0a, 0x00, 0x00, 0x00, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x00, 0x00, 0x00, \\\n  0x13, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, \\\n  0x66, 0x6c, 0x5f, 0x78, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, \\\n  0x01, 0x00, 0x09, 0x00, 0x05, 0x00, 0x00, 0x00, 0x66, 0x6c, 0x5f, 0x79, 0x00, 0x00, 0x00, 0x00, \\\n  0x11, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00, \\\n  0x63, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, \\\n  0x01, 0x00, 0x09, 0x00, 0x03, 0x00, 0x00, 0x00, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \\\n  0x2b, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x90, 0xf3, 0x01, 0x00, 0x00, 0x00, \\\n  0x01, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x74, 0x72, 0x61, 0x6e, \\\n  0x73, 0x66, 0x6f, 0x72, 0x6d, 0x5f, 0x6d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x00, 0x00, 0x00, 0x00, \\\n  0x14, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x06, 0x00, 0x00, 0x00, \\\n  0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, \\\n  0x01, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00, 0x00, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x00, 0x00, \\\n  0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, \\\n  0x01, 0x00, 0x00, 0x02, 0x06, 0x00, 0x00, 0x00, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, \\\n  0x18, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x00, \\\n  0x68, 0x61, 0x73, 0x5f, 0x64, 0x65, 0x70, 0x74, 0x68, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \\\n  0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x70, 0x74, \\\n  0x68, 0x5f, 0x77, 0x69, 0x64, 0x74, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, \\\n  0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x07, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x64, 0x65, 0x70, 0x74, \\\n  0x68, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, \\\n  0x0d, 0x00, 0x00, 0x00, 0x01, 0x00, 0x09, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x64, 0x65, 0x70, 0x74, \\\n  0x68, 0x5f, 0x73, 0x63, 0x61, 0x6c, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, \\\n  0x0e, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0xf3, 0x01, 0x00, 0x00, 0x02, 0x0c, 0x00, 0x00, 0x00, \\\n  0x64, 0x65, 0x70, 0x74, 0x68, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, \\\n  0x22, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf2, 0x29, 0xf4, 0xd0, 0x38, 0x60, 0x9e, 0x4e, \\\n  0x7e, 0x64, 0x77, 0x4d, 0xbd, 0xf9, 0xfc, 0xf1, 0x58, 0xc1, 0x5e, 0x05, 0x1f, 0xee, 0x50, 0x09, \\\n  0x69, 0x36, 0x1b, 0x5d, 0xfc, 0x44\\\n}\n#define TYPE_MAP_CDR_SZ_NeRFCaptureData_NeRFCaptureFrame 870u\nconst dds_topic_descriptor_t NeRFCaptureData_NeRFCaptureFrame_desc =\n{\n  .m_size = sizeof (NeRFCaptureData_NeRFCaptureFrame),\n  .m_align = dds_alignof (NeRFCaptureData_NeRFCaptureFrame),\n  .m_flagset = DDS_TOPIC_FIXED_KEY | DDS_TOPIC_FIXED_KEY_XCDR2 | DDS_TOPIC_XTYPES_METADATA,\n  .m_nkeys = 1u,\n  .m_typename = \"NeRFCaptureData::NeRFCaptureFrame\",\n  .m_keys = NeRFCaptureData_NeRFCaptureFrame_keys,\n  .m_nops = 16,\n  .m_ops = NeRFCaptureData_NeRFCaptureFrame_ops,\n  .m_meta = \"\",\n  .type_information = { .data = TYPE_INFO_CDR_NeRFCaptureData_NeRFCaptureFrame, .sz = TYPE_INFO_CDR_SZ_NeRFCaptureData_NeRFCaptureFrame },\n  .type_mapping = { .data = TYPE_MAP_CDR_NeRFCaptureData_NeRFCaptureFrame, .sz = TYPE_MAP_CDR_SZ_NeRFCaptureData_NeRFCaptureFrame }\n};\n\n"
  },
  {
    "path": "NeRFCapture/DDSModel/NeRFCaptureData.h",
    "content": "/****************************************************************\n\n  Generated by Eclipse Cyclone DDS IDL to C Translator\n  File name: NeRFCaptureData.h\n  Cyclone DDS: V0.11.0\n\n*****************************************************************/\n#ifndef DDSC_NERFCAPTUREDATA_H\n#define DDSC_NERFCAPTUREDATA_H\n\n#include \"dds/ddsc/dds_public_impl.h\"\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n#ifndef DDS_SEQUENCE_OCTET_DEFINED\n#define DDS_SEQUENCE_OCTET_DEFINED\ntypedef struct dds_sequence_octet\n{\n  uint32_t _maximum;\n  uint32_t _length;\n  uint8_t *_buffer;\n  bool _release;\n} dds_sequence_octet;\n\n#define dds_sequence_octet__alloc() \\\n((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet)));\n\n#define dds_sequence_octet_allocbuf(l) \\\n((uint8_t *) dds_alloc ((l) * sizeof (uint8_t)))\n#endif /* DDS_SEQUENCE_OCTET_DEFINED */\n\n#ifndef DDS_SEQUENCE_OCTET_DEFINED\n#define DDS_SEQUENCE_OCTET_DEFINED\ntypedef struct dds_sequence_octet\n{\n  uint32_t _maximum;\n  uint32_t _length;\n  uint8_t *_buffer;\n  bool _release;\n} dds_sequence_octet;\n\n#define dds_sequence_octet__alloc() \\\n((dds_sequence_octet*) dds_alloc (sizeof (dds_sequence_octet)));\n\n#define dds_sequence_octet_allocbuf(l) \\\n((uint8_t *) dds_alloc ((l) * sizeof (uint8_t)))\n#endif /* DDS_SEQUENCE_OCTET_DEFINED */\n\ntypedef struct NeRFCaptureData_NeRFCaptureFrame\n{\n  uint32_t id;\n  double timestamp;\n  float fl_x;\n  float fl_y;\n  float cx;\n  float cy;\n  float transform_matrix[16];\n  uint32_t width;\n  uint32_t height;\n  dds_sequence_octet image;\n  bool has_depth;\n  uint32_t depth_width;\n  uint32_t depth_height;\n  float depth_scale;\n  dds_sequence_octet depth_image;\n} NeRFCaptureData_NeRFCaptureFrame;\n\nextern const dds_topic_descriptor_t NeRFCaptureData_NeRFCaptureFrame_desc;\n\n#define NeRFCaptureData_NeRFCaptureFrame__alloc() \\\n((NeRFCaptureData_NeRFCaptureFrame*) dds_alloc (sizeof (NeRFCaptureData_NeRFCaptureFrame)));\n\n#define NeRFCaptureData_NeRFCaptureFrame_free(d,o) \\\ndds_sample_free ((d), &NeRFCaptureData_NeRFCaptureFrame_desc, (o))\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* DDSC_NERFCAPTUREDATA_H */\n"
  },
  {
    "path": "NeRFCapture/DDSModel/NeRFCaptureData.idl",
    "content": "module NeRFCaptureData\n{\n    @final\n    struct NeRFCaptureFrame\n    {\n      @key\n      uint32 id;\n      double timestamp;\n      float fl_x;\n      float fl_y;\n      float cx;\n      float cy;\n      float transform_matrix[16];\n      uint32 width;\n      uint32 height;\n      sequence<octet> image;\n      boolean has_depth;\n      uint32 depth_width;\n      uint32 depth_height;\n      float depth_scale;\n      sequence<octet> depth_image;\n    };\n};\n"
  },
  {
    "path": "NeRFCapture/DDSWriter.swift",
    "content": "//\n//  DDSWriter.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 11/1/2023.\n//\n\nimport Foundation\nimport ARKit\n\nstruct DDSConstants {\n    static let DDS_PUBLICATION_MATCHED_STATUS: UInt32 = 1 << DDS_PUBLICATION_MATCHED_STATUS_ID.rawValue\n    static let DDS_INCONSISTENT_TOPIC_STATUS: UInt32 = 1 << DDS_INCONSISTENT_TOPIC_STATUS_ID.rawValue\n    static let DDS_OFFERED_DEADLINE_MISSED_STATUS: UInt32 = 1 << DDS_OFFERED_DEADLINE_MISSED_STATUS_ID.rawValue\n}\n\nstruct DDSState {\n    var ready = false\n    var domain: dds_entity_t? = nil\n    var participant: dds_entity_t? = nil\n    var listener: OpaquePointer! = nil\n\n    let topic_name: String = \"Frames\"\n    var topic: dds_entity_t? = nil\n    var writer: dds_entity_t? = nil\n    var qos: OpaquePointer! = nil\n    \n    var rc: dds_return_t = dds_return_t()\n    var status:UInt32 = 0\n}\n\nclass DDSWriter {\n    var dds = DDSState()\n    let rgbConverter = YUVToRGBFilter()\n    var counter = 0\n    @Published var peers: UInt32 = 0\n   \n    func buildConfig() -> String {\n        let xml_config = \"\"\"\n            <General>\n                <Interfaces>\n                    <NetworkInterface name=\"en0\" />\n                </Interfaces>\n            </General>\n            <Tracing>\n                <Category>\n                    config\n                </Category>\n                <OutputFile>\n                    stdout\n                </OutputFile>\n            </Tracing>\n        \"\"\"\n        return xml_config\n    }\n    \n    func setupDDS() {\n        let domain_id: dds_domainid_t = 0\n        let xml_config = buildConfig()\n        dds.domain = dds_create_domain(domain_id, xml_config)\n        \n        // Create listener\n        let observer = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque()) // void pointer to self\n        dds.listener = dds_create_listener(observer)\n        dds_lset_publication_matched(dds.listener) { entity, status, observer in\n            let mySelf = Unmanaged<DDSWriter>.fromOpaque(observer!).takeUnretainedValue()\n                DispatchQueue.main.async {\n                    mySelf.peers = status.current_count\n            }\n        }\n        \n        dds.participant = dds_create_participant(domain_id, nil, dds.listener)\n        if(dds.participant! < 0) {\n            print(\"Could not create participant\")\n            return\n        }\n        \n        // Setup Project Topic\n        withUnsafePointer(to: NeRFCaptureData_NeRFCaptureFrame_desc) { descPtr in\n            dds.topic = dds_create_topic(dds.participant!, descPtr, dds.topic_name, nil, nil)\n        }\n//        dds.topic = dds_create_topic(dds.participant!, &NeRFCaptureData_NeRFCaptureFrame_desc, dds.topic_name, nil, nil)\n//        dds.topic = dds_create_topic(dds.participant!, NeRFCaptureData_NeRFCaptureFrame_desc_ptr, dds.topic_name, nil, nil)\n        \n        if(dds.topic! < 0) {\n            print(\"Could not create topic\")\n            return\n        }\n        \n        dds.qos = dds_create_qos()\n        dds_qset_resource_limits(\n            dds.qos,\n            2,\n            2,\n            2\n        )\n//        dds_qset_reliability(dds.qos, DDS_RELIABILITY_RELIABLE, 1 * 1000000000)\n        \n        dds.writer = dds_create_writer(dds.participant!, dds.topic!, dds.qos!, dds.listener)\n        if(dds.writer! < 0) {\n            print(\"Could not create writer\")\n            return\n        }\n    }\n    \n    func writeFrameToTopic(frame: ARFrame) {\n        let w = UInt32(frame.camera.imageResolution.width)\n        let h = UInt32(frame.camera.imageResolution.height)\n        let flX =  frame.camera.intrinsics[0, 0]\n        let flY =  frame.camera.intrinsics[1, 1]\n        let cx =  frame.camera.intrinsics[2, 0]\n        let cy =  frame.camera.intrinsics[2, 1]\n        \n        \n        rgbConverter.applyFilter(frame: frame)\n        var data = dds_sequence_octet()\n        data._length = UInt32(rgbConverter.rgbBuffer.length)\n        data._buffer = rgbConverter.rgbBuffer.contents().bindMemory(to: UInt8.self, capacity: 1)\n        \n        var depth_width = 0\n        var depth_height = 0\n        var has_depth = false\n        var depth_data = dds_sequence_octet()\n        if let sceneDepth = frame.sceneDepth {\n            CVPixelBufferLockBaseAddress(sceneDepth.depthMap, .readOnly)\n            has_depth = true\n            depth_width = CVPixelBufferGetWidth(sceneDepth.depthMap)\n            depth_height = CVPixelBufferGetHeight(sceneDepth.depthMap)\n            depth_data._length = UInt32(CVPixelBufferGetDataSize(sceneDepth.depthMap))\n            print(\"\\(depth_width)x\\(depth_height) - size = \\(depth_data._length)\")\n            depth_data._buffer = CVPixelBufferGetBaseAddress(frame.sceneDepth!.depthMap)!.bindMemory(to: UInt8.self, capacity: 1)\n        }\n        counter += 1\n        var msg = NeRFCaptureData_NeRFCaptureFrame(\n            id: UInt32(counter),\n            timestamp: frame.timestamp,\n            fl_x: flX,\n            fl_y: flY,\n            cx: cx,\n            cy: cy,\n            transform_matrix: tupleFromTransform(frame.camera.transform),\n            width: w,\n            height: h,\n            image: data,\n            has_depth: has_depth,\n            depth_width: UInt32(depth_width),\n            depth_height: UInt32(depth_height),\n            depth_scale: 1.0,\n            depth_image: depth_data\n        )\n\n        dds.rc = dds_write(dds.writer!, &msg)\n        if(dds.rc != DDS_RETCODE_OK) {\n            let message = String(cString:dds_strretcode(dds.rc))\n            print(\"Write Failed: \\(message)\")\n        }\n        if let sceneDepth = frame.sceneDepth {\n            CVPixelBufferUnlockBaseAddress(sceneDepth.depthMap, .readOnly)\n        }\n    }\n    \n    func cleanDDS() {\n        if let domain = dds.domain {\n            dds.rc = dds_delete(domain)\n        }\n    }\n}\n"
  },
  {
    "path": "NeRFCapture/DatasetWriter.swift",
    "content": "//\n//  DatasetWriter.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 11/1/2023.\n//\n\nimport Foundation\nimport ARKit\nimport Zip\n\nextension UIImage {\n    func resizeImageTo(size: CGSize) -> UIImage? {\n        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)\n        self.draw(in: CGRect(origin: CGPoint.zero, size: size))\n        let resizedImage = UIGraphicsGetImageFromCurrentImageContext()!\n        UIGraphicsEndImageContext()\n        return resizedImage\n    }\n}\n\nclass DatasetWriter {\n    \n    enum SessionState {\n        case SessionNotStarted\n        case SessionStarted\n    }\n    \n    var manifest = Manifest()\n    var projectName = \"\"\n    var projectDir = getDocumentsDirectory()\n    var useDepthIfAvailable = true\n    \n    @Published var currentFrameCounter = 0\n    @Published var writerState = SessionState.SessionNotStarted\n    \n    func projectExists(_ projectDir: URL) -> Bool {\n        var isDir: ObjCBool = true\n        return FileManager.default.fileExists(atPath: projectDir.absoluteString, isDirectory: &isDir)\n    }\n    \n    func initializeProject() throws {\n        let dateFormatter = DateFormatter()\n        dateFormatter.dateFormat = \"YYMMddHHmmss\"\n        projectName = dateFormatter.string(from: Date())\n        projectDir = getDocumentsDirectory()\n            .appendingPathComponent(projectName)\n        if projectExists(projectDir) {\n            throw AppError.projectAlreadyExists\n        }\n        do {\n            try FileManager.default.createDirectory(at: projectDir.appendingPathComponent(\"images\"), withIntermediateDirectories: true)\n        }\n        catch {\n            print(error)\n        }\n        \n        manifest = Manifest()\n        \n        // The first frame will set these properly\n        manifest.w = 0\n        manifest.h = 0\n        \n        // These don't matter since every frame will redefine them\n        manifest.flX = 1.0\n        manifest.flY =  1.0\n        manifest.cx =  320\n        manifest.cy =  240\n        \n        manifest.depthIntegerScale = 1.0\n        writerState = .SessionStarted\n    }\n    \n    func clean() {\n        guard case .SessionStarted = writerState else { return; }\n        writerState = .SessionNotStarted\n        DispatchQueue.global().async {\n            do {\n                try FileManager.default.removeItem(at: self.projectDir)\n            }\n            catch {\n                print(\"Could not cleanup project files\")\n            }\n        }\n    }\n    \n    func finalizeProject(zip: Bool = true) {\n        writerState = .SessionNotStarted\n        let manifest_path = getDocumentsDirectory()\n            .appendingPathComponent(projectName)\n            .appendingPathComponent(\"transforms.json\")\n        \n        writeManifestToPath(path: manifest_path)\n        DispatchQueue.global().async {\n            do {\n                if zip {\n                    let _ = try Zip.quickZipFiles([self.projectDir], fileName: self.projectName)\n                }\n                try FileManager.default.removeItem(at: self.projectDir)\n            }\n            catch {\n                print(\"Could not zip\")\n            }\n        }\n    }\n    \n    func getCurrentFrameName() -> String {\n        let frameName = String(currentFrameCounter)\n        return frameName\n    }\n    \n    func getFrameMetadata(_ frame: ARFrame, withDepth: Bool = false) -> Manifest.Frame {\n        let frameName = getCurrentFrameName()\n        let filePath = \"images/\\(frameName)\"\n        let depthPath = \"images/\\(frameName).depth.png\"\n        let manifest_frame = Manifest.Frame(\n            filePath: filePath,\n            depthPath: withDepth ? depthPath : nil,\n            transformMatrix: arrayFromTransform(frame.camera.transform),\n            timestamp: frame.timestamp,\n            flX:  frame.camera.intrinsics[0, 0],\n            flY:  frame.camera.intrinsics[1, 1],\n            cx:  frame.camera.intrinsics[2, 0],\n            cy:  frame.camera.intrinsics[2, 1],\n            w: Int(frame.camera.imageResolution.width),\n            h: Int(frame.camera.imageResolution.height)\n        )\n        return manifest_frame\n    }\n    \n    func writeManifestToPath(path: URL) {\n        let encoder = JSONEncoder()\n        encoder.keyEncodingStrategy = .convertToSnakeCase\n        encoder.outputFormatting = .withoutEscapingSlashes\n        if let encoded = try? encoder.encode(manifest) {\n            do {\n                try encoded.write(to: path)\n            } catch {\n                print(error)\n            }\n        }\n    }\n    \n    func writeFrameToDisk(frame: ARFrame, useDepthIfAvailable: Bool = true) {\n        let frameName =  \"\\(getCurrentFrameName()).png\"\n        let depthFrameName =  \"\\(getCurrentFrameName()).depth.png\"\n        let baseDir = projectDir\n            .appendingPathComponent(\"images\")\n        let fileName = baseDir\n            .appendingPathComponent(frameName)\n        let depthFileName = baseDir\n            .appendingPathComponent(depthFrameName)\n        \n        if manifest.w == 0 {\n            manifest.w = Int(frame.camera.imageResolution.width)\n            manifest.h = Int(frame.camera.imageResolution.height)\n            manifest.flX =  frame.camera.intrinsics[0, 0]\n            manifest.flY =  frame.camera.intrinsics[1, 1]\n            manifest.cx =  frame.camera.intrinsics[2, 0]\n            manifest.cy =  frame.camera.intrinsics[2, 1]\n        }\n        \n        let useDepth = frame.sceneDepth != nil && useDepthIfAvailable\n        \n        let frameMetadata = getFrameMetadata(frame, withDepth: useDepth)\n        let rgbBuffer = pixelBufferToUIImage(pixelBuffer: frame.capturedImage)\n        let depthBuffer = useDepth ? pixelBufferToUIImage(pixelBuffer: frame.sceneDepth!.depthMap).resizeImageTo(size:  frame.camera.imageResolution) : nil\n        \n        DispatchQueue.global().async {\n            do {\n                let rgbData = rgbBuffer.pngData()\n                try rgbData?.write(to: fileName)\n                if useDepth {\n                    let depthData = depthBuffer!.pngData()\n                    try depthData?.write(to: depthFileName)\n                }\n            }\n            catch {\n                print(error)\n            }\n            DispatchQueue.main.async {\n                self.manifest.frames.append(frameMetadata)\n            }\n        }\n        currentFrameCounter += 1\n    }\n}\n"
  },
  {
    "path": "NeRFCapture/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>UIFileSharingEnabled</key>\n\t<true/>\n\t<key>UILaunchScreen</key>\n\t<dict>\n\t\t<key>UIColorName</key>\n\t\t<string>AccentColor</string>\n\t\t<key>UIImageName</key>\n\t\t<string></string>\n\t\t<key>UIImageRespectsSafeAreaInsets</key>\n\t\t<false/>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "NeRFCapture/Models/AppState.swift",
    "content": "//\n//  AppState.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport Foundation\nimport Metal\nimport MetalKit\n\nenum AppMode: Int, Codable {\n    case Online\n    case Offline\n}\n\nstruct AppState {\n    var appMode: AppMode = .Online\n    var writerState: DatasetWriter.SessionState = .SessionNotStarted\n    \n    var trackingState = \"\"\n    var projectName = \"\"\n    var numFrames = 0\n    var supportsDepth = false\n//    var stream = false\n    \n    var ddsPeers: UInt32 = 0\n    var ddsReady = false\n}\n\nstruct AppSettings: Codable {\n    var zipDataset = true\n    var startingAppMode = AppMode.Online\n}\n\n\n\nstruct MetalState {\n    var device: MTLDevice!\n    var commandQueue: MTLCommandQueue!\n    \n    var sharedUniformBuffer: MTLBuffer!\n    var imagePlaneVertexBuffer: MTLBuffer!\n    \n    var capturedImagePipelineState: MTLRenderPipelineState!\n    var capturedImageTextureY: CVMetalTexture?\n    var capturedImageTextureCbCr: CVMetalTexture?\n    var capturedImageTextureCache: CVMetalTextureCache!\n}\n"
  },
  {
    "path": "NeRFCapture/Models/Manifest.swift",
    "content": "//\n//  Manifest.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport Foundation\n\nstruct Manifest : Codable {\n    struct Frame : Codable {\n        let filePath: String\n        let depthPath: String?\n        let transformMatrix: [[Float]]\n        let timestamp: TimeInterval\n        let flX: Float\n        let flY: Float\n        let cx: Float\n        let cy: Float\n        let w: Int\n        let h: Int\n    }\n    var w: Int = 0\n    var h: Int = 0\n    var flX: Float = 0\n    var flY: Float = 0\n    var cx: Float = 0\n    var cy: Float = 0\n    var depthIntegerScale : Float?\n    var depthSource: String?\n    var frames: [Frame] = [Frame]()\n}\n"
  },
  {
    "path": "NeRFCapture/Networking/CycloneDDS-Bridging-Header.h",
    "content": "//\n//  CycloneDDS-Bridging-Header.h\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 9/12/2022.\n//\n\n#ifndef CycloneDDS_Bridging_Header_h\n#define CycloneDDS_Bridging_Header_h\n\n#include <dds/dds.h>\n#include \"NeRFCaptureData.h\"\n\n//const dds_topic_descriptor_t* NeRFCaptureData_NeRFCaptureFrame_desc_ptr = &NeRFCaptureData_NeRFCaptureFrame_desc;\n\n#endif /* CycloneDDS_Bridging_Header_h */\n"
  },
  {
    "path": "NeRFCapture/Preview Content/Preview Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "NeRFCapture/Shaders.metal",
    "content": "//\n//  Shaders.metal\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 19/12/2022.\n//\n\n#include <metal_stdlib>\nusing namespace metal;\n\n\nkernel void yuv2rgb_kernel(texture2d<float, access::sample> capturedImageTextureY [[ texture(0) ]],\n                           texture2d<float, access::sample> capturedImageTextureCbCr [[ texture(1) ]],\n                           device uint8_t* result [[buffer(0)]],\n                           uint2 position [[thread_position_in_grid]]) {\n    \n    const auto textureSize = ushort2(capturedImageTextureY.get_width(),\n                                     capturedImageTextureY.get_height());\n    \n    constexpr sampler colorSampler(mip_filter::linear,\n                                   mag_filter::linear,\n                                   min_filter::linear);\n    \n    const float4x4 ycbcrToRGBTransform = float4x4(\n        float4(+1.0000f, +1.0000f, +1.0000f, +0.0000f),\n        float4(+0.0000f, -0.3441f, +1.7720f, +0.0000f),\n        float4(+1.4020f, -0.7141f, +0.0000f, +0.0000f),\n        float4(-0.7010f, +0.5291f, -0.8860f, +1.0000f)\n    );\n    float2 texCoord = float2(position)/float2(textureSize);\n    \n    // Sample Y and CbCr textures to get the YCbCr color at the given texture coordinate\n    float4 ycbcr = float4(capturedImageTextureY.sample(colorSampler, texCoord).r,\n                          capturedImageTextureCbCr.sample(colorSampler, texCoord).rg, 1.0);\n    \n    // Return converted RGB color\n    float4 res = ycbcrToRGBTransform * ycbcr * 255.0;\n    int ind = position.y*textureSize[0] + position.x;\n    result[3*ind + 0] = res[0];\n    result[3*ind + 1] = res[1];\n    result[3*ind + 2] = res[2];\n}\n"
  },
  {
    "path": "NeRFCapture/Utils.swift",
    "content": "//\n//  Utils.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport Foundation\nimport ARKit\n\nfunc trackingStateToString(_ trackingState: ARCamera.TrackingState) -> String {\n        switch trackingState {\n            case .notAvailable: return \"Not Available\"\n            case .normal: return \"Tracking Normal\"\n            case .limited(.excessiveMotion): return \"Excessive Motion\"\n            case .limited(.initializing): return \"Tracking Initializing\"\n            case .limited(.insufficientFeatures): return  \"Insufficient Features\"\n            default: return \"Unknown\"\n        }\n}\n\nfunc tupleFromTransform(_ t: matrix_float4x4) -> (Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float, Float) {\n    let tuple = (t.columns.0.x, t.columns.0.y, t.columns.0.z, t.columns.0.w,\n        t.columns.1.x, t.columns.1.y, t.columns.1.z, t.columns.1.w,\n        t.columns.2.x, t.columns.2.y, t.columns.2.z, t.columns.2.w,\n        t.columns.3.x, t.columns.3.y, t.columns.3.z, t.columns.3.w\n    )\n    return tuple\n}\n\nfunc arrayFromTransform(_ transform: matrix_float4x4) -> [[Float]] {\n    var array: [[Float]] = Array(repeating: Array(repeating:Float(), count: 4), count: 4)\n    array[0] = [transform.columns.0.x, transform.columns.1.x, transform.columns.2.x, transform.columns.3.x]\n    array[1] = [transform.columns.0.y, transform.columns.1.y, transform.columns.2.y, transform.columns.3.y]\n    array[2] = [transform.columns.0.z, transform.columns.1.z, transform.columns.2.z, transform.columns.3.z]\n    array[3] = [transform.columns.0.w, transform.columns.1.w, transform.columns.2.w, transform.columns.3.w]\n    return array\n}\n\nfunc arrayFromTransform(_ transform: matrix_float3x3) -> [[Float]] {\n    var array: [[Float]] = Array(repeating: Array(repeating:Float(), count: 3), count: 3)\n    array[0] = [transform.columns.0.x, transform.columns.1.x, transform.columns.2.x]\n    array[1] = [transform.columns.0.y, transform.columns.1.y, transform.columns.2.y]\n    array[2] = [transform.columns.0.z, transform.columns.1.z, transform.columns.2.z]\n    return array\n}\n\nfunc pixelBufferToUIImage(pixelBuffer: CVPixelBuffer) -> UIImage {\n    let ciImage = CIImage(cvPixelBuffer: pixelBuffer)\n    let context = CIContext(options: nil)\n    let cgImage = context.createCGImage(ciImage, from: ciImage.extent)\n    let uiImage = UIImage(cgImage: cgImage!)\n    return uiImage\n}\n\nfunc getDocumentsDirectory() -> URL {\n    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)\n    return paths[0]\n}\n\n\nclass YUVToRGBFilter {\n    \n    var device: MTLDevice\n    var defaultLib: MTLLibrary?\n    var shader: MTLFunction?\n    var commandQueue: MTLCommandQueue?\n    var commandEncoder: MTLComputeCommandEncoder?\n    var pipelineState: MTLComputePipelineState?\n    var width: UInt32 = 0\n    var height: UInt32 = 0\n    let threadsPerBlock = MTLSize(width: 16, height: 16, depth: 1)\n    \n    var capturedImagePipelineState: MTLRenderPipelineState!\n    var capturedImageTextureY: CVMetalTexture?\n    var capturedImageTextureCbCr: CVMetalTexture?\n    var capturedImageTextureCache: CVMetalTextureCache!\n    var rgbBuffer: MTLBuffer!\n    \n    init() {\n        self.device = MTLCreateSystemDefaultDevice()!\n        self.defaultLib = self.device.makeDefaultLibrary()\n        self.shader = self.defaultLib?.makeFunction(name: \"yuv2rgb_kernel\")\n        self.commandQueue = self.device.makeCommandQueue()\n        \n        // Create captured image texture cache\n        var textureCache: CVMetalTextureCache?\n        CVMetalTextureCacheCreate(nil, nil, self.device, nil, &textureCache)\n        self.capturedImageTextureCache = textureCache\n        \n        if let shader = self.shader {\n            do {\n                try self.pipelineState = self.device.makeComputePipelineState(function: shader)\n            } catch {\n                fatalError(\"unable to make compute pipeline\")\n            }\n        }\n        else {\n            fatalError(\"unable to make compute pipeline\")\n        }\n    }\n    \n    func getBlockDimensions() -> MTLSize {\n        let blockWidth = Int(width) / self.threadsPerBlock.width\n        let blockHeight = Int(height) / self.threadsPerBlock.height\n        return MTLSizeMake(blockWidth, blockHeight, 1)\n    }\n    \n    \n    func createTexture(fromPixelBuffer pixelBuffer: CVPixelBuffer, pixelFormat: MTLPixelFormat, planeIndex: Int) -> CVMetalTexture? {\n        let width = CVPixelBufferGetWidthOfPlane(pixelBuffer, planeIndex)\n        let height = CVPixelBufferGetHeightOfPlane(pixelBuffer, planeIndex)\n        var texture: CVMetalTexture? = nil\n        let status = CVMetalTextureCacheCreateTextureFromImage(nil, capturedImageTextureCache, pixelBuffer, nil, pixelFormat, width, height, planeIndex, &texture)\n        if status != kCVReturnSuccess {\n            texture = nil\n        }\n        return texture\n    }\n    \n    func updateCapturedImageTextures(frame: ARFrame) {\n        // Create two textures (Y and CbCr) from the provided frame's captured image\n        let pixelBuffer = frame.capturedImage\n        if (CVPixelBufferGetPlaneCount(pixelBuffer) < 2) {\n            return\n        }\n        capturedImageTextureY = createTexture(fromPixelBuffer: pixelBuffer, pixelFormat:.r8Unorm, planeIndex:0)\n        capturedImageTextureCbCr = createTexture(fromPixelBuffer: pixelBuffer, pixelFormat:.rg8Unorm, planeIndex:1)\n        \n        let w = Int(frame.camera.imageResolution.width)\n        let h = Int(frame.camera.imageResolution.height)\n        if(w != self.width || h != self.height) {\n            rgbBuffer = device.makeBuffer(length: w*h*3, options: .storageModeShared)\n        }\n        width = UInt32(w)\n        height = UInt32(h)\n\n    }\n    \n    func applyFilter(frame:ARFrame) {\n        updateCapturedImageTextures(frame: frame)\n        guard let buffer = self.commandQueue?.makeCommandBuffer(), let encoder = buffer.makeComputeCommandEncoder() else {\n            return;\n        }\n        encoder.setComputePipelineState(self.pipelineState!)\n        encoder.setTextures([CVMetalTextureGetTexture(capturedImageTextureY!), CVMetalTextureGetTexture(capturedImageTextureCbCr!)], range: 0..<2)\n        encoder.setBuffer(rgbBuffer, offset: 0, index: 0)\n        encoder.dispatchThreadgroups(self.getBlockDimensions(), threadsPerThreadgroup: threadsPerBlock)\n        encoder.endEncoding()\n        buffer.commit()\n        buffer.waitUntilCompleted()\n    }\n    \n}\n"
  },
  {
    "path": "NeRFCapture/ViewModels/ARViewModel.swift",
    "content": "//\n//  ARViewModel.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport Foundation\nimport Zip\nimport Combine\nimport ARKit\nimport RealityKit\n\nenum AppError : Error {\n    case projectAlreadyExists\n    case manifestInitializationFailed\n}\n\nclass ARViewModel : NSObject, ARSessionDelegate, ObservableObject {\n    @Published var appState = AppState()\n    var session: ARSession? = nil\n    var arView: ARView? = nil\n//    let frameSubject = PassthroughSubject<ARFrame, Never>()\n    var cancellables = Set<AnyCancellable>()\n    let datasetWriter: DatasetWriter\n    let ddsWriter: DDSWriter\n    \n    init(datasetWriter: DatasetWriter, ddsWriter: DDSWriter) {\n        self.datasetWriter = datasetWriter\n        self.ddsWriter = ddsWriter\n        super.init()\n        self.setupObservers()\n        self.ddsWriter.setupDDS()\n    }\n    \n    func setupObservers() {\n        datasetWriter.$writerState.sink {x in self.appState.writerState = x} .store(in: &cancellables)\n        datasetWriter.$currentFrameCounter.sink { x in self.appState.numFrames = x }.store(in: &cancellables)\n        ddsWriter.$peers.sink {x in self.appState.ddsPeers = UInt32(x)}.store(in: &cancellables)\n        \n        $appState\n            .map(\\.appMode)\n            .prepend(appState.appMode)\n            .removeDuplicates()\n            .sink { x in\n                switch x {\n                case .Offline:\n//                    self.appState.stream = false\n                    print(\"Changed to offline\")\n                case .Online:\n                    print(\"Changed to online\")\n                }\n            }\n            .store(in: &cancellables)\n        \n//        frameSubject.throttle(for: 0.5, scheduler: RunLoop.main, latest: true).sink {\n//            f in\n//            if self.appState.stream && self.appState.appMode == .Online {\n//                self.ddsWriter.writeFrameToTopic(frame: f)\n//            }\n//        }.store(in: &cancellables)\n    }\n    \n    \n    func createARConfiguration() -> ARWorldTrackingConfiguration {\n        let configuration = ARWorldTrackingConfiguration()\n        configuration.worldAlignment = .gravity\n        if type(of: configuration).supportsFrameSemantics(.sceneDepth) {\n            // Activate sceneDepth\n            configuration.frameSemantics = .sceneDepth\n        }\n        return configuration\n    }\n    \n    func resetWorldOrigin() {\n        session?.pause()\n        let config = createARConfiguration()\n        session?.run(config, options: [.resetTracking])\n    }\n    \n    \n    func session(\n        _ session: ARSession,\n        didUpdate frame: ARFrame\n    ) {\n//        frameSubject.send(frame)\n    }\n    \n    func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {\n        self.appState.trackingState = trackingStateToString(camera.trackingState)\n    }\n}\n"
  },
  {
    "path": "NeRFCapture/Views/ARViewContainer.swift",
    "content": "//\n//  ARView.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport SwiftUI\nimport RealityKit\nimport ARKit\n\nstruct ARViewContainer: UIViewRepresentable {\n    @ObservedObject var viewModel: ARViewModel\n    \n    init(_ vm: ARViewModel) {\n        viewModel = vm\n    }\n    \n    func makeUIView(context: Context) -> ARView {\n        let arView = ARView(frame: .zero)\n        let configuration = viewModel.createARConfiguration()\n        configuration.worldAlignment = .gravity\n        configuration.isAutoFocusEnabled = true\n//        configuration.videoFormat = ARWorldTrackingConfiguration.supportedVideoFormats[4] // 1280x720\n        if ARWorldTrackingConfiguration.supportsFrameSemantics(.sceneDepth) {\n            viewModel.appState.supportsDepth = true\n        }\n        arView.debugOptions = [.showWorldOrigin]\n        #if !targetEnvironment(simulator)\n        arView.session.run(configuration)\n        #endif\n        arView.session.delegate = viewModel\n        viewModel.session = arView.session\n        viewModel.arView = arView\n        return arView\n    }\n    \n    func updateUIView(_ uiView: ARView, context: Context) {}\n    \n}\n"
  },
  {
    "path": "NeRFCapture/Views/ContentView.swift",
    "content": "//\n//  ContentView.swift\n//  NeRFCapture\n//\n//  Created by Jad Abou-Chakra on 13/7/2022.\n//\n\nimport SwiftUI\nimport ARKit\nimport RealityKit\n\n\nstruct ContentView : View {\n    @StateObject private var viewModel: ARViewModel\n    @State private var showSheet: Bool = false\n    \n    init(viewModel vm: ARViewModel) {\n        _viewModel = StateObject(wrappedValue: vm)\n    }\n    \n    var body: some View {\n        ZStack{\n            ZStack(alignment: .topTrailing) {\n                ARViewContainer(viewModel).edgesIgnoringSafeArea(.all)\n                VStack() {\n                    ZStack() {\n                        HStack() {\n//                            Button() {\n//                                showSheet.toggle()\n//                            } label: {\n//                                Image(systemName: \"gearshape.fill\")\n//                                    .imageScale(.large)\n//                            }\n//                            .padding(.leading, 16)\n//                            .buttonStyle(.borderless)\n//                            .sheet(isPresented: $showSheet) {\n//                                VStack() {\n//                                    Text(\"Settings\")\n//                                    Spacer()\n//                                }\n//                                .presentationDetents([.medium])\n//                            }\n//                            Spacer()\n                        }\n                        HStack() {\n                            Spacer()\n                            Picker(\"Mode\", selection: $viewModel.appState.appMode) {\n                                Text(\"Online\").tag(AppMode.Online)\n                                Text(\"Offline\").tag(AppMode.Offline)\n                            }\n                            .frame(maxWidth: 200)\n                            .padding(0)\n                            .pickerStyle(.segmented)\n                            .disabled(viewModel.appState.writerState\n                                      != .SessionNotStarted)\n                            \n                            Spacer()\n                        }\n                    }.padding(8)\n                    HStack() {\n                        Spacer()\n                        \n                        VStack(alignment:.leading) {\n                            Text(\"\\(viewModel.appState.trackingState)\")\n                            if case .Online = viewModel.appState.appMode {\n                                Text(\"\\(viewModel.appState.ddsPeers) Connection(s)\")\n                            }\n                            if case .Offline = viewModel.appState.appMode {\n                                if case .SessionStarted = viewModel.appState.writerState {\n                                    Text(\"\\(viewModel.datasetWriter.currentFrameCounter) Frames\")\n                                }\n                            }\n                            \n                            if viewModel.appState.supportsDepth {\n                                Text(\"Depth Supported\")\n                            }\n                        }.padding()\n                    }\n                }\n            }\n            VStack {\n                Spacer()\n                HStack(spacing: 20) {\n                    if case .Online = viewModel.appState.appMode {\n                        Spacer()\n                        Button(action: {\n                            viewModel.resetWorldOrigin()\n                        }) {\n                            Text(\"Reset\")\n                                .padding(.horizontal, 20)\n                                .padding(.vertical, 5)\n                        }\n                        .buttonStyle(.bordered)\n                        .buttonBorderShape(.capsule)\n                        Button(action: {\n                            if let frame = viewModel.session?.currentFrame {\n                                viewModel.ddsWriter.writeFrameToTopic(frame: frame)\n                            }\n                        }) {\n                            Text(\"Send\")\n                                .padding(.horizontal, 20)\n                                .padding(.vertical, 5)\n                        }\n                        .buttonStyle(.borderedProminent)\n                        .buttonBorderShape(.capsule)\n                    }\n                    if case .Offline = viewModel.appState.appMode {\n                        if viewModel.appState.writerState == .SessionNotStarted {\n                            Spacer()\n                            \n                            Button(action: {\n                                viewModel.resetWorldOrigin()\n                            }) {\n                                Text(\"Reset\")\n                                    .padding(.horizontal, 20)\n                                    .padding(.vertical, 5)\n                            }\n                            .buttonStyle(.bordered)\n                            .buttonBorderShape(.capsule)\n                            \n                            Button(action: {\n                                do {\n                                    try viewModel.datasetWriter.initializeProject()\n                                }\n                                catch {\n                                    print(\"\\(error)\")\n                                }\n                            }) {\n                                Text(\"Start\")\n                                    .padding(.horizontal, 20)\n                                    .padding(.vertical, 5)\n                            }\n                            .buttonStyle(.borderedProminent)\n                            .buttonBorderShape(.capsule)\n                        }\n                        \n                        if viewModel.appState.writerState == .SessionStarted {\n                            Spacer()\n                            Button(action: {\n                                viewModel.datasetWriter.finalizeProject()\n                            }) {\n                                Text(\"End\")\n                                    .padding(.horizontal, 20)\n                                    .padding(.vertical, 5)\n                            }\n                            .buttonStyle(.bordered)\n                            .buttonBorderShape(.capsule)\n                            Button(action: {\n                                if let frame = viewModel.session?.currentFrame {\n                                    viewModel.datasetWriter.writeFrameToDisk(frame: frame)\n                                }\n                            }) {\n                                Text(\"Save Frame\")\n                                    .padding(.horizontal, 20)\n                                    .padding(.vertical, 5)\n                            }\n                            .buttonStyle(.borderedProminent)\n                            .buttonBorderShape(.capsule)\n                        }\n                    }\n                }\n                .padding()\n            }\n            .preferredColorScheme(.dark)\n        }\n    }\n}\n\n#if DEBUG\nstruct ContentView_Previews : PreviewProvider {\n    static var previews: some View {\n        ContentView(viewModel: ARViewModel(datasetWriter: DatasetWriter(), ddsWriter: DDSWriter()))\n            .previewInterfaceOrientation(.portrait)\n    }\n}\n#endif\n"
  },
  {
    "path": "NeRFCapture.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 55;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t050A8EFA296E738300C5C638 /* DatasetWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 050A8EF9296E738200C5C638 /* DatasetWriter.swift */; };\n\t\t050A8EFC296E8B8E00C5C638 /* DDSWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 050A8EFB296E8B8E00C5C638 /* DDSWriter.swift */; };\n\t\t0512301F29499F50003915D9 /* NeRFCaptureData.c in Sources */ = {isa = PBXBuildFile; fileRef = 0512301C29499F4F003915D9 /* NeRFCaptureData.c */; };\n\t\t0512302029499F50003915D9 /* NeRFCaptureData.idl in Resources */ = {isa = PBXBuildFile; fileRef = 0512301D29499F4F003915D9 /* NeRFCaptureData.idl */; };\n\t\t0539EAB12965458E00C51AB9 /* Zip in Frameworks */ = {isa = PBXBuildFile; productRef = 0539EAB02965458E00C51AB9 /* Zip */; };\n\t\t0539EAB429654B0400C51AB9 /* cyclonedds in Frameworks */ = {isa = PBXBuildFile; productRef = 0539EAB329654B0400C51AB9 /* cyclonedds */; };\n\t\t057A7AA82950092E000692A0 /* Shaders.metal in Sources */ = {isa = PBXBuildFile; fileRef = 057A7AA72950092E000692A0 /* Shaders.metal */; };\n\t\tC0C52A90287E7F940011820F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52A8F287E7F940011820F /* AppDelegate.swift */; };\n\t\tC0C52A92287E7F940011820F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52A91287E7F940011820F /* ContentView.swift */; };\n\t\tC0C52A96287E7F960011820F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0C52A95287E7F960011820F /* Assets.xcassets */; };\n\t\tC0C52A99287E7F960011820F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C0C52A98287E7F960011820F /* Preview Assets.xcassets */; };\n\t\tC0C52AA3287EC19A0011820F /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52AA2287EC19A0011820F /* Utils.swift */; };\n\t\tC0C52AA8287EC2390011820F /* ARViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52AA7287EC2390011820F /* ARViewModel.swift */; };\n\t\tC0C52AAA287EC2470011820F /* ARViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52AA9287EC2470011820F /* ARViewContainer.swift */; };\n\t\tC0C52AAC287EC26A0011820F /* Manifest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52AAB287EC26A0011820F /* Manifest.swift */; };\n\t\tC0C52AAE287EC33D0011820F /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0C52AAD287EC33D0011820F /* AppState.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t0531C0AA293735DE005F0929 /* Embed Frameworks */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tname = \"Embed Frameworks\";\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t050A8EF9296E738200C5C638 /* DatasetWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DatasetWriter.swift; sourceTree = \"<group>\"; };\n\t\t050A8EFB296E8B8E00C5C638 /* DDSWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DDSWriter.swift; sourceTree = \"<group>\"; };\n\t\t051230122942EE07003915D9 /* CycloneDDS-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"CycloneDDS-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\t0512301C29499F4F003915D9 /* NeRFCaptureData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = NeRFCaptureData.c; sourceTree = \"<group>\"; };\n\t\t0512301D29499F4F003915D9 /* NeRFCaptureData.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = NeRFCaptureData.idl; sourceTree = \"<group>\"; };\n\t\t0512301E29499F50003915D9 /* NeRFCaptureData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NeRFCaptureData.h; sourceTree = \"<group>\"; };\n\t\t052D2374287FD53A0083DC5B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t057A7AA72950092E000692A0 /* Shaders.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = Shaders.metal; sourceTree = \"<group>\"; };\n\t\tC0C52A8C287E7F940011820F /* NeRFCapture.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NeRFCapture.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tC0C52A8F287E7F940011820F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\tC0C52A91287E7F940011820F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = \"<group>\"; };\n\t\tC0C52A95287E7F960011820F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\tC0C52A98287E7F960011820F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = \"Preview Assets.xcassets\"; sourceTree = \"<group>\"; };\n\t\tC0C52AA2287EC19A0011820F /* Utils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = \"<group>\"; };\n\t\tC0C52AA7287EC2390011820F /* ARViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARViewModel.swift; sourceTree = \"<group>\"; };\n\t\tC0C52AA9287EC2470011820F /* ARViewContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ARViewContainer.swift; sourceTree = \"<group>\"; };\n\t\tC0C52AAB287EC26A0011820F /* Manifest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Manifest.swift; sourceTree = \"<group>\"; };\n\t\tC0C52AAD287EC33D0011820F /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tC0C52A89287E7F940011820F /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t0539EAB429654B0400C51AB9 /* cyclonedds in Frameworks */,\n\t\t\t\t0539EAB12965458E00C51AB9 /* Zip in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t0531C0A6293735DD005F0929 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t057E7765293816800014E461 /* Networking */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t051230122942EE07003915D9 /* CycloneDDS-Bridging-Header.h */,\n\t\t\t);\n\t\t\tpath = Networking;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t057E776C293825FE0014E461 /* Packages */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tname = Packages;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t057E7774293827F60014E461 /* DDSModel */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t0512301C29499F4F003915D9 /* NeRFCaptureData.c */,\n\t\t\t\t0512301E29499F50003915D9 /* NeRFCaptureData.h */,\n\t\t\t\t0512301D29499F4F003915D9 /* NeRFCaptureData.idl */,\n\t\t\t);\n\t\t\tpath = DDSModel;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52A83287E7F940011820F = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t057E776C293825FE0014E461 /* Packages */,\n\t\t\t\tC0C52A8E287E7F940011820F /* NeRFCapture */,\n\t\t\t\tC0C52A8D287E7F940011820F /* Products */,\n\t\t\t\t0531C0A6293735DD005F0929 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52A8D287E7F940011820F /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0C52A8C287E7F940011820F /* NeRFCapture.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52A8E287E7F940011820F /* NeRFCapture */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t057E7774293827F60014E461 /* DDSModel */,\n\t\t\t\t057E7765293816800014E461 /* Networking */,\n\t\t\t\t052D2374287FD53A0083DC5B /* Info.plist */,\n\t\t\t\tC0C52AA6287EC2090011820F /* Models */,\n\t\t\t\tC0C52AA5287EC2040011820F /* Views */,\n\t\t\t\tC0C52AA4287EC1FA0011820F /* ViewModels */,\n\t\t\t\tC0C52A8F287E7F940011820F /* AppDelegate.swift */,\n\t\t\t\tC0C52AA2287EC19A0011820F /* Utils.swift */,\n\t\t\t\tC0C52A95287E7F960011820F /* Assets.xcassets */,\n\t\t\t\tC0C52A97287E7F960011820F /* Preview Content */,\n\t\t\t\t057A7AA72950092E000692A0 /* Shaders.metal */,\n\t\t\t\t050A8EF9296E738200C5C638 /* DatasetWriter.swift */,\n\t\t\t\t050A8EFB296E8B8E00C5C638 /* DDSWriter.swift */,\n\t\t\t);\n\t\t\tpath = NeRFCapture;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52A97287E7F960011820F /* Preview Content */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0C52A98287E7F960011820F /* Preview Assets.xcassets */,\n\t\t\t);\n\t\t\tpath = \"Preview Content\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52AA4287EC1FA0011820F /* ViewModels */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0C52AA7287EC2390011820F /* ARViewModel.swift */,\n\t\t\t);\n\t\t\tpath = ViewModels;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52AA5287EC2040011820F /* Views */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0C52A91287E7F940011820F /* ContentView.swift */,\n\t\t\t\tC0C52AA9287EC2470011820F /* ARViewContainer.swift */,\n\t\t\t);\n\t\t\tpath = Views;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC0C52AA6287EC2090011820F /* Models */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tC0C52AAB287EC26A0011820F /* Manifest.swift */,\n\t\t\t\tC0C52AAD287EC33D0011820F /* AppState.swift */,\n\t\t\t);\n\t\t\tpath = Models;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\tC0C52A8B287E7F940011820F /* NeRFCapture */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = C0C52A9C287E7F960011820F /* Build configuration list for PBXNativeTarget \"NeRFCapture\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tC0C52A88287E7F940011820F /* Sources */,\n\t\t\t\tC0C52A89287E7F940011820F /* Frameworks */,\n\t\t\t\tC0C52A8A287E7F940011820F /* Resources */,\n\t\t\t\t0531C0AA293735DE005F0929 /* Embed Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = NeRFCapture;\n\t\t\tpackageProductDependencies = (\n\t\t\t\t0539EAB02965458E00C51AB9 /* Zip */,\n\t\t\t\t0539EAB329654B0400C51AB9 /* cyclonedds */,\n\t\t\t);\n\t\t\tproductName = NeRFCapture;\n\t\t\tproductReference = C0C52A8C287E7F940011820F /* NeRFCapture.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tC0C52A84287E7F940011820F /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = 1;\n\t\t\t\tLastSwiftUpdateCheck = 1340;\n\t\t\t\tLastUpgradeCheck = 1340;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\tC0C52A8B287E7F940011820F = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 13.4.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = C0C52A87287E7F940011820F /* Build configuration list for PBXProject \"NeRFCapture\" */;\n\t\t\tcompatibilityVersion = \"Xcode 13.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = C0C52A83287E7F940011820F;\n\t\t\tpackageReferences = (\n\t\t\t\t0539EAAF2965458E00C51AB9 /* XCRemoteSwiftPackageReference \"Zip\" */,\n\t\t\t\t0539EAB229654B0400C51AB9 /* XCRemoteSwiftPackageReference \"CycloneDDSPrebuild\" */,\n\t\t\t);\n\t\t\tproductRefGroup = C0C52A8D287E7F940011820F /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tC0C52A8B287E7F940011820F /* NeRFCapture */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\tC0C52A8A287E7F940011820F /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t0512302029499F50003915D9 /* NeRFCaptureData.idl in Resources */,\n\t\t\t\tC0C52A99287E7F960011820F /* Preview Assets.xcassets in Resources */,\n\t\t\t\tC0C52A96287E7F960011820F /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\tC0C52A88287E7F940011820F /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tC0C52AAA287EC2470011820F /* ARViewContainer.swift in Sources */,\n\t\t\t\t050A8EFA296E738300C5C638 /* DatasetWriter.swift in Sources */,\n\t\t\t\tC0C52A92287E7F940011820F /* ContentView.swift in Sources */,\n\t\t\t\tC0C52AAE287EC33D0011820F /* AppState.swift in Sources */,\n\t\t\t\t0512301F29499F50003915D9 /* NeRFCaptureData.c in Sources */,\n\t\t\t\tC0C52AAC287EC26A0011820F /* Manifest.swift in Sources */,\n\t\t\t\tC0C52A90287E7F940011820F /* AppDelegate.swift in Sources */,\n\t\t\t\t050A8EFC296E8B8E00C5C638 /* DDSWriter.swift in Sources */,\n\t\t\t\t057A7AA82950092E000692A0 /* Shaders.metal in Sources */,\n\t\t\t\tC0C52AA3287EC19A0011820F /* Utils.swift in Sources */,\n\t\t\t\tC0C52AA8287EC2390011820F /* ARViewModel.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\tC0C52A9A287E7F960011820F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_ENFORCE_EXCLUSIVE_ACCESS = on;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC0C52A9B287E7F960011820F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_ENFORCE_EXCLUSIVE_ACCESS = on;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tC0C52A9D287E7F960011820F /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_ASSET_PATHS = \"\\\"NeRFCapture/Preview Content\\\"\";\n\t\t\t\tDEVELOPMENT_TEAM = 2DFGSA53H4;\n\t\t\t\tENABLE_PREVIEWS = YES;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_FILE = NeRFCapture/Info.plist;\n\t\t\t\tINFOPLIST_KEY_CFBundleDisplayName = \"NeRF Capture\";\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.education\";\n\t\t\t\tINFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;\n\t\t\t\tINFOPLIST_KEY_NSCameraUsageDescription = \"\";\n\t\t\t\tINFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;\n\t\t\t\tINFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen.storyboard;\n\t\t\t\tINFOPLIST_KEY_UIRequiredDeviceCapabilities = arkit;\n\t\t\t\tINFOPLIST_KEY_UIStatusBarHidden = YES;\n\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations = \"UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown\";\n\t\t\t\tINFOPLIST_KEY_UISupportsDocumentBrowser = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = au.edu.qcr.NeRFCapture;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSUPPORTED_PLATFORMS = \"iphoneos iphonesimulator\";\n\t\t\t\tSUPPORTS_MACCATALYST = NO;\n\t\t\t\tSUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"NeRFCapture/Networking/CycloneDDS-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tC0C52A9E287E7F960011820F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_ASSET_PATHS = \"\\\"NeRFCapture/Preview Content\\\"\";\n\t\t\t\tDEVELOPMENT_TEAM = 2DFGSA53H4;\n\t\t\t\tENABLE_PREVIEWS = YES;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_FILE = NeRFCapture/Info.plist;\n\t\t\t\tINFOPLIST_KEY_CFBundleDisplayName = \"NeRF Capture\";\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.education\";\n\t\t\t\tINFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;\n\t\t\t\tINFOPLIST_KEY_NSCameraUsageDescription = \"\";\n\t\t\t\tINFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;\n\t\t\t\tINFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen.storyboard;\n\t\t\t\tINFOPLIST_KEY_UIRequiredDeviceCapabilities = arkit;\n\t\t\t\tINFOPLIST_KEY_UIStatusBarHidden = YES;\n\t\t\t\tINFOPLIST_KEY_UISupportedInterfaceOrientations = \"UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown\";\n\t\t\t\tINFOPLIST_KEY_UISupportsDocumentBrowser = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = au.edu.qcr.NeRFCapture;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSUPPORTED_PLATFORMS = \"iphoneos iphonesimulator\";\n\t\t\t\tSUPPORTS_MACCATALYST = NO;\n\t\t\t\tSUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"NeRFCapture/Networking/CycloneDDS-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\tC0C52A87287E7F940011820F /* Build configuration list for PBXProject \"NeRFCapture\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC0C52A9A287E7F960011820F /* Debug */,\n\t\t\t\tC0C52A9B287E7F960011820F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tC0C52A9C287E7F960011820F /* Build configuration list for PBXNativeTarget \"NeRFCapture\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tC0C52A9D287E7F960011820F /* Debug */,\n\t\t\t\tC0C52A9E287E7F960011820F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\n/* Begin XCRemoteSwiftPackageReference section */\n\t\t0539EAAF2965458E00C51AB9 /* XCRemoteSwiftPackageReference \"Zip\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/marmelroy/Zip\";\n\t\t\trequirement = {\n\t\t\t\tbranch = master;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n\t\t0539EAB229654B0400C51AB9 /* XCRemoteSwiftPackageReference \"CycloneDDSPrebuild\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/jc211/CycloneDDSPrebuild.git\";\n\t\t\trequirement = {\n\t\t\t\tbranch = main;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n/* End XCRemoteSwiftPackageReference section */\n\n/* Begin XCSwiftPackageProductDependency section */\n\t\t0539EAB02965458E00C51AB9 /* Zip */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 0539EAAF2965458E00C51AB9 /* XCRemoteSwiftPackageReference \"Zip\" */;\n\t\t\tproductName = Zip;\n\t\t};\n\t\t0539EAB329654B0400C51AB9 /* cyclonedds */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 0539EAB229654B0400C51AB9 /* XCRemoteSwiftPackageReference \"CycloneDDSPrebuild\" */;\n\t\t\tproductName = cyclonedds;\n\t\t};\n/* End XCSwiftPackageProductDependency section */\n\t};\n\trootObject = C0C52A84287E7F940011820F /* Project object */;\n}\n"
  },
  {
    "path": "NeRFCapture.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "NeRFCapture.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "NeRFCapture.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreviewsEnabled</key>\n\t<false/>\n</dict>\n</plist>\n"
  },
  {
    "path": "NeRFCapture.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved",
    "content": "{\n  \"pins\" : [\n    {\n      \"identity\" : \"cycloneddsprebuild\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/jc211/CycloneDDSPrebuild.git\",\n      \"state\" : {\n        \"branch\" : \"main\",\n        \"revision\" : \"38991d7195f7d64eb9e1ae630bc2efbecada40d2\"\n      }\n    },\n    {\n      \"identity\" : \"zip\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/marmelroy/Zip\",\n      \"state\" : {\n        \"branch\" : \"master\",\n        \"revision\" : \"67fa55813b9e7b3b9acee9c0ae501def28746d76\"\n      }\n    }\n  ],\n  \"version\" : 2\n}\n"
  },
  {
    "path": "NeRFCapture.xcodeproj/xcshareddata/xcschemes/NeRFCapture.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1410\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"C0C52A8B287E7F940011820F\"\n               BuildableName = \"NeRFCapture.app\"\n               BlueprintName = \"NeRFCapture\"\n               ReferencedContainer = \"container:NeRFCapture.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C0C52A8B287E7F940011820F\"\n            BuildableName = \"NeRFCapture.app\"\n            BlueprintName = \"NeRFCapture\"\n            ReferencedContainer = \"container:NeRFCapture.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"C0C52A8B287E7F940011820F\"\n            BuildableName = \"NeRFCapture.app\"\n            BlueprintName = \"NeRFCapture\"\n            ReferencedContainer = \"container:NeRFCapture.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "README.md",
    "content": "# NeRF Capture \n<img src=\"docs/assets_readme/NeRFCaptureReal.png\" height=\"342\"/><img src=\"docs/assets_readme/NeRFCaptureSample.gif\" height=\"342\"/> \n\n\nCollecting NeRF datasets is difficult. NeRF Capture is an iOS application that allows any iPhone or iPad to quickly collect or stream posed images to [InstantNGP](https://github.com/NVlabs/instant-ngp). If your device has a LiDAR, the depth images will be saved/streamed as well. The app has two modes: Offline and Online. In Offline mode, the dataset is saved to the device and can be accessed in the Files App in the NeRFCapture folder. Online mode uses [CycloneDDS](https://github.com/eclipse-cyclonedds/cyclonedds) to publish the posed images on the network. A Python script then collects the images and provides them to InstantNGP.\n\n<a href=\"https://apps.apple.com/us/app/nerfcapture/id6446518379?itsct=apps_box_badge&amp;itscg=30200\" style=\"display: inline-block; overflow: hidden; border-radius: 13px; width: 150px; height: 53px;\"><img src=\"https://tools.applemediaservices.com/api/badges/download-on-the-app-store/black/en-us?size=250x83&amp;releaseDate=1679443200\" alt=\"Download on the App Store\" style=\"border-radius: 13px; width: 150px; height: 53px;\"></a>\n\n\n\n## Online Mode\n\n<img src=\"docs/assets_readme/NeRFCaptureScreenshot.png\" height=\"342\"/>\n\nUse the Reset button to reset the coordinate system to the current position of the camera. This takes a while; wait until the tracking initialized before moving away.\n\nSwitch the app to online mode. On the computer running InstantNGP, make sure that CycloneDDS is installed in the same python environment that is running pyngp. OpenCV and Pillow are needed to save and resize images.\n\n```\npip install cyclonedds\n```\n\nCheck that the computer can see the device on your network by running in your terminal:\n\n```\ncyclonedds ps\n```\n\nInstructions found in [here](https://github.com/NVlabs/instant-ngp/blob/master/docs/nerf_dataset_tips.md#NeRFCapture)\n\n\n## Offline Mode\n\nIn Offline mode, clicking start initializes the dataset. Take a few images then click End when you're done. The dataset can be found as a zip file in your Files App in the format that InstantNGP expects. Unzip the dataset and drag and drop it into InstantNGP. We have found it farely difficult to get files transferred from an iOS device to another computer so we recommend running the app in Online mode and collecting the dataset with the nerfcapture2nerf.py script found in InstantNGP.\n\n<img src=\"docs/assets_readme/NeRFCaptureFile1.png\" height=\"342\"/>\n<img src=\"docs/assets_readme/NeRFCaptureFile2.png\" height=\"342\"/>\n\n## Citation\n\nIf you use this software in your research, please consider citing it. \n```bibtex\n@misc{\n  NeRFCapture,\n  url={https://github.com/jc211/NeRFCapture},\n  journal={NeRFCapture},\n  author={Abou-Chakra, Jad},\n  year={2023},\n  month={Mar}\n} \n```\n\n\n"
  }
]