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 [email protected] or send a message on discord to @radi3nt.