You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

visionOS中如何判断3D Entity是否处于Camera视野内?

visionOS中判断Entity是否处于Camera视野内的实现方案

核心方法:使用RealityKit的isVisible(to:)

RealityKit的Entity类提供了isVisible(to:)方法,可直接判断目标实体是否在指定相机的视野内(会自动考虑视锥体裁剪、遮挡等情况)。

实现步骤与代码示例

  1. 获取目标实体与相机实体
    先创建或加载需要监测的目标Entity,同时获取当前ARView的相机实体。

  2. 实时监听相机状态变化
    通过RealityKit的SceneEvents.Update事件或ARSession的代理方法,在相机姿态变化时触发可见性检查。

完整代码示例:

import SwiftUI
import RealityKit
import ARKit

struct ContentView: View {
    @State private var arView = ARView(frame: .zero)
    @State private var targetEntity: Entity?
    
    var body: some View {
        ARViewContainer(arView: $arView, targetEntity: $targetEntity)
            .onAppear {
                // 创建目标实体(示例为红色立方体)
                let boxMesh = MeshResource.generateBox(size: 0.1)
                let redMaterial = SimpleMaterial(color: .red, isMetallic: true)
                targetEntity = ModelEntity(mesh: boxMesh, materials: [redMaterial])
                
                // 将实体添加到场景
                if let target = targetEntity {
                    target.position = [0, 0, -1] // 置于相机前方1米处
                    arView.scene.addAnchor(target)
                }
                
                // 订阅场景更新事件,每帧检查可见性
                arView.scene.subscribe(to: SceneEvents.Update.self) { _ in
                    checkEntityVisibility()
                }
            }
    }
    
    private func checkEntityVisibility() {
        guard let target = targetEntity, let camera = arView.camera else { return }
        
        let isVisible = target.isVisible(to: camera)
        print(isVisible ? "visible" : "not visible")
    }
}

struct ARViewContainer: UIViewRepresentable {
    @Binding var arView: ARView
    @Binding var targetEntity: Entity?
    
    func makeUIView(context: Context) -> ARView {
        arView.session.delegate = context.coordinator
        return arView
    }
    
    func updateUIView(_ uiView: ARView, context: Context) {}
    
    func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }
    
    class Coordinator: NSObject, ARSessionDelegate {
        var parent: ARViewContainer
        
        init(parent: ARViewContainer) {
            self.parent = parent
        }
        
        // 可选:通过ARSession代理监听相机帧更新,触发检查
        func session(_ session: ARSession, didUpdate frame: ARFrame) {
            parent.checkEntityVisibility()
        }
    }
}

进阶:手动判断视锥体交集(忽略遮挡)

如果只需要判断实体是否在相机视锥体内(不考虑被其他物体遮挡),可以手动计算实体边界框与相机视锥体的交集:

private func isInCameraFrustum(entity: Entity, camera: Entity) -> Bool {
    guard let cameraComponent = camera.components[CameraComponent.self] as? CameraComponent else {
        return false
    }
    let cameraFrustum = cameraComponent.frustum
    // 获取实体相对于相机的边界框
    let entityBounds = entity.bounds(relativeTo: camera)
    
    return cameraFrustum.intersects(entityBounds)
}

注意事项

  • 确保使用的相机实体是当前AR会话的活跃相机,ARView.camera会返回正确的AR相机实体。
  • 实时检查的频率可根据需求调整:SceneEvents.Update是每帧触发,ARSession代理则是在相机姿态变化时触发,后者性能消耗更低。

内容的提问来源于stack exchange,提问作者Santrack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 22:48:42