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):

Listing 1 Stream-ordered operation sequence#
 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: object

High-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 publishes xformOp:transform per 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:transform pose channel is deferred to the first step() 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 (with handle() returning the int cast of ovstage_instance_t*), or a raw int handle.

Preconditions:
  • Instance must be valid.

  • Not already attached to a Stage.

  • stage must outlive this attachment — call detach_stage() (or destroy this instance) before destroying the Stage.

Errors:
  • Raises RuntimeError if already attached, stage is 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,
) int#

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 is stage.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,
) ContactBinding#

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 via ContactBinding.read_contact_data() and ContactBinding.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() or read_force_matrix() after PhysxSDK.step(). Before the first step, both return all-zeros tensors.

Result tensor shapes after step:
  • net forces: [S, 3] where S = matched sensor count

  • force matrix: [S, F, 3] where F = matched filter count per sensor

  • detailed data: flat [C, 1] or [C, 3] buffers indexed by counts and start_indices with shape [S, F]

Use ContactBinding.sensor_paths and ContactBinding.filter_paths to 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. Pass None with filters_per_sensor=0 to 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_sensor to 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,
) TensorBinding#

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, raise ValueError when the binding matches zero prims. The default keeps empty bindings valid.

Returns:

TensorBinding object for reading/writing tensor data.

Raises:
  • ValueError – If neither pattern nor prim_paths is provided, both are, or raise_if_empty is 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 pattern or prim_paths must 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 ValueError for invalid arguments.

  • Raises RuntimeError on 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 RuntimeError on 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,
) dict#

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 of ContactEventHeader structs describing each contact pair (actors, colliders, event type). Length is num_headers.

  • num_headers (int): Number of contact event headers.

  • points: ctypes array of ContactPoint structs with per-contact-point data (position, normal, impulse, separation). Length is num_points.

  • num_points (int): Number of contact point entries.

  • anchors (only if include_friction_anchors=True): ctypes array of FrictionAnchor structs. Length is num_anchors.

  • num_anchors (int, only if include_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 PhysxContactReportAPI applied 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 PhysXType enum members (or matching int) indicating which PhysX object type to look up.

Returns:

Integer address of the PhysX pointer, or 0 if 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 0 return 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() and clone() do NOT invalidate pointers. Do not call release() 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_t for 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,
) list[dict]#

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.

Parameters:
  • geometry_typeSceneQueryGeometryType.

  • modeSceneQueryMode (ANY or ALL; CLOSEST treated as ALL).

  • **kwargs – Geometry parameters (same as sweep()).

Returns:

List of hit dicts (same format as raycast()).

raycast(
origin: tuple | list,
direction: tuple | list,
distance: float,
mode: SceneQueryMode = SceneQueryMode.CLOSEST,
both_sides: bool = False,
) list[dict]#

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).

  • modeSceneQueryMode (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,
) None#

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,
) list[dict]#

Sweep a geometry shape along a direction and return hits.

Parameters:
  • geometry_typeSceneQueryGeometryType.

  • direction – Normalized sweep direction [x, y, z].

  • distance – Maximum sweep distance (>= 0).

  • modeSceneQueryMode.

  • both_sides – If True, test both sides of mesh triangles.

  • **kwargs

    Geometry parameters:

    • SPHERE: radius, position

    • BOX: 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: object

Tensor 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() or torch.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: object

Contact tensor binding backed by IRigidContactView.

Do not instantiate directly. Use PhysxSDK.create_contact_binding() to obtain an instance. The sensor_paths and filter_paths properties 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,
) None#

Read detailed contact data into flat buffers.

Expected shapes are [C, 1] for contact_forces and separations, [C, 3] for positions and normals, and [sensor_count, filter_count] for counts and start_indices. C is max_contact_data_count; both C and filter_count must 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,
) None#

Read detailed friction data into flat buffers.

Expected shapes are [C, 3] for friction_forces and friction_points, and [sensor_count, filter_count] for counts and start_indices. C is max_contact_data_count and must be positive; filter_count must 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,
) None#

Configure S3 credentials for remote USD loading via HTTPS S3 URLs.

Credentials are process-global and take effect immediately for all PhysX instances. Call before PhysX.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 (None if 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 PhysX instances. Call before PhysX.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_2511 from os.environ to force re-registration.

Raises:

RuntimeError – If no existing ovphysx plugins/usd directory 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 False to suppress the built-in console output while keeping callbacks active. Call with True to re-enable it.

This is independent of callback registration and the global log level.

Parameters:

enableTrue to enable (default), False to 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: object

Typed 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: IntEnum

Return 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: IntEnum

Prim 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: IntEnum

Boolean 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: IntEnum

Float 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: IntEnum

Int32 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: IntEnum

String 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: IntEnum

Device 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: IntEnum

Log level for ovphysx output. Mirrors ovphysx_log_level_t.

ERROR = 3#
INFO = 1#
NONE = 4#
VERBOSE = 0#
WARNING = 2#
exception ovphysx.types.PhysXDeviceError#

Bases: RuntimeError

Raised 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: IntEnum

PhysX object type identifiers for ovphysx_get_physx_ptr().

Values match ovphysx_physx_type_t in ovphysx_types.h (which in turn matches omni::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#
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: IntEnum

Geometry 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: IntEnum

Scene 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: IntEnum

Tensor 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_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: Structure

Descriptor 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_ubyte

An 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: Structure

Represents the device where DLTensor memory is allocated.

device_id#

Structure/Union member

device_type#

Structure/Union member

class ovphysx.dlpack.DLDeviceType#

Bases: c_int

The 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: Structure

C structure for managed DLPack tensor.

deleter#

Structure/Union member

dl_tensor#

Structure/Union member

manager_ctx#

Structure/Union member

class ovphysx.dlpack.DLTensor#

Bases: Structure

Plain 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: object

Managed 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 raw_dltensor: DLTensor#

Access underlying DLTensor (advanced use).

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: Structure

Contact 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: Structure

Per-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

class ovphysx.contact_types.FrictionAnchor#

Bases: Structure

Friction anchor data. Mirrors ovphysx_friction_anchor_t.

impulse#

Structure/Union member

position#

Structure/Union member

Constants#

ovphysx.OP_INDEX_ALL#

Sentinel value (0xFFFFFFFFFFFFFFFF) passed to wait_op() to wait for all outstanding operations. Equivalent to OVPHYSX_OP_INDEX_ALL in the C API.