Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Karhu <jhkarh@gmail.com>2009-08-02 23:39:33 +0400
committerJanne Karhu <jhkarh@gmail.com>2009-08-02 23:39:33 +0400
commitdc75023f6ff54d1b7c99360260fa3e70a4e42005 (patch)
treed445af308df4ad8612d0cdd352b48d98b0705a47 /source/blender/blenkernel/intern/softbody.c
parent7b123ff13c21984c36a44962b5e48d8ae8b69c6e (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/intern/softbody.c')
-rw-r--r--source/blender/blenkernel/intern/softbody.c156
1 files changed, 91 insertions, 65 deletions
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);
}
}