2D soft bodies: Gelly and moldable?

2019-06-15 07:54发布

问题:

I am using Matter.js physics in an attempt to create soft bodies. I was able to create a body like this:

However I am not sure if this is the "soft body" I want. It is true that this body is not entirely rigid and has that bouncy feel when it collides and gets dragged. I was looking for a body that shares similarities with a gelly. This image might visually help explaining the concept:

I was wondering how these type of bodies can be made. Is it the same as the as matter.js soft body but with a very specific type of properties? I can only get the body to be kind of rigid-squared and not as moldable and circular as I would like it to be.

I am also interesting in manipulating the physics body with in-game interactions which would increase or decrease the physics body size which leads me once more to the conclusion that the type of body that I want must be quite moldable.

Can matter.js handle this or do I have to change the physics engine? Any solutions to approach this?

NOTE: I am using Phaser.js for some in-game components but matter.js physics for physics manipulation because I believe Phaser integrated Physics can't simulate this type of complex body.

Thanks

EDIT: It is very similar to this Box2d :roll soft body ball. I just need to do that with a js engine I guess. Is there any?

回答1:

As I mentioned in the comments, I am not familiar with phaser or how you would actually implement this within a Javascript framework. My goal here is maybe to give you some ideas on different ways to proceed, so hopefully you'll find this answer useful.


I will try to answer this:

I was wondering how these type of bodies can be made. ... I can only get the body to be kind of rigid-squared and not as moldable and circular as I would like it to be.

It is not necessarily clear what you want given this sentence. As I noted in comments, what I think you are looking for is plasticity, and I will describe a way which you could possible "cheat" that look with somewhat simple tools.

At the moment you describe the motion of your body by "It is true that this body is not entirely rigid and has that bouncy feel when it collides and gets dragged.". Currently your model works as such:

  1. A point is connected to all other points as given in your mesh.
  2. Every time step, a force is calculated between each pair. The total force on a joint (or point) is the sum of all these pair wise forces.
  3. Each joint is associated with a part of the body (i.e. it has some mass m) and you calculate its acceleration with acceleration = force/m. From there on we calculate velocity and finally position.

The most interesting part of the steps above is nr 2, as that will greatly influence the motion of the whole body. A very common way to implement it is as an elastic potential that for a certain distance between two points gives some force. Like so:

function elasticPotential(p1, p2) {
    // Given two positions p1 and p2 we calculate a force between them
    distance = sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2) + pow(p1.z - p2.z, 2));
    force = force_given_distance(distance); // A popular choice here is for example a spring force
    return force;
}

Now, you already have the function described above built in in your framework, so you don't have to implement it. The reason I'm describing this is because it is essential to understanding how we can create plasticity. The problem with the above is that nothing will retain deformation---the nature of the elastic potential is that it has some rest configuration (most likely your first configuration) and it will always try to get back to that shape. We want the shape to remember how it was mis-shaped. This is what plasticity is.

Simple plasticity

Note first here that the problem of plasticity is a big research topic and in many cases far from trivial. My idea is as follows: if the distance between two connected points are larger than some threshold, remesh the points in the current configuration. That is,

for each pair(p1, p2):
    if distance(p1, p2) > threshold:
        recalculate_connection(p1, p2)

As you can see this is a very simple model for plasticity, and most likely not physically correct. However, it should be possible to get interesting behaviours my playing with the remeshing together with what elastic potential you choose.

If you provide me with more details I might be able to discuss the problem further, but right now I feel this answer is already longer than it should be.


TL;DR: Create a "moldable" shape by remeshing your body during deformation. It might be tricky to get an exact desired physical behaviour, but it should be possible to create something that looks "gelly-like".