diff options
author | Janne Karhu <jhkarh@gmail.com> | 2009-08-02 23:39:33 +0400 |
---|---|---|
committer | Janne Karhu <jhkarh@gmail.com> | 2009-08-02 23:39:33 +0400 |
commit | dc75023f6ff54d1b7c99360260fa3e70a4e42005 (patch) | |
tree | d445af308df4ad8612d0cdd352b48d98b0705a47 /source/blender/blenkernel | |
parent | 7b123ff13c21984c36a44962b5e48d8ae8b69c6e (diff) |
Softbody now uses the new pointcache code.
Note: Rna access to softbody point cache is through softbody modifier although the point cache is in softbody settings. This is to make it similar to cloth.
Bugfix: Softbody rna was trying to get "ob->soft->softflag" instead of the correct "ob->softflag".
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_softbody.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pointcache.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/softbody.c | 156 |
3 files changed, 97 insertions, 69 deletions
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h index 971ac7a5f01..0d9682cf842 100644 --- a/source/blender/blenkernel/BKE_softbody.h +++ b/source/blender/blenkernel/BKE_softbody.h @@ -69,7 +69,7 @@ extern void sbObjectToSoftbody(struct Object *ob); extern void sbSetInterruptCallBack(int (*f)(void)); /* writing to cache for bake editing */ -extern void sbWriteCache(struct Object *ob, int framenr); +extern void softbody_write_cache(struct Object *ob, struct SoftBody *soft, int cfra); #endif diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 4bb571aa8ca..beb72c2c13f 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -310,7 +310,7 @@ int BKE_ptcache_file_write_floats(PTCacheFile *pf, float *f, int tot) static int ptcache_pid_elemsize(PTCacheID *pid) { if(pid->type==PTCACHE_TYPE_SOFTBODY) - return 0; // TODO + return 6 * sizeof(float); else if(pid->type==PTCACHE_TYPE_PARTICLES) return sizeof(ParticleKey); else if(pid->type==PTCACHE_TYPE_CLOTH) @@ -320,8 +320,10 @@ static int ptcache_pid_elemsize(PTCacheID *pid) } static int ptcache_pid_totelem(PTCacheID *pid) { - if(pid->type==PTCACHE_TYPE_SOFTBODY) - return 0; // TODO + if(pid->type==PTCACHE_TYPE_SOFTBODY) { + SoftBody *soft = pid->data; + return soft->totpoint; + } else if(pid->type==PTCACHE_TYPE_PARTICLES) { ParticleSystem *psys = pid->data; return psys->totpart; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index fe63585ae1c..0a1963c84f2 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3687,64 +3687,85 @@ static void softbody_to_object(Object *ob, float (*vertexCos)[3], int numVerts, } } -void sbWriteCache(Object *ob, int framenr) +static void softbody_write_state(int index, void *soft_v, float *data) { - SoftBody *sb= ob->soft; - BodyPoint *bp; - PTCacheID pid; - PTCacheFile *pf; - int a; + SoftBody *soft= soft_v; + BodyPoint *bp = soft->bpoint + index; - if(sb->totpoint == 0) - return; + memcpy(data, bp->pos, 3 * sizeof(float)); + memcpy(data + 3, bp->vec, 3 * sizeof(float)); +} +static void softbody_read_state(int index, void *soft_v, float *data) +{ + SoftBody *soft= soft_v; + BodyPoint *bp = soft->bpoint + index; + + memcpy(bp->pos, data, 3 * sizeof(float)); + memcpy(bp->vec, data + 3, 3 * sizeof(float)); +} +static void softbody_cache_interpolate(int index, void *soft_v, float frs_sec, float cfra, float cfra1, float cfra2, float *data1, float *data2) +{ + SoftBody *soft= soft_v; + BodyPoint *bp = soft->bpoint + index; + ParticleKey keys[4]; + float dfra; - BKE_ptcache_id_from_softbody(&pid, ob, sb); - pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, framenr); - if(!pf) + if(cfra1 == cfra2) { + softbody_read_state(index, soft, data1); return; - - for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) - BKE_ptcache_file_write_floats(pf, bp->pos, 3); + } - for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) - BKE_ptcache_file_write_floats(pf, bp->vec, 3); + memcpy(keys[1].co, data1, 3 * sizeof(float)); + memcpy(keys[1].vel, data1 + 3, 3 * sizeof(float)); - BKE_ptcache_file_close(pf); -} + memcpy(keys[2].co, data2, 3 * sizeof(float)); + memcpy(keys[2].vel, data2 + 3, 3 * sizeof(float)); + + dfra = cfra2 - cfra1; + + VecMulf(keys[1].vel, dfra); + VecMulf(keys[2].vel, dfra); + + psys_interpolate_particle(-1, keys, (cfra - cfra1) / dfra, keys, 1); -static int softbody_read_cache(Object *ob, float framenr) + VecMulf(keys->vel, 1.0f / dfra); + + memcpy(bp->pos, keys->co, 3 * sizeof(float)); + memcpy(bp->vec, keys->vel, 3 * sizeof(float)); +} +void softbody_write_cache(Object *ob, SoftBody *soft, int cfra) { - SoftBody *sb= ob->soft; - BodyPoint *bp; + PTCacheWriter writer; PTCacheID pid; - PTCacheFile *pf; - int a; - - if(sb->totpoint == 0) - return 0; - - BKE_ptcache_id_from_softbody(&pid, ob, sb); - pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, framenr); - if(!pf) - return 0; - for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) { - if(!BKE_ptcache_file_read_floats(pf, bp->pos, 3)) { - BKE_ptcache_file_close(pf); - return 0; - } - } + BKE_ptcache_id_from_softbody(&pid, ob, soft); - for(a=0, bp=sb->bpoint; a<sb->totpoint; a++, bp++) { - if(!BKE_ptcache_file_read_floats(pf, bp->vec, 3)) { - BKE_ptcache_file_close(pf); - return 0; - } - } + writer.calldata = soft; + writer.cfra = cfra; + writer.set_elem = softbody_write_state; + writer.pid = &pid; + writer.totelem = soft->totpoint; - BKE_ptcache_file_close(pf); + BKE_ptcache_write_cache(&writer); +} - return 1; +int softbody_read_cache(Scene *scene, Object *ob, SoftBody *soft, float cfra, int *old_framenr) +{ + PTCacheReader reader; + PTCacheID pid; + + BKE_ptcache_id_from_softbody(&pid, ob, soft); + + reader.calldata = soft; + reader.cfra = cfra; + reader.interpolate_elem = softbody_cache_interpolate; + reader.old_frame = old_framenr; + reader.pid = &pid; + reader.scene = scene; + reader.set_elem = softbody_read_state; + reader.totelem = soft->totpoint; + + return BKE_ptcache_read_cache(&reader); } /* +++ ************ maintaining scratch *************** */ @@ -4114,6 +4135,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i PTCacheID pid; float dtime, timescale; int framedelta, framenr, startframe, endframe; + int cache_result, old_framenr; cache= sb->pointcache; @@ -4128,7 +4150,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(sb->bpoint && numVerts != sb->totpoint) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; - + cache->last_exact= 0; return; } @@ -4136,6 +4158,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(framenr < startframe) { cache->flag &= ~PTCACHE_SIMULATION_VALID; cache->simframe= 0; + cache->last_exact= 0; return; } @@ -4198,26 +4221,36 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i } /* try to read from cache */ - if(softbody_read_cache(ob, framenr)) { - if(sb->particles==0) - softbody_to_object(ob, vertexCos, numVerts, sb->local); + cache_result = softbody_read_cache(scene, ob, sb, framenr, &old_framenr); + if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { cache->flag |= PTCACHE_SIMULATION_VALID; cache->simframe= framenr; + if(sb->particles==0) + softbody_to_object(ob, vertexCos, numVerts, sb->local); + return; } + else if(cache_result==PTCACHE_READ_OLD) { + BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_FREE); + cache->flag |= PTCACHE_SIMULATION_VALID; + cache->simframe= old_framenr; + } else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) { /* if baked and nothing in cache, do nothing */ - if(cache->flag & PTCACHE_SIMULATION_VALID) { - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - } - + cache->flag &= ~PTCACHE_SIMULATION_VALID; + cache->simframe= 0; + cache->last_exact= 0; return; } if(framenr == startframe) { + if(cache->flag & PTCACHE_REDO_NEEDED) { + softbody_update_positions(ob, sb, vertexCos, numVerts); + softbody_reset(ob, sb, vertexCos, numVerts); + cache->flag &= ~PTCACHE_REDO_NEEDED; + } /* first frame, no simulation to do, just set the positions */ softbody_update_positions(ob, sb, vertexCos, numVerts); @@ -4227,10 +4260,10 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i /* don't write cache on first frame, but on second frame write * cache for frame 1 and 2 */ } - else if(framedelta == 1) { + else { /* if on second frame, write cache for first frame */ - if(framenr == startframe+1) - sbWriteCache(ob, startframe); + if(cache->simframe == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) + softbody_write_cache(ob, sb, startframe); softbody_update_positions(ob, sb, vertexCos, numVerts); @@ -4246,14 +4279,7 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i if(sb->particles==0) softbody_to_object(ob, vertexCos, numVerts, 0); - sbWriteCache(ob, framenr); - } - else { - /* time step backwards or too large forward - do nothing */ - if(cache->flag & PTCACHE_SIMULATION_VALID) { - cache->flag &= ~PTCACHE_SIMULATION_VALID; - cache->simframe= 0; - } + softbody_write_cache(ob, sb, framenr); } } |