This project aims at creating a realtime physics engine to be used in games
- Different types of integration
- Euler
- Semi implicit
- Implicit
- Runge–Kutta 4
- Euler
- Collision detection
- Shapes
- Square
- Cube
- Capsule
- Triangles
- Broadphase
- Sweeping
- OBBs and AABBs
- Bounding Sphere
- Narrowphase
- Separating axis theorem
- Gilbert–Johnson–Keerthi algorithm
- Shapes
- Manifold generation
- GJK/SAT manifold generation
- Persistent manifold
- Collision response
- Separation/resting/collision contact handling
- Collision contact:
- Bounce factor
- Static/kinetic friction factor
- Resting contact
- Prevents further penetration
- Applies friction
- Constrainted merged in global constraint solver
- Constraints
- Island splitting
- Gauss-Seidel SLE solver
- Support arbitrary constraints
- Sleeping
- Objects are put to sleep if not moving for a while, allowing skipping collision detection
Sparse matrices multiplcation algorithm were implemented to make constraint solving as fast possible.
Currently, the main bottleneck is collision detection.
- More shapes support
- Optimizing collision detection even further
Install with maven, you'll need one dependency, which you can get by clicking on the link below:
public class PhysicsLogic { public static final float DT = 1/120f; private final Simulation simulation = new Simulation(); private boolean stopped; private float timeScale = 1; public PhysicsLogic() { } public void start() { startPhysicsSimulation(); } private void startPhysicsSimulation() { Thread thread = new Thread(() -> { float accumulatedTime = 0; while (!stopped) { long startedTime = System.currentTimeInMillis(); float timeScale = this.timeScale; if (timeScale > 0) { simulation.step(DT * timeScale); accumulatedTime += DT * timeScale; } long ellapsed = System.currentTimeInMillis() - startedTime; if (ellapsed < DT*1_000) { long timeToWait = DT*1_000 - ellapsed; try { Thread.sleep(timeToWait); } catch(Exception e) { e.printStackTrace(); } } } }, "Physics thread"); thread.start(); } public Simulation getSimulation() { return simulation; } public void stop() { stopped = true; } public void setTimeScale(float timeScale) { this.timeScale = timeScale; } }
And then you can add rigidbodies this way
Matrix3x3 iBIT = ArrayMatrix3x3.newIdentity(); float mass = 1; iBIT.scale(new SimpleVector3f(1/(12f*mass), 1/(12f*mass), 1/(12f*mass))); DynamicsProperties dynamicsProperties = new DynamicsProperties(1/mass, iBIT, 1, 1, 1); BoxShape boxShape = new BoxShape(new SimpleVector3f(1f, 1f, 1f)); simulation.getRigidBodyIsland().add(new RigidBody(0, DynamicsData.zero(dynamicsProperties), new CollisionData(boxShape, null), new NoSleepingData()));
For support, email pro.radi3nt@gmail.com or send a message on discord to @radi3nt.