Changelog#
All notable changes to ovphysx are documented in this file.
[0.3] - 2026-03-31#
Breaking changes#
Settings API replaced with typed config system. The old string-based settings (
settings_keys/settings_values/settings_countonovphysx_create_args;ovphysx_set_global_setting()/ovphysx_get_global_setting(); PythonPhysX(settings=...),set_setting(),get_setting(); C++PhysX::setSetting()/getSetting()) are all removed. Use instead: C —ovphysx_config_entry_tarray onconfig_entries/config_entry_countwith builders fromovphysx_config.h(ovphysx_config_entry_num_threads(),_disable_contact_processing(), etc.), runtimeovphysx_set_global_config()and typed gettersovphysx_get_global_config_bool/int32/float/string(). C++ —PhysX::create(physx, entries, count)with the sameovphysx_config_entry_tbuilders. Python —PhysX(config=PhysXConfig(num_threads=4))with thePhysXConfigdataclass, runtimeset_config_bool()/set_config_int32()andget_config_bool()/get_config_int32(). Arbitrary Carbonite paths remain accessible viaovphysx_config_entry_carbonite()(C/C++) orPhysXConfig(carbonite_overrides={...})(Python).OVPHYSX_CONFIG_CUDA_DEVICEremoved fromovphysx_config_int32_tand theovphysx_config_entry_cuda_device()convenience builder. Use thegpu_indexparameter onovphysx_create_args(C) orPhysX(gpu_index=...)(Python) instead. Setting/physics/cudaDeviceviacarbonite_overridesnow raises an error.Removed typed config entries for settings not in Physics Preferences:
OVPHYSX_CONFIG_PHYSX_DISPATCHER,OVPHYSX_CONFIG_OMNI_PVD_OUTPUT_ENABLED,OVPHYSX_CONFIG_UJITSO_COLLISION_COOKING(bool);OVPHYSX_CONFIG_PVD_RECORDING_DIRECTORY(string). These settings remain accessible via thecarbonite_overridesescape hatch.Log level enum reordered to ascending severity (matches ovrtx and industry convention). New values:
OVPHYSX_LOG_VERBOSE=0,OVPHYSX_LOG_INFO=1,OVPHYSX_LOG_WARNING=2(unchanged),OVPHYSX_LOG_ERROR=3,OVPHYSX_LOG_NONE=4. Code using symbolic names (OVPHYSX_LOG_WARNING,LogLevel.WARNING) is unaffected. Code using raw integer values must update. PythonLogLevelIntEnum updated to match.Error handling switched from inline error strings to thread-local
get_last_error()query (matches ovrtx pattern).ovphysx_result_tandovphysx_enqueue_result_tno longer have anerrorfield. On failure, callovphysx_get_last_error()on the same thread to retrieve the error message (valid until the next ovphysx API call on that thread).ovphysx_op_error_tstruct removed;ovphysx_op_wait_result_tnow carrieserror_op_indices(array of failed op indices) instead oferrors(array ofovphysx_op_error_t). Callovphysx_get_last_op_error(op_index)per failed index, thenovphysx_destroy_wait_result(&result)to free the array. Removed:ovphysx_destroy_error(),ovphysx_destroy_errors(). Added:ovphysx_get_last_error(),ovphysx_get_last_op_error(),ovphysx_destroy_wait_result(). Python API is unaffected (errors are raised as exceptions).ContactEventHeader.stageIdtype changed fromlongtoint64_tfor cross-platform ABI stability (longis 4 bytes on Windows, 8 on Linux;int64_tis 8 on both). This changes the struct layout on Windows. BumpsIPhysxSimulationto 5.0 andIPhysicsSimulationto 0.4 in ovruntime.ovphysx_get_contact_report()C signature changed: now returns typed pointers (const ovphysx_contact_event_header_t**,const ovphysx_contact_point_t**) instead ofconst void**, and gained 2 new parameters (out_friction_anchors,out_num_friction_anchors). Existing C callers must update the pointer types and append, NULL, NULLfor the new friction anchor parameters. C++ callers usingPhysX::getContactReport()are unaffected (new params default tonullptr).Removed
ovphysx_articulation_get_dof_count,ovphysx_articulation_get_body_count,ovphysx_articulation_get_joint_count,ovphysx_articulation_get_is_fixed_base,ovphysx_articulation_get_fixed_tendon_count,ovphysx_articulation_get_spatial_tendon_count. Use the newovphysx_get_articulation_metadata(handle, binding, &meta)instead. The PythonTensorBindingproperties (dof_count,body_count, etc.) are unchanged.ovphysx_clone()parameterparent_positions_xyzreplaced withparent_transforms(7 floats per target: px, py, pz, qx, qy, qz, qw instead of 3). This allows specifying both position and rotation for clone parent prims. Quaternion convention: imaginary-first, matching the tensor API pose format. Identity rotation = (0, 0, 0, 1). Python:parent_positions_xyzparameter renamed toparent_transforms(7-tuples). Migration: replaceparent_positions_xyz=[x, y, z]withparent_transforms=[px, py, pz, 0, 0, 0, 1](append identity quaternion).Removed
ovphysx_set_clone_env_root()(C) andset_clone_env_root()(Python). No longer needed — the firstclone(),simulate(), orwarmup_gpu()call triggers stage attach lazily. The API ordering simplifies to:add_usd()→clone()→warmup_gpu()/step().ovphysx_device_tenum reordered:OVPHYSX_DEVICE_AUTO = 0(was 2) so that zero-initializedovphysx_create_argsdefaults to AUTO instead of GPU. Code that passes raw integer device values must update (0=AUTO, 1=GPU, 2=CPU). Code using symbolic names or string device names is unaffected.OVPHYSX_TENSOR_ARTICULATION_CORIOLIS_FORCE_F32renamed toTensorType.ARTICULATION_CORIOLIS_AND_CENTRIFUGAL_FORCE(enum value 72 unchanged). The old name was misleading — the getter computes both Coriolis and centrifugal terms.Scene query enum constants disambiguated:
OVPHYSX_SCENE_QUERY_CLOSEST→OVPHYSX_SCENE_QUERY_MODE_CLOSEST(and_ANY,_ALL);OVPHYSX_SCENE_QUERY_SPHERE→OVPHYSX_SCENE_QUERY_GEOMETRY_SPHERE(and_BOX,_SHAPE).Python: All
OVPHYSX_TENSOR_*_F32bare-int constants removed. UseTensorType.*members instead (e.g.TensorType.ARTICULATION_ROOT_POSE).Python:
OVPHYSX_API_*,OVPHYSX_LOG_*,OVPHYSX_DEVICE_*constants removed. UseApiStatus.*,LogLevel.*,DeviceType.*IntEnum members instead.Python:
OVPHYSX_OP_INDEX_ALLrenamed toOP_INDEX_ALL.Python:
kDLCPU,kDLCUDA,kDLInt,kDLUInt,kDLFloatremoved from the public API. UseDLDeviceType.kDLCPU/DLDataTypeCode.kDLFloatetc. directly.Removed
ovphysx_finalize(). Full Carbonite framework teardown now happens automatically when the last instance is destroyed viaovphysx_destroy_instance()(C/C++) orrelease()(Python). Migration: remove anyovphysx_finalize()calls — they are no longer needed or available.
Added#
OVPHYSX_CONFIG_SCENE_MULTI_GPU_MODE(int32) config entry for/physics/sceneMultiGPUMode.ConfigBool,ConfigInt32,ConfigFloat,ConfigStringIntEnums in Pythontypes.pyfor typed config key access.PhysXConfigdataclass in Pythonconfig.pyfor typed initialization config.ovphysx_articulation_metadata_tstruct (inovphysx_types.h) — plain C struct with 6 scalar topology fields.ovphysx_get_articulation_metadata()— fills the struct in one call, one lock acquire, one stream fence. Result is automatically cached by the PythonTensorBinding.Remote USD loading:
add_usd()now accepts remote URIs (omniverse://, S3 via HTTPS, Azure Blobhttps://) in addition to local file paths. Powered by the Omniverse Client Library, loaded automatically at startup. Use HTTPS virtual-hosted S3 URLs (e.g.https://bucket.s3.region.amazonaws.com/path/scene.usd).ovphysx_configure_s3()/configure_s3()— configure S3 credentials (host, bucket, region, access key, secret key, optional session token) for loading USD scenes from S3 buckets.ovphysx_configure_azure_sas()/configure_azure_sas()— configure an Azure SAS token for loading USD scenes from Azure Blob Storage.TensorBindingsAPI: DOF property tensors — stiffness, damping, limits, max velocity, max force, armature, friction properties (read/write, indexed, masked).
TensorBindingsAPI: body property tensors — mass, center-of-mass pose, inertia tensor (read/write, indexed, masked).
TensorBindingsAPI: link acceleration tensor (
[N, L, 6], read-only) for linear + angular acceleration per link.TensorBindingsAPI: dynamics query tensors (read-only) — Jacobian, generalized mass matrix, Coriolis + centrifugal forces, gravity compensation forces, link incoming joint force.
TensorBindingsAPI: DOF projected joint forces (read-only,
[N, D]).TensorBindingsAPI: standalone rigid body properties — mass (
[N]), inertia ([N, 9]), center-of-mass pose ([N, 7]), all read/write with indexed and masked write support.TensorBindingsAPI: articulation body inverse mass (
[N, L]) and inverse inertia ([N, L, 9]), both read-only.TensorBindingsAPI: fixed tendon properties — stiffness, damping, limit stiffness, limits, rest length, offset (read/write, indexed, masked). Write uses read-back + batch setter internally since PhysX requires all tendon properties to be set together.
TensorBindingsAPI: spatial tendon properties — stiffness (
[N,T]), damping ([N,T]), limit stiffness ([N,T]), offset ([N,T]) (read/write, indexed, masked). Same read-back + batch setter pattern as fixed tendons.TensorBindingsAPI: shape-level tensor types —
RIGID_BODY_SHAPE_FRICTION_AND_RESTITUTION([N,S,3]),RIGID_BODY_CONTACT_OFFSET([N,S]),RIGID_BODY_REST_OFFSET([N,S]), and articulation equivalents (ARTICULATION_SHAPE_FRICTION_AND_RESTITUTION,ARTICULATION_CONTACT_OFFSET,ARTICULATION_REST_OFFSET). All support read, indexed write, and masked write.Articulation metadata name queries:
ovphysx_articulation_get_dof_names,get_body_names,get_joint_names(variable-length string arrays; separate from scalar metadata). Scalar topology fields (dof_count,body_count,joint_count,is_fixed_base,fixed_tendon_count,spatial_tendon_count) are now returned in one call viaovphysx_get_articulation_metadata().Contact binding API:
ovphysx_create_contact_binding/destroy/get_spec/read_net_forces/read_force_matrixbacked byIRigidContactView.Python
ContactBindingclass for reading contact forces via DLPack tensors.PhysX object interop:
ovphysx_get_physx_ptr(handle, prim_path, physx_type, &out_ptr)returns raw PhysX SDK pointers (void*) by USD prim path and type enum (ovphysx_physx_type_t). Covers PxScene, PxRigidActor, PxArticulationLink, PxJoint, PxArticulationReducedCoordinate, PxShape, PxMaterial, and PxArticulationJointReducedCoordinate. The SDK now ships PhysX headers underinclude/physx/(ovphysx_PHYSX_INCLUDE_DIRin CMake). See the PhysX Interop tutorial andtests/c_samples/physx_interop_cpp/for a complete example usingsetKinematicTarget().Python API:
PhysX.get_physx_ptr(prim_path, physx_type)unified accessor.Python API:
PhysX.handleread-only property exposing the rawovphysx_handle_t.Contact report API:
ovphysx_get_contact_report()exposes the Omni PhysX runtime’s per-step contact data as typed C struct pointers (ovphysx_contact_event_header_t,ovphysx_contact_point_t). Struct definitions andovphysx_friction_anchor_tare inovphysx_types.h. Optional friction anchor output params (out_friction_anchors,out_num_friction_anchors) — pass NULL to skip.Python API:
PhysX.get_contact_report()returns a dict with ctypes arrays ofContactEventHeaderandContactPointstructs for zero-copy field access. Optionalinclude_friction_anchors=Trueadds friction anchor data.Scene query API:
ovphysx_raycast(),ovphysx_sweep(),ovphysx_overlap()— raycast, geometry sweep, and overlap queries against the physics scene. Supports CLOSEST/ANY/ALL hit modes with sphere, box, and arbitrary-shape (UsdGeomGPrim) geometry. Hit results stored in internal buffer (valid until next query).Python API:
PhysX.raycast(),PhysX.sweep(),PhysX.overlap()scene query methods.SceneQueryModeandSceneQueryGeometryTypeIntEnums in Pythontypes.py.Synchronous stepping APIs:
ovphysx_step_sync()(C) /PhysX.step_sync()(Python) combines step + wait into a single call, bypassing the async event machinery for lower per-step overhead in synchronous use patterns.ovphysx_step_n_sync()/PhysX.step_n_sync()batches N steps in one call, saving (N-1) ctypes round-trips when using decimation > 1.New status code
OVPHYSX_API_BUFFER_TOO_SMALL = 6added toovphysx_api_status_t.CMake package config (
find_package(ovphysx)) provides the imported targetovphysx::ovphysxand a Windows helperovphysx_copy_runtime_dlls().Visual sample using Rerun to visualize rigid body simulation (Rendering Handoff).
Linux aarch64 support.
Changed or fixed#
Carbonite host coexistence: ovphysx now detects when a host application (Kit, Isaac Sim) has already bootstrapped Carbonite and loaded the PhysX plugin stack. In this scenario, ovphysx skips its own plugin loading, USD preloading, and version checks, and instead acquires the host’s existing interfaces. Settings are applied with
setDefault*()to avoid overwriting host configuration; device-related settings produce a warning on mismatch. The same ovphysx version works in both standalone and host-embedded environments without configuration changes.Physics scene is now parsed lazily on the first
simulate()call instead of duringadd_usd(). This avoids GPU buffer corruption whenclone()adds environments after the initial load. Correct usage sequence:add_usd()→clone()→warmup_gpu()/step().A GPU and CUDA installation is no longer a requirement for using ovphysx with CPU-only simulation.
Fixed a fatal TF_DEBUG crash when ovphysx and OVRTX co-loaded in Python due to a collision with USD libraries.
Fixed various memory leaks across C, C++, and Python error-handling and cleanup paths.
Contact binding read functions (
read_net_forces,read_force_matrix) now validate dtype is float32 before dispatching.ContactBinding.destroy()now checks the result status and raises on failure; also validates parent SDK is still alive.create_contact_bindingnow validatessensor_patternsis non-empty,filters_per_sensor >= 0, andfilter_patternslength matchesn_sensors * filters_per_sensor.All new tensor type constants and
ContactBindingare now exported from theovphysxpackage__init__.py.Wheel metadata corrected:
Root-Is-Purelib: false, OS classifiers set to Linux and Windows.Fixed doubled path bug in
ovphysxConfig.cmakeWindows DLL copy helper. Fixed shutdown crash where stepper tasks could access freed CUDA context (OMPE-81088).Fixed process-exit crashes (OMPE-84139) caused by non-deterministic DLL/SO unload ordering at process exit.
ovphysx_destroy_instance()now performs full Carbonite framework teardown (OmniClient shutdown + plugin unload in dependency order) when the last instance is destroyed. No separate finalize call is needed – just callrelease()(Python) orovphysx_destroy_instance()(C/C++).ovphysx_remove_usd()now validatesusd_handleagainst the instance-owned handle map and returnsOVPHYSX_API_NOT_FOUNDfor unknown handles (Python raisesValueError: Failed to remove USD: USD handle not found).
Removed#
AGENTS.md is no longer shipped in the SDK or wheel (monorepo developer doc only).
ovphysx.pc(pkg-config file) removed; CMake is the supported integration path.hdStorm(Hydra Storm renderer) removed from SDK; not needed for headless physics simulation.
[0.2] - 2026-03-03#
First released version. No changelog was maintained prior to v0.3.