| Crates.io | particle_accelerator |
| lib.rs | particle_accelerator |
| version | 0.2.1 |
| created_at | 2025-12-09 08:16:19.566915+00 |
| updated_at | 2025-12-30 16:48:11.75139+00 |
| description | Particle Accelerator – a modular, ECS-ready physics engine for Rust. |
| homepage | |
| repository | https://github.com/saptak7777/Particle_Accelerator |
| max_upload_size | |
| id | 1975025 |
| size | 428,050 |
A modular physics engine that (hopefully) won't explode your game
Particle Accelerator is a prototype physics engine for Rust. It's built with a Structure-of-Arrays (SoA) architecture and is designed to be "ECS-ready" from the ground up. It handles rigid body dynamics, joint constraints, and collision detection with an optional GPU-accelerated broadphase for when you have too many things on screen.
Fair Warning: This is a physics library, not a complete solution. You'll need to handle your own rendering, scene management, and asset loading. Think of it as the suspension for your car—it handles the bumps and collisions, but you still need a chassis and an engine to actually go anywhere.
[dependencies] particle_accelerator = "0.2.0" glam = "0.28" # Math types
ash, wgpu, or your favorite renderer).move_and_slide).use particle_accelerator::PhysicsWorld;
use glam::Vec3;
fn main() {
// Timestep is usually 1/60s.
let mut world = PhysicsWorld::new(1.0 / 60.0);
// Gravity is off by default.
world.set_gravity(Vec3::new(0.0, -9.81, 0.0));
}
use particle_accelerator::{RigidBody, Collider, ColliderShape};
use particle_accelerator::utils::allocator::EntityId;
fn setup_body(world: &mut PhysicsWorld) {
let mut body = RigidBody::new(EntityId::from_index(0));
body.transform.position = Vec3::new(0.0, 10.0, 0.0);
body.mass_properties.mass = 1.0;
let body_id = world.add_rigidbody(body);
let mut collider = Collider::builder()
.shape(ColliderShape::Sphere { radius: 0.5 })
.build();
collider.rigidbody_id = body_id;
world.add_collider(collider);
}
use particle_accelerator::core::constraints::Joint;
fn add_slider(world: &mut PhysicsWorld, body_a: EntityId, body_b: EntityId) {
let joint = Joint::Prismatic {
local_pivot_a: Vec3::ZERO,
local_pivot_b: Vec3::ZERO,
local_axis_a: Vec3::X,
enable_limit: true,
lower_limit: 0.0,
upper_limit: 5.0,
enable_motor: true,
motor_speed: 2.0,
max_motor_force: 100.0,
};
world.add_joint(body_a, body_b, joint);
}
PhysicsWorld The main entry point. Orchestrates CCD, collision generation, and constraint solving.
RigidBody
Stores physical state (velocity, mass, damping). Uses inverse_mass = 0.0 for static objects.
Collider The geometric representation. Supports Spheres, Boxes, Capsules, and Compound shapes.
world.step(dt)
The heart of the engine. In v0.2.0, it follows a strict Solve -> Integrate order:
What We've Tested:
What We Haven't Tested:
"My object tunneled through the floor!" Check if you're using high velocities and if CCD is enabled for that body. If it is and it still tunnels, your floor might be "too thin" for the timestep.
"The simulation is oscillating/shaking!"
Increase your solver iterations (velocity_iterations in PGSSolver) or decrease your timestep. Physics is sensitive.
rayon to an optional parallel feature (enabled by default).add_collider API signature in the README examples.Questions? Issues? Open a PR on GitHub. I'll probably look at it eventually. Using this in production? You're braver than I am. Let me know how it goes!