Skip to main content
`Ctrl`+`K`

# Quickstart

ovphysx is a self-contained SDK for ovstage/USD-based physics simulation, available as a Python wheel and a C/C++ package. This guide shows how to get started with both. You learn the required SDK layout, CMake configuration, runtime setup, and where to go next.

## Prerequisites

For both Python and C:

- Prepare a simple USD file such as `scene.usda` for ovstage population.

- x86_64 only: a CPU with AVX (Advanced Vector Extensions). Pre-built ovphysx x86_64 binaries require AVX; `ovphysx_initialize()` fails fast when AVX is unavailable. On Linux x86_64, check with `grep -qw avx /proc/cpuinfo`. Linux aarch64 wheels are unaffected.

- Install CUDA Toolkit and a compatible NVIDIA driver (recommended, but can be skipped if only CPU simulation is used).

## Quick Start by Language

### Python

Install the wheel:

    pip install ovphysx

    import ovstage
    import ovphysx
    from ovphysx import PhysX

    stage = ovstage.Stage("scene")
    ovstage.population.open_usd(
        stage, "scene.usda", ordinal=1, domains=ovstage.PopulationDomain.PHYSICS
    )

    physx = PhysX()
    physx.attach_ovstage(stage, read_ordinal=1)
    physx.step(1.0 / 60.0)
    physx.detach_ovstage()
    physx.release()
    stage.destroy()

### C/C++

Download the ovphysx SDK package from the GitHub Releases page and extract it to a local path. You also need CMake 3.16 or newer and a C or C++ compiler.

SDK Directory Layout

    ovphysx/
    ├── SKILLS.md             # Skills index
    ├── skills/               # Agent skills runbooks
    ├── include/ovphysx/     # Public headers (ovphysx.h, ovphysx_types.h, and related headers)
    ├── lib/                 # Shared libraries and CMake package config
    │   └── cmake/ovphysx/   # find_package(ovphysx) support
    ├── plugins/             # Carbonite, PhysX, and USD runtime plugins
    │   └── gpu/             # GPU-only plugins (loaded only when GPU is enabled)
    ├── samples/             # CI-tested C sample source + USD data
    ├── docs/                # Documentation (HTML + Markdown)
    ├── LICENSE.txt
    └── ovstage-THIRD-PARTY-NOTICES.txt

Build Your First App

CMakeLists.txt

The SDK ships a complete, CI-tested sample. Its CMake project links both the ovphysx and ovstage companion targets:

    cmake_minimum_required(VERSION 3.16)
    project(HelloWorldC C)

    set(CMAKE_C_STANDARD 11)
    set(CMAKE_C_STANDARD_REQUIRED ON)

    find_package(ovphysx REQUIRED)

    add_executable(hello_world_c main.c)

    # Explicitly set the language to C (not C++)
    set_source_files_properties(main.c PROPERTIES LANGUAGE C)
    set_target_properties(hello_world_c PROPERTIES
        C_STANDARD 11
        C_STANDARD_REQUIRED ON
    )

    # Add compiler-specific flags to enforce strict C compilation
    if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
        # GCC/Clang: Add -Werror=implicit-function-declaration to catch C++ leakage
        target_compile_options(hello_world_c PRIVATE
            -Werror=implicit-function-declaration
            -pedantic
        )
    endif()

    if(MSVC)
        # MSVC: Compile as C code explicitly
        target_compile_options(hello_world_c PRIVATE /TC)
    endif()

    target_link_libraries(hello_world_c PRIVATE ovphysx::ovphysx ovphysx::ovstage)
    target_include_directories(hello_world_c PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../common")
    get_filename_component(OVPHYSX_TEST_DATA_DIR "${CMAKE_CURRENT_LIST_DIR}/../../data" ABSOLUTE)
    target_compile_definitions(hello_world_c PRIVATE
        OVPHYSX_TEST_DATA="${OVPHYSX_TEST_DATA_DIR}"
    )
    if(WIN32)
        ovphysx_copy_runtime_dlls(hello_world_c)
    endif()

#### Source

The sample creates and populates an ovstage instance, attaches it with the sealed read ordinal, waits for the physics step, and cleans up in lifetime-safe order:

    #include "ovphysx/ovphysx.h"
    #include "ovstage_sample.h"
    #include <stdio.h>

    static int run(void)
    {
      // Create PhysX instance with default args
      ovphysx_create_args create_args = OVPHYSX_CREATE_ARGS_DEFAULT;
      ovphysx_handle_t handle = 0;

      ovphysx_result_t result = ovphysx_create_instance(&create_args, &handle);
      if (result.status != OVPHYSX_API_SUCCESS) {
        fprintf(stderr, "Failed to create PhysX instance\n");
      ovphysx_shutdown();
        return 1;
      }

      // Populate ovstage from USD and attach it to ovphysx
      ovphysx_sample_stage_attachment_t stage_attachment = {0};
      if (!ovphysx_sample_attach_usd_with_ovstage(
              handle, OVPHYSX_TEST_DATA "/simple_physics_scene.usda", &stage_attachment)) {
        fprintf(stderr, "Failed to attach ovstage scene\n");
        ovphysx_destroy_instance(handle);
      ovphysx_shutdown();
        return 1;
      }

      // Step the simulation
      ovphysx_enqueue_result_t step_result = ovphysx_step(handle, 0.016f);
      if (step_result.status != OVPHYSX_API_SUCCESS) {
        fprintf(stderr, "Failed to step simulation\n");
        ovphysx_sample_destroy_stage(handle, &stage_attachment);
        ovphysx_destroy_instance(handle);
      ovphysx_shutdown();
        return 1;
      }

      // Wait for step to complete
      ovphysx_op_wait_result_t step_wait_result = {0};
      ovphysx_result_t step_wait_status = ovphysx_wait_op(handle, step_result.op_index, UINT64_MAX, &step_wait_result);
      int step_ok = (step_wait_status.status == OVPHYSX_API_SUCCESS && step_wait_result.num_errors == 0);
      ovphysx_destroy_wait_result(&step_wait_result);
      if (!step_ok) {
        fprintf(stderr, "Simulation step failed\n");
        ovphysx_sample_destroy_stage(handle, &stage_attachment);
        ovphysx_destroy_instance(handle);
      ovphysx_shutdown();
        return 1;
      }

      printf("Simulation step completed successfully\n");

      ovphysx_sample_destroy_stage(handle, &stage_attachment);
      ovphysx_destroy_instance(handle);
      ovphysx_shutdown();
      printf("Cleanup complete\n");

      return 0;
    }

    int main(void) {
        ovphysx_result_t init_r = ovphysx_initialize();
        if (init_r.status != OVPHYSX_API_SUCCESS) {
            fprintf(stderr, "ovphysx_initialize() failed\n");
            return 1;
        }
      int rc = run();
      return rc;
    }

Configure and Build

Point `CMAKE_PREFIX_PATH` at the SDK root (the directory containing `include/`, `lib/`, and `plugins/`) and build the bundled sample:

    cmake -B build -S /path/to/ovphysx/samples/c_samples/hello_world_c \
      -DCMAKE_PREFIX_PATH=/path/to/ovphysx
    cmake --build build

## Runtime Libraries (C/C++)

### Linux

The CMake config bakes RPATH into your executable automatically. No `LD_LIBRARY_PATH` manipulation is needed. Run the binary directly.

### Windows

Use the `ovphysx_copy_runtime_dlls(<target>)` helper provided by the CMake package (already shown in the `CMakeLists.txt` example). This copies the required DLLs and plugins next to your executable at build time, so no ovphysx-specific `PATH` entries are required.

## Result

You now have a minimal C or C++ application that links against `ovphysx::ovphysx`, consumes an application-owned ovstage, and runs a simulation step.

## Next Steps

- Full C API reference: refer to the C API Reference

- More tutorials: Hello World, Tensor Bindings, Contact Binding