Search code examples
swiftaugmented-realityarkitrealitykit

How to make RealityKit to show only CollisionComponents?


I am trying to see the CollisionComponents on my ARView.

I used the .showPhysics as part of the debugOptions, but since I have 20 objects on screen, I get all the normals going crazy and the color of the CollisionComponents in unclear (some form of weird pink).

Does anyone have any idea how to present only the CollisionComponents without any extra data as part of the .showPhysics?


Solution

  • You can extend a standard functionality of RealityKit's ARView by using simple Swift extension:

    import RealityKit
    import ARKit
    
    fileprivate extension ARView.DebugOptions {
    
        func showCollisions() -> ModelEntity {
    
            print("Code for visualizing collision objects goes here...")
    
            let vc = ViewController()
    
            let box = MeshResource.generateBox(size: 0.04)    
            let color = UIColor(white: 1.0, alpha: 0.15)    
            let colliderMaterial = UnlitMaterial(color: color)
    
            vc.visualCollider = ModelEntity(mesh: box,
                                       materials: [colliderMaterial])    
            return vc.visualCollider
        }
    }
    

    ...and then call this method in ViewController when you're tapping on a screen:

    class ViewController: UIViewController {
    
        @IBOutlet var arView: ARView!
    
        let anchor = AnchorEntity()
        var ballEntity = ModelEntity()
        var visualCollider = ModelEntity()
        var sphere: MeshResource?
    
        @IBAction func onTap(_ sender: UITapGestureRecognizer) {
    
            sphere = MeshResource.generateSphere(radius: 0.02)
    
            let material = SimpleMaterial(color: .systemPink,
                                     isMetallic: false)
    
            ballEntity = ModelEntity(mesh: sphere!,
                                materials: [material])
    
            let point: CGPoint = sender.location(in: arView)
    
            guard let query = arView.makeRaycastQuery(from: point,
                                                  allowing: .estimatedPlane,
                                                 alignment: .any)
            else { return }
    
            let result = arView.session.raycast(query)
    
            guard let raycastResult = result.first
            else { return }
    
            let anchor = AnchorEntity(raycastResult: raycastResult)
            anchor.addChild(ballEntity)
            arView.scene.anchors.append(anchor)
    
            let showCollisions = arView.debugOptions.showCollisions()  // here it is
            ballEntity.addChild(showCollisions)
    
            ballEntity.generateCollisionShapes(recursive: true)
        }
    }
    

    Please consider, it's an approximate visualization. This code just shows you a way to go on.

    enter image description here