C++ API Reference¶
Overview¶
NovaPhy's C++ API is organized under the novaphy namespace. Engine
physics/state quantities use float32 through Eigen *f aliases. Adapter and
diagnostic boundaries have deliberate exceptions: the libuipc compatibility
shape converter exposes Eigen::Vector3d, and performance timing/metric
values use double.
Type Aliases¶
Defined in novaphy/include/novaphy_types.h:
Defined in novaphy/include/math/math_types.h:
namespace novaphy {
using Vec3f = Eigen::Vector3f;
using Mat3f = Eigen::Matrix3f;
using Quatf = Eigen::Quaternionf;
using VecXf = Eigen::VectorXf;
using MatXf = Eigen::MatrixXf;
}
Core Types¶
RigidBody (core/body.h)¶
Stores inertial properties for a single rigid body: mass, center of mass, body-local inertia tensor, and linear / angular damping.
CollisionShape (core/shape.h)¶
ShapeType values are None, Plane, Heightfield, Sphere, Capsule,
Ellipsoid, Cylinder, Box, TriangleMesh, Cone, ConvexHull, and
Gaussian. Gaussian is render-only source geometry.
Per-shape flags are stored as the ShapeFlags bitmask (Visible,
CollideShapes, CollideParticles, Site, Hydroelastic).
Joint (core/joint.h)¶
Joint types: Revolute, Fixed, Free, Prismatic, Ball, Distance,
D6, Cable.
Articulated bodies¶
Articulated systems are represented in NovaPhy as flat per-link Joint /
RigidBody arrays consumed by the Featherstone helpers in
dynamics/featherstone/. There is no separate Articulation struct on the
C++ side; topology is owned by Model and indexed by joint / body indices.
Model (core/model.h)¶
Immutable simulation model. Created by ModelBuilder::finalize().
ModelBuilder (core/model_builder.h)¶
Mutable scene description. Add bodies, shapes, joints, and articulations.
Collision¶
IBroadPhase (collision/ibroadphase.h)¶
Interface for broadphase collision detection.
SweepAndPrune (collision/broadphase.h)¶
Available sort-based Sweep-and-Prune backend. ModelBuilder currently
defaults to the explicit broadphase mode.
Narrowphase (collision/narrowphase.h)¶
Dispatches to specialized collision pair algorithms and generates contact points.
Dynamics¶
SolverBase (dynamics/solver_base.h)¶
Newton-aligned forward-dynamics base class. Subclasses are constructed
against an immutable Model and driven through the out-of-place
step(state_in, state_out, control, contacts, dt) contract:
class SolverBase {
public:
explicit SolverBase(const Model& model);
// Uses the constructor-bound Model for topology and gravity.
virtual void step(const SimState& state_in, SimState& state_out,
const Control* control, Contacts* contacts, float dt) = 0;
virtual const char* name() const = 0;
virtual void notify_model_changed(SolverNotifyFlags flags);
virtual void update_contacts(Contacts& out, const SimState* state) const;
virtual JointSupportMatrix joint_support() const;
virtual SolverBackendInfo backend_info() const;
};
state_in and state_out may alias for in-place stepping; pass
distinct buffers when the input buffer must be preserved.
SolverSemiImplicit (dynamics/semi_implicit/solver_semi_implicit.h)¶
Free-body Sequential Impulse solver with PGS iteration.
SolverFeatherstone (dynamics/featherstone/solver_featherstone.h)¶
Articulated body solver using Featherstone algorithms.
SolverXPBD (dynamics/xpbd/solver_xpbd.h)¶
Extended Position Based Dynamics solver.
Differentiable Simulation¶
The differentiable stack is enabled by NOVAPHY_WITH_DIFF=ON and requires
CUDA. It has two C++ namespaces:
novafor the autodiff tensor, tape, operator, graph-capture, and fused kernel runtime.novaphy::difffor differentiable physics solvers built on Nova.
Nova (nova/*.hpp)¶
Main headers:
| Header | API |
|---|---|
nova/tensor.hpp |
nova::Tensor, nova::DType |
nova/tape.hpp |
nova::Tape, nova::TapeScope |
nova/ops.hpp |
add, sub, mul, div, sin, cos, relu, sum_all, matmul |
nova/operators.hpp |
C++ arithmetic operator sugar for Tensor |
nova/kernel.hpp |
nova::Kernel, nova::TraceVar, nova::make_kernel |
nova/capture_graph.hpp |
CUDA graph capture and replay helpers |
#include "nova/operators.hpp"
#include "nova/ops.hpp"
#include "nova/tape.hpp"
#include "nova/tensor.hpp"
nova::Tensor x({4}, nova::DType::F32, true);
x.fill(2.0f);
nova::Tape tape;
nova::Tensor loss({1}, nova::DType::F32, true);
{
nova::TapeScope scope(tape);
nova::Tensor y = x * x;
loss = nova::sum_all(y);
}
tape.backward(loss);
auto grad = x.grad_to_host(); // [4, 4, 4, 4]
Fused elementwise kernels are traced once and reused:
#include "nova/kernel.hpp"
nova::Kernel square_plus_one = nova::make_kernel(
[] (const nova::TraceVar& x) {
return x * x + 1.0f;
});
nova::Tensor y = square_plus_one(x);
nova::Kernel is currently an elementwise fused-kernel system. It supports
same-shape contiguous F32 tensors, reverse-mode tape records, CUDA graph
capture, and optional NVRTC JIT. Traced scalar expressions include arithmetic,
comparisons, where, sin, cos, sqrt, abs, acos, atan2,
min/max/clamp/step, and the scalar-channel TraceVec3 helper. Kernels
can be created from 1-8 input channels using the typed make_kernel overloads,
or up to 48 input channels using make_kernel_n.
Nova also provides indexed generated kernels and differentiable gather/scatter
operators for physics dataflow. These are implementation building blocks;
physics-level stepping is exposed through DiffSemiImplicitSolver.
Diff Solvers (diff/*.hpp)¶
DiffSemiImplicitSolver is the Nova-backed differentiable SolverBase
implementation. It uses the same SimState/Control/Contacts entry point as
the forward solvers; recording operations on a nova::Tape enables backward.
| Solver | Header | Differentiable entry point |
|---|---|---|
DiffSemiImplicitSolver |
diff/semi_implicit_diff_solver.hpp |
step(SimState, SimState, Control, Contacts, dt) |
#include "core/model_builder.h"
#include "diff/semi_implicit_diff_solver.hpp"
novaphy::ModelBuilder builder;
novaphy::Model model = builder.finalize(novaphy::Device::cuda(), true);
novaphy::diff::DiffSolverConfig cfg;
cfg.angular_damping = 0.05f;
novaphy::diff::DiffSemiImplicitSolver solver(model, cfg);
novaphy::SimState state_in = model.state();
novaphy::SimState state_out = model.state();
novaphy::Control control = model.control();
solver.step(state_in, state_out, &control, nullptr, 1.0f / 120.0f);
SolverMuJoCo (dynamics/mujoco/solver_mujoco.h)¶
Native MuJoCo-style articulated dynamics. The CPU implementation is always built; its CUDA backend is opt-in.
SolverVBD (dynamics/vbd/solver_vbd.h)¶
CPU VBD / AVBD rigid and soft-body solver with optional NVIDIA CUDA and Denglin DLAN backends.
SolverIPC (dynamics/ipc/solver_ipc.h)¶
Optional libuipc adapter, present only when NOVAPHY_WITH_IPC=ON. libuipc
owns its collision/contact solve while SolverIPC preserves the common
SolverBase::step call shape.
Fluid¶
PBFSolver (fluid/pbf_solver.h)¶
Position Based Fluids solver with SPH kernels and iterative density
constraint. Wrapped by SolverPBF (fluid/solver_pbf.h) to expose the
Newton-aligned SolverBase.step contract.
SolverSPH (fluid/solver_sph.h)¶
Smoothed Particle Hydrodynamics SolverBase subclass that reads and writes
external SimState::particle_* buffers. Its only current runnable backend is
enabled by NOVAPHY_WITH_SPH_CUDA=ON; there is no CPU fallback.
SolverMPM¶
fluid/solver_mpm.h exposes an API-parity scaffold. Its step() method
throws until a numerical backend is implemented.
SolverLBM (fluid/solver_lbm.h)¶
Sparse-block Lattice Boltzmann SolverBase subclass. The wrapper and its
configuration are always compiled, while the numerical backend is enabled by
NOVAPHY_WITH_LBM_CUDA=ON. Fluid distributions are solver-owned rather than
stored in SimState::particle_*; backend_info() therefore reports
SolverStateOwnership::InternalWorld. Check has_cuda_backend() before
seeding blocks, exporting a grid, or stepping.
Simulation¶
SimState (sim/state.h)¶
Mutable simulation state: body positions, velocities, joint
coordinates. Created from Model::state() and passed by reference into
SolverBase::step.
Contacts (core/contacts.h)¶
Unified structure-of-arrays contact aggregate shared between collision and
solvers. Rigid contacts live in rigid_contact_* columns; particle /
soft-point contacts live in soft_contact_* columns. Collision is run
explicitly through CollisionPipeline::detect_contacts /
Model::collide; most solvers consume the contact aggregate passed to
SolverBase::step. SolverIPC is the exception: libuipc performs collision
internally and ignores the Contacts pointer.
PerformanceMonitor (sim/performance_monitor.h)¶
Standalone per-phase timing utility with Chrome / Perfetto trace
export. Driven externally with
detail::PerformancePhaseScope from C++ or
with monitor.scoped(): solver.step(...) from Python; solver public
APIs do not take a monitor parameter.
IO¶
UrdfParser (io/urdf_parser.h)¶
Parses URDF files into the UrdfModelData intermediate representation.
OpenUSDImporter (io/openusd_importer.h)¶
Parse NovaPhy's conservative, line-oriented USDA text subset. This class does
not link the OpenUSD SDK or support binary .usdc crates.
Building with CMake¶
find_package(novaphy CONFIG REQUIRED COMPONENTS core)
target_link_libraries(your_target PRIVATE novaphy::core)
# If using Nova/differentiable APIs:
# find_package(novaphy CONFIG REQUIRED COMPONENTS core diff)
# target_link_libraries(your_target PRIVATE novaphy::diff)
# If using the VBD module:
# target_link_libraries(your_target PRIVATE novaphy::vbd)
Or via add_subdirectory: