RUST · PHYSICS & ANIMATION

active-ragdoll-rs — Physical Character Animation & PD Balance Engine in Rust

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
GitHub ↗
Real-Time 3D Active Ragdoll Physics Simulation
Engine: WebGL • 50 Hz PD Loop
RAGDOLL STATE Following
MUSCLE STRENGTH 100%
FORCE COEFF 1.00
TORQUE COEFF 1.00
CONTACTS 0
FPS 60 FPS
Left Click + Drag: Orbit Camera • Scroll: Zoom
Physics Impulses & Life State
Locomotion Gait
PD Controller Gains & Torque Limits
Linear P-Force (Proportional) 12.0
Linear D-Force (Derivative) 0.02
Max Joint Spring Torque 2000
Joint Damper 0.6

Built for Modern Game Physics

High-performance algorithmic character physics designed from scratch for Rust game engines and robotics simulations.

🎯

PD Linear & Joint Drives

Applies Proportional-Derivative forces to Centers of Mass to track master bone poses, with orthonormal joint space target rotation slerping and torque clamping.

⚡

Dynamic Strength Attenuation

32-bit layer-filtered contact detection. Characters lose strength and stumble during continuous collisions, recovering balance smoothly once freed.

🦴

11-Bone Biomechanical Rig

Standard humanoid rig with anatomically realistic mass distributions (~75 kg), joint attachment anchors, swing/twist limits, and per-limb tuning overrides.

🦀

Zero-Lockin + Rapier3D

Engine-agnostic core running on pure glam math, with optional rapier3d adapter synchronizing RigidBodies, joints, and impulses.

🎮

Kinematic Master & Push-Back

Smooth 3rd-person locomotion with SmoothDampAngle turning and push-back constraint ensuring the kinematic guide stays aligned when obstructed.

💀

Knockout & Timed Revival

Supports full loss of consciousness (die()) where joint torques cut to zero for limp ragdolling, followed by timed recovery back to standing.

Unity C# to Idiomatic Rust Mapping

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

Microsecond Active Ragdolls vs. Unity C#

Comparative benchmarks testing 11-bone humanoid PD tracking, state machines, and crowd capacity against Unity.Humanoid.ActiveRagdoll. View Full BENCHMARKS.md →

Single 11-Bone Ragdoll
0.40 µs / update
362× faster than Unity C# (~145 µs)
100-Humanoid Crowd (1,100 bones)
39.3 µs (25,446 FPS)
0.24% of 16.6ms 60 FPS frame budget
250-Humanoid Crowd (2,750 bones)
98.4 µs (10,160 FPS)
Unity C# drops below 30 FPS (>36 ms)
PD Follower Joint Solver
1.09 ns / solve
917.9 Million calcs/sec (Zero Alloc)
📐 Biomechanical Control Accuracy & Stability
Validated analytically via tests/accuracy_test.rs against PID control & inverted pendulum mechanics.
66 / 66 Tests Passing
PD Force Parity
ΔF = 0.00 × 10⁻⁴
Bit-Exact Control Law
Torque Limit Clamping
0.0% Overshoot
Strict Bounded Magnitude
Pendulum Stability
τrest > τg
+50% Stability Margin
Humanoid 11-Bone Rig
100% Valid
Zero Orphan Limbs

Get Started in Seconds

Add active ragdoll physics to your Rust project with Cargo.

Cargo.toml
[dependencies]
active-ragdoll-rs = "0.1.0"
glam = "0.33"
rapier3d = { version = "0.36", optional = true }
main.rs — Standard Active Ragdoll Loop
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(())
}