### Setup and Controls Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/ux/source/omni.physx.cct/docs/index.html Quick start example showing how to spawn a capsule, activate first-person CCT control with gravity, and set up default controls. ```APIDOC ## Setup and Controls ### Description Quick start example for setting up a character controller capsule and activating first-person control with gravity. ### Code ```python from omni.physxcct.scripts import utils # set up a base capsule utils.spawn_capsule(stage, cct_path, position) # start first-person CCT control with gravity utils.activate_cct(stage, cct_path, "/OmniverseKit_Persp", True) # activate default controls (keyboard/mouse or gamepad) control_state = utils.setup_controls(cct_path, speed) ``` ``` -------------------------------- ### Manual Setup Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/ux/source/omni.physx.cct/docs/index.html Example showing how to manually create a capsule prim, apply the PhysxCharacterControllerAPI, and enable first-person control with gravity. ```APIDOC ## Manual Setup ### Description Manual setup of a character controller capsule using USD and the PhysxCharacterControllerAPI. ### Code ```python from omni.physxcct import get_physx_cct_interface from pxr import UsdGeom, PhysxSchema # set up a base capsule capsule_geom = UsdGeom.Capsule.Define(stage, capsule_path) capsule_geom.CreateHeightAttr(50.0) capsule_geom.CreateRadiusAttr(25.0) capsule_geom.CreateAxisAttr(UsdGeom.GetStageUpAxis(stage)) # apply CCT API capsule_prim = stage.GetPrimAtPath(capsule_path) cct = PhysxSchema.PhysxCharacterControllerAPI.Apply(capsule_prim) # start first-person CCT control with gravity physx_cct = get_physx_cct_interface() physx_cct.enable_first_person(self._path_cct, True) physx_cct.enable_gravity(self._path_cct) physx_cct.set_current_camera("/OmniverseKit_Persp") ``` ``` -------------------------------- ### Setup Surface Deformable Hierarchy Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/deformables/deformable_bodies.html Example demonstrating the configuration of a root prim, simulation mesh, and optional render mesh for a surface deformable body. ```python from pxr import Usd, UsdGeom, Vt, Gf, UsdPhysics, PhysxSchema import omni.usd stage = omni.usd.get_context().get_stage() # Create a root prim rootXform = UsdGeom.Xform.Define(stage, "/World/DeformableBody") rootPrim = rootXform.GetPrim() rootPrim.ApplyAPI("OmniPhysicsDeformableBodyAPI") if rootPrim.HasAPI("OmniPhysicsDeformableBodyAPI"): rootPrim.GetAttribute("omniphysics:mass").Set(0.5) # Apply customizations rootPrim.ApplyAPI("PhysxSurfaceDeformableBodyAPI") if rootPrim.HasAPI("PhysxSurfaceDeformableBodyAPI"): rootPrim.GetAttribute("physxDeformableBody:disableGravity").Set(True) rootPrim.GetAttribute("physxDeformableBody:selfCollision").Set(True) # Define a simulation mesh simPath = "/World/DeformableBody/SimulationMesh" simMesh = create_trimesh(stage, simPath, 6) simPrim = simMesh.GetPrim() simPrim.ApplyAPI("OmniPhysicsSurfaceDeformableSimAPI") if simPrim.HasAPI("OmniPhysicsSurfaceDeformableSimAPI"): restShapePointsAttr = simPrim.GetAttribute("omniphysics:restShapePoints") restShapePointsAttr.Set(simMesh.GetPointsAttr().Get()) triVtxIndices = list(zip(*[iter(simMesh.GetFaceVertexIndicesAttr().Get())]*3)) restTriVtxIndicesAttr = simPrim.GetAttribute("omniphysics:restTriVtxIndices") restTriVtxIndicesAttr.Set(triVtxIndices) # Add bind pose for registering other meshes with respect to sim mesh purposesAttrName = "deformablePose:custom:omniphysics:purposes" pointsAttrName = "deformablePose:custom:omniphysics:points" simPrim.ApplyAPI("OmniPhysicsDeformablePoseAPI", "custom") if simPrim.HasAPI("OmniPhysicsDeformablePoseAPI", "custom"): simPrim.GetAttribute(purposesAttrName).Set(["bindPose"]) simPrim.GetAttribute(pointsAttrName).Set(simMesh.GetPointsAttr().Get()) # Mark the simulation mesh for collision detection collisionAPI = UsdPhysics.CollisionAPI.Apply(simPrim) # Apply customizations physxCollisionAPI = PhysxSchema.PhysxCollisionAPI.Apply(simPrim) if (physxCollisionAPI): physxCollisionAPI.GetContactOffsetAttr().Set(0.02) physxCollisionAPI.GetRestOffsetAttr().Set(0.01) # Don't render simulation mesh simMesh.GetPurposeAttr().Set("guide") # Optionally add a render mesh renderPath = "/World/DeformableBody/RenderMesh" renderMesh = create_quadmesh(stage, renderPath, 12) renderPrim = renderMesh.GetPrim() # Add bind pose for registering configuration with respect to sim mesh renderPrim.ApplyAPI("OmniPhysicsDeformablePoseAPI", "custom") if renderPrim.HasAPI("OmniPhysicsDeformablePoseAPI", "custom"): renderPrim.GetAttribute(purposesAttrName).Set(["bindPose"]) renderPrim.GetAttribute(pointsAttrName).Set(renderMesh.GetPointsAttr().Get()) ``` -------------------------------- ### Manual Setup with PhysxCharacterControllerAPI Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/ux/source/omni.physx.cct/docs/index.html Manual setup: create a capsule prim, apply the PhysxCharacterControllerAPI, and enable first-person control with gravity. ```python from omni.physxcct import get_physx_cct_interface from pxr import UsdGeom, PhysxSchema # set up a base capsule capsule_geom = UsdGeom.Capsule.Define(stage, capsule_path) capsule_geom.CreateHeightAttr(50.0) capsule_geom.CreateRadiusAttr(25.0) capsule_geom.CreateAxisAttr(UsdGeom.GetStageUpAxis(stage)) # apply CCT API capsule_prim = stage.GetPrimAtPath(capsule_path) cct = PhysxSchema.PhysxCharacterControllerAPI.Apply(capsule_prim) # start first-person CCT control with gravity physx_cct = get_physx_cct_interface() physx_cct.enable_first_person(self._path_cct, True) physx_cct.enable_gravity(self._path_cct) physx_cct.set_current_camera("/OmniverseKit_Persp") ``` -------------------------------- ### Setup and Controls using utils Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/ux/source/omni.physx.cct/docs/index.html Quick setup using the omni.physxcct.scripts.utils module: spawn a capsule, activate first-person CCT with gravity, and set up default controls. ```python from omni.physxcct.scripts import utils # set up a base capsule utils.spawn_capsule(stage, cct_path, position) # start first-person CCT control with gravity utils.activate_cct(stage, cct_path, "/OmniverseKit_Persp", True) # activate default controls (keyboard/mouse or gamepad) control_state = utils.setup_controls(cct_path, speed) ``` -------------------------------- ### BenchmarkFns Implementation Example (C++) Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Complete C++ example demonstrating how to implement the BenchmarkFns structure with subscribeProfileStatsEvents and unsubscribeProfileStatsEvents, and how to report profiling statistics. ```APIDOC ## BenchmarkFns Implementation Example (C++) ### Description Complete C++ example demonstrating how to implement the BenchmarkFns structure with subscribeProfileStatsEvents and unsubscribeProfileStatsEvents, and how to report profiling statistics. ### Code ```cpp #include using namespace omni::physics; class MyBenchmarkProvider { public: MyBenchmarkProvider() { m_benchmarkFns.subscribeProfileStatsEvents = [this](ProfileStatsNotificationFn callback) -> SubscriptionId { m_statsCallbacks.push_back(callback); return m_statsCallbacks.size(); }; m_benchmarkFns.unsubscribeProfileStatsEvents = [this](SubscriptionId id) { if (id > 0 && id <= m_statsCallbacks.size()) { m_statsCallbacks.erase(m_statsCallbacks.begin() + id - 1); } }; } // Call this after each simulation step to report stats void reportStats() { std::vector stats; PhysicsProfileStats simStats; simStats.zoneName = "Simulation"; simStats.ms = m_simulationTime; stats.push_back(simStats); PhysicsProfileStats collStats; collStats.zoneName = "Collision Detection"; collStats.ms = m_collisionTime; stats.push_back(collStats); // Notify all subscribers for (auto& callback : m_statsCallbacks) { callback(stats); } } BenchmarkFns getBenchmarkFns() const { return m_benchmarkFns; } private: BenchmarkFns m_benchmarkFns; std::vector m_statsCallbacks; float m_simulationTime = 0.0f; float m_collisionTime = 0.0f; }; ``` ``` -------------------------------- ### Assigning multi-material behavior using UsdGeom.Subset Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/deformables/omniphysics_deformable_schema.html Example demonstrating how to define soft and hard materials and apply them to specific subsets of a simulation mesh within a deformable body setup. ```usd def ShadeMaterial "softMat" ( prepend apiSchemas = [ "OmniPhysicsDeformableMaterialAPI" ] ) { ... } def ShadeMaterial "hardMat" ( prepend apiSchemas = [ "OmniPhysicsDeformableMaterialAPI" ] ) { ... } def GeomXform "rubberChickenToy" ( prepend apiSchemas = ["OmniPhysicsDeformableBodyAPI"] ) { # by default the soft material is used rel material:binding:physics = ( bindMaterialAs = "weakerThanDescendants" ) def GeomMesh "body" () { ... } def GeomMesh "eyeballs" () { ... } def GeomXform "left_leg" () { def GeomMesh "left_leg" () { ... } ... } def GeomXform "right_leg" () { def GeomMesh "right_leg" () { ... } ... } def GeomTetMesh "simulationMesh" ( prepend apiSchemas = [ "OmniPhysicsVolumeDeformableSimAPI", "UsdPhysicsCollisionAPI" ] ) { # individual tetrahedra can use the hard material def GeomSubset "subsetHard" ( prepend apiSchemas = ["MaterialBindingAPI"] ) { uniform token elementType = "tetrahedron" uniform token familyName = "materialBind" int[] indices = [...] rel material:binding = ( bindMaterialAs = "weakerThanDescendants" ) } ... } ... } ``` -------------------------------- ### SceneQueryFns Implementation Example Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html C++ example showing how to implement the SceneQueryFns structure, including raycast and overlap functions. ```APIDOC ## SceneQueryFns ### Description Provides scene query functionality for raycasts, sweeps, and overlap tests. Defined in the IPhysicsSceneQuery interface. ### Key Function Groups - Raycasts: raycastClosest, raycastAny, raycastAll - Sphere Sweeps: sweepSphereClosest, sweepSphereAny, sweepSphereAll - Box Sweeps: sweepBoxClosest, sweepBoxAny, sweepBoxAll - Shape Sweeps: sweepShapeClosest, sweepShapeAny, sweepShapeAll - Overlaps: overlapSphere, overlapSphereAny, overlapBox, overlapBoxAny, overlapShape, overlapShapeAny ### C++ Example - Implementing SceneQueryFns ```cpp #include using namespace omni::physics; class MySceneQueryProvider { public: MySceneQueryProvider() { m_sceneQueryFns.raycastClosest = [this](const carb::Float3& origin, const carb::Float3& unitDir, float distance, RaycastHit& hit, bool bothSides) -> bool { // Perform raycast in your physics engine if (performRaycast(origin, unitDir, distance, bothSides, hit)) { return true; } return false; }; m_sceneQueryFns.raycastAny = [this](const carb::Float3& origin, const carb::Float3& unitDir, float distance, bool bothSides) -> bool { RaycastHit hit; return performRaycast(origin, unitDir, distance, bothSides, hit); }; m_sceneQueryFns.raycastAll = [this](const carb::Float3& origin, const carb::Float3& unitDir, float distance, RaycastHitReportFn reportFn, bool bothSides) { std::vector hits; performRaycastAll(origin, unitDir, distance, bothSides, hits); for (const auto& hit : hits) { // Return false from callback to stop traversal if (!reportFn(hit)) break; } }; m_sceneQueryFns.overlapSphere = [this](float radius, const carb::Float3& pos, OverlapHitReportFn reportFn) -> uint32_t { std::vector hits; performSphereOverlap(pos, radius, hits); uint32_t count = 0; for (const auto& hit : hits) { count++; if (!reportFn(hit)) break; } return count; }; m_sceneQueryFns.overlapSphereAny = [this](float radius, const carb::Float3& pos) -> bool { return checkSphereOverlap(pos, radius); }; // Implement other functions similarly... } SceneQueryFns getSceneQueryFns() const { return m_sceneQueryFns; } private: SceneQueryFns m_sceneQueryFns; bool performRaycast(const carb::Float3& origin, const carb::Float3& dir, float distance, bool bothSides, RaycastHit& hit) { /* ... */ return false; } void performRaycastAll(const carb::Float3& origin, const carb::Float3& dir, float distance, bool bothSides, std::vector& hits) { /* ... */ } void performSphereOverlap(const carb::Float3& pos, float radius, std::vector& hits) { /* ... */ } bool checkSphereOverlap(const carb::Float3& pos, float radius) { /* ... */ return false; } }; ``` ``` -------------------------------- ### Benchmark Interface Usage Example (Python) Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Complete Python example demonstrating how to use the benchmark interface, including subscribing to profile stats events and registering a simulation. ```APIDOC ## Benchmark Interface Usage Example (Python) ### Description Complete Python example demonstrating how to use the benchmark interface, including subscribing to profile stats events and registering a simulation. ### Code ```python from omni.physics.core import ( Simulation, PhysicsProfileStats, get_physics_interface, get_physics_benchmarks_interface, k_invalid_subscription_id, ) class MyBenchmarkProvider: """Provide profiling statistics""" def __init__(self): self.callbacks = [] self.simulation_time = 0.0 self.collision_time = 0.0 def subscribe_profile_stats_events(self, callback): self.callbacks.append(callback) return len(self.callbacks) def unsubscribe_profile_stats_events(self, subscription_id): if 0 < subscription_id <= len(self.callbacks): self.callbacks.pop(subscription_id - 1) def report_stats(self): """Call after each simulation step""" stats = [] sim_stat = PhysicsProfileStats() sim_stat.zone_name = "Simulation" sim_stat.ms = self.simulation_time stats.append(sim_stat) coll_stat = PhysicsProfileStats() coll_stat.zone_name = "Collision Detection" coll_stat.ms = self.collision_time stats.append(coll_stat) for callback in self.callbacks: callback(stats) # Wire up to simulation benchmark_provider = MyBenchmarkProvider() simulation = Simulation() simulation.benchmark_fns.subscribe_profile_stats_events = ( benchmark_provider.subscribe_profile_stats_events ) simulation.benchmark_fns.unsubscribe_profile_stats_events = ( benchmark_provider.unsubscribe_profile_stats_events ) # Register and use physics = get_physics_interface() simulation_id = physics.register_simulation(simulation, "BenchmarkDemo") benchmarks = get_physics_benchmarks_interface() def on_profile_stats(stats): for stat in stats: print(f"{stat.zone_name}: {stat.ms:.2f}ms") subscription = benchmarks.subscribe_profile_stats_events(on_profile_stats) # Later, unsubscribe subscription = None # or call unsubscribe explicitly ``` ``` -------------------------------- ### Setup surface deformable using deformableUtils Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/deformables/deformable_bodies.html Uses the deformableUtils helper to simplify the setup of a surface deformable body, followed by manual customization of PhysX attributes. ```python from pxr import Usd, UsdGeom, Vt, Gf, UsdPhysics, PhysxSchema import omni.usd from omni.physx.scripts import deformableUtils stage = omni.usd.get_context().get_stage() triMesh = create_trimesh(stage, "/World/TriMesh", 6) prim = triMesh.GetPrim() # Call deformableUtils helper success = deformableUtils.set_physics_surface_deformable_body(stage, prim.GetPath()) # Apply customizations if prim.HasAPI("OmniPhysicsDeformableBodyAPI"): prim.GetAttribute("omniphysics:mass").Set(0.5) prim.ApplyAPI("PhysxSurfaceDeformableBodyAPI") if prim.HasAPI("PhysxSurfaceDeformableBodyAPI"): prim.GetAttribute("physxDeformableBody:disableGravity").Set(True) prim.GetAttribute("physxDeformableBody:selfCollision").Set(True) physxCollisionAPI = PhysxSchema.PhysxCollisionAPI.Apply(prim) if physxCollisionAPI: physxCollisionAPI.GetContactOffsetAttr().Set(0.02) physxCollisionAPI.GetRestOffsetAttr().Set(0.01) ``` -------------------------------- ### Tire Example with OmniPhysicsDeformablePoseAPI Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/deformables/omniphysics_deformable_schema.html An example showing how to extend a tire geometry with the OmniPhysicsDeformablePoseAPI to specify a bindPose purpose for simulation, collision, and graphics meshes. ```usd def GeomXform "tire" ( prepend apiSchemas = ["OmniPhysicsDeformableBodyAPI"] ) { def GeomTetMesh "simulationMesh" ( prepend apiSchemas = [ "OmniPhysicsVolumeDeformableSimAPI", "OmniPhysicsDeformablePoseAPI:custom" ] ) { token[] deformablePose:custom:omniphysics:purposes = ["bindPose"] point3f[] deformablePose:custom:omniphysics:posePoints = [...] ... } def GeomMesh "collisionMesh" { prepend apiSchemas = [ "UsdPhysicsCollisionAPI", "OmniPhysicsDeformablePoseAPI:custom" ] ) { token[] deformablePose:pose:omniphysics:purposes = ["bindPose"] point3f[] deformablePose:custom:omniphysics:posePoints = [...] ... } def GeomMesh "graphicsMesh" ( prepend apiSchemas = [ "OmniPhysicsDeformablePoseAPI:custom" ] ) { token[] deformablePose:custom:omniphysics:purposes = ["bindPose"] point3f[] deformablePose:custom:omniphysics:posePoints = [...] ... } ... } ``` -------------------------------- ### Python Registering a Simulation Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Demonstrates how to get the physics interface, register a simulation, and manage its activation state in Python. ```python from omni.physics.core import ( Simulation, get_physics_interface, k_invalid_simulation_id ) # Get the physics interface physics = get_physics_interface() # Create a simulation instance simulation = Simulation() # Register the simulation simulation_name = "MyCustomSimulation" simulation_id = physics.register_simulation(simulation, simulation_name) if simulation_id != k_invalid_simulation_id: # Simulation registered successfully # Query simulation state is_active = physics.is_simulation_active(simulation_id) # Get simulation name name = physics.get_simulation_name(simulation_id) # Deactivate/activate as needed physics.deactivate_simulation(simulation_id) physics.activate_simulation(simulation_id) # Unregister when done physics.unregister_simulation(simulation_id) ``` -------------------------------- ### Manual Controls Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/ux/source/omni.physx.cct/docs/index.html Example showing how to compute a movement vector and set it on the character controller interface. ```APIDOC ## Manual Controls ### Description Manual control of the character controller by setting a movement vector. ### Code ```python # multiply speed constant with current frametime speed = 10 * dt # add up directions and normalize to account for possible diagonal movement x = control_up + control_down * -1 y = control_left + control_right * -1 move = Gf.Vec3f(x * speed, y * speed, 0).GetNormalized() # set move to usd get_physx_cct_interface().set_move(state.cct_path, (move[0], move[1], move[2])) ``` ``` -------------------------------- ### Define a tire deformable body with simulation and collision meshes Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/deformables/omniphysics_deformable_schema.html Example of a tire setup using a volumetric simulation mesh and a separate collision mesh, with a graphics mesh embedded in the simulation mesh. ```USD def GeomXform "tire" ( prepend apiSchemas = ["OmniPhysicsDeformableBodyAPI"] ) { def GeomTetMesh "simulationMesh" ( prepend apiSchemas = [ "OmniPhysicsVolumeDeformableSimAPI" ] ) { ... } def GeomMesh "collisionMesh" { prepend apiSchemas = [ "UsdPhysicsCollisionAPI" ] ) { ... } def GeomMesh "graphicsMesh" ( # Deformed according to embedding in simulationMesh. ) { ... } ... } ``` -------------------------------- ### Initialize Vehicle Class Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/vehicles/vehicles.html Sets up the initial state and opens the USD stage. ```python def __init__(self): self._simStarted = False print("Loading Stage " + myStageName) self._usd_context = omni.usd.get_context() self._physxInterface = None # Load the level self._usd_context.open_stage(myStageName, self.load_stage) ``` -------------------------------- ### Headless Session Command Line Example Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/ux/source/omni.physx.pvd/docs/dev_guide/physx_visual_debugger.html Example command to run a headless session with OmniPVD recording enabled. ```bash bash kit/omni.app.dev.sh --no-window --/windowless=True --/persistent/physics/omniPvdOvdRecordingDirectory=/tmp/ --/physics/omniPvdOutputEnabled=true ``` -------------------------------- ### Configure multi-GPU settings in .kit file Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/simulation_control/simulation_control.html Example settings for a .kit file to enable multi-GPU rendering on the first GPU and physics simulation on the second GPU. ```ini [settings] renderer.multiGpu.enabled = true renderer.multiGpu.activeGpus = "0" physics.cudaDevice = 1 ``` -------------------------------- ### C++ Example - Implementing StageUpdateFns Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Example implementation of the StageUpdateFns callbacks in C++ for handling stage lifecycle and simulation events. ```APIDOC ## StageUpdateFns Implementation ### Description Example C++ implementation of the StageUpdateFns callbacks for handling stage attach/detach, frame updates, timeline events, and physics object management. ### Functions - **onAttach** (callback) - Called when a stage is attached. Receives a `long stageId`. - **onDetach** (callback) - Called when a stage is detached. No parameters. - **onUpdate** (callback) - Called on each frame update. Receives `float currentTime`, `float elapsedSecs`, `bool enableUpdate`. - **onResume** (callback) - Called when timeline playback resumes. Receives `float currentTime`. - **onPause** (callback) - Called when timeline is paused. No parameters. - **onReset** (callback) - Called when timeline is stopped/reset. No parameters. - **forceLoadPhysicsFromUSD** (callback) - Force load physics objects from USD. No parameters. - **releasePhysicsObjects** (callback) - Release all physics objects. No parameters. - **startSimulation** (callback) - Called when simulation starts. No parameters. - **resetSimulation** (callback) - Reset simulation state. No parameters. ### Example Code ```cpp #include using namespace omni::physics; class MyStageUpdateHandler { public: MyStageUpdateHandler() { m_stageUpdateFns.onAttach = [this](long stageId) { m_stageId = stageId; // Prepare for stage - but don't load physics yet }; m_stageUpdateFns.onDetach = [this]() { m_stageId = 0; releaseAll(); }; m_stageUpdateFns.onUpdate = [this](float currentTime, float elapsedSecs, bool enableUpdate) { if (enableUpdate) { // Perform physics update update(elapsedSecs); } // Update other subsystems even if physics is disabled updateVisuals(); }; m_stageUpdateFns.onResume = [this](float currentTime) { m_isPlaying = true; storeInitialState(); // Store state for reset }; m_stageUpdateFns.onPause = [this]() { m_isPlaying = false; }; m_stageUpdateFns.onReset = [this]() { m_isPlaying = false; restoreInitialState(); // Restore to pre-play state }; m_stageUpdateFns.forceLoadPhysicsFromUSD = [this]() { // Create physics objects from the attached USD stage loadPhysicsFromStage(m_stageId); }; m_stageUpdateFns.releasePhysicsObjects = [this]() { // Release all physics objects but keep stage attached releasePhysicsObjects(); }; m_stageUpdateFns.startSimulation = [this]() { // Called when simulation begins // Store initial transforms for reset functionality storeInitialTransforms(); }; m_stageUpdateFns.resetSimulation = [this]() { // Reset simulation state while keeping stage attached releasePhysicsObjects(); loadPhysicsFromStage(m_stageId); }; } StageUpdateFns getStageUpdateFns() const { return m_stageUpdateFns; } private: StageUpdateFns m_stageUpdateFns; long m_stageId = 0; bool m_isPlaying = false; void releaseAll() { /* ... */ } void update(float dt) { /* ... */ } void updateVisuals() { /* ... */ } void storeInitialState() { /* ... */ } void restoreInitialState() { /* ... */ } void loadPhysicsFromStage(long stageId) { /* ... */ } void releasePhysicsObjects() { /* ... */ } void storeInitialTransforms() { /* ... */ } }; ``` ``` -------------------------------- ### Create a PhysicsScene prim Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/simulation_control/simulation_control.html Demonstrates how to retrieve the current USD stage and define a new PhysicsScene prim. ```python import omni.usd from pxr import UsdPhysics stage = omni.usd.get_context().get_stage() # Physics scene definition scene = UsdPhysics.Scene.Define(stage, "/physicsScene") ``` -------------------------------- ### Create and Destroy a Rigid Body with Python Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/rigid_bodies_articulations/rigid_bodies.html Demonstrates how to apply the UsdPhysics.RigidBodyAPI to a UsdGeom.Xformable prim and subsequently remove the prim from the stage. ```python from pxr import Usd, UsdGeom, UsdPhysics, Gf import omni.usd # Create a stage omni.usd.get_context().new_stage() stage = omni.usd.get_context().get_stage() # Define the root Xform (transformable object) rootxform = UsdGeom.Xform.Define(stage, "/World") # Create an xformable rigidBodyPath = "/World/rigidBody" rigidBodyXform = UsdGeom.Xform.Define(stage, rigidBodyPath) rigidBodyPrim = rigidBodyXform.GetPrim() # Apply RigidBodyAPI to the xformable rigidBodyAPI = UsdPhysics.RigidBodyAPI.Apply(rigidBodyPrim) # Remove the rigid body stage.RemovePrim(rigidBodyPath) ``` -------------------------------- ### set_physics_volume_deformable_body Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/runtime/source/omni.physx/docs/api/python.html Setup a volume deformable body based on a UsdGeom.TetMesh at prim_path on stage and add necessary prims and APIs. For hierarchical setups use create_auto_volume_deformable_hierarchy. ```APIDOC ## set_physics_volume_deformable_body ### Description Setup a volume deformable body based on a UsdGeom.TetMesh at prim_path on stage and add necessary prims and APIs. For hierarchical setups use create_auto_volume_deformable_hierarchy. ### Signature ```python omni.physx.scripts.deformableUtils.set_physics_volume_deformable_body( stage, prim_path: Path ) -> bool ``` ### Parameters - **stage** - Required - The stage - **prim_path** (Path) - Required - Path to UsdGeom.TetMesh 'sim mesh' to which the UsdPhysics.DeformableBodyAPI is applied to. ### Returns - **bool** - True / False that indicates success of schema application ``` -------------------------------- ### set_physics_surface_deformable_body Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/runtime/source/omni.physx/docs/api/python.html Setup a surface deformable body based on a UsdGeom.Mesh at prim_path on stage and add necessary prims and APIs. For hierarchical setups use create_auto_surface_deformable_hierarchy. ```APIDOC ## set_physics_surface_deformable_body ### Description Setup a surface deformable body based on a UsdGeom.Mesh at prim_path on stage and add necessary prims and APIs. For hierarchical setups use create_auto_surface_deformable_hierarchy. ### Signature ```python omni.physx.scripts.deformableUtils.set_physics_surface_deformable_body( stage, prim_path: Path ) -> bool ``` ### Parameters - **stage** - Required - The stage - **prim_path** (Path) - Required - Path to UsdGeom.Mesh 'sim mesh' to which the UsdPhysics.DeformableBodyAPI is applied to. ### Returns - **bool** - True / False that indicates success of schema application ``` -------------------------------- ### Create a Cone Collider with UsdPhysics.CollisionAPI Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/rigid_bodies_articulations/collision.html Demonstrates initializing a stage and defining a cone geometry prim with the CollisionAPI applied. ```python from pxr import Usd, UsdGeom, UsdPhysics, Gf import omni.usd # Create a stage omni.usd.get_context().new_stage() stage = omni.usd.get_context().get_stage() # Define the root Xform (transformable object) rootxform = UsdGeom.Xform.Define(stage, "/World") conePath = "/World/cone" coneRadius = 1.0 coneHeight = 10.0 coneAxis = UsdGeom.Tokens.y coneGeom = UsdGeom.Cone.Define(stage, conePath) coneGeom.AddTranslateOp().Set(Gf.Vec3f(0.0)) coneGeom.AddOrientOp().Set(Gf.Quatf(1.0)) coneGeom.CreateRadiusAttr(coneRadius) coneGeom.CreateHeightAttr(coneHeight) coneGeom.CreateAxisAttr(coneAxis) conePrim = coneGeom.GetPrim() UsdPhysics.CollisionAPI.Apply(conePrim) ``` -------------------------------- ### Python - is_capable_of_simulating Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Python example demonstrating how to use the is_capable_of_simulating function to check if a simulation supports specific USD schema types. ```APIDOC ## Python - is_capable_of_simulating ### Description Checks whether a registered simulation can simulate specific USD schema types or schema APIs. ### Method is_capable_of_simulating ### Signature success, capabilities = simulation.is_capable_of_simulating(sim_id, schema_names) ### Parameters - **sim_id** (SimulationId) - Required - The ID of the registered simulation to check. - **schema_names** (list of str) - Required - List of schema type names to check. ### Return Value - **success** (bool) - True if the capability check was successful; False if the capability check is not available for the simulation. - **capabilities** (list of bool) - List where each element indicates whether the corresponding schema is supported. ### Example ```python from omni.physics.core import ( get_physics_interface, get_physics_simulation_interface ) # Get interfaces physics = get_physics_interface() simulation = get_physics_simulation_interface() # Get a registered simulation ID simulation_ids = physics.get_simulation_ids() if simulation_ids: sim_id = simulation_ids[0] # Check single schema capability schema_names = ["PhysicsRigidBodyAPI"] success, capabilities = simulation.is_capable_of_simulating(sim_id, schema_names) if success: if capabilities[0]: print("Simulation supports PhysicsRigidBodyAPI") else: print("Simulation does not support PhysicsRigidBodyAPI") else: print("Capability check not available for this simulation") # Check multiple schemas at once schema_names = [ "PhysicsRigidBodyAPI", "PhysicsCollisionAPI", "PhysicsMassAPI", "PhysicsJoint" ] success, capabilities = simulation.is_capable_of_simulating(sim_id, schema_names) if success: for schema, is_capable in zip(schema_names, capabilities): status = "supported" if is_capable else "not supported" print(f"{schema}: {status}") # Practical example: Check stage compatibility def check_stage_compatibility(stage, simulation_id): """Check if a simulation can handle all schemas in a stage""" from pxr import Usd # Collect all unique schema types from stage schema_names = set() for prim in stage.Traverse(): if prim.HasAPI("PhysicsRigidBodyAPI"): schema_names.add("PhysicsRigidBodyAPI") if prim.HasAPI("PhysicsCollisionAPI"): schema_names.add("PhysicsCollisionAPI") if prim.HasAPI("PhysicsMassAPI"): schema_names.add("PhysicsMassAPI") # Add more schema checks as needed if not schema_names: return True, [] # No physics schemas in stage # Check capabilities success, capabilities = simulation.is_capable_of_simulating( simulation_id, list(schema_names)) if not success: return False, [] # Capability check not available # Find unsupported schemas unsupported = [ schema for schema, capable in zip(schema_names, capabilities) if not capable ] return len(unsupported) == 0, unsupported ``` ``` -------------------------------- ### Simplify setup with deformableUtils.set_physics_volume_deformable_body Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/deformables/deformable_bodies.html Uses the omni.physx.scripts.deformableUtils helper to set up a volume deformable body, then applies customizations such as mass, disableGravity, and contact/rest offsets. Requires the create_simulation_tetmesh function. ```python from pxr import Usd, UsdGeom, Vt, Gf, UsdPhysics, PhysxSchema import omni.usd from omni.physx.scripts import deformableUtils stage = omni.usd.get_context().get_stage() tetMesh = create_simulation_tetmesh(stage, "/World/TetMesh", add_surface=True) prim = tetMesh.GetPrim() # Call deformableUtils helper success = deformableUtils.set_physics_volume_deformable_body(stage, prim.GetPath()) # Apply customizations if (prim.HasAPI("OmniPhysicsDeformableBodyAPI")): prim.GetAttribute("omniphysics:mass").Set(30.0) prim.ApplyAPI("PhysxBaseDeformableBodyAPI") if (prim.HasAPI("PhysxBaseDeformableBodyAPI")): prim.GetAttribute("physxDeformableBody:disableGravity").Set(True) physxCollisionAPI = PhysxSchema.PhysxCollisionAPI.Apply(prim) if (physxCollisionAPI): physxCollisionAPI.GetContactOffsetAttr().Set(0.02) physxCollisionAPI.GetRestOffsetAttr().Set(0.01) ``` -------------------------------- ### get_translation() Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/runtime/source/omni.physx/docs/api/python.html Gets the translation of a prim. ```APIDOC ## get_translation() ### Description Gets the translation of a prim. ``` -------------------------------- ### Create and step an independent stage with Fabric output Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/simulation_control/simulation_control.html Demonstrates creating a stage, attaching it to PhysX and Fabric interfaces, and manually stepping the simulation. ```python from pxr import Usd, UsdGeom, UsdPhysics, UsdShade, Sdf, Gf, Tf, UsdUtils from omni.physx import get_physx_simulation_interface from omni.physxfabric import get_physx_fabric_interface from omni.physx.bindings._physx import SETTING_UPDATE_TO_USD manager = omni.kit.app.get_app().get_extension_manager() manager.set_extension_enabled_immediate("omni.physx.fabric", True) # Setup physics to not output to USD settings = carb.settings.get_settings() settings.set(SETTING_UPDATE_TO_USD, False) # Create new stage stage = Usd.Stage.CreateInMemory() # Add stage to the cache, this is required in order to get stage Id cache = UsdUtils.StageCache.Get() cache.Insert(stage) stage_id = cache.GetId(stage).ToLongInt() # Physics scene definitions scene = UsdPhysics.Scene.Define(stage, "/physicsScene") # Create a rigid bodies cube = UsdGeom.Cube.Define(stage, "/cube") UsdPhysics.RigidBodyAPI.Apply(cube.GetPrim()) UsdPhysics.CollisionAPI.Apply(cube.GetPrim()) # Attach the stage to omni.physx and omni.physx.fabric get_physx_simulation_interface().attach_stage(stage_id) get_physx_fabric_interface().attach_stage(stage_id) # Step simulation few times for i in range(0, 40): # Simulate, by provided delta and current time, the current time is used to update for example kinematic bodies with time sampled data # The provided delta time is passed directly to PhysX SDK no substepping happens # Note that this is not a blocking call, separate thread will get executed get_physx_simulation_interface().simulate(1/60.0, 40 * 1/60 + i * 1/60) # Fetch results will wait for simulation to finish get_physx_simulation_interface().fetch_results() # Update the omni.physx.fabric extension and update Fabric output get_physx_fabric_interface().update(1/60.0, 40 * 1/60 + i * 1/60) # Detach stage from omni.physx and omni.physx.fabric get_physx_fabric_interface().detach_stage() get_physx_simulation_interface().detach_stage() # Remove the stage from the cache cache = UsdUtils.StageCache.Get() cache.Erase(stage) settings.set(SETTING_UPDATE_TO_USD, True) ``` -------------------------------- ### getNumSimulations() Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Gets the count of registered simulations. ```APIDOC ## getNumSimulations() ### Description Gets the count of registered simulations. ### Method getNumSimulations ### Returns - **size_t** - The number of registered simulations. ### Example (C++) ```cpp size_t numSimulations = physics->getNumSimulations(); ``` ### Example (Python) ```python num_simulations = physics.get_num_simulations() ``` ``` -------------------------------- ### getSimulationName() Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Gets the simulation name by ID. ```APIDOC ## getSimulationName() ### Description Gets the simulation name by ID. ### Method getSimulationName ### Parameters - **simulationId** (SimulationId) - Required - The ID of the simulation. ### Returns - **const char*** - The name of the simulation. ### Example (C++) ```cpp const char* name = physics->getSimulationName(simId); ``` ### Example (Python) ```python name = physics.get_simulation_name(sim_id) ``` ``` -------------------------------- ### Create and Configure Kinematic Rigid Bodies Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/rigid_bodies_articulations/rigid_bodies.html Demonstrates how to define a stage, create Xform primitives, and apply the UsdPhysics.RigidBodyAPI to toggle kinematic behavior. ```python from pxr import Usd, UsdGeom, UsdPhysics, Gf import omni.usd # Create a stage omni.usd.get_context().new_stage() stage = omni.usd.get_context().get_stage() # Define the root Xform (transformable object) rootxform = UsdGeom.Xform.Define(stage, "/World") rigidBodyPaths = ["/World/rigidBody0", "/World/rigidBody1"] enableKinematic = [False, True] for i in range(2): rigidBodyXform = UsdGeom.Xform.Define(stage, rigidBodyPaths[i]) rigidBodyPrim = rigidBodyXform.GetPrim() rigidBodyAPI = UsdPhysics.RigidBodyAPI.Apply(rigidBodyPrim) if enableKinematic[i]: rigidBodyAPI.CreateKinematicEnabledAttr(True) isKinematic = rigidBodyAPI.GetKinematicEnabledAttr().Get() print(f"i = {i}: Kinematic enabled is {isKinematic}") ``` -------------------------------- ### getSimulation() Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/physics_umbrella/physics_umbrella_runtime.html Gets the simulation structure by ID. ```APIDOC ## getSimulation() ### Description Gets the simulation structure by ID. ### Method getSimulation ### Parameters - **simulationId** (SimulationId) - Required - The ID of the simulation. ### Returns - **const Simulation*** - Pointer to the simulation structure, or nullptr if not found. ### Example (C++) ```cpp const Simulation* sim = physics->getSimulation(simId); ``` ### Example (Python) ```python sim = physics.get_simulation(sim_id) ``` ``` -------------------------------- ### Configure Rigid Body Mass Properties with UsdPhysics.MassAPI Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/rigid_bodies_articulations/rigid_bodies.html This Python snippet demonstrates how to create a rigid body and explicitly set its mass, moment of inertia, center of mass, and principal axes using the UsdPhysics.MassAPI. ```python from pxr import Usd, UsdGeom, UsdPhysics, Gf import omni.usd # Create a stage omni.usd.get_context().new_stage() stage = omni.usd.get_context().get_stage() # Define the root Xform (transformable object) rootxform = UsdGeom.Xform.Define(stage, "/World") rigidBodyPath = "/World/rigidBody" # Mass properties of the rigid body rigidBodyMass = 3.0 rigidBodyMomentOfInertia = Gf.Vec3f(2.0, 2.0, 2.0) rigidBodyCenterOfMass = Gf.Vec3f(0.0, 3.0, 0.0) rigidBodyPrincipalAxes = Gf.Quatf(Gf.Rotation(Gf.Vec3d(0.0, 0.0, 1.0), 90.0).GetQuat()) # Create a rigid body and set the mass distribution properties rigidBodyXform = UsdGeom.Xform.Define(stage, rigidBodyPath) rigidBodyXform.AddTranslateOp().Set(Gf.Vec3f(0.0)) rigidBodyXform.AddOrientOp().Set(Gf.Quatf(1.0)) rigidBodyPrim = rigidBodyXform.GetPrim() UsdPhysics.RigidBodyAPI.Apply(rigidBodyPrim) massAPI = UsdPhysics.MassAPI.Apply(rigidBodyPrim) massAPI.CreateMassAttr(rigidBodyMass) massAPI.CreateDiagonalInertiaAttr(rigidBodyMomentOfInertia) massAPI.CreateCenterOfMassAttr(rigidBodyCenterOfMass) massAPI.CreatePrincipalAxesAttr(rigidBodyPrincipalAxes) ``` -------------------------------- ### GetBody1Rel Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/schemas/usdphysics.html Gets the body1 relationship, which is a relationship to any UsdGeomXformable. ```APIDOC ## GetBody1Rel ### Description Gets the body1 relationship, which is a relationship to any UsdGeomXformable. ### Method Get ### Returns UsdRelationship - The relationship. ``` -------------------------------- ### GetBody0Rel Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/schemas/usdphysics.html Gets the body0 relationship, which is a relationship to any UsdGeomXformable. ```APIDOC ## GetBody0Rel ### Description Gets the body0 relationship, which is a relationship to any UsdGeomXformable. ### Method Get ### Returns UsdRelationship - The relationship. ``` -------------------------------- ### UsdPhysicsGetNextIndex3() Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/dev_guide/schemas/usdphysics.html Utility function to get the next index in a 3-index sequence. ```APIDOC ## UsdPhysicsGetNextIndex3() ### Description Utility function to get the next index in a 3-index sequence. ### Function Signature UsdPhysicsGetNextIndex3() ### Parameters None documented. ### Returns Not documented. ``` -------------------------------- ### setup_transform_as_scale_orient_translate() Source: https://docs.omniverse.nvidia.com/kit/docs/omni_physics/latest/extensions/runtime/source/omni.physx/docs/api/python.html Sets up a transform as scale, orient, translate. ```APIDOC ## setup_transform_as_scale_orient_translate() ### Description Sets up a transform as scale, orient, translate. ```