Skip to content

Quick Start

This guide walks you through your first NovaPhy simulation.

Free Body Simulation

Create a box that falls under gravity onto a ground plane:

import numpy as np
import novaphy

# Build the scene
builder = novaphy.ModelBuilder()
builder.add_ground_plane(y=0.0)

# Add a box (mass=1kg, half-extents 0.5m)
body = novaphy.RigidBody.from_box(1.0, np.array([0.5, 0.5, 0.5]))
idx = builder.add_body(body, novaphy.Transform.from_translation(np.array([0, 5, 0])))
builder.add_shape(novaphy.CollisionShape.make_box(np.array([0.5, 0.5, 0.5]), idx))

# Create world and simulate
world = novaphy.World(builder.build())
for step in range(600):
    world.step(1.0 / 120.0)
    if step % 120 == 0:
        pos = world.state.transforms[idx].position
        print(f"t={step/120:.1f}s  y={pos[1]:.3f}")

Choosing a Solver

NovaPhy supports multiple solver backends. Use the --solver flag in demos:

python demos/demo_pyramid_ball.py --solver semi_implicit    # Default free-body PGS
python demos/demo_pyramid_ball.py --solver featherstone     # Articulated body solver
python demos/demo_pyramid_ball.py --solver xpbd             # XPBD constraints

Articulated Bodies

Create a revolute pendulum with Featherstone dynamics:

import numpy as np
import novaphy

art = novaphy.Articulation()
joint = novaphy.Joint()
joint.type = novaphy.JointType.Revolute
joint.axis = np.array([0, 0, 1])
art.joints = [joint]
art.bodies = [novaphy.RigidBody.from_box(1.0, np.array([0.1, 0.5, 0.1]))]
art.build_spatial_inertias()

q = np.array([0.5])      # initial angle
qd = np.zeros(1)         # initial velocity
gravity = np.array([0, -9.81, 0])

# Forward dynamics: compute acceleration
qdd = novaphy.forward_dynamics(art, q, qd, np.zeros(1), gravity)
print(f"Angular acceleration: {qdd[0]:.4f} rad/s^2")

# Mass matrix
H = novaphy.mass_matrix_crba(art, q)
print(f"Mass matrix: {H}")

Fluid Simulation

Run a Position Based Fluids dam break:

import numpy as np
import novaphy

builder = novaphy.ModelBuilder()
builder.add_ground_plane(y=0.0)

fluid_block = novaphy.FluidBlockDef()
fluid_block.lower = np.array([0.0, 0.0, 0.0])
fluid_block.upper = np.array([1.0, 1.0, 1.0])
fluid_block.particle_spacing = 0.05

settings = novaphy.PBFSettings()
settings.kernel_radius = 4.0 * 0.05
settings.solver_iterations = 4

fluid_world = novaphy.FluidWorld(builder.build(), [fluid_block], pbf_settings=settings)
for _ in range(500):
    fluid_world.step(1.0 / 120.0)

Visualization

NovaPhy uses Polyscope for 3D visualization. Most demos include built-in visualization:

# Install polyscope
pip install polyscope

# Run a visual demo
python demos/demo_pyramid_ball.py
python demos/demo_dam_break.py
python demos/demo_vbd_contacts_gui.py

Next Steps