https://developer.apple.com/documentation/compositorservices/drawing_fully_immersive_content_using_metal
I'm following this doc to use metal in vision os.
I noticed that the tangent is being deprecated which is being used in the sample
https://developer.apple.com/documentation/compositorservices/layerrenderer/drawable/view
will the sample code be updated?
ARKit
RSS for tagIntegrate iOS device camera and motion features to produce augmented reality experiences in your app or game using ARKit.
Post
Replies
Boosts
Views
Activity
Hi everyone, I want to add new joint in addition to joints that provided by ARKit. for example extract the position of wrist and elbow, then add new joint between them in the middle of arm. I can't find a good documentation that can explain ARKit very well. If there is another information that I can use, please share it with me. thanks.
In lots of houses there are different levels but are still on the same floor. What i mean is that there are things like stairs on the entrance that only have a few steps and would count basically as the same story.
RoomPlan already does a nice job recognizing them during the scanning but after the StructureBuilder or the optimization step it is not really satisfying.
Has anyone managed to handle those cases? Or do you have to scan a specific way to capture such small differences within a level?
Hello, I'm using the ARSessionDelegate function:
func session(_ session: ARSession, didUpdate frame: ARFrame)
to extract an HD Image
let hdframe = try? await session.captureHighResolutionFrame().capturedImage
which I am later on use to detect text on the image using VN. I'm using the HD picture, because the text bits I'm looking for can be very tiny.
let requestHandler = VNImageRequestHandler(cgImage: image)//, orientation: .up, options: [:])
let textRequest = VNRecognizeTextRequest()
let vnRequests = [textRequest]
try requestHandler.perform(vnRequests)
My issue is that, each time a captured HD image is extracted from the AR Scene, a shutter sound is played. I'm aware that shutter sounds are important for privacy, but I'm doing this in a very high frequency, which means that my app is currently unusable, when not muted.
My two questions are:
Is there any way to disable the sound in this case?
Is there a better way to constantly scan the AR video stream for text than this approach?
I would like to implement the following but I am not sure if this is a supported use case based on the current documentation:
Run one ARKitSession with a WorldTrackingProvider in Swift for mixed immersion Metal rendering (to get the device anchor for the layer renderer drawable & view matrix)
Run another ARKitSession with a WorldTrackingProvider and a CameraFrameProvider in a different library (that is part of the same app) using the ARKit C API and using the transforms from the anchors in that session to render objects in the Swift application part.
In general, is this a supported use case or is it necessary to have one shared ARKitSession?
Assuming this is supported, will the (device) anchors from both WorldTrackingProviders reference the same world coordinate system?
Are there any performance downsides to having multiple ARKitSessions?
Thanks
Devices running iOS 18 using RealityKit do not seem to receive lighting supplied via ARKit Environment Texturing (https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration/2977509-environmenttexturing).
Instead just a default IBL is used by RealityKit.
This happens with RealityView as well as ARView.
It also happens when I explicitly opt-in to environment texturing:
let worldTrackingConfig = ARWorldTrackingConfiguration()
worldTrackingConfig.environmentTexturing = .automatic
arView.session.run(worldTrackingConfig)
Even the Xcode AR Template has this issue.
I'm attaching a screenshot of the sample app running on iOS 18 where it's broken and from iOS 17 where it works as expected.
I hope this can get resolved quickly since I see it as a major regression.
Feedback ID: FB15091335
UPDATE:
It works on my older iPhone XS (iOS 18 22A5282m)
Broken on iPad Pro (11-inch) (3rd generation) (iPadOS 18.0 (22A5350a))
Maybe it's related to LiDAR?
Thank you!
iOS 17 (works):
iOS 18 (broken):
Hello
We are exploring the iOS 17 RoomPlan updates that allow for a custom ARSession to be passed into the RoomCaptureSession via the new initializer.
let roomCaptureSession = RoomCaptureSession(arSession: myARSession)
Currently we use our ARSession to extract sceneDepth from the ARFrames via the delegate callback. This works prior to activation of the RoomCaptureSession via session.run(configuration).
However, when we do call run on the RoomCaptureSession, sceneDepth is no longer present on the incoming ARFrames.
Are these mutually exclusive? Should we expect ARFrame depth data to be present when a RoomCaptureSession is running with the shared ARSession?
Hello,
Has anyone had success with implementing object tracking in Unity or adding native tracking capability to the VisionOS project built from Unity?
I am working on an application for Vision Pro mainly in Unity using Polyspatial. The application requires me to track objects and make decisions based on tracked object's location. I was able to create an object tracking application on Native Swift, but could not successfully combine this with my Unity project yet. Each separate project (Main Unity app using Polyspatial and the native app on Swift) can successfully build and be deployed onto VisionPro.
I know that Polyspatial and ARFoundation does not have support for ARKit's object tracking feature for VIsion Pro as of today, and they only support image tracking inside Unity. For that reason I have been exploring different ways of creating a bridge for two way interaction of the native tracking functionality and the other functionality in Unity.
Below are the methods I tried and failed so far:
Package the tracking functionality as a Swift Plugin and access this in Unity, and then build for Vision Pro: I can create packages and access them for simple exposed variables and methods, but not for outputs and methods from ARKit, which throw dependency errors while trying to make the swift package.
Build project from Unity to VIsion Pro and expose a boolean to start/stop tracking that can be read by the native code, and then carry the tracking classes into the built project. In this approach I keep getting an error that says _TrackingStateChanged cannot be found, which is the class that exposes the bool toggled by the Unity button press:
using System.Runtime.InteropServices;
public class UnityBridge
{
[DllImport("__Internal")]
private static extern void TrackingStateChanged(bool isTracking);
public static void NotifyTrackingState()
{
// Call the Swift method
TrackingStateChanged(TrackingStartManager.IsTrackingActive());
}
}
This seems to be translated to C++ code in the ill2cpp output from Unity, and even though I made sure that all necessary packages were added to the target, I keep receiving this error. from the UnityFramework plugin:
Undefined symbol: _TrackingStateChanged
I have considered extending the current Image Tracking approach in ARFoundation to include object tracking, but that seems to be too complicated for my use case and time frame for now.
The final resort will be to forego Unity implementation and do everything in native code. However, I really want to be able to use Unity's conveniences and I have very limited experience with Swift development.
Hi, My camera access method is like this
func processCameraUpdates() async {
print("Process camera called")
let formats = CameraVideoFormat.supportedVideoFormats(for: .main, cameraPositions:[.left])
guard let cameraFrameUpdates =
cameraFrameProvider.cameraFrameUpdates(for: formats[0]) else {
return
}
for await cameraFrame in cameraFrameUpdates {
guard let mainCameraSample = cameraFrame.sample(for: .left) else {
continue
}
pixelBuffer = mainCameraSample.pixelBuffer
print("Pixel buffer updated)")
}
}
In my ImmersiveSpace I am calling that method in this way
task {
// Main camera access
await placeManager.processCameraUpdates()
}
This works fine as long as app is in active / opened / foreground. Once I close the app and re-open, I cannot capture any image. What am I missing here? Do I need to do something when scene become active?
Is there anyway to reset the scan memory Vision Pro stores on-device, so that upon every new scanning in my application, it starts from scratch rather than getting instantly recognized. In Apple Vision Pro Privacy overview (https://www.apple.com/privacy/docs/Apple_Vision_Pro_Privacy_Overview.pdf), it is stated:
"visionOS builds a three-dimensional model to map your surroundings on-device. Apple Vision Pro uses a combination of camera and LiDAR data to map the area around you and save that model on-device. The model enables visionOS to alert you about real-life obstacles, as well as appropriately reflect the lighting and shadows of your physical space. visionOS uses audio ray tracing to analyze your room’s acoustic properties on-device to adapt and match sound to your space. The underlying scene mesh is stored on-device and encrypted with your passcode if one is set"
How to access and erase the, and I quote, “underlying scene mesh stored on-device”?
In this code:
https://developer.apple.com/documentation/visionos/incorporating-real-world-surroundings-in-an-immersive-experience
It contains a physical collision reaction between virtual objects and the real world, which is realized by creating a grid with physical components. However, I don't understand the information in the document very well. Who can give me a solution? Thank you!
The light of RealityView can only be effective on virtual objects. I hope it can be projected into the real world. What API can be implemented?
arScnView = ARSCNView(frame: CGRect.zero, options: nil)
arScnView.delegate = self
arScnView.automaticallyUpdatesLighting = true
arScnView.allowsCameraControl = true
addSubview(arScnView)
arSession = arScnView.session
arSession.delegate = self
config = ARWorldTrackingConfiguration()
config.sceneReconstruction = .meshWithClassification
config.environmentTexturing = .automatic
func session(_ session: ARSession, didAdd anchors: [ARAnchor])
{
anchors.forEach({ anchor in
if let meshAnchor = anchor as? ARMeshAnchor {
let node = meshAnchor.toSCNNode()
self.arScnView.scene.rootNode.addChildNode(node)
}
if let environmentProbeAnchor = anchor as? AREnvironmentProbeAnchor {
// Can I retrieve the texture map corresponding to ARMeshAnchor from Environment Probe Anchor?
// Or how can I retrieve the texture map corresponding to ARMeshAnchor?
}
})
}
How can I scan a 3D scene and save it as USDZ?
I want to achieve the following scenario?
The structure builder provides walls and floors for each captured story, but not a ceiling. For my case it is necessary that the scanned geometry is closed to open up the possibility to place objects on the ceiling for example and therefore it is important that there is an estimated ceiling for different rooms within a story.
Is there any info that apple has something like this on the roadmap in the future because i think this can open opportunities especially when thinking about industrial application of the API.
If somebody has more insights on this topic pls share :)
Hello there,
I'm currently working on a Hand Tracking System. I've already placed some spheres on some joint points on the left and right hand. Now I want to access the translation/position value of these entities in the update(context: Scene) function. Now my question is, is it possible to access them via .handAnchors(), or which types of .handSkeleton.joint(name) are referencing the same entity? (E.g. is AnchorEntity(.hand(.right, location: .indexFingerTip)) the same as handSkeleton.joint(.indexFingerTip). The goal would be to access the translation of the joints where a sphere has been placed per hand and to be able to update the data every frame through the update(context) function.
I would very much appreciate any help!
See code example down below:
ImmersiveView.swift
import SwiftUI
import RealityKit
import ARKit
struct ImmersiveView: View {
public var body: some View {
RealityView { content in
/* HEAD */
let headEntity = AnchorEntity(.head)
content.add(headEntity)
/* LEFT HAND */
let leftHandWristEntity = AnchorEntity(.hand(.left, location: .wrist))
let leftHandIndexFingerEntity = AnchorEntity(.hand(.left, location: .indexFingerTip))
let leftHandWristSphere = ModelEntity(mesh: .generateSphere(radius: 0.02), materials: [SimpleMaterial(color: .red, isMetallic: false)])
let leftHandIndexFingerSphere = ModelEntity(mesh: .generateSphere(radius: 0.01), materials: [SimpleMaterial(color: .orange, isMetallic: false)])
leftHandWristEntity.addChild(leftHandWristSphere)
content.add(leftHandWristEntity)
leftHandIndexFingerEntity.addChild(leftHandIndexFingerSphere)
content.add(leftHandIndexFingerEntity)
}
}
}
TrackingSystem.swift
import SwiftUI
import simd
import ARKit
import RealityKit
public class TrackingSystem: System {
static let query = EntityQuery(where: .has(AnchoringComponent.self))
private let arKitSession = ARKitSession()
private let worldTrackingProvider = WorldTrackingProvider()
private let handTrackingProvider = HandTrackingProvider()
public required init(scene: RealityKit.Scene) {
setUpSession()
}
private func setUpSession() {
Task {
do {
try await arKitSession.run([worldTrackingProvider, handTrackingProvider])
} catch {
print("Error: \(error)")
}
}
}
public func update(context: SceneUpdateContext) {
guard worldTrackingProvider.state == .running && handTrackingProvider.state == .running else { return }
let _ = context.entities(matching: Self.query, updatingSystemWhen: .rendering)
if let avp = worldTrackingProvider.queryDeviceAnchor(atTimestamp: currentTime) {
let hands = handTrackingProvider.handAnchors(at: currentTime)
...
}
}
}
Hi everyone,
I'm working on an AR application where I need to accurately locate the center of the pupil and measure anatomical distances between the pupil and eyelids. I’ve been using ARKit’s face tracking, but I’m having trouble pinpointing the exact center of the pupil.
My Questions:
Locating Pupil Center in ARKit: Is there a reliable way to detect the exact center of the pupil using ARKit? If so, how can I achieve this?
Framework Recommendation: Given the need for fine detail in measurements, would ARKit be sufficient, or would it be better to use the Vision framework for more accurate 2D facial landmark detection? Alternatively, would a hybrid approach, combining Vision for precision and ARKit for 3D tracking, be more effective?
What I've Tried:
Using ARKit’s ARFaceAnchor to detect face landmarks, but the results for the pupil position seem imprecise for my needs.
Considering Vision for 2D detection, but concerned about integrating it into a 3D AR experience.
Any insights, code snippets, or guidance would be greatly appreciated!
Thanks in advance!
Hello,
Im not able to get any 3d object visible in ARView.
struct ARViewContainer: UIViewRepresentable {
var trackingState: ARCamera.TrackingState? = nil
func makeUIView(context: Context) -> ARView {
// Create the view.
let view = ARView(frame: .zero)
// Set the coordinator as the session delegate.
view.session.delegate = context.coordinator
let anchor = AnchorEntity(plane: .horizontal)
let box = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .red, isMetallic: true)])
box.generateCollisionShapes(recursive: true)
anchor.addChild(box)
view.scene.addAnchor(anchor)
// Return the view.
return view
}
final class Coordinator: NSObject, ARSessionDelegate {
var parent: ARViewContainer
init(_ parent: ARViewContainer) {
self.parent = parent
}
func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
print("Camera tracking state: \(camera.trackingState)")
parent.trackingState = camera.trackingState
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func updateUIView(_ uiView: ARView, context: Context) { }
}
View is loaded correctly but anything cant appear. I also tried to create 3D object in
func updateUIView(_ uiView: ARView, context: Context) {
let anchor = AnchorEntity(plane: .horizontal)
let box = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .red, isMetallic: true)])
box.generateCollisionShapes(recursive: true)
anchor.addChild(box)
uiView.scene.addAnchor(anchor)
print("Added into the view")
}
Print statement is printed but there is still no object in the ARView. Is it bug or what am I missing?
Steps to Reproduce:
Create a SwiftUI view that initializes an ARKit session and a camera frame provider.
Attempt to run the ARKit session and retrieve camera frames.
Extract the intrinsics and extrinsics matrices from the camera frame’s sample data.
Attempt to project a 3D point from the world space onto the 2D screen using the retrieved camera parameters.
Encounter issues due to lack of detailed documentation on the correct usage and structure of the intrinsics and extrinsics matrices.
struct CodeLevelSupportView: View {
@State
private var vm = CodeLevelSupportViewModel()
var body: some View {
RealityView { realityViewContent in }
.onAppear {
vm.receiveCamera()
}
}
}
@MainActor
@Observable
class CodeLevelSupportViewModel {
let cameraSession = CameraFrameProvider()
let arSession = ARKitSession()
init() {
Task {
await arSession.requestAuthorization(for: [.cameraAccess])
}
}
func receiveCamera() {
Task {
do {
try await arSession.run([cameraSession])
guard let sequence = cameraSession.cameraFrameUpdates(for: .supportedVideoFormats(for: .main, cameraPositions: [.left])[0]) else {
print("failed to get cameraAccess authorization")
return
}
for try await frame in sequence {
guard let sample = frame.sample(for: .left) else {
print("failed to get camera sample")
return
}
let leftEyeScreenImage:CVPixelBuffer = sample.pixelBuffer
let leftEyeViewportWidth:Int = CVPixelBufferGetWidth(leftEyeScreenImage)
let leftEyeViewportHeight:Int = CVPixelBufferGetHeight(leftEyeScreenImage)
let intrinsics = sample.parameters.intrinsics
let extrinsics = sample.parameters.extrinsics
let oneMeterInFront:SIMD3<Float> = .init(x: 0, y: 0, z: -1)
projectWorldLocationToLeftEyeScreen(worldLocation: oneMeterInFront, intrinsics: intrinsics, extrinsics: extrinsics, viewportSize: (leftEyeViewportWidth,leftEyeViewportHeight))
}
} catch {
}
}
}
//After the function implementation is completed, it should return a CGPoint?, representing the point of this worldLocation in the LeftEyeViewport. If this worldLocation is not visible in the LeftEyeViewport (out of bounds), return nil.
func projectWorldLocationToLeftEyeScreen(worldLocation:SIMD3<Float>,intrinsics:simd_float3x3,extrinsics:simd_float4x4,viewportSize:(width:Int,height:Int)) {
//The API documentation does not provide the structure of intrinsics and extrinsics, making it hard to done this function.
}
}
We are experiencing a crash when attempting to capture a high resolution frame. The crash only happens on the A12 and A12X devices (iPhone11,8 or iPad8,7). The crash did occur on older versions of iOS and continues to happen with more recent versions, iOS 17.6 and iPadOS 17.5.1.
Any ideas on how to get a high-resolution image & frame from an AR Session using these devices?
To reproduce the crash:
Use an A12 or A12X device. Other devices have not produced the same result.
Setup an AR session that can capture high resolution static images:
Create a class that conforms to UIViewController and ARSessionDelegate and connect it to an Interface with an ARView.
@IBOutlet var arView: ARView!
During view setup configure the AR session:
let configuration = ARBodyTrackingConfiguration()
if let hiResFormat = ARBodyTrackingConfiguration.recommendedVideoFormatForHighResolutionFrameCapturing {
configuration.videoFormat = hiResFormat
}
self.arView.session.run(configuration)
Trigger code to capture the high resolution image (we call this from a button @IBAction:
Task {
let hiResFrame = try? await self.arView.session.captureHighResolutionFrame()
print("crash above. this print never occurs")
}
The crash occurs with both the sync & async versions of the captureHighResolutionFrame call.
Code above crashes in Apple AltruisticBodyPoseKit :
0 libsystem_kernel.dylib 0xc2ec __pthread_kill + 8
1 libsystem_pthread.dylib 0x7c0c pthread_kill + 268
2 libsystem_c.dylib 0x75ba0 abort + 180
3 libsystem_c.dylib 0x74eac err + 282
4 AltruisticBodyPoseKit 0x4b2b0 cva::MatrixData<int, 0ul, 0ul, false>::allocate(unsigned long) (.cold.1) + 42
5 AltruisticBodyPoseKit 0x20dac std::__1::vector<std::__1::pair<cva::Matrix<double, 3u, 1u, false>, cva::Matrix<double, 2u, 1u, false> >, std::__1::allocator<std::__1::pair<cva::Matrix<double, 3u, 1u, false>, cva::Matrix<double, 2u, 1u, false> > > >::vector(unsigned long) + 1186
6 AltruisticBodyPoseKit 0x2058c btr::(anonymous namespace)::EstimatePoseFromCorrespondences(btr::CameraPoseInfo&, btr::Correspondences2d3d const&, bool) + 564
7 AltruisticBodyPoseKit 0x2018c btr::BodyRegistration::RegisterBody(float vector[2] const*, unsigned long, float vector[3] const*, unsigned long, simd_float4x4 const*, unsigned long, simd_float3x3 const*, simd_float4x4 const*) + 1228
8 AltruisticBodyPoseKit 0x4354c -[ABPKCameraRegistration estimateCameraPoseFromMatchingwithImageIntrinsics:imageResolution:joints2d:jointsLifted3D:jointsLifted3DCount:] + 1160
9 ARKitCore 0x131d30 -[AR3DSkeletonRegistrationTechnique _estimateCameraPoseFromMatchingImageData:to3DData:worldTrackingPose:pCameraFromBody:depthData:pScaleOut:] + 396
10 ARKitCore 0x131818 -[AR3DSkeletonRegistrationTechnique requestResultDataAtTimestamp:context:] + 388
11 ARKitCore 0x91fd8 -[ARParentTechnique technique:didOutputResultData:timestamp:context:onTechniques:] + 1400
12 ARKitCore 0x91a28 -[ARParentTechnique technique:didOutputResultData:timestamp:context:] + 112
13 ARKitCore 0x8150c -[ARExposureLightEstimationTechnique requestResultDataAtTimestamp:context:] + 352
14 ARKitCore 0x91fd8 -[ARParentTechnique technique:didOutputResultData:timestamp:context:onTechniques:] + 1400
15 ARKitCore 0x91a28 -[ARParentTechnique technique:didOutputResultData:timestamp:context:] + 112
16 ARKitCore 0xcd9c4 -[ARWorldAlignmentTechnique requestResultDataAtTimestamp:context:] + 1044
17 ARKitCore 0x91fd8 -[ARParentTechnique technique:didOutputResultData:timestamp:context:onTechniques:] + 1400
18 ARKitCore 0x91a28 -[ARParentTechnique technique:didOutputResultData:timestamp:context:] + 112
19 ARKitCore 0x92584 -[ARParentTechnique _submitResultsForTimestamp:context:] + 396
20 ARKitCore 0x90124 __71-[ARParentTechnique requestResultDataAtTimestamp:context:onTechniques:]_block_invoke_3 + 72
We are encountering an issue with our app on Vision Pro with OS version 1.3. The app runs perfectly in the VisionOS Simulator, but when tested on the actual device, no content is displayed.
Here’s the expected behavior: When the app launches, a video should play in a window. Once the video ends, another information window should open. After a series of these information windows, we will load to an immersive space to handle 3D elements.
We've set the "Preferred Default Scene Session Role" to "Window Application Session Role" in info.plist, but the issue persists.
Below is the code we're using. Any advice or suggestions would be greatly appreciated.
import SwiftUI
@main
struct myApp: App {
@StateObject var sharedData = SharedDataModel()
@State private var isFactoryEnabled = false
var body: some Scene {
WindowGroup(id: "LaunchScreen", content: {
LaunchScreen()
})
.windowStyle(.plain)
.environmentObject(sharedData)
WindowGroup(id: "LoginView", content: {
ZStack {
let _ = UserDefaults.standard.set(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")
let _ = print(FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.path)
LoginView()
}
}).windowStyle(.plain)
.environmentObject(sharedData)
WindowGroup(id: "TrainingSelection", content: {
if !sharedData.showNavigationHintView{
NavigationHintView()
.glassBackgroundEffect()
.cornerRadius(30)
}
else {
TrainingSelection()
}
}).windowStyle(.plain)
.environmentObject(sharedData)
WindowGroup(id: "Salutations", content: {
Salutations()
}).windowStyle(.plain)
.environmentObject(sharedData)
WindowGroup {
ContentView()
}
.environmentObject(sharedData)
ImmersiveSpace(id: "myImmersiveSpace") {
ImmersiveView(viewModel: .init())
}
.environmentObject(sharedData)
}
}
import SwiftUI
import AVFoundation
import RealityKit
import RealityKitContent
struct LaunchScreen: View {
@State private var player: AVPlayer?
@State private var navigateToContentView = false
@EnvironmentObject var audioPlayer: AudioPlayer
var body: some View {
ZStack {
ZStack {
if navigateToContentView {
WarningView()
.transition(.opacity)
.glassBackgroundEffect()
.cornerRadius(15)
} else {
if let player = player {
AVPlayerView(player: player)
.onAppear {
player.play()
addObserver()
}
.cornerRadius(30)
} else {
Text("Unable to Load the Video")
.foregroundColor(.white)
.onAppear {
loadVideo()
}
}
}
}
.edgesIgnoringSafeArea(.all)
.animation(.easeIn, value: 1)
}
.glassBackgroundEffect()
}
private func loadVideo() {
if let videoUrl = Bundle.main.url(forResource: "launchScreen", withExtension: "mp4") {
player = AVPlayer(url: videoUrl)
} else {
print("Unable to Load the Video")
}
}
private func addObserver() {
NotificationCenter.default.addObserver(
forName: .AVPlayerItemDidPlayToEndTime,
object: player?.currentItem,
queue: .main
) { _ in
self.navigateToContentView = true
}
}
}