Created
July 16, 2025 08:12
-
-
Save banjun/a9fb69548914ff16ffdfd11e26653def to your computer and use it in GitHub Desktop.
Remote visionOS CompositorLayer with required ARKit session enabled for RemoteImmersiveSpace
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copied from Apple Sample Codes: CS_HoverEffect https://developer.apple.com/documentation/compositorservices/rendering_hover_effects_in_metal_immersive_apps | |
// and modified by banjun | |
#if os(macOS) | |
import CompositorServices | |
import SwiftUI | |
/// Usage: | |
/// ```swift | |
/// RemoteVisionOSARKitLayer { renderer, worldTracker in | |
/// while renderer.state != .invalidated { | |
/// guard let frame = renderer.queryNextFrame() else { continue } | |
/// // draw here | |
/// } | |
/// } | |
/// ``` | |
/// NOTE: RemoteImmersiveSpace requires drawables to be attached a DeviceAnchor, that can be get from WorldTrackingProvider, that can be run in ARKitSession, that can be initialized with \.remoteDeviceIdentifier, that can be obtained after Pairing UI, presented by RemoteImmersiveSpace. | |
/// NOTE: the `Debug Executable` setting can affect to whether content is head-anchored (debug) or not (not in debug) | |
struct RemoteVisionOSARKitLayer: CompositorContent { | |
@Environment(\.remoteDeviceIdentifier) private var remoteDeviceIdentifier: RemoteDeviceIdentifier? | |
var configuration: any CompositorLayerConfiguration = .default | |
var renderLoop: (LayerRenderer, WorldTrackingProvider?) async -> Void | |
var body: some CompositorContent { | |
CompositorLayer(configuration: configuration) { renderer in | |
Task(priority: .high) { | |
if let remoteDeviceIdentifier { | |
// NSLog("%@", "remoteDeviceIdentifier = \(remoteDeviceIdentifier)") | |
let arkitSession = ARKitSession(device: remoteDeviceIdentifier) | |
let worldTracker = WorldTrackingProvider() | |
// NSLog("%@", "starting arkitSession.run") | |
try await arkitSession.run([worldTracker]) | |
NSLog("%@", "starting render loop") | |
await renderLoop(renderer, worldTracker) | |
NSLog("%@", "reached to end of render loop") | |
} else { | |
NSLog("%@", "remoteDeviceIdentifier = \(String(describing: remoteDeviceIdentifier))") | |
} | |
} | |
} | |
} | |
} | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment