Передача значения из SwiftUI в ARKit динамически - PullRequest
2 голосов
/ 23 января 2020

В настоящее время я работаю над личным проектом, используя ARkit и swift. В этом приложении скелет появляется по обнаруженному телу и отслеживает движение тела.

Я хочу знать, как изменить положение скелета путем динамического прикосновения к ползунку.

положение скелета определяется в ARKit классе ARDelegateHandler, например self.characterOffset = [1, 0, 0], что означает 1 м справа от обнаруженного тела. Я хочу изменить значение оси x в CharacterOffset с помощью ползунка в swiftUI. (Что-то вроде self.characterOffset = [x, 0, 0])

Вот мой код. ARViewContainer.swift

import SwiftUI
import RealityKit
import ARKit
import Combine

struct ARViewContainer: UIViewRepresentable {
    let characterAnchor = AnchorEntity()
    @Binding var offsetValue:Float
    @ObservedObject var offsetInstance = Offset()

    func makeUIView(context: Context) -> ARView {

        let arView = ARView(frame: .zero)
        arView.session.delegate = context.coordinator
        return arView
    }

    func updateUIView(_ uiView: ARView, context: Context) {
        let configuration = ARBodyTrackingConfiguration()
        uiView.session.run(configuration)
        uiView.scene.addAnchor(characterAnchor)
        print(offsetValue)
    }

    func makeCoordinator() -> ARDelegateHandler {
        ARDelegateHandler(self, anchor: characterAnchor)
    }

    class ARDelegateHandler: NSObject, ARSessionDelegate {
        var arVC: ARViewContainer
        let characterAnchor: AnchorEntity
        var character: BodyTrackedEntity?
        var characterOffset: SIMD3<Float>

        init(_ control: ARViewContainer, anchor: AnchorEntity) {
            self.arVC = control
            self.characterAnchor = anchor
            self.characterOffset = [1, 0, 0]
            super.init()
            setSkeleton()
        }

        func setSkeleton(){
            var cancellable: AnyCancellable? = nil
            cancellable = Entity.loadBodyTrackedAsync(named: "character/robot").sink(
                receiveCompletion: { completion in
                    if case let .failure(error) = completion {
                        print("Error: Unable to load model: \(error.localizedDescription)")
                    }
                    cancellable?.cancel()
            }, receiveValue: { (character: Entity) in
                if let character = character as? BodyTrackedEntity {
                    character.scale = [1, 1, 1]
                    self.character = character
                    cancellable?.cancel()
                } else {
                    print("Error: Unable to load model as BodyTrackedEntity")
                }
            })
        }

            func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
                for anchor in anchors {
                    guard let bodyAnchor = anchor as? ARBodyAnchor else { continue }

                    let bodyPosition = simd_make_float3(bodyAnchor.transform.columns.3)
                    characterAnchor.position = bodyPosition + characterOffset
                    characterAnchor.orientation = Transform(matrix: bodyAnchor.transform).rotation

                    if let character = character, character.parent == nil {
                        characterAnchor.addChild(character)
                    }
                }
            }
    }
}

ContentView.swift (ожидается, что пользователь коснется слайдера, и будет изменено значение offsetValue. SlideView уже реализован)

import SwiftUI
import RealityKit
import ARKit
import Combine


struct ContentView : View {
    @State var offsetValue:Float = 0.0
    @ObservedObject var offsetInstance = Offset()
    var body: some View {
        VStack{
            Button(action:{self.offsetInstance.setOffset(offset: 1.0)},
                   label:{Text("check")})
            ZStack(alignment: .bottom) {
                ARViewContainer(offsetValue: $offsetValue)
                SlideView(offSetValue: $offsetValue)
            }
        }

    }
}

Большое спасибо за вашу помощь !

...