diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-06-27 18:08:58 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-06-28 15:20:11 +0300 |
commit | 98a0bcd4252e952fa5438e9d1b69b0204f8a8746 (patch) | |
tree | f3bf13553441e60b7097395220de9b146019135c /source/blender/blenloader | |
parent | 9b050b736baea22547b6c6baaab37bba3356e42b (diff) |
Prevent copying too much in the Rigid Body simulation
To prevent the pointcache from being copied-on-write too (and requiring
copying back), the cache is now shared between the original and
evaluated scenes. Reading from the cache is always allowed; running the
sim and writing to the cache is only allowed when the depsgraph is
active.
Some pointers have moved from RigidBodyWorld (RBO) to
RigidBodyWorldShared (RBOS). writefile.c copies some pointers back from
RBOS to RBO so that the file can still be opened on older Blenders
without crashing on a segfault.
The RigidBodyWorldShared struct is written to the blend file, because it
refers to the PointCache ID block.
The RigidObjectShared struct is runtime-only, and thus not saved to the
blend file.
An RNA getter-function is used to hide the new 'shared' pointer. As a
result the Python API hasn't changed.
Reviewed by: campbellbarton
Differential Revision: https://developer.blender.org/D3508
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 47 | ||||
-rw-r--r-- | source/blender/blenloader/intern/versioning_280.c | 29 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 7 |
3 files changed, 65 insertions, 18 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 9166caff5e0..c94a565216a 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5476,12 +5476,8 @@ static void direct_link_object(FileData *fd, Object *ob) ob->rigidbody_object = newdataadr(fd, ob->rigidbody_object); if (ob->rigidbody_object) { RigidBodyOb *rbo = ob->rigidbody_object; - - /* must nullify the references to physics sim objects, since they no-longer exist - * (and will need to be recalculated) - */ - rbo->physics_object = NULL; - rbo->physics_shape = NULL; + /* Allocate runtime-only struct */ + rbo->shared = MEM_callocN(sizeof(*rbo->shared), "RigidBodyObShared"); } ob->rigidbody_constraint = newdataadr(fd, ob->rigidbody_constraint); if (ob->rigidbody_constraint) @@ -6280,10 +6276,34 @@ static void direct_link_scene(FileData *fd, Scene *sce) sce->rigidbody_world = newdataadr(fd, sce->rigidbody_world); rbw = sce->rigidbody_world; if (rbw) { - /* must nullify the reference to physics sim object, since it no-longer exist - * (and will need to be recalculated) - */ - rbw->physics_world = NULL; + rbw->shared = newdataadr(fd, rbw->shared); + + if (rbw->shared == NULL) { + /* Link deprecated caches if they exist, so we can use them for versioning. + * We should only do this when rbw->shared == NULL, because those pointers + * are always set (for compatibility with older Blenders). We mustn't link + * the same pointcache twice. */ + direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false); + + /* make sure simulation starts from the beginning after loading file */ + if (rbw->pointcache) { + rbw->ltime = (float)rbw->pointcache->startframe; + } + } + else { + /* must nullify the reference to physics sim object, since it no-longer exist + * (and will need to be recalculated) + */ + rbw->shared->physics_world = NULL; + + /* link caches */ + direct_link_pointcache_list(fd, &rbw->shared->ptcaches, &rbw->shared->pointcache, false); + + /* make sure simulation starts from the beginning after loading file */ + if (rbw->shared->pointcache) { + rbw->ltime = (float)rbw->shared->pointcache->startframe; + } + } rbw->objects = NULL; rbw->numbodies = 0; @@ -6291,13 +6311,6 @@ static void direct_link_scene(FileData *fd, Scene *sce) rbw->effector_weights = newdataadr(fd, rbw->effector_weights); if (!rbw->effector_weights) rbw->effector_weights = BKE_add_effector_weights(NULL); - - /* link cache */ - direct_link_pointcache_list(fd, &rbw->ptcaches, &rbw->pointcache, false); - /* make sure simulation starts from the beginning after loading file */ - if (rbw->pointcache) { - rbw->ltime = (float)rbw->pointcache->startframe; - } } sce->preview = direct_link_preview_image(fd, sce->preview); diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c index 06017668c02..3fa059989a3 100644 --- a/source/blender/blenloader/intern/versioning_280.c +++ b/source/blender/blenloader/intern/versioning_280.c @@ -49,6 +49,7 @@ #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_particle_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_view3d_types.h" @@ -65,6 +66,7 @@ #include "BKE_main.h" #include "BKE_mesh.h" #include "BKE_node.h" +#include "BKE_pointcache.h" #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" @@ -1530,5 +1532,32 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain) scene->toolsettings->manipulator_flag = SCE_MANIP_TRANSLATE | SCE_MANIP_ROTATE | SCE_MANIP_SCALE; } } + + if (!DNA_struct_elem_find(fd->filesdna, "RigidBodyWorld", "RigidBodyWorld_Shared", "*shared")) { + for (Scene *scene = bmain->scene.first; scene; scene = scene->id.next) { + RigidBodyWorld *rbw = scene->rigidbody_world; + + if (rbw == NULL) { + continue; + } + + if (rbw->shared == NULL) { + rbw->shared = MEM_callocN(sizeof(*rbw->shared), "RigidBodyWorld_Shared"); + } + + /* Move shared pointers from deprecated location to current location */ + rbw->shared->pointcache = rbw->pointcache; + rbw->shared->ptcaches = rbw->ptcaches; + + rbw->pointcache = NULL; + BLI_listbase_clear(&rbw->ptcaches); + + if (rbw->shared->pointcache == NULL) { + rbw->shared->pointcache = BKE_ptcache_add(&(rbw->shared->ptcaches)); + } + + } + } + } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 1a33b9440b5..5402114c8f8 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -2646,9 +2646,14 @@ static void write_scene(WriteData *wd, Scene *sce) /* writing RigidBodyWorld data to the blend file */ if (sce->rigidbody_world) { + /* Set deprecated pointers to prevent crashes of older Blenders */ + sce->rigidbody_world->pointcache = sce->rigidbody_world->shared->pointcache; + sce->rigidbody_world->ptcaches = sce->rigidbody_world->shared->ptcaches; writestruct(wd, DATA, RigidBodyWorld, 1, sce->rigidbody_world); + + writestruct(wd, DATA, RigidBodyWorld_Shared, 1, sce->rigidbody_world->shared); writestruct(wd, DATA, EffectorWeights, 1, sce->rigidbody_world->effector_weights); - write_pointcaches(wd, &(sce->rigidbody_world->ptcaches)); + write_pointcaches(wd, &(sce->rigidbody_world->shared->ptcaches)); } write_previews(wd, sce->preview); |