Python API Reference#
High-level Python API for the ovphysx library.
Stream-Ordered Execution Model#
All operations in this API are stream-ordered, meaning they execute in submission order as if on a single queue. This provides sequential consistency:
Operations appear to complete in submission order
Writes from operation N are visible to operation N+1
You don’t need explicit synchronization between dependent operations
Independent operations may execute concurrently internally for performance
Example (no explicit waits needed between dependent operations):
usd_handle, _ = physx.add_usd("scene.usda") # Returns immediately
physx.step(dt, time) # Sees the USD load (stream-ordered)
binding = physx.create_tensor_binding(...) # Sees step results
binding.read(output) # Reads current state
Use wait_op() when:
Before accessing results outside the stream (e.g., reading data on CPU/GPU)
To ensure operations complete before program exit
For explicit synchronization points in your application
Thread Safety#
Multiple PhysX instances: fully thread-safe
Single instance: NOT thread-safe. Use external synchronization if calling from multiple threads
Core Classes#
- class ovphysx.api.PhysX(
- config: PhysXConfig | None = None,
- ignore_version_mismatch: bool = False,
- device: str | int | None = None,
- active_cuda_gpus: str | None = None,
Bases:
objectHigh-level wrapper around the C API using ctypes.
- add_usd(usd_path: str, path_prefix: str = '') tuple[int, int]#
Add USD file to stage (async, returns immediately).
- Parameters:
usd_path – Path to USD file
path_prefix – Optional prefix for all paths in USD
- Returns:
Tuple of (usd_handle, op_index). The usd_handle is used for remove_usd(). op_index can be used with wait_op() if you need explicit synchronization.
Examples
# Simple usage (stream-ordered) usd_handle, _ = physx.add_usd(“scene.usda”) physx.step(dt, time) # Automatically waits for USD to load
# Explicit synchronization (if needed before non-stream operations) usd_handle, op = physx.add_usd(“scene.usda”) physx.wait_op(op) # Ensure load completes before external access
- Preconditions:
usd_path must exist and be readable.
- Side effects:
Enqueues stage load and allocates runtime resources.
- Ownership/Lifetime:
The returned usd_handle is owned by this instance until remove_usd/reset.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises RuntimeError on load or enqueue failure.
- attach_stage(stage) None#
Attach an ovstage Stage as the orchestration data surface.
Once attached,
step()pulls dirty control attributes from the Stage (drive:force,drive:velocity,drive:position_target,physics:mass,physics:gravityMagnitude,physics:gravityDirection) before integrating, and publishesxformOp:transformper rigid body / articulation link to the Stage after integrating. The application then writes data only to ovstage; tensor bindings remain available as a perf escape hatch.Interest registration (the dispatch table’s input attributes) runs eagerly during this call, but output-buffer registration for the
xformOp:transformpose channel is deferred to the firststep()that observes a non-empty rigid-body set, since the prim list is not known at attach time. Steps issued before any rigid bodies exist on the Stage are no-ops on the publish side and re-attempt initialisation on the next step.- Parameters:
stage – An
ovstage.Stage(withhandle()returning the int cast ofovstage_instance_t*), or a raw int handle.
- Preconditions:
Instance must be valid.
Not already attached to a Stage.
stagemust outlive this attachment — calldetach_stage()(or destroy this instance) before destroying the Stage.
- Errors:
Raises
RuntimeErrorif already attached,stageis null, or interest registration fails. Instance remains unattached on failure.
- clone(
- source_path: str,
- target_paths: list[str],
- parent_transforms: list[tuple[float, float, float, float, float, float, float]] | None = None,
Clone a USD prim hierarchy to create multiple Fabric-based copies (asynchronous, returns immediately).
Creates physics-optimized clones in Fabric for high-performance simulation. The source prim must exist in the loaded USD stage and have physics properties. Due to stream-ordered execution, subsequent operations automatically see the result of clone.
When an ovstage Stage is attached via
attach_stage(), the canonical user-facing clone path isstage.clone_subtree(source, [targets])on the attached Stage; the OvstageBridge consumes the resulting clone events during step ingest and drives PhysX-side replication via the same plugin this method uses. This direct method remains supported for standalone callers (no ovstage attached) and for callers that want the async multi-target convenience.- Parameters:
source_path – USD path of the source prim hierarchy to clone (e.g., “/World/env0”)
target_paths – List of USD paths for the cloned hierarchies (e.g., [“/World/env1”, “/World/env2”])
parent_transforms – Optional list of (px, py, pz, qx, qy, qz, qw) transforms for each target’s parent Xform prim. Position followed by quaternion rotation (imaginary-first, matching tensor API convention). Identity rotation = (0, 0, 0, 1). Must have the same length as target_paths. When provided, newly-created parent prims are placed at the given transform. Pass None to use identity for all parents.
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
- Raises:
ValueError – If source_path is empty, target_paths is empty, or any target path matches source path
RuntimeError – If clone fails to queue or if no USD scene is loaded
- Preconditions:
A USD stage is loaded and source_path exists.
target_paths are unique and do not already exist.
- Side effects:
Creates cloned runtime prims that immediately participate in simulation.
- Ownership/Lifetime:
Clones remain valid until reset/remove_usd.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises ValueError for invalid inputs.
Raises RuntimeError on enqueue or internal failure.
- create_contact_binding(
- sensor_patterns: list[str],
- filter_patterns: list[str] | None = None,
- filters_per_sensor: int = 0,
- max_contact_data_count: int = 0,
Create a contact binding for reading aggregate and detailed contact tensors.
Returns DLPack-compatible tensors of net forces
[S, 3]or force matrices[S, F, 3]. Detailed contact and friction data are exposed as flat[C, ...]buffers plus[S, F]count/start-index tensors viaContactBinding.read_contact_data()andContactBinding.read_friction_data().A sensor is a set of rigid body prims matched by a USD prim path pattern. A filter is a second set of bodies whose contacts with each sensor you want to measure. No extra USD schema is needed beyond the rigid bodies themselves.
The binding must be created before the first simulation step whose contacts you want to observe. Call
read_net_forces()orread_force_matrix()afterPhysxSDK.step(). Before the first step, both return all-zeros tensors.- Result tensor shapes after step:
net forces:
[S, 3]where S = matched sensor countforce matrix:
[S, F, 3]where F = matched filter count per sensordetailed data: flat
[C, 1]or[C, 3]buffers indexed bycountsandstart_indiceswith shape[S, F]
Use
ContactBinding.sensor_pathsandContactBinding.filter_pathsto map rows and columns back to resolved USD prim paths.Example:
cb = sdk.create_contact_binding( sensor_patterns=["/World/robot_0/ee"], filter_patterns=["/World/obstacles/box"], filters_per_sensor=1, max_contact_data_count=256, ) # After sdk.step(): forces = torch.zeros(cb.sensor_count, 3, device="cuda") cb.read_net_forces(forces)
- Parameters:
sensor_patterns – USD prim path patterns for sensor bodies.
filter_patterns – Flat list of USD prim path patterns for filters. Total length must equal
len(sensor_patterns) * filters_per_sensor. PassNonewithfilters_per_sensor=0to get contacts with all bodies.filters_per_sensor – Number of filter patterns per sensor (same for all sensors).
max_contact_data_count – Max raw contact pairs to track in the native backend; also caps the detailed contact/friction flat-buffer reads. Detailed reads require this value and
filters_per_sensorto be positive.
- create_tensor_binding(
- pattern: str = None,
- prim_paths: list[str] = None,
- tensor_type: int = TensorType.RIGID_BODY_POSE,
- *,
- raise_if_empty: bool = False,
Create tensor binding for bulk physics data access (synchronous).
A tensor binding connects USD prims (by pattern or explicit paths) to a tensor type, enabling efficient bulk read/write of physics data.
- Parameters:
pattern – USD path glob pattern (e.g., “/World/robot*”, “/World/env[N]/robot”). Mutually exclusive with
prim_paths.prim_paths – Explicit list of prim paths. Mutually exclusive with
pattern.tensor_type – Tensor type enum value (
TensorType.*).raise_if_empty – If
True, raiseValueErrorwhen the binding matches zero prims. The default keeps empty bindings valid.
- Returns:
TensorBinding object for reading/writing tensor data.
- Raises:
ValueError – If neither
patternnorprim_pathsis provided, both are, orraise_if_emptyis true and no prims match.RuntimeError – If binding creation fails.
Examples:
# Read all robot poses by pattern with sdk.create_tensor_binding( "/World/robot*", tensor_type=TensorType.RIGID_BODY_POSE ) as binding: poses = np.zeros(binding.shape, dtype=np.float32) binding.read(poses) # Set joint position targets for specific articulations binding = physx.create_tensor_binding( prim_paths=["/World/env1/robot", "/World/env2/robot"], tensor_type=TensorType.ARTICULATION_DOF_POSITION_TARGET, ) targets = np.zeros(binding.shape, dtype=np.float32) binding.write(targets) binding.destroy()
- Preconditions:
Exactly one of
patternorprim_pathsmust be provided.A USD stage is loaded.
- Side effects:
Allocates native binding resources.
- Ownership/Lifetime:
Returned TensorBinding owns native resources until
destroy().
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises
ValueErrorfor invalid arguments.Raises
RuntimeErroron creation failure.
- detach_stage() None#
Detach the currently-attached ovstage Stage.
Idempotent — calling on an unattached instance is a no-op success. Clears registered interests and output-buffer registrations, so a subsequent
attach_stage()to a different Stage starts clean. After detach,step()reverts to unattached behaviour (tensor bindings still work; no auto-pull from ovstage).- Errors:
Raises
RuntimeErroron internal failures.
- get_config_bool(key: int) bool#
Get a boolean config value.
- Parameters:
key – Boolean config key (e.g.,
ovphysx.ConfigBool.DISABLE_CONTACT_PROCESSING).- Returns:
Current boolean value.
- get_config_float(key: int) float#
Get a float config value.
- Parameters:
key – Float config key.
- Returns:
Current float value.
- get_config_int32(key: int) int#
Get an int32 config value.
- Parameters:
key – Int32 config key (e.g.,
ovphysx.ConfigInt32.NUM_THREADS).- Returns:
Current int32 value.
- get_config_string(key: int) str | None#
Get a string config value.
- Parameters:
key – String config key from
ovphysx.ConfigString.- Returns:
Current string value, or None if not found.
- get_contact_report(
- include_friction_anchors: bool = False,
Get per-contact-point event data for the current simulation step.
Use this for custom contact sensors, collision debugging, or per-point force analysis. For aggregate force tensors (net forces or force matrices between sensor/filter body sets), use
create_contact_binding()instead.- Parameters:
include_friction_anchors – If True, also return friction anchor data (position and impulse at each friction anchor point).
- Returns a dict with:
headers: ctypes array ofContactEventHeaderstructs describing each contact pair (actors, colliders, event type). Length isnum_headers.num_headers(int): Number of contact event headers.points: ctypes array ofContactPointstructs with per-contact-point data (position, normal, impulse, separation). Length isnum_points.num_points(int): Number of contact point entries.anchors(only ifinclude_friction_anchors=True): ctypes array ofFrictionAnchorstructs. Length isnum_anchors.num_anchors(int, only ifinclude_friction_anchors=True): Number of friction anchors.
The arrays are zero-copy views into internal buffers, valid until the next simulation step. Individual fields are accessible by index:
report = physx.get_contact_report() for i in range(report["num_headers"]): h = report["headers"][i] print(h.actor0, h.numContactData) for j in range(report["num_points"]): p = report["points"][j] print(p.position[0], p.normal[1], p.impulse[2])
Prims must have
PhysxContactReportAPIapplied in the USD stage for contacts to be reported.- Raises:
RuntimeError – If the call fails.
- get_physx_ptr(prim_path: str, physx_type: int) int#
Return a raw PhysX SDK pointer by USD prim path and type.
- Parameters:
prim_path – Absolute USD prim path (e.g.
"/World/physicsScene").physx_type – One of the
PhysXTypeenum members (or matching int) indicating which PhysX object type to look up.
- Returns:
Integer address of the PhysX pointer, or
0if no object of the requested type exists at the given path.- Raises:
RuntimeError – On infrastructure failures (no stage loaded, invalid handle, etc.). A missing object does not raise; check for a
0return value instead.
The returned address can be passed to C/C++ code that casts it to the appropriate PhysX type (see
ovphysx_physx_type_t).Pointer lifetime: valid until
remove_usd(),reset(), or instance destruction.step()andclone()do NOT invalidate pointers. Do not callrelease()on returned pointers.Thread safety: PhysX APIs on returned pointers must only be called between simulation steps.
- get_stage_id() int#
Return the attached USD stage id.
- Preconditions:
Instance must be valid.
- Side effects:
None.
- Ownership/Lifetime:
Returned ID is owned by the runtime and may change after stage reload.
- Threading:
Do not call concurrently with stage mutation without external sync.
- Errors:
Returns -1 if the query fails.
- property handle: int#
The raw
ovphysx_handle_tfor this instance (read-only).Use this when passing the handle to C/C++ code that calls the ovphysx C API directly (e.g.
ovphysx_get_physx_ptr).- Raises:
RuntimeError – If the instance has been released.
- overlap(
- geometry_type: SceneQueryGeometryType,
- mode: SceneQueryMode = SceneQueryMode.ALL,
- **kwargs,
Test geometry overlap against objects in the scene.
For overlap queries, location fields (normal, position, distance, face_index, material) are zeroed – only object identity is populated.
- raycast(
- origin: tuple | list,
- direction: tuple | list,
- distance: float,
- mode: SceneQueryMode = SceneQueryMode.CLOSEST,
- both_sides: bool = False,
Cast a ray and return hits.
- Parameters:
origin – Ray origin [x, y, z].
direction – Normalized ray direction [x, y, z].
distance – Maximum ray length (>= 0).
mode –
SceneQueryMode(CLOSEST, ANY, or ALL).both_sides – If True, test both sides of mesh triangles.
- Returns:
List of hit dicts. Each dict contains
collision,rigid_body,proto_index,normal,position,distance,face_index,material. For ANY mode, hit fields are zeroed.
- release() None#
Release PhysX instance.
- Preconditions:
Instance is valid and not in use by other threads.
- Side effects:
Releases native resources and unregisters the instance.
- Ownership/Lifetime:
All tensor bindings and contact bindings created by this instance are automatically released.
The instance becomes unusable after release.
- Threading:
Do not call concurrently with other operations on this instance.
- Errors:
Errors during cleanup are suppressed for robustness.
- remove_usd(usd_handle: int) int#
Remove USD file from stage (async, returns immediately).
- Parameters:
usd_handle – Handle from add_usd()
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
Example
# Simple usage (stream-ordered) physx.remove_usd(usd_handle) physx.step(dt, time) # Automatically waits for removal
- Preconditions:
usd_handle must be valid for this instance.
- Side effects:
Removes USD data from the runtime stage when complete.
- Ownership/Lifetime:
usd_handle becomes invalid after completion.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises RuntimeError on failure.
- reset() int#
Reset stage to empty (async, invalidates all usd_handles).
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
Example
# Simple usage (stream-ordered) physx.reset() usd_handle, _ = physx.add_usd(“new_scene.usda”) # Automatically waits for reset
- Preconditions:
Instance must be valid.
- Side effects:
Clears the runtime stage and invalidates all USD handles.
- Ownership/Lifetime:
All previously returned usd_handles become invalid after completion.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises RuntimeError on failure.
- set_config(
- entry: ovphysx._bindings.ovphysx_config_entry_t,
Set a typed global config entry at runtime (process-global).
Prefer the typed setters (
set_config_bool(),set_config_int32(),set_config_float()) for a cleaner API.- Parameters:
entry – Typed config entry (
ovphysx_config_entry_t).
- set_config_bool(key: int, value: bool) None#
Set a boolean config value at runtime (process-global).
- Parameters:
key – Boolean config key (e.g.,
ConfigBool.DISABLE_CONTACT_PROCESSING).value – Boolean value.
- set_config_float(key: int, value: float) None#
Set a float config value at runtime (process-global).
- Parameters:
key – Float config key.
value – Float value.
- set_config_int32(key: int, value: int) None#
Set an int32 config value at runtime (process-global).
- Parameters:
key – Int32 config key (e.g.,
ConfigInt32.NUM_THREADS).value – Int32 value.
- step(dt: float, sim_time: float) int#
Initiate physics step (async, returns op_index).
- Parameters:
dt – Delta time for this step
sim_time – Current simulation time
- Returns:
op_index (can be used with wait_op() for explicit synchronization)
Examples
# Simple usage (stream-ordered) physx.step(0.016, 0.0) binding.read(output) # Automatically waits for step
# Explicit wait (if accessing results outside stream) op = physx.step(0.016, 0.0) physx.wait_op(op) # Ensure step completes before external GPU work
- Preconditions:
A USD stage is loaded if physics content is expected.
- Side effects:
Advances simulation time and mutates physics state.
- Ownership/Lifetime:
Returned op_index is single-use and must be waited once if needed.
- Threading:
Do not call concurrently on the same instance without external sync.
- Errors:
Raises RuntimeError on failure to enqueue.
- step_n_sync(n: int, dt: float, current_time: float) None#
Run N steps in a single C call, saving (N-1) ctypes round-trips.
Equivalent to calling
step_sync(dt, current_time + i*dt)for i in[0, n), but with only one Python-to-C transition.- Parameters:
n – Number of steps to run (must be >= 1).
dt – Duration of each step [s].
current_time – Simulation time at the start of the first step [s].
- Raises:
RuntimeError – If any step fails.
- step_sync(dt: float, sim_time: float) None#
Step simulation and wait for completion in a single call.
Faster than
step()+wait_op()for performance-critical applications like RL training that always wait immediately.- Parameters:
dt – Delta time [s] for this step.
sim_time – Current simulation time [s].
- Raises:
RuntimeError – If the step or wait fails.
- sweep(
- geometry_type: SceneQueryGeometryType,
- direction: tuple | list,
- distance: float,
- mode: SceneQueryMode = SceneQueryMode.CLOSEST,
- both_sides: bool = False,
- **kwargs,
Sweep a geometry shape along a direction and return hits.
- Parameters:
geometry_type –
SceneQueryGeometryType.direction – Normalized sweep direction [x, y, z].
distance – Maximum sweep distance (>= 0).
mode –
SceneQueryMode.both_sides – If True, test both sides of mesh triangles.
**kwargs –
Geometry parameters:
SPHERE:
radius,positionBOX:
half_extent,position,rotation(xyzw quaternion)SHAPE:
prim_path(USD prim path string)
- Returns:
List of hit dicts (same format as
raycast()).
- update_articulations_kinematic() None#
Update articulation link poses from current joint positions.
This performs a synchronous articulation forward-kinematics update without running a normal simulation step, collision detection, or contact generation. Call it after writing articulation DOF positions and before reading articulation link pose tensors when fresh link poses are needed in the same frame.
In GPU mode, the first kinematic update after loading USD may perform the same automatic DirectGPU warmup step used by tensor reads/writes.
- Raises:
RuntimeError – If the update fails.
- wait_all(timeout_ns: int | None = None) None#
Wait for all pending operations (convenience wrapper for wait_op(ALL)).
- Parameters:
timeout_ns – Timeout in nanoseconds (None = infinite, 0 = poll)
- Preconditions:
Instance must be valid.
- Side effects:
Blocks until all pending ops complete or timeout.
- Threading:
Safe to call if no other thread is waiting on specific op_indices.
- Errors:
Raises RuntimeError on failure.
Raises TimeoutError if timeout expired (e.g., when polling with timeout_ns=0 and operations are not ready).
- wait_op(op_index: int, timeout_ns: int = None) None#
Wait for operation(s) to complete.
- Parameters:
op_index – Operation index to wait for, or OP_INDEX_ALL for all ops
timeout_ns – Timeout in nanoseconds (None = infinite, 0 = poll)
- Raises:
RuntimeError – If operation failed
TimeoutError – If timeout expired (e.g., when polling with timeout_ns=0 and the operation is not ready)
- Preconditions:
op_index must be valid and not previously consumed.
- Side effects:
Consumes op_index on successful wait.
- Ownership/Lifetime:
Error strings returned by the API are destroyed internally.
- Threading:
Do not wait on the same op_index from multiple threads.
Examples:
# Blocking wait (default) physx.wait_op(op_index) # Non-blocking poll try: physx.wait_op(op_index, timeout_ns=0) except TimeoutError: pass # operation not yet complete
- warmup_gpu() None#
Explicitly initialize GPU buffers (synchronous).
In GPU mode, PhysX DirectGPU buffers need one simulation step to initialize. This is normally done automatically on the first tensor read (auto-warmup).
Call this function explicitly if you want to: - Control exactly when the warmup latency occurs - Avoid a latency spike on the first tensor read - Verify GPU initialization succeeded before starting your main loop
This function is idempotent - calling it multiple times has no effect after the first successful call. In CPU mode, this is a no-op.
- Raises:
RuntimeError – If GPU warmup fails.
- Preconditions:
Instance is configured for GPU mode.
- Side effects:
Advances simulation by a minimal timestep on first call.
- Ownership/Lifetime:
No ownership changes; affects current stage state.
- Threading:
Do not call concurrently with other operations on this instance.
- class ovphysx.api.TensorBinding(
- sdk,
- handle: int,
- tensor_type: int,
- ndim: int,
- shape: tuple,
Bases:
objectTensor binding for bulk physics data access via DLPack.
A tensor binding connects a USD prim pattern to a tensor type, enabling efficient bulk read/write of physics data (poses, velocities, joint positions, etc.).
This is a synchronous API - operations complete before returning.
Usage patterns:
Context manager (auto-cleanup):
with sdk.create_tensor_binding("/World/robot*", TensorType.RIGID_BODY_POSE) as binding: poses = np.zeros(binding.shape, dtype=np.float32) binding.read(poses) # ... modify poses ... binding.write(poses) # Auto-destroyed here
Manual (explicit cleanup):
binding = sdk.create_tensor_binding("/World/robot*", TensorType.RIGID_BODY_POSE) poses = np.zeros(binding.shape, dtype=np.float32) binding.read(poses) binding.destroy()
- property body_count: int#
Number of links.
- property body_names: list[str]#
List of body/link names.
- property count: int#
Get number of entities (first dimension of shape).
- destroy() None#
Release binding resources.
Safe to call multiple times. Called automatically on garbage collection or when exiting a context manager.
- Preconditions:
Binding must not be in use by other threads.
- Side effects:
Releases native resources and invalidates the binding.
- Ownership/Lifetime:
After destruction, the binding cannot be used.
- Threading:
Serialized per binding via an internal lock.
- Errors:
RuntimeError if destruction fails.
- property dof_count: int#
Number of degrees of freedom (DOFs). 0 if not an articulation binding.
- property dof_names: list[str]#
List of DOF names (one per DOF).
- property fixed_tendon_count: int#
Number of fixed tendons per articulation (0 if none).
Use to decide whether to allocate buffers for fixed tendon property tensors (types 80-85) and to skip tendon code paths when T=0.
- property handle: int#
Get the binding handle.
- property is_fixed_base: bool#
Whether the articulation has a fixed base.
- property joint_count: int#
Number of joints per articulation.
- property joint_names: list[str]#
List of joint names.
- property ndim: int#
Get the number of dimensions (2 or 3).
- property prim_paths: list[str]#
Resolved USD prim paths in tensor row order.
Rigid-body bindings return one path per rigid-body tensor row. Articulation bindings return one root prim path per articulation row. For per-articulation link names, use
body_names.
- read(tensor) None#
Read simulation data into a user-provided tensor (synchronous).
The tensor must have matching shape and dtype (float32). Can be a NumPy array, PyTorch tensor, or any object with __dlpack__ protocol.
When called repeatedly with the same buffer object, an internal cache skips DLPack acquisition and attribute chain lookups, giving near-raw-C-call overhead. The numpy writeable guard is preserved on the fast path. Callers that want this fast path should reuse the same tensor object with unchanged backing storage across calls. Calling
numpy.ndarray.resize()ortorch.Tensor.resize_()between calls is safe (a staleness guard detects the pointer change and rebuilds the cache) but defeats the purpose of caching.- Parameters:
tensor – DLPack-compatible tensor with pre-allocated storage matching self.shape. Must be float32 on matching device (CPU or GPU).
- Preconditions:
This binding is not destroyed.
tensor has matching shape, dtype (float32), and device.
- Side effects:
Blocks until data is available and writes into the provided tensor.
- Ownership/Lifetime:
Caller owns tensor storage and must keep it alive for the duration of the call.
Do not mutate the tensor’s backing storage (
resize(),set_(), etc.) between cached calls. For numpy and torch tensors, a staleness guard detects common mutations and falls back to the slow path; other types rely on the caller honouring this contract.
- Threading:
Serialized per binding via an internal lock.
- Errors:
RuntimeError if read fails (shape mismatch, device mismatch, etc.).
- property shape: tuple#
Get tensor shape as tuple.
- Returns:
(N, C) where N=count, C=components (e.g., 7 for pose, 6 for velocity) - 3D tensors: (N, L, C) where L=links for articulation link data
- Return type:
2D tensors
- property spatial_tendon_count: int#
Number of spatial tendons per articulation (0 if none).
Use to decide whether to allocate buffers for spatial tendon property tensors (types 90-93) and to skip tendon code paths when T=0.
- property tensor_type: int#
Get the tensor type enum value.
- write(tensor, indices=None, mask=None) None#
Write data from a user-provided tensor into the simulation (synchronous).
The tensor must have matching shape and dtype (float32). Can be a NumPy array, PyTorch tensor, or any object with __dlpack__ protocol.
When called repeatedly with the same buffer object and no indices/mask, an internal cache skips DLPack acquisition and attribute chain lookups, giving near-raw-C-call overhead. Callers that want this fast path should reuse the same tensor object with unchanged backing storage across calls; see
read()for the full contract.- Parameters:
tensor – DLPack-compatible tensor with data to write, shape matching self.shape. Must be float32 on matching device (CPU or GPU).
indices – Optional int32 tensor of indices for partial update. If provided, only the rows at the given indices are written. The tensor argument must still be full shape [N, …] matching the binding spec; only the selected rows are applied. Shape of indices: [K] where K <= N.
mask –
Optional bool/uint8 tensor for masked update. If provided, only elements where mask[i] != 0 are written. Shape: [N] matching the binding’s first dimension. When mask is provided, tensor must be full shape [N, …]. If both mask and indices are provided, mask takes precedence and indices are ignored (with a warning).
Note: there is no corresponding
read(..., mask=...); reads always return the full [N,…] tensor and callers can index the result themselves. This write-only mask design matches other RL physics APIs such as Newton’s selectionAPI, where masks selectively apply actions but observations are always returned in full.
- Preconditions:
This binding is not destroyed.
tensor matches shape, dtype (float32), and device.
indices (if provided) is int32 and within bounds.
mask (if provided) is bool/uint8 with shape [N] on matching device.
- Side effects:
Updates simulation state for the bound entities.
- Ownership/Lifetime:
Caller owns tensor/indices/mask storage and must keep it alive for the call.
- Threading:
Serialized per binding via an internal lock.
- Errors:
RuntimeError if write fails (shape mismatch, device mismatch, etc.).
- class ovphysx.api.ContactBinding(
- sdk,
- handle: int,
- sensor_count: int,
- filter_count: int,
- max_contact_data_count: int,
Bases:
objectContact tensor binding backed by IRigidContactView.
Do not instantiate directly. Use
PhysxSDK.create_contact_binding()to obtain an instance. Thesensor_pathsandfilter_pathsproperties expose the row/column metadata for the returned tensors.- destroy() None#
Release contact binding resources.
Safe to call multiple times. Captures strong references to the SDK and library before the C call to guard against GC ordering issues (Python may collect self._sdk before self if both go out of scope together).
- property filter_count: int#
Number of filter bodies per sensor (0 when no filters specified).
- property filter_paths: list[list[str]]#
Resolved filter USD prim paths in contact tensor column order.
The outer list is indexed by sensor row and the inner list by filter column. Each inner list is empty for unfiltered contact bindings (i.e. when
filter_count == 0).
- property max_contact_data_count: int#
Flat-buffer capacity for detailed contact and friction reads.
- read_contact_data(
- contact_forces,
- positions,
- normals,
- separations,
- counts,
- start_indices,
Read detailed contact data into flat buffers.
Expected shapes are
[C, 1]forcontact_forcesandseparations,[C, 3]forpositionsandnormals, and[sensor_count, filter_count]forcountsandstart_indices.Cismax_contact_data_count; bothCandfilter_countmust be positive. Count and start-index tensors may be int32 or uint32.
- read_force_matrix(output) None#
Read contact force matrix into output. Expected shape: [sensor_count, filter_count, 3].
The dt for impulse-to-force conversion is taken automatically from the last
PhysxSDK.step()call.
- read_friction_data(
- friction_forces,
- friction_points,
- counts,
- start_indices,
Read detailed friction data into flat buffers.
Expected shapes are
[C, 3]forfriction_forcesandfriction_points, and[sensor_count, filter_count]forcountsandstart_indices.Cismax_contact_data_countand must be positive;filter_countmust also be positive. Count and start-index tensors may be int32 or uint32. Friction entries are per-anchor; sum each flat slice to build a pair-level[sensor_count, filter_count, 3]force tensor.
- read_net_forces(output) None#
Read net contact forces into output. Expected shape: [sensor_count, 3].
The dt for impulse-to-force conversion is taken automatically from the last
PhysxSDK.step()call.
- property sensor_count: int#
Number of sensor bodies matched.
- property sensor_paths: list[str]#
Resolved sensor USD prim paths in contact tensor row order.
Cloud Storage Configuration#
- ovphysx.api.configure_s3(
- host: str,
- bucket: str,
- region: str,
- access_key_id: str,
- secret_access_key: str,
- session_token: str | None = None,
Configure S3 credentials for remote USD loading via HTTPS S3 URLs.
Credentials are process-global and take effect immediately for all
PhysXinstances. Call beforePhysX.add_usd()with an S3 HTTPS URL.- Parameters:
host – S3 endpoint (e.g.,
"my-bucket.s3.us-east-1.amazonaws.com").bucket – S3 bucket name.
region – AWS region (e.g.,
"us-east-1").access_key_id – AWS access key ID.
secret_access_key – AWS secret access key.
session_token – STS session token (
Noneif not using temporary credentials).
- Raises:
ValueError – If a required parameter is empty.
RuntimeError – If the OmniClient library is unavailable.
- ovphysx.api.configure_azure_sas(host: str, container: str, sas_token: str) None#
Configure an Azure SAS token for remote USD loading via Azure Blob Storage.
Credentials are process-global and take effect immediately for all
PhysXinstances. Call beforePhysX.add_usd()with an Azure Blob URL.- Parameters:
host – Azure Blob host (e.g.,
"myaccount.blob.core.windows.net").container – Azure container name.
sas_token – SAS token string (without leading
'?').
- Raises:
ValueError – If a required parameter is empty.
RuntimeError – If the OmniClient library is unavailable.
Schema Path Registration#
- ovphysx.register_schema_paths() None#
Register ovphysx’s namespaced USD schema/plugin paths before native bootstrap.
Call this before any USD stage open or schema-registry access when ovphysx shares a process with another USD-aware subsystem such as ovrtx. Standalone ovphysx applications do not need to call it because native startup registers the same ovphysx path automatically.
Always idempotent: re-reads the live env (Python and native views), merges, dedupes, and writes back only if the merged value differs. Safe to call repeatedly and after callers pop
OV_PXR_PLUGINPATH_2511fromos.environto force re-registration.- Raises:
RuntimeError – If no existing ovphysx
plugins/usddirectory can be found.
Logging#
- ovphysx.api.set_log_level(level: int) None#
Set the global log level threshold.
Messages below this level are suppressed for all outputs (console and registered callbacks). Callable at any time, including before instance creation.
- Parameters:
level – Log level threshold (LogLevel.VERBOSE through LogLevel.NONE). Default: LogLevel.WARNING.
- Raises:
ValueError – If level is out of range. No state change is applied.
- ovphysx.api.get_log_level() int#
Get the current global log level threshold.
- Returns:
The current log level (int matching ovphysx_log_level_t constants).
- ovphysx.api.enable_default_log_output(enable: bool = True) None#
Enable or disable Carbonite’s built-in console log output.
By default, Carbonite logs to the console. When custom callbacks are registered (or
enable_python_logging()is active), both the built-in console output and the callbacks receive messages, which may cause duplicate output.Call with
Falseto suppress the built-in console output while keeping callbacks active. Call withTrueto re-enable it.This is independent of callback registration and the global log level.
- Parameters:
enable –
Trueto enable (default),Falseto disable.
- ovphysx.api.enable_python_logging(logger_name: str = 'ovphysx') None#
Route native log messages to Python’s logging module.
Registers a C-level callback that forwards every message (at or above the global log level) to
logging.getLogger(logger_name)at the corresponding Python log level.Call
disable_python_logging()to stop forwarding.- Parameters:
logger_name – Name of the Python logger to route to (default: “ovphysx”).
- ovphysx.api.disable_python_logging() None#
Stop routing native log messages to Python’s logging module.
If
enable_python_logging()was not called, this is a no-op.
Configuration#
Typed config for ovphysx.
Provides PhysXConfig, a dataclass whose fields map 1:1 to the
C typed config enums in ovphysx_types.h. Only non-None fields are
applied; the rest keep their Carbonite/PhysX defaults.
Usage:
from ovphysx import PhysX, PhysXConfig
physx = PhysX(config=PhysXConfig(
disable_contact_processing=True,
num_threads=4,
carbonite_overrides={"/physics/fabricUpdateVelocities": True},
))
- class ovphysx.config.PhysXConfig(
- disable_contact_processing: bool | None = None,
- collision_cone_custom_geometry: bool | None = None,
- collision_cylinder_custom_geometry: bool | None = None,
- num_threads: int | None = None,
- scene_multi_gpu_mode: int | None = None,
- omnipvd_output_enabled: bool | None = None,
- omnipvd_ovd_recording_directory: str | None = None,
- carbonite_overrides: dict[str, bool | int | float | str] | None = None,
Bases:
objectTyped configuration for ovphysx.
All fields default to
None(= use Carbonite/PhysX default). Only non-None fields are applied.Example:
from ovphysx import PhysX, PhysXConfig physx = PhysX(config=PhysXConfig( disable_contact_processing=True, num_threads=4, carbonite_overrides={"/physics/fabricUpdateVelocities": True}, ))
- carbonite_overrides: dict[str, bool | int | float | str] | None = None#
- collision_cone_custom_geometry: bool | None = None#
- collision_cylinder_custom_geometry: bool | None = None#
- disable_contact_processing: bool | None = None#
- num_threads: int | None = None#
- omnipvd_output_enabled: bool | None = None#
Must be set before instance creation
- omnipvd_ovd_recording_directory: str | None = None#
Must be set before instance creation
- scene_multi_gpu_mode: int | None = None#
0=disabled, 1=all GPUs, 2=skip first GPU
Types and Enums#
Pure-Python type definitions for ovphysx.
This module contains IntEnum definitions that mirror the C enums in ovphysx/include/ovphysx/ovphysx_types.h. It has zero native dependencies (no ctypes, no shared library loading, no USD) and is safe to import in any Python process regardless of USD version or native library state.
Keeping this module dependency-free is intentional: downstream consumers like IsaacLab can import TensorType without triggering ovphysx’s native bootstrap or USD version checks.
Naming convention: strip the OVPHYSX_TENSOR_ prefix and _F32 suffix
from the C enum name. This keeps names unambiguous (ARTICULATION_ vs
RIGID_BODY_) and makes the _bindings.py aliases mechanically verifiable.
- class ovphysx.types.ApiStatus(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumReturn codes from the ovphysx C API. Mirrors ovphysx_api_status_t.
- BUFFER_TOO_SMALL = 6#
- DEVICE_MISMATCH = 7#
- ERROR = 1#
- GPU_NOT_AVAILABLE = 8#
- INVALID_ARGUMENT = 4#
- NOT_FOUND = 5#
- NOT_IMPLEMENTED = 3#
- SUCCESS = 0#
- TIMEOUT = 2#
- class ovphysx.types.BindingPrimMode(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumPrim selection mode for tensor bindings.
Unlike the other enums in this module, BindingPrimMode does not have a named typedef in ovphysx_types.h – the values come from the internal implementation. It is not covered by test_types_sync.py.
- CREATE_NEW = 2#
- EXISTING_ONLY = 0#
- MUST_EXIST = 1#
- class ovphysx.types.ConfigBool(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumBoolean config keys. Mirrors ovphysx_config_bool_t.
- COLLISION_CONE_CUSTOM_GEOMETRY = 1#
- COLLISION_CYLINDER_CUSTOM_GEOMETRY = 2#
- DISABLE_CONTACT_PROCESSING = 0#
- OMNIPVD_OUTPUT_ENABLED = 3#
- class ovphysx.types.ConfigFloat(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumFloat config keys (reserved). Mirrors ovphysx_config_float_t.
- class ovphysx.types.ConfigInt32(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumInt32 config keys. Mirrors ovphysx_config_int32_t.
- NUM_THREADS = 0#
- SCENE_MULTI_GPU_MODE = 1#
- class ovphysx.types.ConfigString(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumString config keys. Mirrors ovphysx_config_string_t.
- OMNIPVD_OVD_RECORDING_DIRECTORY = 0#
- class ovphysx.types.DeviceType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumDevice selection for PhysX instance creation. Mirrors ovphysx_device_t.
- AUTO = 0#
- CPU = 2#
- GPU = 1#
- class ovphysx.types.LogLevel(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumLog level for ovphysx output. Mirrors ovphysx_log_level_t.
- ERROR = 3#
- INFO = 1#
- NONE = 4#
- VERBOSE = 0#
- WARNING = 2#
- exception ovphysx.types.PhysXDeviceError#
Bases:
RuntimeErrorRaised when a PhysX instance requests a device mode that conflicts with the process-global mode locked by a prior
PhysX()call.Device mode (CPU or GPU) is set once per process on the first
PhysX()instantiation and cannot be changed. To use a different device mode, run the code in a separate subprocess:import subprocess, sys subprocess.run([sys.executable, "my_cpu_script.py"], check=True)
- class ovphysx.types.PhysXType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumPhysX object type identifiers for
ovphysx_get_physx_ptr().Values match
ovphysx_physx_type_tinovphysx_types.h(which in turn matchesomni::physx::PhysXType). Alignment is enforced by static_asserts in ovphysxClone.cpp (C <-> internal) and by test_types_sync.py (C <-> Python).- ACTOR = 5#
- ARTICULATION = 8#
- COMPOUND_SHAPE = 4#
- CUSTOM_JOINT = 7#
- JOINT = 6#
- LINK = 9#
- LINK_JOINT = 10#
- MATERIAL = 2#
- PARTICLE_SET = 12#
- PARTICLE_SYSTEM = 11#
- PHYSICS = 31#
- SCENE = 1#
- SHAPE = 3#
- class ovphysx.types.SceneQueryGeometryType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumGeometry type for sweep/overlap queries. Mirrors ovphysx_scene_query_geometry_type_t.
- BOX = 1#
- SHAPE = 2#
- SPHERE = 0#
- class ovphysx.types.SceneQueryMode(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumScene query hit mode. Mirrors ovphysx_scene_query_mode_t.
- ALL = 2#
- ANY = 1#
- CLOSEST = 0#
- class ovphysx.types.TensorType(
- value,
- names=<not given>,
- *values,
- module=None,
- qualname=None,
- type=None,
- start=1,
- boundary=None,
Bases:
IntEnumTensor type identifiers for TensorBindingsAPI.
Values match ovphysx_tensor_type_t in ovphysx_types.h. IntEnum members compare equal to plain ints, so they pass directly to the C API without conversion.
- ARTICULATION_BODY_COM_POSE = 61#
- ARTICULATION_BODY_INERTIA = 62#
- ARTICULATION_BODY_INV_INERTIA = 64#
- ARTICULATION_BODY_INV_MASS = 63#
- ARTICULATION_BODY_MASS = 60#
- ARTICULATION_CONTACT_OFFSET = 111#
- ARTICULATION_CORIOLIS_AND_CENTRIFUGAL_FORCE = 72#
- ARTICULATION_DOF_ACTUATION_FORCE = 34#
- ARTICULATION_DOF_ARMATURE = 40#
- ARTICULATION_DOF_DAMPING = 36#
- ARTICULATION_DOF_FRICTION_PROPERTIES = 41#
- ARTICULATION_DOF_LIMIT = 37#
- ARTICULATION_DOF_MAX_FORCE = 39#
- ARTICULATION_DOF_MAX_VELOCITY = 38#
- ARTICULATION_DOF_POSITION = 30#
- ARTICULATION_DOF_POSITION_TARGET = 32#
- ARTICULATION_DOF_PROJECTED_JOINT_FORCE = 75#
- ARTICULATION_DOF_STIFFNESS = 35#
- ARTICULATION_DOF_VELOCITY = 31#
- ARTICULATION_DOF_VELOCITY_TARGET = 33#
- ARTICULATION_FIXED_TENDON_DAMPING = 81#
- ARTICULATION_FIXED_TENDON_LIMIT = 83#
- ARTICULATION_FIXED_TENDON_LIMIT_STIFFNESS = 82#
- ARTICULATION_FIXED_TENDON_OFFSET = 85#
- ARTICULATION_FIXED_TENDON_REST_LENGTH = 84#
- ARTICULATION_FIXED_TENDON_STIFFNESS = 80#
- ARTICULATION_GRAVITY_FORCE = 73#
- ARTICULATION_JACOBIAN = 70#
- ARTICULATION_LINK_ACCELERATION = 22#
- ARTICULATION_LINK_INCOMING_JOINT_FORCE = 74#
- ARTICULATION_LINK_POSE = 20#
- ARTICULATION_LINK_VELOCITY = 21#
- ARTICULATION_LINK_WRENCH = 52#
- ARTICULATION_MASS_MATRIX = 71#
- ARTICULATION_REST_OFFSET = 112#
- ARTICULATION_ROOT_POSE = 10#
- ARTICULATION_ROOT_VELOCITY = 11#
- ARTICULATION_SHAPE_FRICTION_AND_RESTITUTION = 110#
- ARTICULATION_SPATIAL_TENDON_DAMPING = 91#
- ARTICULATION_SPATIAL_TENDON_LIMIT_STIFFNESS = 92#
- ARTICULATION_SPATIAL_TENDON_OFFSET = 93#
- ARTICULATION_SPATIAL_TENDON_STIFFNESS = 90#
- INVALID = 0#
- RIGID_BODY_ACCELERATION = 6#
- RIGID_BODY_COM_POSE = 5#
- RIGID_BODY_CONTACT_OFFSET = 101#
- RIGID_BODY_FORCE = 50#
- RIGID_BODY_INERTIA = 4#
- RIGID_BODY_INV_INERTIA = 8#
- RIGID_BODY_INV_MASS = 7#
- RIGID_BODY_MASS = 3#
- RIGID_BODY_POSE = 1#
- RIGID_BODY_REST_OFFSET = 102#
- RIGID_BODY_SHAPE_FRICTION_AND_RESTITUTION = 100#
- RIGID_BODY_VELOCITY = 2#
- RIGID_BODY_WRENCH = 51#
DLPack Tensor Structures#
DLPack tensor structures for zero-copy data interchange.
This module provides ctypes wrappers for the vendored DLPack C header, enabling efficient data sharing between the C library and Python without copying.
NOTE: This file is NOT copied from another repo. It is a hand-written Python/ctypes mirror of the C structs defined in ovphysx/dlpack/dlpack.h (which itself is the upstream header from https://github.com/dmlc/dlpack). When the vendored C header is updated, this file must be updated to match.
- class ovphysx.dlpack.DLDataType#
Bases:
StructureDescriptor of data type for elements of DLTensor.
- TYPE_MAP = {'bfloat16': (4, 16, 1), 'float16': (2, 16, 1), 'float32': (2, 32, 1), 'float32x4': (2, 32, 4), 'float64': (2, 64, 1), 'int16': (0, 16, 1), 'int32': (0, 32, 1), 'int64': (0, 64, 1), 'int8': (0, 8, 1), 'uint16': (1, 16, 1), 'uint32': (1, 32, 1), 'uint64': (1, 64, 1), 'uint8': (1, 8, 1), 'uint8x4': (1, 8, 4)}#
- bits#
Structure/Union member
- code#
Structure/Union member
- lanes#
Structure/Union member
- class ovphysx.dlpack.DLDataTypeCode#
Bases:
c_ubyteAn integer that encodes the category of DLTensor elements’ data type.
- kDLBfloat = 4#
- kDLBool = 6#
- kDLComplex = 5#
- kDLFloat = 2#
- kDLFloat4_e2m1fn = 17#
- kDLFloat6_e2m3fn = 15#
- kDLFloat6_e3m2fn = 16#
- kDLFloat8_e3m4 = 7#
- kDLFloat8_e4m3 = 8#
- kDLFloat8_e4m3b11fnuz = 9#
- kDLFloat8_e4m3fn = 10#
- kDLFloat8_e4m3fnuz = 11#
- kDLFloat8_e5m2 = 12#
- kDLFloat8_e5m2fnuz = 13#
- kDLFloat8_e8m0fnu = 14#
- kDLInt = 0#
- kDLOpaqueHandle = 3#
- kDLUInt = 1#
- class ovphysx.dlpack.DLDevice#
Bases:
StructureRepresents the device where DLTensor memory is allocated.
- device_id#
Structure/Union member
- device_type#
Structure/Union member
- class ovphysx.dlpack.DLDeviceType#
Bases:
c_intThe enum that encodes the type of the device where DLTensor memory is allocated.
- kDLCPU = 1#
- kDLCUDA = 2#
- kDLCUDAHost = 3#
- kDLCUDAManaged = 13#
- kDLExtDev = 12#
- kDLHexagon = 16#
- kDLMAIA = 17#
- kDLMetal = 8#
- kDLOneAPI = 14#
- kDLOpenCL = 4#
- kDLROCM = 10#
- kDLROCMHost = 11#
- kDLTrn = 18#
- kDLVPI = 9#
- kDLVulkan = 7#
- kDLWebGPU = 15#
- class ovphysx.dlpack.DLManagedTensor#
Bases:
StructureC structure for managed DLPack tensor.
- deleter#
Structure/Union member
- dl_tensor#
Structure/Union member
- manager_ctx#
Structure/Union member
- class ovphysx.dlpack.DLTensor#
Bases:
StructurePlain C Tensor object, does not manage memory.
- byte_offset#
Structure/Union member
- data#
Structure/Union member
- device#
Structure/Union member
- dtype#
Structure/Union member
- ndim#
Structure/Union member
- shape#
Structure/Union member
- strides#
Structure/Union member
- class ovphysx.dlpack.ManagedDLTensor(
- dl_tensor: DLTensor,
- manager_ctx: Any,
- deleter_callback: Callable | None = None,
Bases:
objectManaged DLPack tensor wrapper (CPU-only).
- property data: int#
Data pointer address.
- property device#
Device info.
- property dtype#
Data type descriptor.
- property ndim: int#
Number of dimensions.
- property shape: tuple[int, ...]#
Shape as Python tuple.
- to_bytes() bytes#
Get pixel data as bytes (creates copy).
Contact Report Structures#
ctypes mirrors of the C ABI structs returned by
ovphysx.api.PhysX.get_contact_report(); see the C API Reference
for full field semantics.
Contact report ctypes structures.
These ctypes.Structure mirrors of the C ABI structs returned by
ovphysx_get_contact_report() are used to access per-step contact data
in Python without copying. Field layouts must stay in sync with the C definitions
in ovphysx/include/ovphysx/ovphysx_types.h.
The module has no native-library dependencies and is safe to import in any Python process; the structures are populated by ctypes against pointers returned from the C API.
- class ovphysx.contact_types.ContactEventHeader#
Bases:
StructureContact event header. Mirrors
ovphysx_contact_event_header_t.- actor0#
Structure/Union member
- actor1#
Structure/Union member
- collider0#
Structure/Union member
- collider1#
Structure/Union member
- contactDataOffset#
Structure/Union member
- frictionAnchorsDataOffset#
Structure/Union member
- numContactData#
Structure/Union member
- numfrictionAnchorsData#
Structure/Union member
- protoIndex0#
Structure/Union member
- protoIndex1#
Structure/Union member
- stageId#
Structure/Union member
- type#
Structure/Union member
- class ovphysx.contact_types.ContactPoint#
Bases:
StructurePer-contact-point data. Mirrors
ovphysx_contact_point_t.- faceIndex0#
Structure/Union member
- faceIndex1#
Structure/Union member
- impulse#
Structure/Union member
- material0#
Structure/Union member
- material1#
Structure/Union member
- normal#
Structure/Union member
- position#
Structure/Union member
- separation#
Structure/Union member
Constants#
- ovphysx.OP_INDEX_ALL#
Sentinel value (
0xFFFFFFFFFFFFFFFF) passed towait_op()to wait for all outstanding operations. Equivalent toOVPHYSX_OP_INDEX_ALLin the C API.