Rigid Body Physics#

The Physics Simulation Interface (PSI)#

Getting cached prims#

For performance reasons, the PSI often uses cached versions of a prim and the stage. prim_id is an ID to the cached prim with the path in the string var my_prim_path.

from pxr import PhysicsSchemaTools, UsdUtils

prim_id = PhysicsSchemaTools.sdfPathToInt(my_prim_path)
stage_cache = UsdUtils.StageCache.Get()
stage_id = stage_cache.GetId(self._stage).ToLongInt()

Apply a Force to a Rigid Body#

Apply a force to our prim using its cached id prim_id

from omni.physx import get_physx_simulation_interface

force = carb._carb.Float3(0.0, up_force_scalar, 0)

psi = get_physx_simulation_interface()
psi.apply_force_at_pos(stage_id, prim_id, force, carb._carb.Float3(location))

Apply a Torque to a Rigid Body#

torque_roll = carb._carb.Float3(foward_vect * roll_torque_scalar)

psi = get_physx_simulation_interface()
psi.apply_torque(stage_id, prim_id, torque_roll)

Rigid Body Collisions#

Contact Reporter (Collisions)#

Subscribe to Contact Reports by registering our callback function

from pxr import PhysicsSchemaTools, PhysxSchema, UsdPhysics

my_stage = usd_context.get_stage()
my_prim = my_stage.GetPrimAtPath(my_prim_path)

contactReportAPI = PhysxSchema.PhysxContactReportAPI.Apply(my_prim)
contact_report_sub = get_physx_simulation_interface().subscribe_contact_report_events(self.on_contact_report_event)

The callback to handle Contact Report events#

from pxr import PhysicsSchemaTools

def on_contact_report_event(self, contact_headers, contact_data):

    for contact_header in contact_headers:
        # instigator
        act0_path = str(PhysicsSchemaTools.intToSdfPath(contact_header.actor0))
        # recipient
        act1_path = str(PhysicsSchemaTools.intToSdfPath(contact_header.actor1))
        # the specific collision mesh that belongs to the Rigid Body
        cur_collider = str(PhysicsSchemaTools.intToSdfPath(contact_header.collider0))

        # iterate over all contacts
        contact_data_offset = contact_header.contact_data_offset
        num_contact_data = contact_header.num_contact_data
        for index in range(contact_data_offset, contact_data_offset + num_contact_data, 1):
            cur_contact = contact_data[index]

            # find the magnitude of the impulse
            cur_impulse =  cur_contact.impulse[0] * cur_contact.impulse[0]
            cur_impulse += cur_contact.impulse[1] * cur_contact.impulse[1]
            cur_impulse += cur_contact.impulse[2] * cur_contact.impulse[2]
            cur_impulse = math.sqrt(cur_impulse)