ARKit / RealityKit - Конфигурация People Occlusion не работает

По какой-то причине я не могу заставить людей работать, хотя я смотрел чей-то вопрос на Stackoverflow. Вот мой код:

//Load ARView
let arView = ARView(frame: .zero)

//Load people occlusion
let session = ARSession()

if let configuration = session.configuration as? ARWorldTrackingConfiguration {
    configuration.frameSemantics.insert(.personSegmentationWithDepth)
    session.run(configuration)
}

//Load custom model(not in use)
let model = try! Entity.loadModel(named: "Mug")

//Load Anchor + Entity
let anchor = AnchorEntity(plane: .horizontal)
let box = MeshResource.generateBox(size: 0.1)
let material = SimpleMaterial(color: .red, isMetallic: true)
let entity = ModelEntity(mesh: box, materials: [material])
arView.scene.anchors.append(anchor)
anchor.addChild(entity)
return arView

Что мне не хватает?


person Elementio 21809    schedule 02.04.2020    source источник


Ответы (1)


Ваш код должен выглядеть так:

let arView = ARView(frame: .zero)

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    self.switchOcclusion()
}
    
fileprivate func switchOcclusion() {
        
    guard let config = arView.session.configuration as ARWorldTrackingConfiguration
    else { return }
        
    guard ARWorldTrackingConfiguration.supportsFrameSemantics(.personSegmentationWithDepth)
    else { return }
        
    switch config.frameSemantics {            
        case [.personSegmentationWithDepth]: config.frameSemantics.remove(.personSegmentationWithDepth)                    
        default: config.frameSemantics.insert(.personSegmentationWithDepth)
    }           
    arView.session.run(config)
}
person Andy Fedoroff    schedule 02.04.2020
comment
По какой-то причине я попытался сделать именно то, что вы ответили, и получаю значение типа «ARViewContainer», не имеющее члена «arView», даже когда я меняю на универсальное устройство iOS. - person Elementio 21809; 02.04.2020
comment
У меня есть этот точный код (за исключением того, что print должен быть fatalError в блоке guard), и он не работает. Похоже, есть какое-то время, пока arView.session.configuration будет nil. - person Boris; 08.06.2021
comment
@ Борис, а какая у тебя модель iPhone? - person Andy Fedoroff; 08.06.2021
comment
@AndyFedoroff 11-дюймовый iPad Pro 3-го поколения. Купил в прошлом месяце. - person Boris; 08.06.2021
comment
@Boris, обновил свой ответ. Проверил, работает. - person Andy Fedoroff; 08.06.2021
comment
@AndyFedoroff не могли бы вы объяснить, зачем нужен touchesBegan? Я не хочу ждать, пока пользовательский ввод включит исключение. Я просто хочу, чтобы он был включен как можно скорее. - person Boris; 08.06.2021
comment
Это просто для включения и выключения Occlusion, когда это необходимо, потому что Occlusion чрезвычайно интенсивно использует CPU / GPU. - person Andy Fedoroff; 08.06.2021
comment
@AndyFedoroff, но почему я не могу (или как я могу) запустить приложение с включенной окклюзией людей? Если я попытаюсь получить доступ к .configuration во время создания представления, он окажется nil - person Boris; 09.06.2021
comment
Есть несколько случаев, когда вы можете получить nil. Позвольте вашему приложению AR собрать некоторые данные о сцене перед включением окклюзии. Используйте .asyncAfter(deadline:execute:)method, чтобы запланировать выполнение в указанное время (например, deadline = .now() + 1.0). - person Andy Fedoroff; 09.06.2021
comment
Учтите, что вы начинаете получать данные о глубине из Depth API только после запуска сеанса + некоторое время для процедуры отслеживания камеры + синхронизацию загрузки вашей модели. Данные глубины начинают генерироваться не из первого кадра ARSession, потому что окклюзия происходит из второго этапа ARKit - Scene Understanding ... - person Andy Fedoroff; 09.06.2021
comment
Надеюсь, это поможет, Борис! - person Andy Fedoroff; 09.06.2021
comment
@AndyFedoroff благодарю за помощь. Есть ли способ определить, когда он доступен, вместо того, чтобы просто жестко кодировать, ожидая N секунд? Или мне придется опросить? - person Boris; 10.06.2021
comment
Попробуйте что-нибудь вроде этого - let frame = arView.session.currentFrame, а затем guard frame?.estimatedDepthData != nil else { print("depth is being captured") return } внутри метода делегата renderer(...) или session(...). - person Andy Fedoroff; 10.06.2021