feat(av-live-body): wire USB consumer to renderer
ContentView owns and starts a USBSkeletonConsumer, threaded through BodyView into Skeleton3DRenderer.attach. The renderer subscribes its $bodies into lastArkit, so the iPhone's USB skeleton drives the on-screen 91-joint markers.
This commit is contained in:
@@ -67,17 +67,20 @@ struct ContentView: View {
|
||||
@StateObject private var poseListener = PoseOSCListener()
|
||||
@StateObject private var arkitListener = ArkitOSCListener()
|
||||
@StateObject private var dataFeeds = DataFeedsOSCListener()
|
||||
@StateObject private var usbConsumer = USBSkeletonConsumer()
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .topLeading) {
|
||||
BodyView(renderer: renderer, settings: settings,
|
||||
poseListener: poseListener,
|
||||
arkitListener: arkitListener)
|
||||
arkitListener: arkitListener,
|
||||
usbConsumer: usbConsumer)
|
||||
.onAppear {
|
||||
renderer.startOSCServer()
|
||||
poseListener.start()
|
||||
arkitListener.start()
|
||||
dataFeeds.start()
|
||||
usbConsumer.start()
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(
|
||||
for: .toggleSettings)) { _ in
|
||||
|
||||
@@ -13,6 +13,7 @@ struct BodyView: NSViewRepresentable {
|
||||
@ObservedObject var settings: RenderSettings
|
||||
@ObservedObject var poseListener: PoseOSCListener
|
||||
@ObservedObject var arkitListener: ArkitOSCListener
|
||||
@ObservedObject var usbConsumer: USBSkeletonConsumer
|
||||
|
||||
func makeNSView(context: Context) -> NSView {
|
||||
let container = NSView(frame: .zero)
|
||||
@@ -109,7 +110,8 @@ struct BodyView: NSViewRepresentable {
|
||||
arView.scene.addAnchor(skel3dAnchor)
|
||||
let skel3d = Skeleton3DRenderer()
|
||||
skel3d.attach(to: skel3dAnchor, listener: poseListener,
|
||||
arkitListener: arkitListener)
|
||||
arkitListener: arkitListener,
|
||||
usbConsumer: usbConsumer)
|
||||
context.coordinator.skel3dAnchor = skel3dAnchor
|
||||
context.coordinator.skel3d = skel3d
|
||||
context.coordinator.keyLight = key
|
||||
|
||||
@@ -87,6 +87,7 @@ final class Skeleton3DRenderer: ObservableObject {
|
||||
private var faceSub: AnyCancellable?
|
||||
private var handSub: AnyCancellable?
|
||||
private var arkitSub: AnyCancellable?
|
||||
private var usbSub: AnyCancellable?
|
||||
private var lastArkit: [Int: ArkitOSCListener.ArkitBodyFrame] = [:]
|
||||
private var lastUpdateAt: TimeInterval = 0
|
||||
/// Optional per-pid offset to align the skeleton with another
|
||||
@@ -112,7 +113,8 @@ final class Skeleton3DRenderer: ObservableObject {
|
||||
/// Attach to a scene by giving it an AnchorEntity that owns all
|
||||
/// skeleton entities, and start observing the listener.
|
||||
func attach(to anchor: Entity, listener: PoseOSCListener,
|
||||
arkitListener: ArkitOSCListener? = nil) {
|
||||
arkitListener: ArkitOSCListener? = nil,
|
||||
usbConsumer: USBSkeletonConsumer? = nil) {
|
||||
rootAnchor = anchor
|
||||
poseSub = listener.$body3d
|
||||
.receive(on: DispatchQueue.main)
|
||||
@@ -136,6 +138,13 @@ final class Skeleton3DRenderer: ObservableObject {
|
||||
Task { @MainActor in self?.lastArkit = frames }
|
||||
}
|
||||
}
|
||||
if let usb = usbConsumer {
|
||||
usbSub = usb.$bodies
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] frames in
|
||||
Task { @MainActor in self?.lastArkit = frames }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func detach() {
|
||||
@@ -147,6 +156,8 @@ final class Skeleton3DRenderer: ObservableObject {
|
||||
handSub = nil
|
||||
arkitSub?.cancel()
|
||||
arkitSub = nil
|
||||
usbSub?.cancel()
|
||||
usbSub = nil
|
||||
for (_, p) in persons { p.root.removeFromParent() }
|
||||
persons.removeAll()
|
||||
lastSeenAt.removeAll()
|
||||
|
||||
Reference in New Issue
Block a user