diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c index 60ae37da09a..eec0e8b387d 100644 --- a/source/blender/blenkernel/intern/rigidbody.c +++ b/source/blender/blenkernel/intern/rigidbody.c @@ -1691,6 +1691,27 @@ void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime #endif /* WITH_BULLET */ + +/* Copy the pointcache from the evaluated to the original scene. + * This allows the re-evaluation of the original scene to use the + * physics cache. + */ +static void rigidbody_copy_cache_to_orig(Scene *scene_eval) +{ + if ((scene_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) { + /* Scene is already an original, this function is a no-op. */ + return; + } + + Scene *scene_orig = (Scene *)DEG_get_original_id(&scene_eval->id); + RigidBodyWorld *rbw_orig = scene_orig->rigidbody_world; + RigidBodyWorld *rbw_eval = scene_eval->rigidbody_world; + + BKE_ptcache_free_list(&rbw_orig->ptcaches); + rbw_orig->pointcache = BKE_ptcache_copy_list(&rbw_orig->ptcaches, &rbw_eval->ptcaches, LIB_ID_COPY_CACHES); +} + + /* -------------------- */ /* Depsgraph evaluation */ @@ -1710,10 +1731,18 @@ void BKE_rigidbody_eval_simulation(Depsgraph *depsgraph, { float ctime = DEG_get_ctime(depsgraph); DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime); + /* evaluate rigidbody sim */ - if (BKE_scene_check_rigidbody_active(scene)) { - BKE_rigidbody_do_simulation(depsgraph, scene, ctime); + if (!BKE_scene_check_rigidbody_active(scene)) { + return; } + BKE_rigidbody_do_simulation(depsgraph, scene, ctime); + + /* Make sure re-evaluation can use the cache from this simulation */ + if (!DEG_is_active(depsgraph)) { + return; + } + rigidbody_copy_cache_to_orig(scene); } void BKE_rigidbody_object_sync_transforms(Depsgraph *depsgraph,