Real-time ECS physics
README
ofxEdyn
Real-time ECS physics for openFrameworks, powered by Edyn.

Edyn (_Entity Dynamics_) is a multi-threaded rigid body physics engine organised entirely as an ECS using EnTT. Because rigid bodies are just components on
entt::entity handles, they compose naturally with ofxEnTTKit and ofxKit.Features
- Dynamic, static and kinematic rigid bodies
- Shapes: box, sphere, capsule, cylinder, plane, convex polyhedron, triangle mesh
- Constraints: distance, hinge, point, CV-joint, cone, generic
- Broad-phase DBVT + narrow-phase SAT collision detection
- Raycasting and AABB queries
- Parallel island simulation
- Networked physics (client/server extrapolation)
- Sequential-impulse solver with warm-starting and proper restitution propagation
Dependencies
| Addon | Role |
|---|---|
| ofxEnTT | Provides the EnTT headers used by Edyn |
addons/ folder of your openFrameworks installation.Edyn submodule
Edyn's source is included as a git submodule at
libs/edyn/.The submodule uses sparse checkout so only
include/, src/ and cmake/ are checked out — Edyn's test/ and examples/ directories never land on disk and can't accidentally be compiled.First-time setup
git clone https://github.com/ofKitty/ofxEdyn.git
cd ofxEdyn
bash setup.shsetup.sh runs git submodule update --init then configures sparse checkout in one step.Updating Edyn
cd libs/edyn && git pull origin master && cd ..
git add libs/edyn && git commit -m "chore: bump edyn submodule"
sparse-checkout settings are preserved on pull
Component overlap (what duplicates, what doesn't)
ecs:: side | edyn:: side | Notes | |
|---|---|---|---|
| Shape | ecs::primitive_component (BOX, SPHERE …) | edyn::box_shape, edyn::sphere_shape … | Intentional duplicate. ecs::primitive_component is the source of truth. attachPhysics() copies dimensions into Edyn's internal shape component, which its collision systems require. Resize via ecs::primitive_component and call attachPhysics again. |
| Position | ecs::LocalTransform | edyn::position + edyn::present_position | Not a conflict — Edyn owns the live simulation state, syncToLocalTransform() writes the interpolated result back to ecs::LocalTransform each frame. |
| Material | ecs::material_component | edyn::material | No overlap. ecs:: = render (diffuse, specular). edyn:: = physics surface (restitution, friction). Different structs, different domains. |
| Body desc | ecs::rigidbody_component | edyn::dynamic_tag, edyn::mass, edyn::linvel … | ecs::rigidbody_component is inspector-facing (initial values). attachPhysics() reads it once; live simulation state lives in Edyn's components. |
Quick-start
#include "ofxEdyn.h"
// ---- ofApp members ----
entt::registry registry;
ofxEdyn physics;
// ---- setup() ----
physics.setup(registry);
// Optional: run synchronously (single-threaded, easier to debug)
// edyn::init_config cfg;
// cfg.execution_mode = edyn::execution_mode::sequential;
// physics.setup(registry, cfg);
// Static ground
ofxEdyn::makeStaticPlane(registry);
// Dynamic box at (0, 5, 0)
ofxEdyn::makeBox(registry, glm::vec3(0, 5, 0));
// ---- update() ----
physics.update(registry);
// ---- draw() ----
ofxEdyn::drawDebug(registry); // wire-frame boxes + spheres
// ---- exit() ----
physics.exit(registry);Advanced: raw Edyn API
ofxEdyn.h is a thin convenience layer — you can call the Edyn API directly at any time:// Component-level rigidbody definition
auto def = edyn::rigidbody_def{};
def.kind = edyn::rigidbody_kind::rb_dynamic;
def.position = {0, 4, 0};
def.shape = edyn::capsule_shape{0.3f, 0.8f};
def.mass = 2.0f;
def.material = edyn::material{0.25f, 0.6f}; // restitution, friction
def.gravity = edyn::gravity_earth;
auto entity = edyn::make_rigidbody(registry, def);
// Refresh a value you changed directly on a component
registry.patch<edyn::linvel>(entity, [](auto& v){ v = {0, 5, 0}; });
edyn::refresh<edyn::linvel>(registry, entity);Type conversions
// glm ↔ edyn
edyn::vector3 ev = ofxEdyn::toEdyn(glm::vec3(1, 2, 3));
glm::vec3 gv = ofxEdyn::toGlm(ev);
edyn::quaternion eq = ofxEdyn::toEdyn(glm::quat(...));
glm::quat gq = ofxEdyn::toGlm(eq);build_settings.h
The file
libs/edyn/include/edyn/build_settings.h replaces the header that CMake normally generates. Edit it to toggle:| Define | Effect |
|---|---|
EDYN_DOUBLE_PRECISION | Use double instead of float for all scalar math |
EDYN_DISABLE_PROFILING | Strip profiling instrumentation (on by default) |
Examples
| Folder | Description |
|---|---|
example-rigidbodies | Falling boxes and spheres; keyboard controls to spawn, reset and pause |
License
Edyn is MIT licensed — see
libs/edyn/LICENSE. ofxEdyn wrapper code is also MIT — see LICENSE.
ofxAddons