active-ragdoll-rs is a pure Rust physics animation library for blending keyframe character poses with real-time rigid-body dynamics. It uses proportional-derivative (PD) joint torque controllers and center-of-mass balance solvers so game characters react naturally to impacts and uneven terrain.
$ cargo add active-ragdoll-rs
High-performance algorithmic character physics designed from scratch for Rust game engines and robotics simulations.
Applies Proportional-Derivative forces to Centers of Mass to track master bone poses, with orthonormal joint space target rotation slerping and torque clamping.
32-bit layer-filtered contact detection. Characters lose strength and stumble during continuous collisions, recovering balance smoothly once freed.
Standard humanoid rig with anatomically realistic mass distributions (~75 kg), joint attachment anchors, swing/twist limits, and per-limb tuning overrides.
Engine-agnostic core running on pure glam math, with optional rapier3d adapter synchronizing RigidBodies, joints, and impulses.
Smooth 3rd-person locomotion with SmoothDampAngle turning and push-back constraint ensuring the kinematic guide stays aligned when obstructed.
Supports full loss of consciousness (die()) where joint torques cut to zero for limp ragdolling, followed by timed recovery back to standing.
Direct 1:1 architectural parity with Unity Humanoid Active Ragdoll.
| Unity C# Component | Rust Port Module | Mathematical Model / Responsibility |
|---|---|---|
AnimationFollowing.cs |
src/follower.rs |
PD controller linear COM tracking ($F = P(e + D \frac{\Delta e}{\Delta t})$) & joint space target rotation |
SlaveController.cs |
src/controller.rs |
State machine (FollowingAnimation, LoosingStrength, GainingStrength, Dead) |
CollisionDetector.cs |
src/collision.rs |
32-bit LayerMask filtering and active contact counter |
HumanoidSetUp.cs |
src/humanoid.rs |
Humanoid hierarchy validation & 11-bone standard anatomical rig |
MasterController.cs |
src/master.rs |
3rd-person kinematic locomotion, smooth turning, push-back distance constraint |
ShootObject.cs |
src/projectile.rs |
Ballistic projectile shooting and momentum transfer for knockdown testing |
FlyCamera.cs |
src/camera.rs |
6DOF free-look inspection camera controller |
ConfigurableJoint |
src/rapier/adapter.rs |
Direct Rapier3D rigid bodies, spherical impulse joints, and velocity impulses |
Comparative benchmarks testing 11-bone humanoid PD tracking, state machines, and crowd capacity against Unity.Humanoid.ActiveRagdoll. View Full BENCHMARKS.md →
tests/accuracy_test.rs against PID control & inverted pendulum mechanics.Add active ragdoll physics to your Rust project with Cargo.
[dependencies]
active-ragdoll-rs = "0.1.0"
glam = "0.33"
rapier3d = { version = "0.36", optional = true }
use active_ragdoll_rs::prelude::*;
use glam::{Quat, Vec3};
fn main() -> Result<()> {
// 1. Build a standard 11-bone humanoid active ragdoll
let mut ragdoll = HumanoidActiveRagdollBuilder::standard_humanoid_11()
.build()?;
let dt = 0.02; // 50 Hz physics step
let limb_count = ragdoll.limb_count();
// 2. Supply animated master transforms and current slave physics states
let master_world = vec![Transform3d::IDENTITY; limb_count];
let master_local = vec![Quat::IDENTITY; limb_count];
let slave_states = vec![
SlaveLimbPhysicsState {
world_center_of_mass: Vec3::ZERO,
world_rotation: Quat::IDENTITY,
local_rotation: Quat::IDENTITY,
angular_velocity: Vec3::ZERO,
};
limb_count
];
// 3. Step active ragdoll physics
let drive_outputs = ragdoll.update(&master_world, &master_local, &slave_states, dt)?;
for (i, drive) in drive_outputs.iter().enumerate() {
// Apply linear force impulse to slave rigid body
println!("Limb [{}] force: {:?}", i, drive.linear_force);
}
Ok(())
}