Collisions & Physics: Physics Mass Properties

We can adjust mass, inertia, and center of mass for Physics Bodies.

Overview

When we add Physics Body Components to our entities, there are a number of properties we can configure. This post will focus on the Mass Properties.

When working in Reality Composer Pro, we are presented with these options:

  • Mass
  • Inertia
  • Center of Mass
    • Position
    • Orientation

I will often need to adjust the mass and the center of mass position. Personally, I’ve never had a reason to adjust inertia or the center of mass orientation.

We can adjust these same values in code by using this initializer. Alternatively, we can use some other initializers to calculate these properties based on a shape with density or mass.

Video Example

Let’s look at some examples. This scene has three capsules. We visualize the center of pass position with the small red sphere.

  1. Top heavy – the center of mass is positioned at the top of the capsule
  2. Centered – the center of mass is positioned at the center of the capsule
  3. Bottom heavy – the center of mass is positioned at the bottom of the capsule

Example Code

These capsules were set up in Reality Composer Pro. The example code below loads the scene and provides a way to top each capsule to see the result.

struct Example065: View {
    // We'll use this subject as the parent. We'll clone one of the capsules and add it to the subject to run the simulation.
    @State var subject = Entity()
    @State var capTop = Entity()
    @State var capCenter = Entity()
    @State var capBottom = Entity()


    var body: some View {
        RealityView { content in

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

            // Get the capsules from the scene, disable them, and stash them in state
            guard let capsuleTop = scene.findEntity(named: "Capsule_Top") else { return }
            guard let capsuleCenter = scene.findEntity(named: "Capsule_Center") else { return }
            guard let capsuleBottom = scene.findEntity(named: "Capsule_Bottom") else { return }

            capsuleTop.isEnabled = false
            capsuleCenter.isEnabled = false
            capsuleBottom.isEnabled = false

            capTop = capsuleTop
            capCenter = capsuleCenter
            capBottom = capsuleBottom

            content.add(scene)
            scene.position.y = -0.4
            scene.addChild(subject)

        }
        .toolbar {
            ToolbarItem(placement: .bottomOrnament, content: {
                HStack {
                    Button(action: {
                        subject.children.removeAll()
                        let clone = capTop.clone(recursive: true)
                        subject.addChild(clone)
                        clone.isEnabled = true
                    }, label: {
                        Text("Top Heavy")
                    })
                    Button(action: {
                        subject.children.removeAll()
                        let clone = capCenter.clone(recursive: true)
                        subject.addChild(clone)
                        clone.isEnabled = true
                    }, label: {
                        Text("Centered")
                    })
                    Button(action: {
                        subject.children.removeAll()
                        let clone = capBottom.clone(recursive: true)
                        subject.addChild(clone)
                        clone.isEnabled = true
                    }, label: {
                        Text("Bottom Heavy")
                    })
                }
            })
        }
    }
}

Support our work so we can continue to bring you new examples and articles.

Questions or feedback?