RealityKit Basics: Visual Bounds

We can use visual bounds to get the center, extent, and other properties of a bounding box for a given entity.

Overview

Each entity in RealityKit has a bounding box. We can access this by reading data from entity.visualBounds.

let earthBounds = earth.visualBounds(relativeTo: nil)
let earthSize = earthBounds.extents
let earthCenter = earthBounds.center
// also: min, max, and boundingRadius

These values can be useful when positioning entities, or when fitting content to a volume. See how we used extents in this article: Using onGeometryChange3D to scale RealityView content when a Volume is resized.

Let’s draw a box around the Earth model in this scene.

guard let earth = scene.findEntity(named: "Earth") else { return }
let earthBounds = earth.visualBounds(relativeTo: nil)
let earthSize = earthBounds.extents
let earthCenter = earthBounds.center
let earthBox = ModelEntity(mesh: .generateBox(size: earthSize), materials: [boundsMat])
earthBox.position = scene.position + earthCenter
content.add(earthBox)

We can also draw a box around multiple entities or children of a parent entity.

guard let earth = scene.findEntity(named: "Earth") else { return }
let earthBounds = earth.visualBounds(relativeTo: nil)
let earthSize = earthBounds.extents
let earthCenter = earthBounds.center
let earthBox = ModelEntity(mesh: .generateBox(size: earthSize), materials: [boundsMat])
earthBox.position = scene.position + earthCenter
content.add(earthBox)

RealityKit seems to add a bit of padding to visual bounds so it may not line up with the edges of a collision shape or model.

Example Code

struct Example135: View {

    var boundsMat: PhysicallyBasedMaterial {
        var boundsMat = PhysicallyBasedMaterial()
        boundsMat.baseColor = .init(tint: .stepRed)
        boundsMat.blending = .transparent(opacity: .init(floatLiteral:0.2))
        return boundsMat
    }

    var body: some View {
        RealityView { content in

            guard let scene = try? await Entity(named: "VisualBounds", in: realityKitContentBundle) else { return }
            content.add(scene)

            // Draw bounds around a single entity
            guard let earth = scene.findEntity(named: "Earth") else { return }
            let earthBounds = earth.visualBounds(relativeTo: nil)
            let earthSize = earthBounds.extents
            let earthCenter = earthBounds.center
            let earthBox = ModelEntity(mesh: .generateBox(size: earthSize), materials: [boundsMat])
            earthBox.position = scene.position + earthCenter
            content.add(earthBox)

            // Draw bounds around all entites in the scene
            let sceneBounds = scene.visualBounds(recursive: true, relativeTo: scene)
            let sceneSize = sceneBounds.extents
            let sceneCenter = sceneBounds.center
            let sceneBox = ModelEntity(mesh: .generateBox(size: sceneSize), materials: [boundsMat])
            sceneBox.position = scene.position + sceneCenter
            content.add(sceneBox)

        }
    }
}

Download the Xcode project with this and many more examples from Step Into Vision.

Some examples are provided as standalone Xcode projects. You can find those here.

Questions or feedback?