Physics Schemas
Physics behavior in a USD scene is described by schemas: typed sets of
attributes and relationships applied to prims. ovphysx loads and simulates scenes
authored with these schemas. This page explains the schema layers ovphysx
understands and how to make the PhysX-specific ones available when you author
with a stock usd-core.
Schema Layers
USD Physics Schema (UsdPhysics) — the standard OpenUSD schema for
annotating assets with physics: PhysicsScene, PhysicsRigidBodyAPI,
PhysicsCollisionAPI, PhysicsMassAPI, PhysicsMaterialAPI, the joint types,
and articulation APIs. It ships with stock usd-core and has typed Python
bindings, for example UsdPhysics.RigidBodyAPI.Apply(prim). Refer to the
OpenUSD UsdPhysics reference.
PhysX Schema (Physx*, codeless) — extends UsdPhysics with PhysX-specific
functionality and tuning: PhysxSceneAPI (solver, GPU settings),
PhysxRigidBodyAPI (CCD, sleep, stabilization), PhysxCollisionAPI (contact
and rest offsets), PhysxForceAPI, joint extensions such as
PhysxJointAxisAPI (refer to
Joints), deformable extensions
(refer to Deformables), and more. ovphysx ships
this schema as codeless artifacts (plugInfo.json plus generatedSchema.usda,
no compiled library).
Omni Physics Deformable Schema (codeless) — extends UsdPhysics with
deformable bodies (OmniPhysicsDeformableBodyAPI and friends). Refer to
Deformables.
The complete attribute set for each schema — types, defaults, and allowed values
— is authoritative in the schema definitions themselves and is rendered in the
Omni Physics documentation
and the OpenUSD UsdPhysics reference.
This guide describes intent, not full attribute definitions, so the two do not
drift.
How ovphysx Ships the PhysX Schemas
ovphysx exposes the PhysX USD schemas as codeless artifacts: a
plugInfo.json (Type: resource) plus a generatedSchema.usda per module, with
no compiled library. Codeless schemas carry no typed helper class — there is no
PhysxSchema.PhysxRigidBodyAPI binding. You apply them by identifier and author
their attributes generically.
Because they are codeless, the core UsdPhysics typed APIs (rigid body,
collider, mass, scene) work out of the box with stock usd-core, while
Physx* attributes require registering the codeless schemas first.
Making Schemas Available
There are two registration paths, depending on which USD runtime is in play.
ovphysx’s bundled USD runtime
When you run the simulator, ovphysx uses its bundled OV namespaced USD runtime.
Importing ovphysx automatically calls register_schema_paths(), which appends
ovphysx’s schema plugin path to OV_PXR_PLUGINPATH_2511 before the first USD
stage open. In a process that mixes ovphysx with another USD-aware subsystem
(for example ovrtx), call register_schema_paths() (and the peer subsystem’s
equivalent) explicitly before the first stage open so USD’s schema registry sees
every plugin root. See the USD coexistence notes in the
Overview.
Authoring with a stock usd-core
The codeless PhysX USD schemas shipped in ovphysx can be registered with any USD
runtime — including stock usd-core from PyPI — without starting the simulator.
This is useful for offline authoring, validation, and non-interactive tooling:
import sys
import ovphysx
try:
from pxr import Plug, Tf, Usd
except ImportError:
# Stock usd-core has no wheel for some platforms (e.g. linux-aarch64). The
# codeless schemas still ship in the wheel; there is simply no stock USD
# runtime to register them into here, so skip rather than fail.
print("usd-core is not available on this platform; skipping codeless schema demo.")
sys.exit(0)
def main() -> int:
print("ovphysx version:", ovphysx.__version__)
# Discover the codeless PhysX USD schema packages bundled with ovphysx.
# Each path is a resources/ directory holding a codeless plugInfo.json
# (Type=resource) and generatedSchema.usda -- no compiled library.
schema_paths = ovphysx.codeless_schema_paths()
print("Codeless schema packages:")
for path in schema_paths:
print(" ", path)
# Register them with the stock usd-core runtime.
registry = Plug.Registry()
registered = []
for path in schema_paths:
registered.extend(registry.RegisterPlugins(str(path)))
registered_names = sorted(plugin.name for plugin in registered)
print("Registered USD plugins:", registered_names)
assert "physxSchema" in registered_names, registered_names
assert "omniUsdPhysicsDeformableSchema" in registered_names, registered_names
# Codeless schemas carry no compiled C++/Python bindings, so apply API
# schemas by their schema identifier and query with the generic USD API.
stage = Usd.Stage.CreateInMemory()
prim = stage.DefinePrim("/World/Box", "Cube")
assert prim.ApplyAPI("PhysxRigidBodyAPI"), "failed to apply PhysxRigidBodyAPI"
assert prim.ApplyAPI("PhysxCollisionAPI"), "failed to apply PhysxCollisionAPI"
rigid_body_type = Tf.Type.FindByName("PhysxSchemaPhysxRigidBodyAPI")
assert rigid_body_type != Tf.Type.Unknown, "PhysxRigidBodyAPI not in schema registry"
assert prim.HasAPI(rigid_body_type), "prim is missing PhysxRigidBodyAPI after apply"
print("Applied API schemas:", list(prim.GetAppliedSchemas()))
print("Codeless PhysX schema registration succeeded.")
return 0
if __name__ == "__main__":
sys.exit(main())
After registration, apply the PhysX APIs by identifier and set attributes with
USD’s generic attribute API:
from pxr import Sdf
prim.ApplyAPI("PhysxRigidBodyAPI")
prim.CreateAttribute("physxRigidBody:disableGravity", Sdf.ValueTypeNames.Bool).Set(True)
codeless_schema_paths() returns the per-module resources directories, and
codeless_schema_root() returns the directory that holds them. Both are
pure-Python and never trigger native loading, so they are safe to use in an
authoring-only process.
Authoring Routes
The same physics content can be authored two ways; both produce a .usda/.usd
file that ovphysx loads identically.
Hand-authored .usda text. Apply schemas through the apiSchemas
metadata list and set attributes directly. No Python or schema registration
needed to write the file:
def Cube "box" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysxRigidBodyAPI", "PhysicsCollisionAPI"]
)
{
bool physxRigidBody:disableGravity = 0
}
Python with a USD runtime. Use typed UsdPhysics bindings for core
schemas and the codeless ApplyAPI pattern above for Physx* schemas.
Common pitfall. Using a typed PhysxSchema.* class instead of the codeless
prim.ApplyAPI("Physx...") pattern silently no-ops with stock usd-core —
there is no compiled PhysxSchema module. Register the codeless schemas and
apply by identifier.
For a hands-on authoring walkthrough (scene, ground, rigid body, colliders), see
the bundled ovphysx-usd-authoring skill and the per-topic pages under
Simulation Setup.