Tojó Tojó - 29 days ago 9
Javascript Question

Make a multi-part "fluid body" act as one single body

I am using Phaser.js and its p2 physics in order to simulate what "fluid bodies". You can see in this example that a kind of fluid body is created (credits to John Watson). The only possible interaction is with mouse movement.

I have noticed some interesting properties that could probably help me getting what I pretend which are restitution, gravity and damping. All of these are in included in the shown example.

// Add a force that slows down the droplet over time
droplet.body.damping = 0.3;

// Add bounciness and gravity
this.game.physics.p2.restitution = 0.8;
this.game.physics.p2.gravity.y = 250;


After some research and reflexion I concluded that the body I seek must be more united than the example body which means that, within certain limits, a force with the direction of the center of the body (center +- top of body) should be applied to all the "small bodies" that make the body. I suppose that after achieving that even if I move the entire body with cursors it will move all together. The overall efect I want is a pile-type body form (less mass on upper part and more mass on the bottom part):
basic illustration

The only way for the body to lose mass should be an external force applied to the body that surpasses the resistance force that keeps the body united.

Even after researcing for quite a while I seem very lost in the matter...


  • Should I literally opt for p2 forces ( I believe that exists ) ?

  • Should I use springs to connect all the small bodies? (springs)

  • How would I always get the "center of the body"?



Thanks.

Answer

Disclaimer: I have not used Phaser.js, so I can't help you with the framework. I will however try to share some of my ideas on the problem, and hopefully it helps you.

I recently wrote this answer regarding plasticity (which could be of interest to you), but what you want is slightly different.


The simulation

First, lets talk some about the simulation you showed. You write "fluid bodies", but from what I see in the code example is nothing fluid -- it's a pure particle simulation with "cheated" physics features that comes from (1) the automatic damping of the particles and (2) the restitution which in normal speak means how elastic a collision with the object is (e.g. the 0.8 value in this case means that 20% of the kinetic energy is lost with every collision). So basically, we have a particle simulation with a lot of damping.

That this yields something that looks 'fluid like' is really pretty cool, but my guess is that this is also due to the rendering (e.g. show the particles as small disks instead of the blurred thing and it will look a lot more like what you'd expect).

Your questions

Should I literally opt for p2 forces ( I believe that exists ) ?

I am actually not sure what this means, but I'm guessing it's Phaser related.

Should I use springs to connect all the small bodies? (springs)

No. If you use a elastic potential to calculate the force you will get an elastic body as differing from plasticity which is what you're looking for. What other function you use will entirely determine the behaviour of your simulation, so going with this idea there will be a lot of experimentation.

If x_cm is the position (vector) to the center of mass, and x[i] is the position of particle i, then one example could be:

F(i) = F_constant*(x_cm - x[i])

A purely linear function. F_constant is some (constant) coefficient. Particles far away will receive a greater force than particles nearby. You would then calculate this force for all particles, and apply it accordingly.

How would I always get the "center of the body"?

The center of mass of the body is straight forward to calculate. In pseudo code it looks like this:

var x_cm
var total_mass = 0
for each particle p:
    total_mass += p.mass()
    x_cm += p.mass()*p.position()
x_cm /= total_mass

Formulas are hard to display nicely here, but it's just the same as described on wikipedia.


Another possibility

This answer is already long, but just a finishing thought. From my perspective it sounds like you want something similar to sand (i.e. it is a particle simulation similar to the one you showed, but it piles as well). A common way to simulate sand is by the exact simulation as you have above, but with friction added to the particles. If this is possible to do with Phaser I don't know, but I would expect it being easy to do.


EDIT: Had a typo in the last sentence. Simulating sand with Phaser, by adding friction to the example simulation, should be easy.

Comments