1

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?

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
YanivH
  • 539
  • 4
  • 18

1 Answers1

1

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

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • Thank you Andy! How would you go about actually visualizing those collision components? Simply show a box on the same coordinates? – YanivH Apr 23 '20 at 11:07
  • 1
    But the ShapeResource of a CollisionComponent is not a MeshResource, and I can't seem to find any way to create a MeshResource from a ShapeResource. So how would you go about doing that? – YanivH Apr 23 '20 at 11:20
  • @YanivH, I've updated my answer. And I haven't used `ShapeResource` class. – Andy Jazz Apr 23 '20 at 12:10
  • Thank you!! One last question: Is there a way to make the texture look exactly like the .showPhysics texture, in which it is much easier to see the 3D visualisation? – YanivH Apr 30 '20 at 07:36
  • 1
    Yes, you can create a UV-mapped texture (white stripes on edges) and assign it as a premultiplied RGB*A `png` texture on this cube. https://stackoverflow.com/questions/59084240/realitykit-how-to-set-a-modelentitys-transparency/59117633#59117633 – Andy Jazz May 01 '20 at 14:16