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)