How to make verlet integration collisions more stable?
Asked Answered
F

1

18

I'm not using any engine, but instead trying to build my own softbody dynamics for fun using verlet integeration. I made a cube defined by 4x4 points with segments keeping its shape like so:

The structure of my box

I have the points collide against the edges of the scene and it seems to work fine. Though I do get some cases where the points collapses in itself and it'll create a dent instead of maintaining its box shape. For example, if it's a high enough velocity and it lands on its corner it tends to crumble:

enter image description here

I must be doing something wrong or out of order when solving the collision. Here's how I'm handling it. It's in Javascript, though the language doesn't matter, feel free to reply with any language:

sim = function() {
    // Sim all points.
    for (let i = 0; i < this.points.length; i++) { 
        this.points[i].sim();
    }

    // Keep in bounds.
    let border = 100;

    for (let i = 0; i < this.points.length; i++) { 
        let p = this.points[i];

        let vx = p.pos.x - p.oldPos.x;
        let vy = p.pos.y - p.oldPos.y;

        if (p.pos.y > height - border) {
         // Bottom screen
         p.pos.y = height - border;
         p.oldPos.y = p.pos.y + vy;
        } else if (p.pos.y < 0 + border) {
         // Top screen
         p.pos.y = 0 + border;
         p.oldPos.y = p.pos.y + vy;
        }

        if (p.pos.x < 0 + border) {
         // Left screen
         p.pos.x = 0 + border;
         p.oldPos.x = p.pos.x + vx;
        } else if (p.pos.x > width - border) {
         // Right screen
         p.pos.x = width - border;
         p.oldPos.x = p.pos.x + vx;
        }  
    }

    // Sim its segments.
    let timesteps = 20;

    for (let ts = 0; ts < timesteps; ts++) {
        for (let i = 0; i < this.segments.length; i++) { 
            this.segments[i].sim();
        }
    }
}

Please let me know if I need to post any other details.

Firstrate answered 17/4, 2018 at 13:33 Comment(2)
Can you provide a jsfiddle.Triacid
You can use this as an example openprocessing.org/sketch/536805Firstrate
C
1

This may be better answered on a physics or game-dev exchange (and likely has already been), but i'll give it a crack because it's nice to revisit this stuff...

Verlet integration is a fantastically stable if not physically accurate method, but the problem here is not the integration method, or anything you've done wrong as far as I can see; it's the type of simulation: mass-aggregate physics (the building of geometry out of dynamic constraints), which is really nice and simple :) but has some inherent deficiencies and limitations, and this particular problem is inherent to the simulation type.

First, look carefully at the arrangement of constraints in the collapsed box - they are just as valid as the initial one. Although individual constraints may not be as satisfied, in combination they are still in a local equilibrium with each other - there nothing compelling them to form their original arrangement.

Second, the external force (collision with immovable plane) is what overcame the constraint forces originally. Even if the constraints respond proportionally towards infinity as they compress - the simulation can never match reality because it works a frame at a time not continuously, and the longer the frame the more error.

To retain shape more reliably, a more explicit angular constraint is needed, which usually involves quaternions - these are quite a bit harder to implement than distance constraints, and once you have them you will be pretty far along the road to implementing rigid body physics anyway. But there are ways to mitigate instead:

1. Use a smaller interval

All posteriori simulations and numerical integration in general has some inherent instability. While different integration methods (e.g verlet) can mitigate this, generally the smaller the interval the better the stability. This alone will give the constraints more opportunity to push back against external forces, but it will also increase the maximum stable constraint stiffness.

This will probably require you to optimise your engine more. Additionally make sure you don't couple your render step to the simulation, you want to be able to render at multiples of the simulation interval which allows you to run the simulation faster for stability without unnecessarily rendering more frames than is useful, as it will just slow down the simulation.

2. Try more stable shapes

For your box-of-boxes shape, see what happens when you add more constraints between far vertices, it will add more global stability to the shape.

A common type of shape people make with mass-aggregate physics are polygons, because it's straight forward to make them highly interconnected (a little bit like a bicycle wheel, but where each spoke point connects to every other spoke point). In- fact spoke-like designs are one of the most stable, but you can usually apply the same principles to more irregular shapes once you get an intuition for it.

3. A different type of constraint

Quaternions are not the only possible constraint that will help retain configuration, the main problem is not so much that explicit angle isn't being maintained; but rather that when points are forced past a certain position relative to their siblings, their distance constraints flip and start working in reverse - keeping them on that side.

There could be many different ways to solve this without something as complex as quarternions - in fact I will give it some thought and edit this post if I come up with anything, I have a bit more ammunition since I last explored mass-aggregate physics...

Corum answered 26/7, 2018 at 21:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.