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:
- Author a
.usdafile with aRigidBodycomponent including validm_massandm_inertiavalues - Load the entity at runtime via
Entity(named: "MyEntity.usdz", in: bundle) - Read the existing
PhysicsBodyComponent, modifymassProperties, 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)
}
- Add the entity to the scene
- Perform any
awaitcall (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 — onlymassPropertiestriggers 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.