Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colliding objects (RigidBody2d) gain energy #29639

Open
Tracked by #45334
codecachet opened this issue Jun 9, 2019 · 7 comments
Open
Tracked by #45334

Colliding objects (RigidBody2d) gain energy #29639

codecachet opened this issue Jun 9, 2019 · 7 comments

Comments

@codecachet
Copy link

codecachet commented Jun 9, 2019

Godot version: 3.1.1

OS/device including version: MacBookPro (Retinia 15", Mid 2015), 16gb, AMD Radeon R9 M370X 2048 MB, Intel Iris Pro 1536 MB, OS: MacOS High Sierra 10.13.6

Issue description:
See enclosed screenshot. With "elastic" collisions, the "energy" of the system appears to increase, and eventually, a ball disappears. Eventually, all balls except one disappear.

screen_shot

I have several circular balls (RigidBody2d) enclosed by walls (StaticBody2d). They are given a random initial velocity and linear_damp, angular_damp, and friction are all set to 0.

Everything works fine for a while. The balls all collide with one another and the walls (like particles in an ideal gas). However, the "energy" (basically, the scalar speed) of the entire system slowly increases. After a while, a ball node completely disappears. The node is still in the list, however, and there are no noticeable error messages. Eventually, all the balls except one disappear.

Steps to reproduce:
Just run, and you will see this happen. Once running, click to add balls with random initial velocities. - try it with, say, 10 balls. Then let things progress. You will see the energy increasing, and after about 15 minutes (on my machine), a ball will disappear. After a while, another will disappear, and eventually, you will be left with a single ball, which seems to be fine as it bounces off the walls.

Minimal reproduction project:
gas.zip

@NuclearPhoenixx
Copy link

The minimal reproduction project doesn't look like it's the same one as your screenshot. Not sure if that's also affected by the issue.

@codecachet
Copy link
Author

Hmmm. I'm travelling right now - I'll take a look when I get back. Sorry.

@codecachet
Copy link
Author

I updated a few things - please let me know if I have given enough information. What I am doing is very simple - and perhaps the physics engine was never meant to run continuously like this. Nevertheless, it probably should be fixed to work properly. I am thrilled it works as well as it does with a minimum of (newbie) code on my part!

@NuclearPhoenixx
Copy link

Thanks, for getting back to this. Now your project is working great - it looks like this is indeed a striking issue with the physics engine if I may say so.

Reproduced the issue with just 25 balls and after 5 minutes you could already see a huge increase in energy.

@KoBeWi
Copy link
Member

KoBeWi commented Jul 28, 2020

Can anyone still reproduce this bug in Godot 3.2.3 rc1 or any later release?

EDIT:
I just tried the repro and it still seems to happen in the mentioned version.

@e344fde6bf
Copy link
Contributor

e344fde6bf commented Mar 20, 2021

Since the rigidbody simulation is a discrete algorithm, objects will overlap when they collide.
discrete-collision

When this happens, the engine will separate them by pushing them apart. When it's only a one-on-one collision, the algorithm used seems to mostly conserve energy. However, if a ball collides with multiple objects on the same frame, then it doesn't conserve energy. This can easily be seen by this example:

gain-energy.mp4

To combat this you can use a smaller physics timestep, which will reduce the number of times multiple objects will collide on the same frame. Continuous collision detection would probably also help, but it's not working (#9071).

The algorithm could probably be adapted to conserve energy better when it collides with multiple objects, but I don't know what would be involved to get that to work.

@lmsonic
Copy link

lmsonic commented Jun 11, 2024

gas.zip
I converted the MRP to Godot 4.2.2, and changed the physics material settings as described in the note in the bounce variables in the docs:

The body's bounciness. Values range from 0 (no bounce) to 1 (full bounciness).

Note: Even with bounce set to 1.0, some energy will be lost over time due to linear and angular damping. To have a PhysicsBody3D that preserves all its energy over time, set bounce to 1.0, the body's linear damp mode to Replace (if applicable), its linear damp to 0.0, its angular damp mode to Replace (if applicable), and its angular damp to 0.0.

I have setup a script that prints the change in kinetic energy (calculated in the original MRP as 1/2mv^2) every 30s and did a test with 20 balls, there does seem to be a trend up, in both Godot and Jolt physics:
Godot Default Physics:

Starting energy = 1584148.52638391
Change in kinetic energy = 3839.60679270793
Change in kinetic energy = 1408.02858727984
Change in kinetic energy = 828.354852700606
Change in kinetic energy = 3948.69090215629
Change in kinetic energy = -393.172947919462
Change in kinetic energy = 6406.53619679948
Change in kinetic energy = 3368.23608563654
Change in kinetic energy = 2250.09267986682
Change in kinetic energy = 1845.8897795279
Change in kinetic energy = 502.633470579516
Change in kinetic energy = 19.4672882489394
Change in kinetic energy = 11120.9729568968
Change in kinetic energy = 3388.33447203017
Change in kinetic energy = 5630.83549214667
Change in kinetic energy = 1272.95750903897
Change in kinetic energy = 859.23097243486
Change in kinetic energy = -3256.39556521643
Change in kinetic energy = 126.308350115316
Change in kinetic energy = 3471.44570447761

Jolt:

Starting energy = 1625428.40727502
Change in kinetic energy = 1350.59771061409
Change in kinetic energy = 323.386545828776
Change in kinetic energy = 252.591505671851
Change in kinetic energy = 1026.2785957614
Change in kinetic energy = 2054.90110408538
Change in kinetic energy = 2488.02682291251
Change in kinetic energy = 2800.56676824391
Change in kinetic energy = 2383.66981428652
Change in kinetic energy = 1809.15994167561
Change in kinetic energy = 762.775181993376
Change in kinetic energy = 5785.58086550469
Change in kinetic energy = 3023.34471320664

(I ended the jolt one prematurely because i fucked up and clicked and added another ball)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants