Rigid body point cache jumps
Closed, ResolvedPublic


We noticed some unclean behaviour when working with rigid bodies, which leads to bad simulation results. When scrubbing through the timeline the last simulation state is being used for later continuation of the "main" simulation, which doesn't always work as shown in the following example.

Steps to reproduce based on the attached blend file:

  1. Start simulation (Alt+a)
  2. Stop simulation (Alt+a)
  3. Jump to a future point in the timeline and simulate a bit further and stop again
  4. Jump back to start range and continue the already cached simulation (or press Bake)

Resulting simulation with motion path and frame numbers:

Tested on Windows 7 x64 with the official buildbot version.

Luca Rood (LucaRood) closed this task as "Archived".Jan 8 2017, 4:54 AM
Luca Rood (LucaRood) triaged this task as "Confirmed" priority.
Luca Rood (LucaRood) claimed this task.

I finally had some time to look into this...

The issue is that the rigid body simulation state isn't updated when read from cache. But the greater issue is that rigid body cache is currently only storing positions and rotations, so even if the simulation state is updated from the cache, we can only update the positions/rotations, and not the velocities.

This little diff calls a simulation state update when the cache is read, and thus correctly sets the position even when the timeline is set back to the initial cached bit after having jumped a few frames... But notice that the speed is reset to 0, so despite being in the correct location, you'll see your objects suddenly stopping, and re-accelerating.

1diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
2index b5f34a2..447f459 100644
3--- a/source/blender/blenkernel/intern/rigidbody.c
4+++ b/source/blender/blenkernel/intern/rigidbody.c
5@@ -1583,6 +1583,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
6​ bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
8​ if (BKE_ptcache_read(&pid, ctime, can_simulate)) {
9+ rigidbody_update_simulation(scene, rbw, true);
10​ BKE_ptcache_validate(cache, (int)ctime);
11​ rbw->ltime = ctime;
12​ return;

So this diff is only really a demonstration, and doesn't really fix the issue at all. To resolve this, the velocities would have to be cached as well, which isn't really worth the trouble for now, especially with this outdated caching system...

So I'm closing this for the time being... But I have added this to ToDo, and this shall probably be addressed with an eventual cache overhaul (provided it is even possible to get/set the velocities from Bullet...).

Luca Rood (LucaRood) reopened this task as "Open".Jan 10 2017, 6:09 AM

I'm reopening this, because I realized that I shouldn't try to fix it by having everything cached and then rolling back once you go to to a point in time before a cache gap. Having a simulation with a time gap in it doesn't actually make any sense at all, so I realized that I should rather prevent the cache from forming such a gap in the first place.

That is a trivial fix, and should prevent accidental rigid body cache corruption by the user if playing outside of the currently cached period.