diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-07-04 12:22:15 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-07-04 12:33:27 +0300 |
commit | 769c57b38a707397ac7fdda15b1deb561194b66c (patch) | |
tree | c618131eb63627c5a353c8ba1437c359b72ddbad /source/blender/blenkernel/intern/softbody.c | |
parent | 9e4d667c2cfd4a81f9a69628b69facd8fd4e0a01 (diff) |
SoftBody: share point cache between CoW copies
This is the same approach as 98a0bcd4252e952fa5438e9d1b69b0204f8a8746
applied to soft body simulation. In short, CoW copies share the point cache,
and treat it as read-only except when the depsgraph is active.
Diffstat (limited to 'source/blender/blenkernel/intern/softbody.c')
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index 4960714b47c..d3429622573 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3276,7 +3276,8 @@ SoftBody *sbNew(Scene *scene) sb->shearstiff = 1.0f; sb->solverflags |= SBSO_OLDERR; - sb->pointcache = BKE_ptcache_add(&sb->ptcaches); + sb->shared = MEM_callocN(sizeof(*sb->shared), "SoftBody_Shared"); + sb->shared->pointcache = BKE_ptcache_add(&sb->shared->ptcaches); if (!sb->effector_weights) sb->effector_weights = BKE_add_effector_weights(NULL); @@ -3295,8 +3296,13 @@ void sbFree(Object *ob) } free_softbody_intern(sb); - BKE_ptcache_free_list(&sb->ptcaches); - sb->pointcache = NULL; + + if ((ob->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) { + /* Only free shared data on non-CoW copies */ + BKE_ptcache_free_list(&sb->shared->ptcaches); + sb->shared->pointcache = NULL; + MEM_freeN(sb->shared); + } if (sb->effector_weights) MEM_freeN(sb->effector_weights); MEM_freeN(sb); @@ -3608,7 +3614,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c float dtime, timescale; int framedelta, framenr, startframe, endframe; int cache_result; - cache= sb->pointcache; + cache= sb->shared->pointcache; framenr= (int)cfra; framedelta= framenr - cache->simframe; @@ -3676,7 +3682,8 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c } /* try to read from cache */ - bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED); + bool can_write_cache = DEG_is_active(depsgraph); + bool can_simulate = (framenr == sb->last_frame + 1) && !(cache->flag & PTCACHE_BAKED) && can_write_cache; cache_result = BKE_ptcache_read(&pid, (float)framenr+scene->r.subframe, can_simulate); @@ -3687,7 +3694,7 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c BKE_ptcache_validate(cache, framenr); - if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED) + if (cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED && can_write_cache) BKE_ptcache_write(&pid, framenr); sb->last_frame = framenr; @@ -3699,7 +3706,9 @@ void sbObjectStep(struct Depsgraph *depsgraph, Scene *scene, Object *ob, float c } else if (/*ob->id.lib || */(cache->flag & PTCACHE_BAKED)) { /* "library linking & pointcaches" has to be solved properly at some point */ /* if baked and nothing in cache, do nothing */ - BKE_ptcache_invalidate(cache); + if (can_write_cache) { + BKE_ptcache_invalidate(cache); + } return; } |