From 405bff7fd8ed5df8d44a1362763fac7c00e2060b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 14 Apr 2022 16:58:15 +1000 Subject: Fix T68290: Baked particles don't render in final frame Particles baked into memory would never load the final frame because of an off-by-one error calculating the particles `dietime`. This value indicates the frame which the particle ceases to exist but was being set to the end-frame which caused this bug as the scenes end-frame is inclusive. While the last frame was properly written and read from memory, the `dietime` was set to the last frame causing all the particles to be considered dead when calculating the cached particle system. --- source/blender/blenkernel/intern/pointcache.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source/blender/blenkernel/intern/pointcache.c') diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 19abff19b77..d5d304343df 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -285,8 +285,10 @@ static int ptcache_particle_write(int index, void *psys_v, void **data, int cfra } } else { - /* Particles are only stored in their lifetime. */ - if (cfra < pa->time - step || cfra > pa->dietime + step) { + /* Inclusive ranges for particle lifetime (`dietime - 1` for an inclusive end-frame). */ + const int pa_sfra = (int)pa->time - step; + const int pa_efra = ((int)pa->dietime - 1) + step; + if (!(cfra >= pa_sfra && cfra <= pa_efra)) { return 0; } } @@ -399,9 +401,12 @@ static void ptcache_particle_interpolate(int index, pa = psys->particles + index; - /* particle wasn't read from first cache so can't interpolate */ - if ((int)cfra1 < pa->time - psys->pointcache->step || - (int)cfra1 > pa->dietime + psys->pointcache->step) { + /* Inclusive ranges for particle lifetime (`dietime - 1` for an inclusive end-frame). */ + const int pa_sfra = (int)pa->time - psys->pointcache->step; + const int pa_efra = ((int)pa->dietime - 1) + psys->pointcache->step; + + /* Particle wasn't read from first cache so can't interpolate. */ + if (!(cfra1 >= pa_sfra && cfra1 <= pa_efra)) { return; } @@ -482,12 +487,16 @@ static int ptcache_particle_totwrite(void *psys_v, int cfra) if (psys->part->flag & PART_DIED) { /* Also store dead particles when they are displayed. */ for (p = 0; p < psys->totpart; p++, pa++) { - totwrite += (cfra >= pa->time - step); + const int pa_sfra = (int)pa->time - step; + totwrite += (cfra >= pa_sfra); } } else { for (p = 0; p < psys->totpart; p++, pa++) { - totwrite += (cfra >= pa->time - step && cfra <= pa->dietime + step); + /* Inclusive ranges for particle lifetime (`dietime - 1` for an inclusive end-frame). */ + const int pa_sfra = (int)pa->time - step; + const int pa_efra = ((int)pa->dietime - 1) + step; + totwrite += (cfra >= pa_sfra) && (cfra <= pa_efra); } } -- cgit v1.2.3