Setting massProperties on a USDZ-loaded entity corrupts its transform (position/scale → NaN)

Setting massProperties on a USDZ-loaded entity corrupts its transform (position/scale → NaN)

Category: RealityKit / visionOS

Environment:

  • visionOS 26.x

Summary:

Modifying PhysicsBodyComponent.massProperties at runtime on an entity loaded from a .usdz file silently corrupts the entity's transform. The translation and scale components become NaN, while rotation remains valid. The corruption occurs during the next RealityKit scene update cycle (e.g., during an await suspension on the main actor).

Steps to Reproduce:

  1. Author a .usda file with a RigidBody component including valid m_mass and m_inertia values
  2. Load the entity at runtime via Entity(named: "MyEntity.usdz", in: bundle)
  3. Read the existing PhysicsBodyComponent, modify massProperties, and set it back:
if var physics = entity.components[PhysicsBodyComponent.self] {
    physics.massProperties = .init(
        mass: 1.944,
        inertia: SIMD3<Float>(0.013, 0.026, 0.016),
        centerOfMass: (position: .zero, orientation: .init())
    )
    entity.components.set(physics)
}
  1. Add the entity to the scene
  2. Perform any await call (e.g., TextureResource(contentsOf:)) that yields to the main actor, allowing a RealityKit scene update to run

Expected: The entity retains its position and scale with the updated mass/inertia values.

Actual: The entity's transform becomes corrupted:

Transform(
    scale: SIMD3<Float>(nan, nan, nan),
    rotation: simd_quatf(real: 1.0, imag: SIMD3<Float>(0.0, 0.0, 0.0)),  // ← fine
    translation: SIMD3<Float>(-nan, -nan, -nan)
)

Additional findings from investigation:

  • The entity's physics mode does not matter — corruption occurs even when the entity is .kinematic
  • Creating a new PhysicsBodyComponent(...) and replacing the existing one also triggers the bug
  • Modifying other properties on the same component (linearDamping, angularDamping, material, mode) does not cause corruption — only massProperties triggers it
  • The parent entity's transform remains valid
  • The computed mass/inertia values themselves are valid (finite, positive)
  • The corruption is silent — no error, no warning, no crash from RealityKit itself

Workaround:

Author mass and inertia values directly in the .usda file and do not modify massProperties at runtime:

def RealityKitStruct "massFrame"
{
    float3 m_inertia = (0.02, 0.02, 0.038)
    float m_mass = 2.5

    def RealityKitStruct "m_pose"
    {
    }
}

Other PhysicsBodyComponent properties (damping, material, mode) can safely be modified at runtime.

Setting massProperties on a USDZ-loaded entity corrupts its transform (position/scale → NaN)
 
 
Q