├── README.md ├── RealityKit ARMeshAnchor.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── travishall.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ └── xcschememanagement.plist ├── RealityKit Example ARMeshAnchor ├── AppDelegate.swift ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── Contents.json ├── ContentView.swift ├── Demo │ ├── demo.gif │ └── demo2.gif ├── Extensions.swift ├── MeshAnchorGeometry.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json └── Shaders │ ├── warpGeometry.metal │ └── warpSurface.metal ├── RealityKit Example ARMeshAnchorTests └── RealityKit_Example_ARMeshAnchorTests.swift └── RealityKit Example ARMeshAnchorUITests ├── RealityKit_Example_ARMeshAnchorUITests.swift └── RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift /README.md: -------------------------------------------------------------------------------- 1 | # RealityKit - Extracting anchor geometry to create a custom Mesh 2 | 3 | An example project showing how to extract anchor geometry from ARMeshAnchor, create a new custom mesh and color per face in RealityKit. 4 | 5 | ## Description 6 | Last year, ARKit 3.5 introduced the ability to use the LIDAR sensor to understand more about the scene and surroudings. At the time you were limited by RealityKit's lack of procedural geometry, if you wanted to visualise the scene understanding with custom models you needed to use SceneKit. With ARKit 5, Apple has introduced a way to create procedural meshes, so we can now use the geometry to create custom model entities in RealityKit. 7 | 8 | This project uses the [ARMeshAnchor](https://developer.apple.com/documentation/arkit/armeshgeometry) geometry returned using the LIDAR scanner with scene reconstruction to generate a custom mesh using the new (From iOS 15 Beta) RealityKit [MeshBuffers](https://developer.apple.com/documentation/realitykit/meshbuffers) api. It uses the **vertices**, **faces**, **normals** and **classificationIds** to display a new mesh anchored at the same position. The faces are then coloured using the matching classificationIds. You can change the colors and blending mode for each classification in the example app. 9 | 10 | Visualising the ARMeshAnchor geometry. 11 | 12 | ![Alt Text](https://github.com/TravisHall/RealityKit-Example-ARMeshAnchor-Geometry/blob/main/RealityKit%20Example%20ARMeshAnchor/Demo/demo2.gif) 13 | 14 | Changing colours of the classifications. 15 | 16 | ![Alt Text](https://github.com/TravisHall/RealityKit-Example-ARMeshAnchor-Geometry/blob/main/RealityKit%20Example%20ARMeshAnchor/Demo/demo.gif) 17 | 18 | 19 | 20 | ## Further reading 21 | **[Max Cobb - Getting Started with RealityKit: Procedural Geometries](https://maxxfrazer.medium.com/getting-started-with-realitykit-procedural-geometries-5dd9eca659ef)**. 22 | 23 | **[Visualizing and Interacting with a Reconstructed Scene](https://developer.apple.com/documentation/arkit/content_anchors/visualizing_and_interacting_with_a_reconstructed_scene)** 24 | 25 | -------------------------------------------------------------------------------- /RealityKit ARMeshAnchor.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 55; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B4DD6BB9274EDC0B004A1D8E /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BB8274EDC0B004A1D8E /* AppDelegate.swift */; }; 11 | B4DD6BBB274EDC0B004A1D8E /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BBA274EDC0B004A1D8E /* ContentView.swift */; }; 12 | B4DD6BBF274EDC0E004A1D8E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4DD6BBE274EDC0E004A1D8E /* Assets.xcassets */; }; 13 | B4DD6BC2274EDC0E004A1D8E /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B4DD6BC1274EDC0E004A1D8E /* Preview Assets.xcassets */; }; 14 | B4DD6BCC274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BCB274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorTests.swift */; }; 15 | B4DD6BD6274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BD5274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITests.swift */; }; 16 | B4DD6BD8274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BD7274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift */; }; 17 | B4DD6BE6274EE688004A1D8E /* MeshAnchorGeometry.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BE5274EE688004A1D8E /* MeshAnchorGeometry.swift */; }; 18 | B4DD6BE8274FB248004A1D8E /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BE7274FB248004A1D8E /* Extensions.swift */; }; 19 | B4DD6BEF27512001004A1D8E /* warpSurface.metal in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BEE27512001004A1D8E /* warpSurface.metal */; }; 20 | B4DD6BF127512734004A1D8E /* warpGeometry.metal in Sources */ = {isa = PBXBuildFile; fileRef = B4DD6BF027512734004A1D8E /* warpGeometry.metal */; }; 21 | /* End PBXBuildFile section */ 22 | 23 | /* Begin PBXContainerItemProxy section */ 24 | B4DD6BC8274EDC0F004A1D8E /* PBXContainerItemProxy */ = { 25 | isa = PBXContainerItemProxy; 26 | containerPortal = B4DD6BAD274EDC0B004A1D8E /* Project object */; 27 | proxyType = 1; 28 | remoteGlobalIDString = B4DD6BB4274EDC0B004A1D8E; 29 | remoteInfo = "RealityKit Example ARMeshAnchor"; 30 | }; 31 | B4DD6BD2274EDC0F004A1D8E /* PBXContainerItemProxy */ = { 32 | isa = PBXContainerItemProxy; 33 | containerPortal = B4DD6BAD274EDC0B004A1D8E /* Project object */; 34 | proxyType = 1; 35 | remoteGlobalIDString = B4DD6BB4274EDC0B004A1D8E; 36 | remoteInfo = "RealityKit Example ARMeshAnchor"; 37 | }; 38 | /* End PBXContainerItemProxy section */ 39 | 40 | /* Begin PBXFileReference section */ 41 | B4DD6BB5274EDC0B004A1D8E /* RealityKit ARMeshAnchor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RealityKit ARMeshAnchor.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 42 | B4DD6BB8274EDC0B004A1D8E /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 43 | B4DD6BBA274EDC0B004A1D8E /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 44 | B4DD6BBE274EDC0E004A1D8E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 45 | B4DD6BC1274EDC0E004A1D8E /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 46 | B4DD6BC7274EDC0F004A1D8E /* RealityKit ARMeshAnchorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RealityKit ARMeshAnchorTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | B4DD6BCB274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealityKit_Example_ARMeshAnchorTests.swift; sourceTree = ""; }; 48 | B4DD6BD1274EDC0F004A1D8E /* RealityKit ARMeshAnchorUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "RealityKit ARMeshAnchorUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 49 | B4DD6BD5274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealityKit_Example_ARMeshAnchorUITests.swift; sourceTree = ""; }; 50 | B4DD6BD7274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift; sourceTree = ""; }; 51 | B4DD6BE5274EE688004A1D8E /* MeshAnchorGeometry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeshAnchorGeometry.swift; sourceTree = ""; }; 52 | B4DD6BE7274FB248004A1D8E /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; 53 | B4DD6BEE27512001004A1D8E /* warpSurface.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = warpSurface.metal; sourceTree = ""; }; 54 | B4DD6BF027512734004A1D8E /* warpGeometry.metal */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.metal; path = warpGeometry.metal; sourceTree = ""; }; 55 | /* End PBXFileReference section */ 56 | 57 | /* Begin PBXFrameworksBuildPhase section */ 58 | B4DD6BB2274EDC0B004A1D8E /* Frameworks */ = { 59 | isa = PBXFrameworksBuildPhase; 60 | buildActionMask = 2147483647; 61 | files = ( 62 | ); 63 | runOnlyForDeploymentPostprocessing = 0; 64 | }; 65 | B4DD6BC4274EDC0F004A1D8E /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | ); 70 | runOnlyForDeploymentPostprocessing = 0; 71 | }; 72 | B4DD6BCE274EDC0F004A1D8E /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | /* End PBXFrameworksBuildPhase section */ 80 | 81 | /* Begin PBXGroup section */ 82 | B4DD6BAC274EDC0B004A1D8E = { 83 | isa = PBXGroup; 84 | children = ( 85 | B4DD6BB7274EDC0B004A1D8E /* RealityKit Example ARMeshAnchor */, 86 | B4DD6BCA274EDC0F004A1D8E /* RealityKit Example ARMeshAnchorTests */, 87 | B4DD6BD4274EDC0F004A1D8E /* RealityKit Example ARMeshAnchorUITests */, 88 | B4DD6BB6274EDC0B004A1D8E /* Products */, 89 | ); 90 | sourceTree = ""; 91 | }; 92 | B4DD6BB6274EDC0B004A1D8E /* Products */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | B4DD6BB5274EDC0B004A1D8E /* RealityKit ARMeshAnchor.app */, 96 | B4DD6BC7274EDC0F004A1D8E /* RealityKit ARMeshAnchorTests.xctest */, 97 | B4DD6BD1274EDC0F004A1D8E /* RealityKit ARMeshAnchorUITests.xctest */, 98 | ); 99 | name = Products; 100 | sourceTree = ""; 101 | }; 102 | B4DD6BB7274EDC0B004A1D8E /* RealityKit Example ARMeshAnchor */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | B4DD6BE927511F5F004A1D8E /* Shaders */, 106 | B4DD6BE4274EDF32004A1D8E /* Entities */, 107 | B4DD6BB8274EDC0B004A1D8E /* AppDelegate.swift */, 108 | B4DD6BE7274FB248004A1D8E /* Extensions.swift */, 109 | B4DD6BBA274EDC0B004A1D8E /* ContentView.swift */, 110 | B4DD6BE5274EE688004A1D8E /* MeshAnchorGeometry.swift */, 111 | B4DD6BBE274EDC0E004A1D8E /* Assets.xcassets */, 112 | B4DD6BC0274EDC0E004A1D8E /* Preview Content */, 113 | ); 114 | path = "RealityKit Example ARMeshAnchor"; 115 | sourceTree = ""; 116 | }; 117 | B4DD6BC0274EDC0E004A1D8E /* Preview Content */ = { 118 | isa = PBXGroup; 119 | children = ( 120 | B4DD6BC1274EDC0E004A1D8E /* Preview Assets.xcassets */, 121 | ); 122 | path = "Preview Content"; 123 | sourceTree = ""; 124 | }; 125 | B4DD6BCA274EDC0F004A1D8E /* RealityKit Example ARMeshAnchorTests */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | B4DD6BCB274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorTests.swift */, 129 | ); 130 | path = "RealityKit Example ARMeshAnchorTests"; 131 | sourceTree = ""; 132 | }; 133 | B4DD6BD4274EDC0F004A1D8E /* RealityKit Example ARMeshAnchorUITests */ = { 134 | isa = PBXGroup; 135 | children = ( 136 | B4DD6BD5274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITests.swift */, 137 | B4DD6BD7274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift */, 138 | ); 139 | path = "RealityKit Example ARMeshAnchorUITests"; 140 | sourceTree = ""; 141 | }; 142 | B4DD6BE4274EDF32004A1D8E /* Entities */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | ); 146 | path = Entities; 147 | sourceTree = ""; 148 | }; 149 | B4DD6BE927511F5F004A1D8E /* Shaders */ = { 150 | isa = PBXGroup; 151 | children = ( 152 | B4DD6BEE27512001004A1D8E /* warpSurface.metal */, 153 | B4DD6BF027512734004A1D8E /* warpGeometry.metal */, 154 | ); 155 | path = Shaders; 156 | sourceTree = ""; 157 | }; 158 | /* End PBXGroup section */ 159 | 160 | /* Begin PBXNativeTarget section */ 161 | B4DD6BB4274EDC0B004A1D8E /* RealityKit ARMeshAnchor */ = { 162 | isa = PBXNativeTarget; 163 | buildConfigurationList = B4DD6BDB274EDC0F004A1D8E /* Build configuration list for PBXNativeTarget "RealityKit ARMeshAnchor" */; 164 | buildPhases = ( 165 | B4DD6BB1274EDC0B004A1D8E /* Sources */, 166 | B4DD6BB2274EDC0B004A1D8E /* Frameworks */, 167 | B4DD6BB3274EDC0B004A1D8E /* Resources */, 168 | ); 169 | buildRules = ( 170 | ); 171 | dependencies = ( 172 | ); 173 | name = "RealityKit ARMeshAnchor"; 174 | productName = "RealityKit Example ARMeshAnchor"; 175 | productReference = B4DD6BB5274EDC0B004A1D8E /* RealityKit ARMeshAnchor.app */; 176 | productType = "com.apple.product-type.application"; 177 | }; 178 | B4DD6BC6274EDC0F004A1D8E /* RealityKit ARMeshAnchorTests */ = { 179 | isa = PBXNativeTarget; 180 | buildConfigurationList = B4DD6BDE274EDC0F004A1D8E /* Build configuration list for PBXNativeTarget "RealityKit ARMeshAnchorTests" */; 181 | buildPhases = ( 182 | B4DD6BC3274EDC0F004A1D8E /* Sources */, 183 | B4DD6BC4274EDC0F004A1D8E /* Frameworks */, 184 | B4DD6BC5274EDC0F004A1D8E /* Resources */, 185 | ); 186 | buildRules = ( 187 | ); 188 | dependencies = ( 189 | B4DD6BC9274EDC0F004A1D8E /* PBXTargetDependency */, 190 | ); 191 | name = "RealityKit ARMeshAnchorTests"; 192 | productName = "RealityKit Example ARMeshAnchorTests"; 193 | productReference = B4DD6BC7274EDC0F004A1D8E /* RealityKit ARMeshAnchorTests.xctest */; 194 | productType = "com.apple.product-type.bundle.unit-test"; 195 | }; 196 | B4DD6BD0274EDC0F004A1D8E /* RealityKit ARMeshAnchorUITests */ = { 197 | isa = PBXNativeTarget; 198 | buildConfigurationList = B4DD6BE1274EDC0F004A1D8E /* Build configuration list for PBXNativeTarget "RealityKit ARMeshAnchorUITests" */; 199 | buildPhases = ( 200 | B4DD6BCD274EDC0F004A1D8E /* Sources */, 201 | B4DD6BCE274EDC0F004A1D8E /* Frameworks */, 202 | B4DD6BCF274EDC0F004A1D8E /* Resources */, 203 | ); 204 | buildRules = ( 205 | ); 206 | dependencies = ( 207 | B4DD6BD3274EDC0F004A1D8E /* PBXTargetDependency */, 208 | ); 209 | name = "RealityKit ARMeshAnchorUITests"; 210 | productName = "RealityKit Example ARMeshAnchorUITests"; 211 | productReference = B4DD6BD1274EDC0F004A1D8E /* RealityKit ARMeshAnchorUITests.xctest */; 212 | productType = "com.apple.product-type.bundle.ui-testing"; 213 | }; 214 | /* End PBXNativeTarget section */ 215 | 216 | /* Begin PBXProject section */ 217 | B4DD6BAD274EDC0B004A1D8E /* Project object */ = { 218 | isa = PBXProject; 219 | attributes = { 220 | BuildIndependentTargetsInParallel = 1; 221 | LastSwiftUpdateCheck = 1300; 222 | LastUpgradeCheck = 1300; 223 | TargetAttributes = { 224 | B4DD6BB4274EDC0B004A1D8E = { 225 | CreatedOnToolsVersion = 13.0; 226 | }; 227 | B4DD6BC6274EDC0F004A1D8E = { 228 | CreatedOnToolsVersion = 13.0; 229 | TestTargetID = B4DD6BB4274EDC0B004A1D8E; 230 | }; 231 | B4DD6BD0274EDC0F004A1D8E = { 232 | CreatedOnToolsVersion = 13.0; 233 | TestTargetID = B4DD6BB4274EDC0B004A1D8E; 234 | }; 235 | }; 236 | }; 237 | buildConfigurationList = B4DD6BB0274EDC0B004A1D8E /* Build configuration list for PBXProject "RealityKit ARMeshAnchor" */; 238 | compatibilityVersion = "Xcode 13.0"; 239 | developmentRegion = en; 240 | hasScannedForEncodings = 0; 241 | knownRegions = ( 242 | en, 243 | Base, 244 | ); 245 | mainGroup = B4DD6BAC274EDC0B004A1D8E; 246 | productRefGroup = B4DD6BB6274EDC0B004A1D8E /* Products */; 247 | projectDirPath = ""; 248 | projectRoot = ""; 249 | targets = ( 250 | B4DD6BB4274EDC0B004A1D8E /* RealityKit ARMeshAnchor */, 251 | B4DD6BC6274EDC0F004A1D8E /* RealityKit ARMeshAnchorTests */, 252 | B4DD6BD0274EDC0F004A1D8E /* RealityKit ARMeshAnchorUITests */, 253 | ); 254 | }; 255 | /* End PBXProject section */ 256 | 257 | /* Begin PBXResourcesBuildPhase section */ 258 | B4DD6BB3274EDC0B004A1D8E /* Resources */ = { 259 | isa = PBXResourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | B4DD6BC2274EDC0E004A1D8E /* Preview Assets.xcassets in Resources */, 263 | B4DD6BBF274EDC0E004A1D8E /* Assets.xcassets in Resources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | B4DD6BC5274EDC0F004A1D8E /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | B4DD6BCF274EDC0F004A1D8E /* Resources */ = { 275 | isa = PBXResourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | ); 279 | runOnlyForDeploymentPostprocessing = 0; 280 | }; 281 | /* End PBXResourcesBuildPhase section */ 282 | 283 | /* Begin PBXSourcesBuildPhase section */ 284 | B4DD6BB1274EDC0B004A1D8E /* Sources */ = { 285 | isa = PBXSourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | B4DD6BE6274EE688004A1D8E /* MeshAnchorGeometry.swift in Sources */, 289 | B4DD6BEF27512001004A1D8E /* warpSurface.metal in Sources */, 290 | B4DD6BBB274EDC0B004A1D8E /* ContentView.swift in Sources */, 291 | B4DD6BF127512734004A1D8E /* warpGeometry.metal in Sources */, 292 | B4DD6BB9274EDC0B004A1D8E /* AppDelegate.swift in Sources */, 293 | B4DD6BE8274FB248004A1D8E /* Extensions.swift in Sources */, 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | B4DD6BC3274EDC0F004A1D8E /* Sources */ = { 298 | isa = PBXSourcesBuildPhase; 299 | buildActionMask = 2147483647; 300 | files = ( 301 | B4DD6BCC274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorTests.swift in Sources */, 302 | ); 303 | runOnlyForDeploymentPostprocessing = 0; 304 | }; 305 | B4DD6BCD274EDC0F004A1D8E /* Sources */ = { 306 | isa = PBXSourcesBuildPhase; 307 | buildActionMask = 2147483647; 308 | files = ( 309 | B4DD6BD8274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift in Sources */, 310 | B4DD6BD6274EDC0F004A1D8E /* RealityKit_Example_ARMeshAnchorUITests.swift in Sources */, 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | /* End PBXSourcesBuildPhase section */ 315 | 316 | /* Begin PBXTargetDependency section */ 317 | B4DD6BC9274EDC0F004A1D8E /* PBXTargetDependency */ = { 318 | isa = PBXTargetDependency; 319 | target = B4DD6BB4274EDC0B004A1D8E /* RealityKit ARMeshAnchor */; 320 | targetProxy = B4DD6BC8274EDC0F004A1D8E /* PBXContainerItemProxy */; 321 | }; 322 | B4DD6BD3274EDC0F004A1D8E /* PBXTargetDependency */ = { 323 | isa = PBXTargetDependency; 324 | target = B4DD6BB4274EDC0B004A1D8E /* RealityKit ARMeshAnchor */; 325 | targetProxy = B4DD6BD2274EDC0F004A1D8E /* PBXContainerItemProxy */; 326 | }; 327 | /* End PBXTargetDependency section */ 328 | 329 | /* Begin XCBuildConfiguration section */ 330 | B4DD6BD9274EDC0F004A1D8E /* Debug */ = { 331 | isa = XCBuildConfiguration; 332 | buildSettings = { 333 | ALWAYS_SEARCH_USER_PATHS = NO; 334 | CLANG_ANALYZER_NONNULL = YES; 335 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 336 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 337 | CLANG_CXX_LIBRARY = "libc++"; 338 | CLANG_ENABLE_MODULES = YES; 339 | CLANG_ENABLE_OBJC_ARC = YES; 340 | CLANG_ENABLE_OBJC_WEAK = YES; 341 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 342 | CLANG_WARN_BOOL_CONVERSION = YES; 343 | CLANG_WARN_COMMA = YES; 344 | CLANG_WARN_CONSTANT_CONVERSION = YES; 345 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 346 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 347 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 348 | CLANG_WARN_EMPTY_BODY = YES; 349 | CLANG_WARN_ENUM_CONVERSION = YES; 350 | CLANG_WARN_INFINITE_RECURSION = YES; 351 | CLANG_WARN_INT_CONVERSION = YES; 352 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 353 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 354 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 355 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 356 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 357 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 358 | CLANG_WARN_STRICT_PROTOTYPES = YES; 359 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 360 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 361 | CLANG_WARN_UNREACHABLE_CODE = YES; 362 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 363 | COPY_PHASE_STRIP = NO; 364 | DEBUG_INFORMATION_FORMAT = dwarf; 365 | ENABLE_STRICT_OBJC_MSGSEND = YES; 366 | ENABLE_TESTABILITY = YES; 367 | GCC_C_LANGUAGE_STANDARD = gnu11; 368 | GCC_DYNAMIC_NO_PIC = NO; 369 | GCC_NO_COMMON_BLOCKS = YES; 370 | GCC_OPTIMIZATION_LEVEL = 0; 371 | GCC_PREPROCESSOR_DEFINITIONS = ( 372 | "DEBUG=1", 373 | "$(inherited)", 374 | ); 375 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 376 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 377 | GCC_WARN_UNDECLARED_SELECTOR = YES; 378 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 379 | GCC_WARN_UNUSED_FUNCTION = YES; 380 | GCC_WARN_UNUSED_VARIABLE = YES; 381 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 382 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 383 | MTL_FAST_MATH = YES; 384 | ONLY_ACTIVE_ARCH = YES; 385 | SDKROOT = iphoneos; 386 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 387 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 388 | }; 389 | name = Debug; 390 | }; 391 | B4DD6BDA274EDC0F004A1D8E /* Release */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | ALWAYS_SEARCH_USER_PATHS = NO; 395 | CLANG_ANALYZER_NONNULL = YES; 396 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 397 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++17"; 398 | CLANG_CXX_LIBRARY = "libc++"; 399 | CLANG_ENABLE_MODULES = YES; 400 | CLANG_ENABLE_OBJC_ARC = YES; 401 | CLANG_ENABLE_OBJC_WEAK = YES; 402 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 403 | CLANG_WARN_BOOL_CONVERSION = YES; 404 | CLANG_WARN_COMMA = YES; 405 | CLANG_WARN_CONSTANT_CONVERSION = YES; 406 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 407 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 408 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 409 | CLANG_WARN_EMPTY_BODY = YES; 410 | CLANG_WARN_ENUM_CONVERSION = YES; 411 | CLANG_WARN_INFINITE_RECURSION = YES; 412 | CLANG_WARN_INT_CONVERSION = YES; 413 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 414 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 415 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 416 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 417 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 418 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 419 | CLANG_WARN_STRICT_PROTOTYPES = YES; 420 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 421 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 422 | CLANG_WARN_UNREACHABLE_CODE = YES; 423 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 424 | COPY_PHASE_STRIP = NO; 425 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 426 | ENABLE_NS_ASSERTIONS = NO; 427 | ENABLE_STRICT_OBJC_MSGSEND = YES; 428 | GCC_C_LANGUAGE_STANDARD = gnu11; 429 | GCC_NO_COMMON_BLOCKS = YES; 430 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 431 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 432 | GCC_WARN_UNDECLARED_SELECTOR = YES; 433 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 434 | GCC_WARN_UNUSED_FUNCTION = YES; 435 | GCC_WARN_UNUSED_VARIABLE = YES; 436 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 437 | MTL_ENABLE_DEBUG_INFO = NO; 438 | MTL_FAST_MATH = YES; 439 | SDKROOT = iphoneos; 440 | SWIFT_COMPILATION_MODE = wholemodule; 441 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 442 | VALIDATE_PRODUCT = YES; 443 | }; 444 | name = Release; 445 | }; 446 | B4DD6BDC274EDC0F004A1D8E /* Debug */ = { 447 | isa = XCBuildConfiguration; 448 | buildSettings = { 449 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 450 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 451 | CODE_SIGN_STYLE = Automatic; 452 | CURRENT_PROJECT_VERSION = 1; 453 | DEVELOPMENT_ASSET_PATHS = "\"RealityKit Example ARMeshAnchor/Preview Content\""; 454 | DEVELOPMENT_TEAM = MSFV9JEB3U; 455 | ENABLE_PREVIEWS = YES; 456 | GENERATE_INFOPLIST_FILE = YES; 457 | INFOPLIST_KEY_NSCameraUsageDescription = ""; 458 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 459 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 460 | INFOPLIST_KEY_UIRequiredDeviceCapabilities = arkit; 461 | INFOPLIST_KEY_UIStatusBarHidden = YES; 462 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 463 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 464 | LD_RUNPATH_SEARCH_PATHS = ( 465 | "$(inherited)", 466 | "@executable_path/Frameworks", 467 | ); 468 | MARKETING_VERSION = 1.0; 469 | PRODUCT_BUNDLE_IDENTIFIER = "TH.RealityKit-Example-ARMeshAnchor"; 470 | PRODUCT_NAME = "RealityKit ARMeshAnchor"; 471 | SWIFT_EMIT_LOC_STRINGS = YES; 472 | SWIFT_VERSION = 5.0; 473 | TARGETED_DEVICE_FAMILY = "1,2"; 474 | }; 475 | name = Debug; 476 | }; 477 | B4DD6BDD274EDC0F004A1D8E /* Release */ = { 478 | isa = XCBuildConfiguration; 479 | buildSettings = { 480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 481 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 482 | CODE_SIGN_STYLE = Automatic; 483 | CURRENT_PROJECT_VERSION = 1; 484 | DEVELOPMENT_ASSET_PATHS = "\"RealityKit Example ARMeshAnchor/Preview Content\""; 485 | DEVELOPMENT_TEAM = MSFV9JEB3U; 486 | ENABLE_PREVIEWS = YES; 487 | GENERATE_INFOPLIST_FILE = YES; 488 | INFOPLIST_KEY_NSCameraUsageDescription = ""; 489 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 490 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 491 | INFOPLIST_KEY_UIRequiredDeviceCapabilities = arkit; 492 | INFOPLIST_KEY_UIStatusBarHidden = YES; 493 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 494 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 495 | LD_RUNPATH_SEARCH_PATHS = ( 496 | "$(inherited)", 497 | "@executable_path/Frameworks", 498 | ); 499 | MARKETING_VERSION = 1.0; 500 | PRODUCT_BUNDLE_IDENTIFIER = "TH.RealityKit-Example-ARMeshAnchor"; 501 | PRODUCT_NAME = "RealityKit ARMeshAnchor"; 502 | SWIFT_EMIT_LOC_STRINGS = YES; 503 | SWIFT_VERSION = 5.0; 504 | TARGETED_DEVICE_FAMILY = "1,2"; 505 | }; 506 | name = Release; 507 | }; 508 | B4DD6BDF274EDC0F004A1D8E /* Debug */ = { 509 | isa = XCBuildConfiguration; 510 | buildSettings = { 511 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 512 | BUNDLE_LOADER = "$(TEST_HOST)"; 513 | CODE_SIGN_STYLE = Automatic; 514 | CURRENT_PROJECT_VERSION = 1; 515 | DEVELOPMENT_TEAM = MSFV9JEB3U; 516 | GENERATE_INFOPLIST_FILE = YES; 517 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 518 | LD_RUNPATH_SEARCH_PATHS = ( 519 | "$(inherited)", 520 | "@executable_path/Frameworks", 521 | "@loader_path/Frameworks", 522 | ); 523 | MARKETING_VERSION = 1.0; 524 | PRODUCT_BUNDLE_IDENTIFIER = "TH.RealityKit-Example-ARMeshAnchorTests"; 525 | PRODUCT_NAME = "$(TARGET_NAME)"; 526 | SWIFT_EMIT_LOC_STRINGS = NO; 527 | SWIFT_VERSION = 5.0; 528 | TARGETED_DEVICE_FAMILY = "1,2"; 529 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RealityKit ARMeshAnchor.app/RealityKit ARMeshAnchor"; 530 | }; 531 | name = Debug; 532 | }; 533 | B4DD6BE0274EDC0F004A1D8E /* Release */ = { 534 | isa = XCBuildConfiguration; 535 | buildSettings = { 536 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 537 | BUNDLE_LOADER = "$(TEST_HOST)"; 538 | CODE_SIGN_STYLE = Automatic; 539 | CURRENT_PROJECT_VERSION = 1; 540 | DEVELOPMENT_TEAM = MSFV9JEB3U; 541 | GENERATE_INFOPLIST_FILE = YES; 542 | IPHONEOS_DEPLOYMENT_TARGET = 15.0; 543 | LD_RUNPATH_SEARCH_PATHS = ( 544 | "$(inherited)", 545 | "@executable_path/Frameworks", 546 | "@loader_path/Frameworks", 547 | ); 548 | MARKETING_VERSION = 1.0; 549 | PRODUCT_BUNDLE_IDENTIFIER = "TH.RealityKit-Example-ARMeshAnchorTests"; 550 | PRODUCT_NAME = "$(TARGET_NAME)"; 551 | SWIFT_EMIT_LOC_STRINGS = NO; 552 | SWIFT_VERSION = 5.0; 553 | TARGETED_DEVICE_FAMILY = "1,2"; 554 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RealityKit ARMeshAnchor.app/RealityKit ARMeshAnchor"; 555 | }; 556 | name = Release; 557 | }; 558 | B4DD6BE2274EDC0F004A1D8E /* Debug */ = { 559 | isa = XCBuildConfiguration; 560 | buildSettings = { 561 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 562 | CODE_SIGN_STYLE = Automatic; 563 | CURRENT_PROJECT_VERSION = 1; 564 | DEVELOPMENT_TEAM = MSFV9JEB3U; 565 | GENERATE_INFOPLIST_FILE = YES; 566 | LD_RUNPATH_SEARCH_PATHS = ( 567 | "$(inherited)", 568 | "@executable_path/Frameworks", 569 | "@loader_path/Frameworks", 570 | ); 571 | MARKETING_VERSION = 1.0; 572 | PRODUCT_BUNDLE_IDENTIFIER = "TH.RealityKit-Example-ARMeshAnchorUITests"; 573 | PRODUCT_NAME = "$(TARGET_NAME)"; 574 | SWIFT_EMIT_LOC_STRINGS = NO; 575 | SWIFT_VERSION = 5.0; 576 | TARGETED_DEVICE_FAMILY = "1,2"; 577 | TEST_TARGET_NAME = "RealityKit Example ARMeshAnchor"; 578 | }; 579 | name = Debug; 580 | }; 581 | B4DD6BE3274EDC0F004A1D8E /* Release */ = { 582 | isa = XCBuildConfiguration; 583 | buildSettings = { 584 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 585 | CODE_SIGN_STYLE = Automatic; 586 | CURRENT_PROJECT_VERSION = 1; 587 | DEVELOPMENT_TEAM = MSFV9JEB3U; 588 | GENERATE_INFOPLIST_FILE = YES; 589 | LD_RUNPATH_SEARCH_PATHS = ( 590 | "$(inherited)", 591 | "@executable_path/Frameworks", 592 | "@loader_path/Frameworks", 593 | ); 594 | MARKETING_VERSION = 1.0; 595 | PRODUCT_BUNDLE_IDENTIFIER = "TH.RealityKit-Example-ARMeshAnchorUITests"; 596 | PRODUCT_NAME = "$(TARGET_NAME)"; 597 | SWIFT_EMIT_LOC_STRINGS = NO; 598 | SWIFT_VERSION = 5.0; 599 | TARGETED_DEVICE_FAMILY = "1,2"; 600 | TEST_TARGET_NAME = "RealityKit Example ARMeshAnchor"; 601 | }; 602 | name = Release; 603 | }; 604 | /* End XCBuildConfiguration section */ 605 | 606 | /* Begin XCConfigurationList section */ 607 | B4DD6BB0274EDC0B004A1D8E /* Build configuration list for PBXProject "RealityKit ARMeshAnchor" */ = { 608 | isa = XCConfigurationList; 609 | buildConfigurations = ( 610 | B4DD6BD9274EDC0F004A1D8E /* Debug */, 611 | B4DD6BDA274EDC0F004A1D8E /* Release */, 612 | ); 613 | defaultConfigurationIsVisible = 0; 614 | defaultConfigurationName = Release; 615 | }; 616 | B4DD6BDB274EDC0F004A1D8E /* Build configuration list for PBXNativeTarget "RealityKit ARMeshAnchor" */ = { 617 | isa = XCConfigurationList; 618 | buildConfigurations = ( 619 | B4DD6BDC274EDC0F004A1D8E /* Debug */, 620 | B4DD6BDD274EDC0F004A1D8E /* Release */, 621 | ); 622 | defaultConfigurationIsVisible = 0; 623 | defaultConfigurationName = Release; 624 | }; 625 | B4DD6BDE274EDC0F004A1D8E /* Build configuration list for PBXNativeTarget "RealityKit ARMeshAnchorTests" */ = { 626 | isa = XCConfigurationList; 627 | buildConfigurations = ( 628 | B4DD6BDF274EDC0F004A1D8E /* Debug */, 629 | B4DD6BE0274EDC0F004A1D8E /* Release */, 630 | ); 631 | defaultConfigurationIsVisible = 0; 632 | defaultConfigurationName = Release; 633 | }; 634 | B4DD6BE1274EDC0F004A1D8E /* Build configuration list for PBXNativeTarget "RealityKit ARMeshAnchorUITests" */ = { 635 | isa = XCConfigurationList; 636 | buildConfigurations = ( 637 | B4DD6BE2274EDC0F004A1D8E /* Debug */, 638 | B4DD6BE3274EDC0F004A1D8E /* Release */, 639 | ); 640 | defaultConfigurationIsVisible = 0; 641 | defaultConfigurationName = Release; 642 | }; 643 | /* End XCConfigurationList section */ 644 | }; 645 | rootObject = B4DD6BAD274EDC0B004A1D8E /* Project object */; 646 | } 647 | -------------------------------------------------------------------------------- /RealityKit ARMeshAnchor.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RealityKit ARMeshAnchor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /RealityKit ARMeshAnchor.xcodeproj/xcuserdata/travishall.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /RealityKit ARMeshAnchor.xcodeproj/xcuserdata/travishall.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | RealityKit Example ARMeshAnchor.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // RealityKit Example ARMeshAnchor 4 | // 5 | // Created by Travis Hall on 24/11/2021. 6 | // 7 | 8 | import UIKit 9 | import SwiftUI 10 | 11 | @main 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | 19 | // Create the SwiftUI view that provides the window contents. 20 | let contentView = ContentView().environmentObject(Settings()) 21 | 22 | // Use a UIHostingController as window root view controller. 23 | let window = UIWindow(frame: UIScreen.main.bounds) 24 | window.rootViewController = UIHostingController(rootView: contentView) 25 | self.window = window 26 | window.makeKeyAndVisible() 27 | return true 28 | } 29 | 30 | func applicationWillResignActive(_ application: UIApplication) { 31 | // 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. 32 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 33 | } 34 | 35 | func applicationDidEnterBackground(_ application: UIApplication) { 36 | // 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. 37 | } 38 | 39 | func applicationWillEnterForeground(_ application: UIApplication) { 40 | // 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. 41 | } 42 | 43 | func applicationDidBecomeActive(_ application: UIApplication) { 44 | // 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. 45 | } 46 | 47 | 48 | } 49 | 50 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // RealityKit Example ARMeshAnchor 4 | // 5 | // Created by Travis Hall on 24/11/2021. 6 | // 7 | 8 | import SwiftUI 9 | import RealityKit 10 | import ARKit 11 | 12 | let delegate = SessionDelegate() 13 | 14 | class Settings: ObservableObject { 15 | /// Set the initial colours used for each classification 16 | @Published var colorZero = Color.gray 17 | @Published var colorOne = Color.green 18 | @Published var colorTwo = Color.red 19 | @Published var colorThree = Color.cyan 20 | @Published var colorFour = Color.yellow 21 | @Published var colorFive = Color.purple 22 | @Published var colorSix = Color.blue 23 | @Published var colorSeven = Color.brown 24 | 25 | @Published var update = true 26 | } 27 | 28 | struct ContentView : View { 29 | @EnvironmentObject var settings: Settings 30 | @State private var present = true 31 | 32 | var body: some View { 33 | return ( 34 | ZStack(alignment: .bottom) { 35 | ARViewContainer() 36 | .frame(maxWidth: .infinity, maxHeight: .infinity) 37 | .sheet(isPresented: $present) { 38 | HalfSheet { 39 | ColorPickerContainer() 40 | }} 41 | HStack() { 42 | Button { 43 | present = true 44 | } label: { 45 | Text("Settings") 46 | }.frame(height: 48, alignment: .center) 47 | .buttonStyle(.borderedProminent) 48 | .padding(.all, 24) 49 | 50 | }.padding(.all, 16) 51 | } 52 | .edgesIgnoringSafeArea(.all) 53 | ) 54 | } 55 | } 56 | 57 | struct ColorPickerContainer: View { 58 | @EnvironmentObject var settings: Settings 59 | 60 | var body: some View { 61 | return ( 62 | VStack(alignment: .leading, spacing: 16){ 63 | Toggle("Update Mesh", isOn: $settings.update) 64 | ColorPicker(".None", selection: $settings.colorZero) 65 | ColorPicker(".Wall", selection: $settings.colorOne) 66 | ColorPicker(".Floor", selection: $settings.colorTwo) 67 | ColorPicker(".Ceiling", selection: $settings.colorThree) 68 | ColorPicker(".Table", selection: $settings.colorFour) 69 | ColorPicker(".Seat", selection: $settings.colorFive) 70 | ColorPicker(".Window", selection: $settings.colorSix) 71 | ColorPicker(".Door", selection: $settings.colorSeven) 72 | }.padding(.all, 16) 73 | ) 74 | } 75 | } 76 | 77 | struct ARViewContainer: UIViewRepresentable { 78 | @EnvironmentObject var settings: Settings 79 | 80 | func makeUIView(context: Context) -> ARView { 81 | 82 | let arView = ARView(frame: .zero) 83 | 84 | let config = ARWorldTrackingConfiguration() 85 | 86 | config.planeDetection = [.horizontal, .vertical] 87 | config.environmentTexturing = .automatic 88 | config.sceneReconstruction = .meshWithClassification 89 | config.worldAlignment = .gravity 90 | 91 | delegate.set(arView: arView, settings: _settings) 92 | arView.session.delegate = delegate 93 | arView.debugOptions = [] 94 | arView.session.run(config) 95 | 96 | // SetupAnchor 97 | let anchorEntity = AnchorEntity(plane: .horizontal) 98 | anchorEntity.name = "Global" 99 | arView.scene.addAnchor(anchorEntity) 100 | arView.physicsOrigin = anchorEntity 101 | 102 | return arView 103 | } 104 | func updateUIView(_ uiView: ARView, context: Context) {} 105 | 106 | } 107 | 108 | final class SessionDelegate: NSObject, ARSessionDelegate { 109 | var arView: ARView! 110 | var settings: EnvironmentObject! 111 | 112 | func set(arView: ARView, settings: EnvironmentObject) { 113 | self.arView = arView 114 | self.settings = settings 115 | } 116 | 117 | func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { 118 | if settings.wrappedValue.update == true { 119 | for anchor in anchors { 120 | if anchor is ARMeshAnchor { 121 | let meshAnchor = anchor as! ARMeshAnchor 122 | addMeshEntity(with: meshAnchor, to: self.arView, settings: settings) 123 | } 124 | } 125 | } 126 | } 127 | 128 | func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) { 129 | if settings.wrappedValue.update == true{ 130 | for anchor in anchors { 131 | if anchor is ARMeshAnchor { 132 | let meshAnchor = anchor as! ARMeshAnchor 133 | updateMeshEntity(with: meshAnchor, in: self.arView, settings: settings) 134 | } 135 | } 136 | } 137 | } 138 | 139 | func session(_ session: ARSession, didRemove anchors: [ARAnchor]) { 140 | if settings.wrappedValue.update == true { 141 | for anchor in anchors { 142 | if anchor is ARMeshAnchor { 143 | let meshAnchor = anchor as! ARMeshAnchor 144 | removeMeshEntity(with: meshAnchor, from: self.arView) 145 | } 146 | } 147 | } 148 | } 149 | } 150 | 151 | class HalfSheetController: UIHostingController where Content : View { 152 | override func viewWillAppear(_ animated: Bool) { 153 | super.viewWillAppear(animated) 154 | 155 | 156 | if let presentation = sheetPresentationController { 157 | // configure at will 158 | presentation.detents = [.medium()] 159 | presentation.prefersGrabberVisible = true 160 | presentation.prefersEdgeAttachedInCompactHeight = true 161 | presentation.prefersScrollingExpandsWhenScrolledToEdge = false 162 | presentation.largestUndimmedDetentIdentifier = .medium 163 | } 164 | } 165 | } 166 | 167 | struct HalfSheet: UIViewControllerRepresentable where Content : View { 168 | private let content: Content 169 | 170 | @inlinable init(@ViewBuilder content: () -> Content) { 171 | self.content = content() 172 | } 173 | 174 | func makeUIViewController(context: Context) -> HalfSheetController { 175 | return HalfSheetController(rootView: content) 176 | } 177 | 178 | func updateUIViewController(_: HalfSheetController, context: Context) { 179 | 180 | } 181 | } 182 | 183 | 184 | #if DEBUG 185 | struct ContentView_Previews : PreviewProvider { 186 | static var previews: some View { 187 | ContentView() 188 | } 189 | } 190 | #endif 191 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Demo/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TravisHall/RealityKit-Example-ARMeshAnchor-Geometry/f4a1092b0ec83b620719ca9fcd2201db61f2a842/RealityKit Example ARMeshAnchor/Demo/demo.gif -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Demo/demo2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TravisHall/RealityKit-Example-ARMeshAnchor-Geometry/f4a1092b0ec83b620719ca9fcd2201db61f2a842/RealityKit Example ARMeshAnchor/Demo/demo2.gif -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // Extensions 4 | // 5 | // Created by Travis Hall on 25/11/2021. 6 | // 7 | import ARKit 8 | import RealityKit 9 | 10 | extension ARMeshClassification { 11 | var description: String { 12 | switch self { 13 | case .ceiling: return "Ceiling" 14 | case .door: return "Door" 15 | case .floor: return "Floor" 16 | case .seat: return "Seat" 17 | case .table: return "Table" 18 | case .wall: return "Wall" 19 | case .window: return "Window" 20 | case .none: return "None" 21 | @unknown default: return "Unknown" 22 | } 23 | } 24 | 25 | var color: UIColor { 26 | switch self { 27 | case .ceiling: return .cyan 28 | case .door: return .brown 29 | case .floor: return .red 30 | case .seat: return .purple 31 | case .table: return .yellow 32 | case .wall: return .green 33 | case .window: return .blue 34 | case .none: return .lightGray 35 | @unknown default: return .gray 36 | } 37 | } 38 | } 39 | 40 | // From VisualizingSceneSemantics 41 | extension simd_float4x4 { 42 | var position: SIMD3 { 43 | return SIMD3(columns.3.x, columns.3.y, columns.3.z) 44 | } 45 | } 46 | 47 | // From VisualizingSceneSemantics 48 | extension Transform { 49 | static func * (left: Transform, right: Transform) -> Transform { 50 | return Transform(matrix: simd_mul(left.matrix, right.matrix)) 51 | } 52 | } 53 | 54 | // From VisualizingSceneSemantics 55 | extension ARMeshGeometry { 56 | func vertex(at index: UInt32) -> (Float, Float, Float) { 57 | assert(vertices.format == MTLVertexFormat.float3, "Expected three floats (twelve bytes) per vertex.") 58 | let vertexPointer = vertices.buffer.contents().advanced(by: vertices.offset + (vertices.stride * Int(index))) 59 | let vertex = vertexPointer.assumingMemoryBound(to: (Float, Float, Float).self).pointee 60 | return vertex 61 | } 62 | 63 | /// To get the mesh's classification, the sample app parses the classification's raw data and instantiates an 64 | /// `ARMeshClassification` object. For efficiency, ARKit stores classifications in a Metal buffer in `ARMeshGeometry`. 65 | func classificationOf(faceWithIndex index: Int) -> ARMeshClassification { 66 | guard let classification = classification else { return .none } 67 | assert(classification.format == MTLVertexFormat.uchar, "Expected one unsigned char (one byte) per classification") 68 | let classificationPointer = classification.buffer.contents().advanced(by: classification.offset + (classification.stride * index)) 69 | let classificationValue = Int(classificationPointer.assumingMemoryBound(to: CUnsignedChar.self).pointee) 70 | return ARMeshClassification(rawValue: classificationValue) ?? .none 71 | } 72 | 73 | func vertexIndicesOf(faceWithIndex faceIndex: Int) -> [UInt32] { 74 | assert(faces.bytesPerIndex == MemoryLayout.size, "Expected one UInt32 (four bytes) per vertex index") 75 | let vertexCountPerFace = faces.indexCountPerPrimitive 76 | let vertexIndicesPointer = faces.buffer.contents() 77 | var vertexIndices = [UInt32]() 78 | vertexIndices.reserveCapacity(vertexCountPerFace) 79 | for vertexOffset in 0...size) 81 | vertexIndices.append(vertexIndexPointer.assumingMemoryBound(to: UInt32.self).pointee) 82 | } 83 | return vertexIndices 84 | } 85 | 86 | func verticesOf(faceWithIndex index: Int) -> [(Float, Float, Float)] { 87 | let vertexIndices = vertexIndicesOf(faceWithIndex: index) 88 | let vertices = vertexIndices.map { vertex(at: $0) } 89 | return vertices 90 | } 91 | 92 | func centerOf(faceWithIndex index: Int) -> (Float, Float, Float) { 93 | let vertices = verticesOf(faceWithIndex: index) 94 | let sum = vertices.reduce((0, 0, 0)) { ($0.0 + $1.0, $0.1 + $1.1, $0.2 + $1.2) } 95 | let geometricCenter = (sum.0 / 3, sum.1 / 3, sum.2 / 3) 96 | return geometricCenter 97 | } 98 | 99 | func normalsOf(at index: UInt32) -> (Float, Float, Float) { 100 | assert(normals.format == MTLVertexFormat.float3, "Expected three floats (twelve bytes) per vertex.") 101 | 102 | let normalPointer = normals.buffer.contents().advanced(by: normals.offset + (normals.stride * Int(index))) 103 | 104 | let normal = normalPointer.assumingMemoryBound(to: (Float, Float, Float).self).pointee 105 | return normal 106 | } 107 | 108 | } 109 | 110 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/MeshAnchorGeometry.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MeshAnchorGeo.swift 3 | // MeshAnchorGeo 4 | // 5 | // Created by Travis Hall on 24/11/2021. 6 | // 7 | 8 | import ARKit 9 | import RealityKit 10 | import Metal 11 | import SwiftUI 12 | 13 | struct generatedMesh { 14 | var vertices: [SIMD3] = [] 15 | var triangles: [faceObj] = [] 16 | var normals: [SIMD3] = [] 17 | } 18 | 19 | struct faceObj { 20 | var classificationId: UInt32 21 | var triangles: [UInt32] = [] 22 | } 23 | 24 | // The ARMeshAnchor contains polygonal geometry which we can use to create our own entity 25 | func addMeshEntity(with anchor: ARMeshAnchor, to view: ARView, settings: EnvironmentObject) { 26 | /// 1. Create two entities, an AnchorEntity using the ARMeshAnchors position 27 | /// And a ModelEntity used to store our extracted mesh 28 | let meshAnchorEntity = AnchorEntity(world: anchor.transform) 29 | let meshModelEntity = createMeshEntity(with: anchor, from: view, settings: settings) 30 | meshAnchorEntity.name = anchor.identifier.uuidString + "_anchor" 31 | meshModelEntity.name = anchor.identifier.uuidString + "_model" 32 | 33 | /// 2. Add to scene 34 | meshAnchorEntity.addChild(meshModelEntity) 35 | view.scene.addAnchor(meshAnchorEntity) 36 | } 37 | 38 | func createMeshEntity(with anchor: ARMeshAnchor, from arView: ARView, settings: EnvironmentObject) -> ModelEntity { 39 | /// 1. Extract the the geometry from the ARMeshAnchor. Geometry is stored in a buffer-based array, format before using in MeshBuffers 40 | let anchorMesh = extractARMeshGeometry(with: anchor, in: arView) 41 | 42 | /// 2. Create a custom MeshDescriptor using the extracted mesh 43 | let mesh = createCustomMesh(name: "mesh", geometry: anchorMesh) 44 | 45 | /// 3. Create a new model entity for our mesh 46 | let generatedModel = ModelEntity( 47 | mesh: try! .generate(from: [mesh]), 48 | materials: generateMaterials(settings: settings) 49 | ) 50 | return generatedModel 51 | } 52 | 53 | func removeMeshEntity(with anchor: ARMeshAnchor, from arView: ARView) { 54 | guard let meshAnchorEntity = arView.scene.findEntity(named: anchor.identifier.uuidString+"_anchor") else { return } 55 | arView.scene.removeAnchor(meshAnchorEntity as! AnchorEntity) 56 | } 57 | 58 | func updateMeshEntity(with anchor: ARMeshAnchor, in view: ARView, settings: EnvironmentObject ) { 59 | /// 1.Find the previously added meshes 60 | guard let entity = view.scene.findEntity(named: anchor.identifier.uuidString+"_model") else { return } 61 | let modelEntity = entity as! ModelEntity 62 | 63 | /// 2. Extact new geometry 64 | let anchorMesh = extractARMeshGeometry(with: anchor, in: view) 65 | 66 | /// 3. Create a new MeshDescriptor using the extracted mesh 67 | let mesh = createCustomMesh(name: "mesh", geometry: anchorMesh) 68 | 69 | /// 4. Try to update the mesh with the new geometry 70 | do { 71 | modelEntity.model!.mesh = try .generate(from: [mesh]) 72 | modelEntity.model!.materials = generateMaterials(settings: settings) 73 | } catch { 74 | print("Error updating mesh geometry") 75 | } 76 | } 77 | 78 | func extractARMeshGeometry(with anchor: ARMeshAnchor, in view: ARView) -> generatedMesh { 79 | var vertices: [SIMD3] = [] 80 | var triangles: [faceObj] = [] 81 | var normals: [SIMD3] = [] 82 | 83 | /// Extract the vertices using the Extension from Apple (VisualizingSceneSemantics) 84 | for index in 0..(x: vertex.0, y: vertex.1, z: vertex.2) 87 | vertices.append(vertexPos) 88 | } 89 | /// Extract the faces 90 | for index in 0..(normal.0, normal.1, normal.2)) 99 | } 100 | 101 | let extractedMesh = generatedMesh(vertices: vertices, triangles: triangles, normals: normals) 102 | return extractedMesh 103 | } 104 | 105 | func createCustomMesh(name: String, geometry: generatedMesh ) -> MeshDescriptor{ 106 | /// Create a new MeshDescriptor using the generate geometry 107 | var mesh = MeshDescriptor(name: name) 108 | let faces = geometry.triangles.flatMap{ $0.triangles } 109 | let faceMaterials = geometry.triangles.compactMap{ $0.classificationId } 110 | let positions = MeshBuffers.Positions(geometry.vertices) 111 | let triangles = MeshDescriptor.Primitives.triangles(faces) 112 | let normals = MeshBuffers.Normals(geometry.normals) 113 | 114 | mesh.positions = positions 115 | mesh.primitives = triangles 116 | mesh.normals = normals 117 | 118 | /// Use the classificationIds to set the material on each face 119 | mesh.materials = MeshDescriptor.Materials.perFace(faceMaterials) 120 | 121 | return mesh 122 | } 123 | 124 | func generateMaterials(settings: EnvironmentObject) -> [PhysicallyBasedMaterial] { 125 | /// This could be alot tidier 126 | /// We're creating materials for each classification with the colors in settings 127 | 128 | //case 0 .none 129 | var material0 = PhysicallyBasedMaterial() 130 | material0.baseColor = PhysicallyBasedMaterial.BaseColor(tint:UIColor( settings.wrappedValue.colorZero)) 131 | material0.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorZero.cgColor?.alpha ?? 0.8))) 132 | 133 | //case 1 .wall 134 | var material1 = PhysicallyBasedMaterial() 135 | material1.baseColor = PhysicallyBasedMaterial.BaseColor(tint:UIColor( settings.wrappedValue.colorOne)) 136 | material1.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorOne.cgColor?.alpha ?? 0.8))) 137 | 138 | //case 2 .floor 139 | var material2 = PhysicallyBasedMaterial() 140 | material2.baseColor = PhysicallyBasedMaterial.BaseColor(tint: UIColor( settings.wrappedValue.colorTwo)) 141 | material2.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorTwo.cgColor?.alpha ?? 0.8))) 142 | 143 | //case 3 .ceiling 144 | var material3 = PhysicallyBasedMaterial() 145 | material3.baseColor = PhysicallyBasedMaterial.BaseColor(tint: UIColor( settings.wrappedValue.colorThree)) 146 | material3.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorThree.cgColor?.alpha ?? 0.8))) 147 | 148 | //case 4 .table 149 | var material4 = PhysicallyBasedMaterial() 150 | material4.baseColor = PhysicallyBasedMaterial.BaseColor(tint: UIColor( settings.wrappedValue.colorFour)) 151 | material4.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorFour.cgColor?.alpha ?? 0.8))) 152 | 153 | //case 5 .seat 154 | var material5 = PhysicallyBasedMaterial() 155 | material5.baseColor = PhysicallyBasedMaterial.BaseColor(tint: UIColor( settings.wrappedValue.colorFive)) 156 | material5.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorFive.cgColor?.alpha ?? 0.8))) 157 | 158 | //case 6 .window 159 | var material6 = PhysicallyBasedMaterial() 160 | material6.baseColor = PhysicallyBasedMaterial.BaseColor(tint: UIColor( settings.wrappedValue.colorSix)) 161 | material6.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorSix.cgColor?.alpha ?? 0.8))) 162 | 163 | //case 7 .door 164 | var material7 = PhysicallyBasedMaterial() 165 | material7.baseColor = PhysicallyBasedMaterial.BaseColor(tint: UIColor( settings.wrappedValue.colorSeven)) 166 | material7.blending = .transparent(opacity: .init(floatLiteral: Float(settings.wrappedValue.colorSeven.cgColor?.alpha ?? 0.8))) 167 | 168 | return [material0, material1, material2, material3, material4, material5, material6, material7] 169 | } 170 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Shaders/warpGeometry.metal: -------------------------------------------------------------------------------- 1 | // 2 | // warpGeometry.metal 3 | // warpGeometry 4 | // 5 | // Created by Travis Hall on 26/11/2021. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | using namespace metal; 12 | 13 | [[visible]] 14 | void warpGeometry(realitykit::geometry_parameters params) 15 | { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchor/Shaders/warpSurface.metal: -------------------------------------------------------------------------------- 1 | // 2 | // Warp.metal 3 | // Warp 4 | // 5 | // Created by Travis Hall on 26/11/2021. 6 | // 7 | 8 | #include 9 | #include 10 | 11 | using namespace metal; 12 | 13 | [[visible]] 14 | void warpSurface(realitykit::surface_parameters params) 15 | { 16 | 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchorTests/RealityKit_Example_ARMeshAnchorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealityKit_Example_ARMeshAnchorTests.swift 3 | // RealityKit Example ARMeshAnchorTests 4 | // 5 | // Created by Travis Hall on 24/11/2021. 6 | // 7 | 8 | import XCTest 9 | @testable import RealityKit_Example_ARMeshAnchor 10 | 11 | class RealityKit_Example_ARMeshAnchorTests: XCTestCase { 12 | 13 | override func setUpWithError() throws { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | } 16 | 17 | override func tearDownWithError() throws { 18 | // Put teardown code here. This method is called after the invocation of each test method in the class. 19 | } 20 | 21 | func testExample() throws { 22 | // This is an example of a functional test case. 23 | // Use XCTAssert and related functions to verify your tests produce the correct results. 24 | } 25 | 26 | func testPerformanceExample() throws { 27 | // This is an example of a performance test case. 28 | self.measure { 29 | // Put the code you want to measure the time of here. 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchorUITests/RealityKit_Example_ARMeshAnchorUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealityKit_Example_ARMeshAnchorUITests.swift 3 | // RealityKit Example ARMeshAnchorUITests 4 | // 5 | // Created by Travis Hall on 24/11/2021. 6 | // 7 | 8 | import XCTest 9 | 10 | class RealityKit_Example_ARMeshAnchorUITests: XCTestCase { 11 | 12 | override func setUpWithError() throws { 13 | // Put setup code here. This method is called before the invocation of each test method in the class. 14 | 15 | // In UI tests it is usually best to stop immediately when a failure occurs. 16 | continueAfterFailure = false 17 | 18 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 19 | } 20 | 21 | override func tearDownWithError() throws { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | } 24 | 25 | func testExample() throws { 26 | // UI tests must launch the application that they test. 27 | let app = XCUIApplication() 28 | app.launch() 29 | 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | func testLaunchPerformance() throws { 35 | if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { 36 | // This measures how long it takes to launch your application. 37 | measure(metrics: [XCTApplicationLaunchMetric()]) { 38 | XCUIApplication().launch() 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /RealityKit Example ARMeshAnchorUITests/RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RealityKit_Example_ARMeshAnchorUITestsLaunchTests.swift 3 | // RealityKit Example ARMeshAnchorUITests 4 | // 5 | // Created by Travis Hall on 24/11/2021. 6 | // 7 | 8 | import XCTest 9 | 10 | class RealityKit_Example_ARMeshAnchorUITestsLaunchTests: XCTestCase { 11 | 12 | override class var runsForEachTargetApplicationUIConfiguration: Bool { 13 | true 14 | } 15 | 16 | override func setUpWithError() throws { 17 | continueAfterFailure = false 18 | } 19 | 20 | func testLaunch() throws { 21 | let app = XCUIApplication() 22 | app.launch() 23 | 24 | // Insert steps here to perform after app launch but before taking a screenshot, 25 | // such as logging into a test account or navigating somewhere in the app 26 | 27 | let attachment = XCTAttachment(screenshot: app.screenshot()) 28 | attachment.name = "Launch Screen" 29 | attachment.lifetime = .keepAlways 30 | add(attachment) 31 | } 32 | } 33 | --------------------------------------------------------------------------------