Vision OS Torus Collision Shape

Hi,

I have a usdz asset of a torus / hoop shape that I would like to pass another Reality Kit Entity cube-like object through (without touching the torus) in VisionOS. Similar to how a basketball goes through a hoop.

Whenever I pass the cube through, I am getting a collision notification, even if the objects are not actually colliding. I want to be able to detect when the objects are actually colliding, vs when the cube passes cleanly through the opening in the torus.

I am using entity.generateCollisionShapes(recursive: true) to generate the collision shapes. I believe the issue is in the fact that the collision shape of the torus is a rectangular box, and not the actual shape of the torus. I know that the collision shape is a rectangular box because I can see this in the vision os simulator by enabling "Collision Shapes"

Does anyone know how to programmatically create a torus in collision shape in SwiftUI / RealityKit for VisionOS. Followup, can I create a torus in reality kit, so I don't even have to use a .usdz asset?

Post not yet marked as solved Up vote post of thearijain Down vote post of thearijain
613 views

Replies

I believe you can generate a collision Shape from a mesh. Thats the recommendation for creating entities when using a SceneReconstruction provider, for example.

See the raycasting portion ARKit and spatial computing WWDC video for slightly more.

You have to add it to the Main Bundle as a resource in a folder within the visionOS project. It doesn't work with realityKitContentBundle.

if let modelEntity = try? await ModelEntity(
    named: "model.usdz",
    in: Bundle.main
) {
                            
    // collision
    
    modelEntity.generateCollisionShapes(
        recursive: false
    )
    
    if let modelCollisionComponent = modelEntity.components[CollisionComponent.self] {
        modelEntity.components[PhysicsBodyComponent.self] = PhysicsBodyComponent(
            shapes: modelCollisionComponent.shapes,
            mass: 0,
            material: nil,
            mode: .static
        )
    }

}  

Here's how you would generate a Convex physics shape. That wouldn't help with the torus but may work for other models.

if let modelEntity = try? await ModelEntity(
    named: "model.usdz",
    in: Bundle.main
) {
                            
    // collision
    
    modelEntity.generateCollisionShapes(
        recursive: false
    )
    
    // create a convex physics shape
    
    let modelCollisionComponent = try? await CollisionComponent(
        shapes: [
            ShapeResource.generateConvex(
                from: modelEntity.model!.mesh
            )
        ]
    )
                    
    modelEntity.components.set(
        modelCollisionComponent!
    )
    
    modelEntity.components[PhysicsBodyComponent.self] = PhysicsBodyComponent(
        shapes: modelCollisionComponent!.shapes,
        mass: 0,
        material: nil,
        mode: .static
    )

}