Skip to content

This project aims at creating a realtime physics engine to be used in games

License

Notifications You must be signed in to change notification settings

Radi3nt/LWPhysicsEngine

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Lightweight Physics Engine (LWPhysicsEngine)

This project aims at creating a realtime physics engine to be used in games

Features

  • Different types of integration
    • Euler
      • Semi implicit
      • Implicit
    • Runge–Kutta 4
  • Collision detection
    • Shapes
      • Square
      • Cube
      • Capsule
      • Triangles
    • Broadphase
      • Sweeping
      • OBBs and AABBs
      • Bounding Sphere
    • Narrowphase
      • Separating axis theorem
      • Gilbert–Johnson–Keerthi algorithm
  • 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

Optimizations

Sparse matrices multiplcation algorithm were implemented to make constraint solving as fast possible.
Currently, the main bottleneck is collision detection.

Roadmap

  • More shapes support
  • Optimizing collision detection even further

Screenshots

App Screenshot

App Screenshot

App Screenshot

Installation

Install with maven, you'll need one dependency, which you can get by clicking on the link below:

Usage/Examples

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()));

Support

For support, email [email protected] or send a message on discord to @radi3nt.

Authors