0

My iOS app uses RealityKit with Physics to move entities. It requires to put objects on a board. This must be done with a totally inelastic impact, i.e. the object must not bounce back when put on the board.
Unfortunately, I was not able to achieve this behavior. I thus wrote a little test app to investigate the situation. This app is shown below.
The app sets up a board and above it a box. Both entities use a physicsBody so that they can participate in the Physics simulation.
The mode of the board is .static, i.e. it does not move. The mode of the box is .dynamic, i.e. it moves immediately after app start down by gravity.
The PhysicsMaterialResource of both entities has its restitution set to 0, i.e. the impact should be totally inelastic.
Both entities have collision shapes, so that the box collides with the board after a short fall.

The essential test parameter is the scaleFactor at the beginning of the code. Depending on its value, I observed different behavior:

  • If scaleFactor is = 0.1, the box collides with the board, and stops as expected.
  • If scaleFactor is = 0.02, the box is bounced back hardly, and disappears towards the top.
  • If scaleFactor is = 0.01, The box does not collide with the board, and falls through.

I believe this is RealityKit bug, and if somebody can confirm this, I will write a bug report.

The code:

import SwiftUI

@main
struct RestitutionApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

import RealityKit
import SwiftUI

let scaleFactor: Float = 0.1 // correct behavior
//let scaleFactor: Float = 0.02 // impact is not inelastic
//let scaleFactor: Float = 0.01 // box falls through the board

struct ContentView: View {
    let scale = scaleFactor * SIMD3<Float>(1, 1, 1)
    let boxSize: Float = 0.5/scaleFactor
    
    var body: some View {
        RealityView { content in
            let board = makeBoard()
            board.position = [0, 0, -3]
            content.add(board)
            
            let box = makeBox()
            box.position = [0, 1, 0]
            board.addChild(box)
        }
    }
    
    func makeBoard() -> ModelEntity {
        let mesh = MeshResource.generateBox(width: 2, height: 0.2, depth: 1.0)
        var material = UnlitMaterial(); material.color.tint = .red
        let boardEntity = ModelEntity(mesh: mesh, materials: [material])
        
        boardEntity.generateCollisionShapes(recursive: false)
        
        let physicsMaterial = PhysicsMaterialResource.generate(friction: 0, restitution: 0)
        boardEntity.physicsBody = PhysicsBodyComponent(massProperties: .default, 
                                                       material: physicsMaterial, 
                                                       mode: .static) // The board does not move
        
        return boardEntity
    }
    
    func makeBox() -> ModelEntity {
        let mesh = MeshResource.generateBox(size: boxSize)
        var material = UnlitMaterial(); material.color.tint = .green
        let boxEntity = ModelEntity(mesh: mesh, materials: [material])
        
        boxEntity.scale = scale
        
        boxEntity.generateCollisionShapes(recursive: false)
        
        let physicsMaterial = PhysicsMaterialResource.generate(friction: 0, restitution: 0)
        boxEntity.physicsBody = PhysicsBodyComponent(massProperties: .default, 
                                                         material: physicsMaterial, 
                                                         mode: .dynamic)
        
        return boxEntity
    }

}
2
  • Did you ever figure this out? I had similar issues with scaling and physics. I got better behavior by raising the inertia in PhysicsMassProperties from the defaults ([0.1, 0.1, 0.1]). Also, with the PhysicsSimulationComponent from last year, properly scaling the simulation entity might help. I tried inertia of [1.0, 1.0, 1.0] or higher (inversely to scaleFactor) and got better results, but still need to test the simulation approach more. Do you need to scale it like that, or was it just for testing? Commented Apr 27 at 19:55
  • 1
    I use OpenSCAD to create my models. The dimensions of these models don't have a unit. If converted to STL and then to USDZ, the unit is about 1 cm, but RealityKit works with meters. I thus scaled the models using the entities scale property. Later II realized that I can open the STL files by RealityConverter Pro, scale them there in the Transform property, and export them as USDZ. Thus, my entity scales are now 1 and the problem is solved. Commented Apr 28 at 6:21

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.