Skip to content

Create Solver to run your simulation

tecno-master edited this page Aug 8, 2024 · 2 revisions

A Scene by itself does nothing. It stores spheres but thats it. If you want your scene to physically function you will need to create and use a solver.

Step 1: Create a Solver
A Solver needs a scene object in order to be created. This scene will be "solved" during the runtime.

Solver solver = Verlet.createSolver(scene);

Step 2: Step the simulation
This step requires some sort of gameloop. You will probably want to run the simulation at a stable framerate. Often game engines / game frameworks have such a gameloop. You can also program this gameloop by yourself. There is tutorials online.

The following code is executed 60 times every second. You can obviously customize that yourself.

the "step" method iterates the simulation with a given time. The float parameter is time in seconds that should be iterated. Calling it once with an input of 1f will step the simulation forward for 1 second.

solver.step(0.02f);

Step 3: Rerendering the simulation
After iterating the simulation you will want to render it, to see the changes. In this example we use java.swing for the rendering so just we repaint the panel

solver.step(0.02f);
panel.repaint();

Additional options

You can customize your solver to fit the correct scenario and to improve performance.

Set gravity
Read more about gravity here.

You can customize the gravity of your simulation to your needs. The custom gravity is (0, -1000). This means the x axis is not affected at all and the y axis gets a force of -1000. This results the spheres to fall down.
In this example gravity is inverted, making spheres to fly up.

solver.setGravity(0, 1000);

Use sub-steps
Read more about sub-stepping here.

When your scene has alot of spheres, you will notice that these spheres start to look weird. They look like they are trying to squash each other. This is because scenes with more spheres require more sub-steps.
Sub steps are steps that are additionally performed on each step. Having 4 sub steps means on each step. The whole simulation gets solved 4 times, which increases its accuracy.

solver.setSubSteps(8);

Use multi-threading
Read more about multi-threading here.

Using multi-threading will split the process of solving sphere collisions between multiple threads that run at the same time. Default for multi-threading is one meaning no additional threads are running. This can speed up process depending on the scene and your computer. Using too many threads will slow performance down, so don't go too crazy. It is best to just try out what works the fastest on your device.

solver.setMultiThreading(8);

Use the VerletGrid
Read more about the VerletGrid here.

You can apply a VerletGrid to your scene. You will have to specify the position and size of that grid. After applying a grid, spheres will be solved using this grid. Therefor spheres that are outside this grid cannot be solved. You also need to specify the grid radius which means how big each grid cell is. The grid cells need to be atleast as big as the biggest sphere radius in your scene. If there is a sphere that is bigger than the grid radius, unexpected things will happen.
This code sets a centered grid with the width of 1920 and the height of 1080. It sets the grid radius to 25 meaning no spheres are allowed to be bigger than 25.

solver.setGrid(new VerletGrid(1920,1080, 25));

Full code:

// Runs when your program starts
public void start() {
  Solver solver = Verlet.createSolver(scene);

  solver.setGravity(0, 1000);
  solver.setSubSteps(8);
  solver.setMultiThreading(8);
  solver.setGrid(new VerletGrid(1920,1080, 25));
}

// Runs 60 times a second
public void tick() {
  solver.step(0.02f);
  panel.repaint();
}

Clone this wiki locally