Readable data#
The inventory of every quantity readable through the read API, per object type.
Every table lists the readable attributes for one object type.
dtype × lanes is the element type and tuple width; Residency is device (kDLCUDA on a
DirectGPU scene, kDLCPU on CPU) or host (always kDLCPU). Quaternions are xyzw.
Rigid bodies#
Standalone bodies (RIGID_BODY) emit a fixed group, one row per body:
Attribute |
Meaning |
dtype × lanes |
Frame |
Units |
Residency / validity |
|---|---|---|---|---|---|
|
body position |
f32 × 3 |
world |
length |
device |
|
rotation |
f32 × 4 |
world |
— |
device |
|
COM linear velocity |
f32 × 3 |
world |
length/s |
device |
|
angular velocity |
f32 × 3 |
world |
rad/s |
device |
|
linear acceleration |
f32 × 3 |
world |
length/s² |
device |
|
angular acceleration |
f32 × 3 |
world |
rad/s² |
device |
|
body mass |
f32 × 1 |
— |
mass |
host |
|
1/mass |
f32 × 1 |
— |
1/mass |
host |
|
inertia tensor |
f32 × 9 |
COM |
mass·length² |
host |
|
inverse inertia |
f32 × 9 |
COM |
— |
host |
|
COM offset |
f32 × 3 |
body |
length |
host |
|
COM frame rotation |
f32 × 4 |
body |
— |
host |
|
gravity-off flag |
u8 × 1 |
— |
bool |
host |
|
excluded-from-sim flag |
u8 × 1 |
— |
bool |
host |
|
current sleep state: 1 asleep, 0 awake (read-only) |
u8 × 1 |
— |
bool |
host |
|
per-shape static friction |
f32 × per-shape |
— |
— |
host |
|
per-shape dynamic friction |
f32 × per-shape |
— |
— |
host |
|
per-shape restitution |
f32 × per-shape |
— |
— |
host |
|
per-shape contact offset |
f32 × per-shape |
— |
length |
host |
|
per-shape rest offset |
f32 × per-shape |
— |
length |
host |
|
real shapes per row |
i32 × 1 |
— |
count |
host |
|
pending kinematic target position (else the body’s pose) |
f32 × 3 |
world |
length |
host |
|
pending kinematic target rotation (else the body’s pose) |
f32 × 4 |
world |
— |
host |
Per-shape columns are padded to the widest queried body’s shape count (varies per read — do not
cache); read shapeCount for the real length. A shape with several materials reports only its first
(material 0). On DirectGPU, disabled (eDISABLE_SIMULATION) bodies are omitted from fixed columns
while discovery keeps the full count.
kinematicTargetPosition / kinematicTargetOrientation return the pending kinematic target of a
kinematic body; a body with no target set (non-kinematic, or an undriven kinematic body) falls back
to its current world pose. They are host-authoritative and readable on a DirectGPU scene — read
position / orientation for a device-fresh pose.
isSleeping reports PhysX state when the read executes, independently of the last wake
command. Use ALL scope to inspect sleeping bodies; ACTIVE is a selection of bodies that
were active, not a sleep-state query. Zero velocity alone does not prove that a body is asleep.
On CPU and GPU scenes with CPU readback, dynamic bodies report their live state. Kinematic bodies report PhysX’s kinematic sleep state: setting a target wakes them, and they sleep after two consecutive simulation steps without a new target. Simulation-disabled bodies are included on these modes and report asleep when scene sleeping is enabled.
On scenes with
eDISABLE_SLEEPING, including DirectGPU, every emitted value is0because the scene disables sleeping. This follows PhysX’s reported state even for a disabled body on a CPU/readback scene; usedisableSimulationto determine whether it participates in simulation. This does not enablewakewrites on DirectGPU.DirectGPU keeps its existing selection rules: no groups before the first completed step, and no rows for simulation-disabled bodies. A missing row is not an awake value.
The host column is a read-session snapshot. Complete preceding simulation work before reading; a later step or write requires a new read to observe the changed state. Retained snapshots keep their original values under the usual read-buffer lifetime rules.
isSleeping has no point-instancer array form and is not emitted for whole-articulation,
vehicle-wheel, deformable, particle or tendon queries.
Point-instancer instances read only the state attributes listed below, as an array group (one tensor per instancer, indexed by instance slot, holes zero-filled) under different names. The property and per-shape columns have no instancer form.
Standalone |
Instancer array |
Frame |
|---|---|---|
|
|
instancer-local |
|
|
instancer-local |
|
|
world |
|
|
world |
|
|
world |
|
|
world |
Articulation links#
Articulation links (ARTICULATION_LINK) are rigid bodies, so they read the full rigid-body attribute set, plus one link-only column:
Attribute |
Meaning |
dtype × lanes |
Frame |
Units |
Residency |
|---|---|---|---|---|---|
|
link position |
f32 × 3 |
world |
length |
device |
|
link rotation |
f32 × 4 |
world |
— |
device |
|
COM linear velocity |
f32 × 3 |
world |
length/s |
device |
|
angular velocity |
f32 × 3 |
world |
rad/s |
device |
|
linear acceleration |
f32 × 3 |
world |
length/s² |
device |
|
angular acceleration |
f32 × 3 |
world |
rad/s² |
device |
|
link mass |
f32 × 1 |
— |
mass |
host |
|
1/mass |
f32 × 1 |
— |
1/mass |
host |
|
inertia tensor |
f32 × 9 |
COM |
mass·length² |
host |
|
inverse inertia |
f32 × 9 |
COM |
— |
host |
|
COM offset |
f32 × 3 |
body |
length |
host |
|
COM frame rotation |
f32 × 4 |
body |
— |
host |
|
gravity-off flag |
u8 × 1 |
— |
bool |
host |
|
excluded-from-sim flag |
u8 × 1 |
— |
bool |
host |
|
current sleep state: 1 asleep, 0 awake (read-only) |
u8 × 1 |
— |
bool |
host |
|
per-shape static friction |
f32 × per-shape |
— |
— |
host |
|
per-shape dynamic friction |
f32 × per-shape |
— |
— |
host |
|
per-shape restitution |
f32 × per-shape |
— |
— |
host |
|
per-shape contact offset |
f32 × per-shape |
— |
length |
host |
|
per-shape rest offset |
f32 × per-shape |
— |
length |
host |
|
real shapes per row |
i32 × 1 |
— |
count |
host |
|
spatial force the inbound joint exerts on the link |
f32 × 6 (force xyz, torque xyz) |
joint |
force / torque |
device |
|
world pose fallback (a link cannot be a kinematic target) |
f32 × 3 |
world |
length |
host |
|
world pose fallback (a link cannot be a kinematic target) |
f32 × 4 |
world |
— |
host |
|
borrowed |
u64 × 1 |
— |
— |
host |
For isSleeping, every link reports the state of its owning articulation. Links do not
sleep independently; this read does not make per-link wake writes valid.
Character controllers#
CHARACTER_CONTROLLER has no readable columns. The controller prim is a row of
RIGID_BODY position and orientation: the backing kinematic actor’s global
pose. That orientation includes the capsule-axis rotation and is not the
fixup-corrected orientation written back to the prim. move updates the controller
and its kinematic target immediately; that rigid-body pose changes on the next
simulation step, when the target is integrated.
SDF shapes#
SDF_SHAPE has no readable columns. Evaluate the shapes’ signed distance fields at
your own points with ovphysx_evaluate_sdf_shapes; see SDF shapes.
Whole articulations#
Whole articulations (ARTICULATION) emit one fixed group with one row per articulation in root-record order. Inverse dynamics columns are
cohort-partitioned.
Attribute |
Meaning |
dtype × lanes |
Frame |
Units |
Residency |
|---|---|---|---|---|---|
|
root-link position |
f32 × 3 |
world |
length |
device |
|
root-link rotation |
f32 × 4 |
world |
— |
device |
|
root linear velocity |
f32 × 3 |
world |
length/s |
device |
|
root angular velocity |
f32 × 3 |
world |
rad/s |
device |
|
articulation COM |
f32 × 3 |
world |
length |
device |
|
articulation COM |
f32 × 3 |
root-link COM |
length |
device |
|
per-shape (all links) |
f32 × per-shape |
— |
— |
host |
|
total shapes across links |
i32 × 1 |
— |
count |
host |
|
degrees of freedom |
i32 × 1 |
— |
count |
host |
|
articulation links (not standalone rigid bodies) |
i32 × 1 |
— |
count |
host |
|
inter-link joints |
i32 × 1 |
— |
count |
host |
|
fixed tendons on this articulation |
i32 × 1 |
— |
count |
host |
|
spatial tendons on this articulation |
i32 × 1 |
— |
count |
host |
|
1 = fixed base, 0 = floating |
i32 × 1 |
— |
— |
host |
|
owning joint prim for each DOF column (interned prim-path handle; |
u64 × dofCount (padded) |
— |
— |
host |
|
each DOF’s ordinal among its joint’s unlocked axes |
i32 × dofCount (padded) |
— |
— |
host |
|
dense Jacobian |
f32 × rows·cols |
— |
angular in radians |
device |
|
(rows, cols) of |
i32 × 2 |
— |
count |
host |
|
generalized mass matrix |
f32 × M·M |
— |
— |
device |
|
Coriolis + centrifugal compensation |
f32 × M |
— |
— |
device |
|
gravity compensation |
f32 × M |
— |
— |
device |
|
centroidal momentum matrix (floating-base only; a fixed-base articulation contributes no row) |
f32 × 6·(numDofs+7) |
— |
— |
device |
|
borrowed |
u64 × 1 |
— |
— |
host |
Root state and centerOfMassWorld are in scene-world coordinates; centerOfMassLocal is in the root
link’s COM frame — place it in the world with the root’s mass-frame pose, not its actor/prim pose
(the two differ when the root has a non-identity mass pose).
The six int32 topology scalars — dofCount, linkCount, jointCount, fixedTendonCount,
spatialTendonCount and isFixedBase — replace the deprecated ovphysx_get_articulation_metadata
field-for-field. They are host-resident on every device like shapeCount (read from host-side
articulation state, so no device copy is needed) and emitted in the one scene-wide group even when base
type varies per row. isFixedBase reflects the live base flag, so a runtime
setArticulationFlag(eFIX_BASE, …) toggle is visible on the next read. The tendon counts are per
articulation, not the view-wide maxima the deprecated getter reported; linkCount counts
articulation links (the old struct’s
mislabelled body_count), not standalone rigid bodies; and isFixedBase is an int32 0/1 flag.
The dofJointPath / dofAxisIndex descriptor is the non-binding successor to the DOF / body / joint
name lists: each is a padded per-DOF array (host-resident, one row per articulation, in cache-DOF
order) that maps inverse-dynamics column (isFixedBase ? 0 : 6) + k to its owning joint prim — an
interned prim-path handle, resolved through the attached Stage’s path dictionary like prims.list (0 pads) — and to
that DOF’s ordinal among the joint’s unlocked axes. Link and joint names are then the leaf of the
kOvxArticulationLink / kOvxArticulationJoint prim read by ovphysx_read. Limitation: only
DOF-bearing joints appear — a fully-locked (zero-DOF) joint has no read group or descriptor entry, so its
name/path is not recoverable through the read API; the deprecated ovphysx_articulation_get_joint_names
still lists those fixed joints.
Note. A group’s tuple width is a 16-bit field, so a single inverse dynamics column wider than 65 535 (roughly a 64-link / 189-DOF articulation’s Jacobian, or a mass matrix past M ≈ 256) is omitted for that cohort. The read succeeds, other supported columns remain available, and the optional summary reports
OVPHYSX_READ_OMISSION_UNSUPPORTED_CONFIGURATIONfor the affected request.
Articulation joints — DOFs#
Articulation joints (ARTICULATION_JOINT) emit an array group with one tensor per joint prim. Each
tensor has one row per unlocked axis, in PxArticulationAxis order — one value per row
(dtype.lanes is 1), except jointLimit, whose row is the (low, high) pair (dtype.lanes is 2).
Don’t confuse the axis count (the tensor’s shape) with lanes. A read may ask for state, control, or
properties in any combination. Rotational axes carry the joint’s body-order sign; angular DOF
quantities are in degrees (as USD-authored).
Note. A requested attribute produces one array group whose
tensors[i]holds joint i’s axis values — not one group per joint. Code that readstensors[0]and advances to the next group sees only the first joint, and does so silently on a single-joint scene.
State / control (device on DirectGPU):
Attribute |
Meaning |
dtype × lanes |
Units |
|---|---|---|---|
|
generalized position |
f32 × 1 |
deg / length |
|
generalized velocity |
f32 × 1 |
deg/s / length/s |
|
drive position target |
f32 × 1 |
deg / length |
|
drive velocity target |
f32 × 1 |
deg/s / length/s |
|
applied actuation effort |
f32 × 1 |
force / torque |
|
inbound joint force on this axis |
f32 × 1 |
force / torque (read-only, derived) |
Properties (authoring inputs — host-resident even on DirectGPU):
Attribute |
Meaning |
dtype × lanes |
Units |
|---|---|---|---|
|
drive effort per unit position error |
f32 × 1 |
effort/coord |
|
drive effort per unit rate error |
f32 × 1 |
effort/rate |
|
(low, high) motion limit |
f32 × 2 |
degrees / length; |
|
joint rate bound |
f32 × 1 |
USD rate |
|
drive effort bound |
f32 × 1 |
force |
|
added rotor inertia |
f32 × 1 |
inertia |
|
break-away / sliding effort |
f32 × 1 |
effort |
|
effort per unit rate |
f32 × 1 |
effort/rate |
|
drive-envelope rate per effort |
f32 × 1 |
USD |
|
actuator rate bound |
f32 × 1 |
USD rate |
|
envelope resistance per rate |
f32 × 1 |
effort/rate |
|
0 none / 1 force / 2 accel |
u8 × 1 |
enum |
|
borrowed |
u64 × 1 |
— |
jointLimit is reported as the authored (lower, upper) pair, in order, regardless of the joint’s
body order — unlike jointPosition, which negates when body0 is the child.
jointProjectedForce and linkIncomingJointForce (on articulation links) are computed per read
rather than gathered from stored state, so each costs several times a four-column pose/velocity read
of the same prims — request them in the read that needs them, not in a per-step pose read.
jointProjectedForce uses the same one-row-per-unlocked-axis shape as the other joint columns: a
locked axis is omitted (not a zero-filled row), and a fixed joint — which has no DOF — contributes
no row.
Whole vehicles#
Whole vehicles (VEHICLE) emit fixed, host-resident groups with one row per vehicle prim.
The chassis pose and velocity use a separate RIGID_BODY query on that same prim; wheel
attachments use VEHICLE_WHEEL. Vehicles are unavailable on DirectGPU scenes.
Attribute |
Meaning |
dtype x lanes |
Units |
Applicability |
|---|---|---|---|---|
|
persistent accelerator input |
f32 x 1 |
normalized [0,1] |
DriveBasic / DriveStandard |
|
persistent brake-channel input |
f32 x 1 |
normalized [0,1] |
DriveBasic / DriveStandard |
|
persistent steering input |
f32 x 1 |
normalized [-1,1] |
DriveBasic / DriveStandard |
|
native clutch command state |
f32 x 1 |
normalized [0,1] |
DriveStandard |
|
engaged gear |
i32 x 1 |
gear index |
DriveStandard |
|
internal transmission target, distinct from the requested control |
i32 x 1 |
gear index |
DriveStandard |
|
engine angular speed |
f32 x 1 |
rad/s |
DriveStandard |
|
automatic transmission enabled |
u8 x 1 |
boolean |
DriveStandard |
|
elapsed time in current gear change; negative when no change is active |
f32 x 1 |
seconds |
DriveStandard |
|
automatic-gearbox time since the last shift; zero without an autobox |
f32 x 1 |
seconds |
DriveStandard |
Gear indices use -1 for reverse, 0 for neutral and positive values for forward gears.
Before a recorded automatic shift, autoboxTimeSinceLastShift can hold the native float32-maximum
sentinel instead of an elapsed duration.
The readable controls use the same names as writes. An unconfigured brake channel reads zero;
writing it has no effect. requestedGear, tank thrust0 / thrust1, and resetToRestState are
write-only. targetGear reports the transmission’s internal state, not an echo of requestedGear.
Discovery lists readable attributes supported by at least one selected vehicle. Mixed reads emit
only applicable rows, with UNSUPPORTED_CONFIGURATION in the optional session summary for omitted
vehicles. Always use each group’s prim list: a Standard-only column can have fewer rows than a
control column. A disabled vehicle remains in ALL membership.
Vehicle wheels#
Vehicle wheels (VEHICLE_WHEEL) emit fixed, host-resident groups with one row per wheel attachment.
The wheel pose is composed from chassis, suspension and steering. Other columns report native
vehicle state from its latest update. Vehicles are unavailable on DirectGPU scenes.
Attribute |
Meaning |
dtype x lanes |
Frame / units |
|---|---|---|---|
|
composed wheel position |
f32 x 3 |
world; length |
|
composed wheel rotation, xyzw |
f32 x 4 |
world |
|
wheel angular speed |
f32 x 1 |
rad/s |
|
wheel rotation angle |
f32 x 1 |
radians |
|
actual wheel steering angle |
f32 x 1 |
radians |
|
suspension compression |
f32 x 1 |
length |
|
suspension force |
f32 x 3 |
world; force |
|
effective tire friction |
f32 x 1 |
dimensionless |
|
tire’s longitudinal direction |
f32 x 3 |
world; unit vector |
|
tire’s lateral direction |
f32 x 3 |
world; unit vector |
|
longitudinal slip |
f32 x 1 |
dimensionless ratio |
|
lateral slip |
f32 x 1 |
radians |
|
tire force |
f32 x 3 |
world; force |
|
validity of the current ground-contact sample |
u8 x 1 |
boolean |
|
contact plane |
f32 x 4 |
world; d in length |
|
contact hit position |
f32 x 3 |
world; length |
|
ground actor prim identity |
u64 x 1 |
attached Stage path dictionary |
|
ground shape prim identity |
u64 x 1 |
attached Stage path dictionary |
|
ground material prim identity |
u64 x 1 |
attached Stage path dictionary |
All these columns are read-only. The existing raw-wheel driveTorque, brakeTorque and
steerAngle controls are write-only; wheelSteerAngle is actual telemetry, separate from that
steering command.
isOnGround == 0 means no valid current contact sample. It does not prove that a sleeping vehicle
is physically airborne. Adding or removing any runtime object record in the owning attachment
invalidates contact data until the next completed vehicle update, even when the changed object
is unrelated to that contact. Before the first update and for sleeping or disabled vehicles,
contact data can also be invalid. In that case groundPlane,
groundHitPosition and all three ground identities are zero. Other telemetry retains its native
last-update state; it is not forcibly cleared when contact becomes invalid.
A ground identity is an ovx_primpath_t represented as uint64. Resolve it with the attached Stage’s
path dictionary, exactly as a group’s prim identities. Zero means absent or unrepresentable,
including an implicit default material. These values are not pointers or private object IDs.
Length, force and torque follow the stage’s units.
Deformable volumes / surfaces#
Deformable volumes / surfaces (DEFORMABLE_VOLUME, DEFORMABLE_SURFACE) emit an array group with one tensor per sim-mesh prim. GPU-only — with no CUDA context the read emits no
deformable groups.
Attribute |
Meaning |
dtype × lanes |
Frame |
Residency |
Applies to |
|---|---|---|---|---|---|
|
current nodal positions |
f32 × 3 |
sim-mesh-local |
device |
volume + surface |
|
nodal velocities |
f32 × 3 |
world |
device |
volume + surface |
|
rest nodal positions |
f32 × 3 |
sim-mesh-local |
host |
volume + surface |
|
sim-mesh connectivity |
i32 × 4 (tet) / 3 (tri) |
— |
host |
volume + surface |
|
collision-mesh connectivity |
i32 × 4 (tet) |
— |
host |
volume only |
|
pending sim-node kinematic target ( |
f32 × 4 |
sim-mesh-local |
device |
volume only |
A surface body’s simulation mesh is its collision mesh, so it has no separate
collisionElementIndices — discovery omits it for surfaces, and a surface query for it returns no
group.
kinematicTarget is served only for bodies actually being driven (through
setKinematicTargetBufferD); an undriven body contributes no tensor, so its group covers a subset of
the points prims. The .w lane is an active-flag with inverted polarity: w == 0 drives the
node to its xyz target, w != 0 leaves it free.
Note.
pointsandrestPointsshare the sim-mesh-local frame (their difference is meaningful), butvelocitiesis in world space. Do not differencepointsagainst a time-integratedvelocities.
Particle sets#
Particle sets (PARTICLE_SET) emit an array group with one tensor per particle-set prim. GPU-only.
Attribute |
Meaning |
dtype × lanes |
Frame |
Residency |
|---|---|---|---|---|
|
particle positions |
f32 × 3 |
particle-set-prim-local |
device |
|
particle velocities |
f32 × 3 |
world |
device |
|
borrowed particle-set address |
u64 × 1 |
— |
host |
positions is accepted as an alias and canonicalized to points in groups and session summaries;
discovery advertises only points. Requesting both spellings is a duplicate and fails the open.
Fixed / spatial tendons#
Fixed / spatial tendons (FIXED_TENDON, SPATIAL_TENDON) emit a fixed group with one row per tendon-root prim. Authoring values, but device-resident on GPU /
host on CPU.
Attribute |
Meaning |
dtype × lanes |
Fixed |
Spatial |
|---|---|---|---|---|
|
stiffness |
f32 × 1 |
yes |
yes |
|
damping |
f32 × 1 |
yes |
yes |
|
limit-region stiffness |
f32 × 1 |
yes |
yes |
|
offset |
f32 × 1 |
yes |
yes |
|
(low, high) length limit |
f32 × 2 |
yes |
— |
|
rest length |
f32 × 1 |
yes |
— |
Deformable materials#
Deformable materials (DEFORMABLE_MATERIAL) emit a fixed group with one row per material prim. Host-only always. Volume and surface materials share
this type; three fields apply to surface materials only, and a volume material contributes no row for
them (rather than reporting zero).
Attribute |
Meaning |
dtype × lanes |
Applies to |
|---|---|---|---|
|
dynamic friction |
f32 × 1 |
volume + surface |
|
Young’s modulus |
f32 × 1 |
volume + surface |
|
Poisson’s ratio |
f32 × 1 |
volume + surface |
|
elasticity damping |
f32 × 1 |
volume + surface |
|
bending stiffness |
f32 × 1 |
surface only |
|
shell thickness |
f32 × 1 |
surface only |
|
bending damping |
f32 × 1 |
surface only |
Debug render#
Debug render (DEBUG_RENDER) is one instance-level target, not a prim. A query does not require an
attached stage. Settings are one row. Geometry columns are a snapshot of PhysX debug primitives for
scenes whose attach handle matches this instance. Position index i and color index i are the
same primitive. Shape 0 is an empty list. Host-only always.
Geometry timing. Complete simulation before reading. On CPU scenes, PhysX actor/shape wireframes use poses from the start of each scene’s latest simulation step, before integration. With substepping, this is the start of that scene’s last substep. Contact and friction primitives describe contacts computed for that step. Reading copies the existing primitives; a moving body’s wireframe can therefore trail its rendered post-step pose. The simulated body state is not delayed.
Attribute |
Meaning |
dtype × lanes / Python shape |
Residency |
|---|---|---|---|
|
visualization on/off |
u8 × 1 → |
host |
|
visualization scale |
f32 × 1 → |
host |
|
one float per visualization parameter (see |
f32 × 1 → |
host |
|
cull box min xyz, max xyz; leading shape 0 means no box |
f32 × 6 → |
host |
|
interned path tokens; length 0 draws everything |
u64 × 1 → |
host |
|
point positions |
f32, shape |
host |
|
point colors ( |
u32, shape |
host |
|
line endpoint positions |
f32, shape |
host |
|
line endpoint colors |
u32, shape |
host |
|
triangle vertex positions |
f32, shape |
host |
|
triangle vertex colors |
u32, shape |
host |
In C, pass &OVPHYSX_NAME_DEBUG_*. In Python, pass the string names above. With a stage
attached, each returned group’s attribute token resolves to that name. With no stage the
token is 0, because there is no path dictionary to intern it. A token-only read then fails.
Contact sensors#
Contact sensors (CONTACT_SENSOR) include rigid bodies and articulation links carrying
PhysxContactReportAPI, and every link of an articulation carrying it. On CPU simulation and GPU
dynamics with CPU readback, each collider carrying the schema is also a sensor. A body row aggregates
all of its shapes’ contacts and each collider row reads only its own shape’s, so the two overlap:
do not sum net forces or count contacts/events across a body and its own colliders, or they double-count.
Collider rows are host-only — a DirectGPU scene enumerates only reporting bodies (a selection naming
only a separate child collider discovers no rows there). Every attribute is read-only and describes
the last step; each scene’s sensors come back as
their own groups, reduced with that scene’s step dt. Three query forms select them — the whole set
(ovphysx_query), a prim-set selection (ovphysx_query_selection; pattern= / prim_paths= in
Python), and a contact query that pairs each sensor with F filter bodies.
ACTIVE scope behaves as ALL.
Child collider sensors#
On CPU simulation and GPU dynamics with CPU readback, a child collider can be selected as a contact
sensor when PhysxContactReportAPI is applied to that collider. This makes the sensor available; it
does not by itself enable contact reporting for its owning rigid body.
To enable reporting from that body, also apply PhysxContactReportAPI to the owning rigid-body prim.
For an articulation, reporting can be enabled on the owning link or on the articulation root, which
enables reporting for every link. A child sensor can also receive contacts reported by the other actor
in the pair. If neither actor reports matching contacts, the child remains a valid sensor but reads
zero force, even while touching another object.
For example, add this authoring fragment at the stage root and select /Body/Collider to read that
shape’s contacts:
def Xform "Body" (
prepend apiSchemas = ["PhysicsRigidBodyAPI", "PhysxContactReportAPI"]
)
{
float physxContactReport:threshold = 0
def Cube "Collider" (
prepend apiSchemas = ["PhysicsCollisionAPI", "PhysxContactReportAPI"]
)
{
double size = 0.5
}
}
Configure reporting settings, including physxContactReport:threshold and
physxContactReport:reportPairs, on the reporting body, link, or articulation root. Settings on a
separate child collider do not configure its owner’s reporting. The example enables reporting from
/Body without depending on the other actor; sleeping and other reporting conditions still apply.
Deprecated contact bindings. On CPU simulation and GPU dynamics with CPU readback, selecting
the owning body as a sensor in the same binding or another live contact binding on the same attachment
credits the contacts to the body and leaves the child sensor at zero. Wildcard patterns can select
both. For a child binding, enable reporting on /Body but select only /Body/Collider as a sensor,
and establish the bindings before stepping. Session contact reads support body and child rows together;
see the Contact Binding tutorial for the binding limitations.
A standalone static collider is its own rigid actor, so applying the schema to that prim enables reporting directly on CPU simulation and GPU dynamics with CPU readback. On DirectGPU, a standalone static collider remains a sensor row but reads zero force. DirectGPU session queries omit separate child-collider rows; select a dynamic body or articulation link to read forces instead.
Reading contact data#
Sleeping contacts. On CPU and GPU-dynamics scenes with CPU readback, persistent
contacts stop being reported when neither body in the pair is active. A settled
sensor can therefore have zero forces and no contact arrays while still touching
the ground. This also applies to contact bindings;
environment IDs do not disable contact reporting. DirectGPU disables sleeping,
so its contact tensors can remain nonzero on the same settled scene.
For continuous reporting, disable sleeping before attachment (for example,
physxScene:disableSleeping = true on a scene with PhysxSceneAPI), or wake the
bodies and complete another simulation step before reading. Use
isSleeping to inspect sleep state.
On a DirectGPU scene a sensor or a filter that is a point-instancer prototype stands for its first instance only, as in the contact binding: every column reads that instance’s contacts, where a CPU scene reads every instance’s. Another sensor’s contacts with each instance are unaffected.
Net forces — a fixed group, one row per sensor, on every query form:
Attribute |
Meaning |
dtype × lanes |
Frame |
Units |
Residency |
|---|---|---|---|---|---|
|
the sensor’s contact-point impulses, summed, / dt |
f32 × 3 |
world |
force |
device |
|
the sensor’s friction-anchor impulses, summed, / dt |
f32 × 3 |
world |
force |
device |
Their sum is the total contact force. Friction anchor forces that oppose each other cancel, so a friction torque does not show.
Per filter — on a contact query with filters only (F filters per sensor); a query without filters does not serve these names:
Attribute |
Meaning |
dtype × lanes |
Frame |
Units |
Residency |
|---|---|---|---|---|---|
|
normal force from each filter’s body; filter f at lanes 3f..3f+2 |
f32 × 3F |
world |
force |
device |
|
friction force from each filter’s body, same layout |
f32 × 3F |
world |
force |
device |
|
contact points from each filter’s body |
i32 × F |
— |
count |
device |
|
friction anchors from each filter’s body |
i32 × F |
— |
count |
device |
|
per point: its normal force (see below) |
f32 × 1 (array) |
— |
force |
device |
|
per point: its position |
f32 × 3 (array) |
world |
length |
device |
|
per point: its normal, as reported |
f32 × 3 (array) |
world |
— |
device |
|
per point: its separation |
f32 × 1 (array) |
— |
length |
device |
|
per anchor: its impulse / dt |
f32 × 3 (array) |
world |
force |
device |
|
per anchor: its position |
f32 × 3 (array) |
world |
length |
device |
The four matrix and count columns are fixed groups over every sensor. The six filtered* element
attributes are array groups: one array per sensor, its elements ordered by filter column —
filteredContactCount / filteredFrictionCount split it into per-filter runs, in lane order. A filter
that is a collider rather than a body is matched on a CPU scene, but reads zero on a DirectGPU scene, as
in the contact binding.
Raw contacts — array groups, one array per sensor, on every query form; every contact point of every pair the sensor is in, whatever the other body:
Attribute |
Meaning |
dtype × lanes |
Frame |
Units |
Residency |
|---|---|---|---|---|---|
|
per point: its normal force (see below) |
f32 × 1 |
— |
force |
device |
|
per point: its position |
f32 × 3 |
world |
length |
device |
|
per point: its normal, as reported |
f32 × 3 |
world |
— |
device |
|
per point: its separation |
f32 × 1 |
— |
length |
device |
|
per point: the other body’s prim |
u64 prim handle |
— |
— |
device |
Events — array groups, one array per sensor, on every query form over a CPU scene only: each contact-report pair the sensor is a side of — found, persisting or lost — as seen from the sensor, in report order. A pair between two sensors appears under each.
Attribute |
Per |
Meaning |
dtype × lanes |
Units |
|---|---|---|---|---|
|
event |
0 found, 1 lost, 2 persist |
i32 × 1 |
— |
|
event |
the pair side (0 or 1) the sensor is |
i32 × 1 |
— |
|
event |
the sensor’s own collider prim |
u64 prim handle |
— |
|
event |
the other body’s prim |
u64 prim handle |
— |
|
event |
the other collider’s prim |
u64 prim handle |
— |
|
event |
the collider’s instance index in its point instancer — its slot in |
u32 × 1 |
— |
|
event |
the event’s contact points / friction anchors |
i32 × 1 |
count |
|
point |
position (world) |
f32 × 3 |
length |
|
point |
normal, as reported (world) |
f32 × 3 |
— |
|
point |
impulse, as reported (world) |
f32 × 3 |
force·s |
|
point |
separation |
f32 × 1 |
length |
|
point |
triangle-mesh face index, own / other |
u32 × 1 |
— |
|
point |
material prim, own / other |
u64 prim handle |
— |
|
anchor |
position (world) |
f32 × 3 |
length |
|
anchor |
impulse, as reported (world) |
f32 × 3 |
force·s |
A sensor’s points (anchors) are concatenated in event order; contactEventPointCount
(contactEventAnchorCount), one value per event, splits them per event. A sensor has an array when it has
at least one element at the attribute’s level this step, so a sensor whose only event is a lost pair, which
carries no point, has event arrays but no point or anchor array. Event values are as reported: impulses,
not forces, never negated.
How to read these values:
Force sign. A force is the one the sensor receives: a point’s normal force is its impulse divided by dt — the impulse’s magnitude on a CPU scene, the solver’s normal impulse on a DirectGPU scene — negated when the sensor is the pair’s second body, and normals are never flipped. So
force × normalis the force on the sensor.Identities are prim-path handles interned in the attached Stage’s dictionary; obtain it through
stage->vtable->get_path_dictionary(stage->context)in C and resolve through the ovx path-dictionary API, or useovstage.PathDictionary.path_to_stringin Python. An identity with no prim reads 0.Exact sizing. Each array holds the step’s elements — no capacity, no truncation. A sensor with no element this step is absent from an array group, and the group is absent when no sensor has one.
Order. On a CPU scene a sensor’s elements keep report order (within a filter column for the filtered detail); on a DirectGPU scene their order is unspecified, as it is in the contact binding.
DirectGPU. The filtered detail’s arrays and the raw contacts synchronize the host once per read, to size them from the per-sensor counts; a read that asks for none of them does not, nor does one of the count columns alone. Events are not served (PhysX’s GPU contact pairs carry no event type): the read completes without them. Before the first step the fixed columns read zero and the arrays are absent.
Native PhysX pointers#
These query types publish only physxPointer: a host uint64 snapshot of a
borrowed PhysX address. PHYSICS is one row whose path is / and ignores
prim-set selection. The others have no active notion, so ACTIVE matches ALL.
Query type |
Address |
|---|---|
|
|
|
|
|
|
|
compound-shape wrapper |
|
|
|
standalone |
|
plugin custom joint |
|
particle system |
|
process-global |
The same column is also on articulation, articulation link, articulation joint, and particle set, listed in those tables. A missing object is absent. Reading the name on a type that does not publish it skips the name. See PhysX Pointer Interop.