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:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/particle.c6
-rw-r--r--source/blender/blenkernel/intern/pointcache.c223
2 files changed, 133 insertions, 96 deletions
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index b88df677c9b..97e8d6c7f7d 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1067,12 +1067,12 @@ static void get_pointcache_keys_for_time(Object *ob, PointCache *cache, int inde
while(pm && pm->next && (float)pm->frame < t)
pm = pm->next;
- BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] : index, pm->data, (float)pm->frame);
- BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] : index, pm->prev->data, (float)pm->prev->frame);
+ BKE_ptcache_make_particle_key(key2, pm->index_array ? pm->index_array[index] - 1 : index, pm->data, (float)pm->frame);
+ BKE_ptcache_make_particle_key(key1, pm->prev->index_array ? pm->prev->index_array[index] - 1 : index, pm->prev->data, (float)pm->prev->frame);
}
else if(cache->mem_cache.first) {
PTCacheMem *pm2 = cache->mem_cache.first;
- BKE_ptcache_make_particle_key(key2, pm2->index_array ? pm2->index_array[index] : index, pm2->data, (float)pm2->frame);
+ BKE_ptcache_make_particle_key(key2, pm2->index_array ? pm2->index_array[index] - 1 : index, pm2->data, (float)pm2->frame);
copy_particle_key(key1, key2, 1);
}
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 7ae2898ab8d..9c393ad0ae1 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -135,7 +135,7 @@ static int ptcache_write_basic_header(PTCacheFile *pf)
return 1;
}
/* Softbody functions */
-static int ptcache_write_softbody(int index, void *soft_v, void **data)
+static int ptcache_write_softbody(int index, void *soft_v, void **data, int cfra)
{
SoftBody *soft= soft_v;
BodyPoint *bp = soft->bpoint + index;
@@ -191,13 +191,13 @@ static void ptcache_interpolate_softbody(int index, void *soft_v, void **data, f
VECCOPY(bp->pos, keys->co);
VECCOPY(bp->vec, keys->vel);
}
-static int ptcache_totpoint_softbody(void *soft_v)
+static int ptcache_totpoint_softbody(void *soft_v, int cfra)
{
SoftBody *soft= soft_v;
return soft->totpoint;
}
/* Particle functions */
-static int ptcache_write_particle(int index, void *psys_v, void **data)
+static int ptcache_write_particle(int index, void *psys_v, void **data, int cfra)
{
ParticleSystem *psys= psys_v;
ParticleData *pa = psys->particles + index;
@@ -205,11 +205,9 @@ static int ptcache_write_particle(int index, void *psys_v, void **data)
float times[3] = {pa->time, pa->dietime, pa->lifetime};
int step = psys->pointcache->step;
- if(data[BPHYS_DATA_INDEX]) {
- /* No need to store unborn or died particles */
- if(pa->time - step > pa->state.time || pa->dietime + step < pa->state.time)
- return 0;
- }
+ /* No need to store unborn or died particles outside cache step bounds */
+ if(data[BPHYS_DATA_INDEX] && (cfra < pa->time - step || cfra > pa->dietime + step))
+ return 0;
PTCACHE_DATA_FROM(data, BPHYS_DATA_INDEX, &index);
PTCACHE_DATA_FROM(data, BPHYS_DATA_LOCATION, pa->state.co);
@@ -236,8 +234,14 @@ void BKE_ptcache_make_particle_key(ParticleKey *key, int index, void **data, flo
static void ptcache_read_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float *old_data)
{
ParticleSystem *psys= psys_v;
- ParticleData *pa = psys->particles + index;
- BoidParticle *boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
+ ParticleData *pa;
+ BoidParticle *boid;
+
+ if(index >= psys->totpart)
+ return;
+
+ pa = psys->particles + index;
+ boid = (psys->part->phystype == PART_PHYS_BOIDS) ? pa->boid : NULL;
if(cfra > pa->state.time)
memcpy(&pa->prev_state, &pa->state, sizeof(ParticleKey));
@@ -288,10 +292,19 @@ static void ptcache_read_particle(int index, void *psys_v, void **data, float fr
static void ptcache_interpolate_particle(int index, void *psys_v, void **data, float frs_sec, float cfra, float cfra1, float cfra2, float *old_data)
{
ParticleSystem *psys= psys_v;
- ParticleData *pa = psys->particles + index;
+ ParticleData *pa;
ParticleKey keys[4];
float dfra;
+ if(index >= psys->totpart)
+ return;
+
+ 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)
+ return;
+
cfra = MIN2(cfra, pa->dietime);
cfra1 = MIN2(cfra1, pa->dietime);
cfra2 = MIN2(cfra2, pa->dietime);
@@ -338,26 +351,20 @@ static void ptcache_interpolate_particle(int index, void *psys_v, void **data, f
pa->state.time = cfra;
}
-static int ptcache_totpoint_particle(void *psys_v)
+static int ptcache_totpoint_particle(void *psys_v, int cfra)
{
ParticleSystem *psys = psys_v;
return psys->totpart;
}
-static int ptcache_totwrite_particle(void *psys_v)
+static int ptcache_totwrite_particle(void *psys_v, int cfra)
{
ParticleSystem *psys = psys_v;
+ ParticleData *pa= psys->particles;
+ int p, step = psys->pointcache->step;
int totwrite = 0;
- /* TODO for later */
- //if((psys->part->flag & (PART_UNBORN|PART_DIED))==0) {
- // ParticleData *pa= psys->particles;
- // int p, step = psys->pointcache->step;
-
- // for(p=0; p<psys->totpart; p++,pa++)
- // totwrite += (pa->time - step > pa->state.time || pa->dietime + step > pa->state.time);
- //}
- //else
- totwrite= psys->totpart;
+ for(p=0; p<psys->totpart; p++,pa++)
+ totwrite += (cfra >= pa->time - step && cfra <= pa->dietime + step);
return totwrite;
}
@@ -489,7 +496,7 @@ static int ptcache_totwrite_particle(void *psys_v)
//}
//
/* Cloth functions */
-static int ptcache_write_cloth(int index, void *cloth_v, void **data)
+static int ptcache_write_cloth(int index, void *cloth_v, void **data, int cfra)
{
ClothModifierData *clmd= cloth_v;
Cloth *cloth= clmd->clothObject;
@@ -554,7 +561,7 @@ static void ptcache_interpolate_cloth(int index, void *cloth_v, void **data, flo
/* should vert->xconst be interpolated somehow too? - jahka */
}
-static int ptcache_totpoint_cloth(void *cloth_v)
+static int ptcache_totpoint_cloth(void *cloth_v, int cfra)
{
ClothModifierData *clmd= cloth_v;
return clmd->clothObject->numverts;
@@ -615,11 +622,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
pid->write_header= ptcache_write_basic_header;
pid->read_header= ptcache_read_basic_header;
- pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY);
-
- /* TODO for later */
- //if((psys->part->flag & (PART_UNBORN|PART_DIED))==0)
- // pid->data_types|= (1<<BPHYS_DATA_INDEX);
+ pid->data_types= (1<<BPHYS_DATA_LOCATION) | (1<<BPHYS_DATA_VELOCITY) | (1<<BPHYS_DATA_INDEX);
if(psys->part->phystype == PART_PHYS_BOIDS)
pid->data_types|= (1<<BPHYS_DATA_AVELOCITY) | (1<<BPHYS_DATA_ROTATION) | (1<<BPHYS_DATA_BOIDS);
@@ -635,7 +638,7 @@ void BKE_ptcache_id_from_particles(PTCacheID *pid, Object *ob, ParticleSystem *p
}
/* Smoke functions */
-static int ptcache_totpoint_smoke(void *smoke_v)
+static int ptcache_totpoint_smoke(void *smoke_v, int cfra)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -648,7 +651,7 @@ static int ptcache_totpoint_smoke(void *smoke_v)
}
/* Smoke functions */
-static int ptcache_totpoint_smoke_turbulence(void *smoke_v)
+static int ptcache_totpoint_smoke_turbulence(void *smoke_v, int cfra)
{
SmokeModifierData *smd= (SmokeModifierData *)smoke_v;
SmokeDomainSettings *sds = smd->domain;
@@ -1266,12 +1269,32 @@ static void ptcache_file_seek_pointers(int index, PTCacheFile *pf)
int i, size=0;
int data_types = pf->data_types;
- for(i=0; i<BPHYS_TOT_DATA; i++)
- size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+ if(data_types & (1<<BPHYS_DATA_INDEX)) {
+ int totpoint;
+ /* The simplest solution is to just write to the very end. This may cause
+ * some data duplication, but since it's on disk it's not so bad. The correct
+ * thing would be to search through the file for the correct index and only
+ * write to the end if it's not found, but this could be quite slow.
+ */
+ fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
+ fread(&totpoint, sizeof(int), 1, pf->fp);
+
+ totpoint++;
+
+ fseek(pf->fp, 8 + sizeof(int), SEEK_SET);
+ fwrite(&totpoint, sizeof(int), 1, pf->fp);
+
+ fseek(pf->fp, 0, SEEK_END);
+ }
+ else {
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ size += pf->data_types & (1<<i) ? ptcache_data_size[i] : 0;
+
+ /* size of default header + data up to index */
+ fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
+ }
ptcache_file_init_pointers(pf);
- /* size of default header + data up to index */
- fseek(pf->fp, 8 + 3*sizeof(int) + index * size, SEEK_SET);
}
void BKE_ptcache_mem_init_pointers(PTCacheMem *pm)
{
@@ -1291,13 +1314,24 @@ void BKE_ptcache_mem_incr_pointers(PTCacheMem *pm)
pm->cur[i] = (char*)pm->cur[i] + ptcache_data_size[i];
}
}
-void BKE_ptcache_mem_seek_pointers(int index, PTCacheMem *pm)
+static int BKE_ptcache_mem_seek_pointers(int point_index, PTCacheMem *pm)
{
int data_types = pm->data_types;
- int i;
+ int i, index = pm->index_array ? pm->index_array[point_index] - 1 : point_index;
+
+ if(index < 0) {
+ /* Can't give proper location without reallocation, so don't give any location.
+ * Some points will be cached improperly, but this only happens with simulation
+ * steps bigger than cache->step, so the cache has to be recalculated anyways
+ * at some point.
+ */
+ return 0;
+ }
for(i=0; i<BPHYS_TOT_DATA; i++)
pm->cur[i] = data_types & (1<<i) ? (char*)pm->data[i] + index * ptcache_data_size[i] : NULL;
+
+ return 1;
}
static void ptcache_alloc_data(PTCacheMem *pm)
{
@@ -1310,14 +1344,20 @@ static void ptcache_alloc_data(PTCacheMem *pm)
pm->data[i] = MEM_callocN(totpoint * ptcache_data_size[i], "PTCache Data");
}
}
-static void ptcache_free_data(void *data[])
+static void ptcache_free_data(PTCacheMem *pm)
{
+ void **data = pm->data;
int i;
for(i=0; i<BPHYS_TOT_DATA; i++) {
if(data[i])
MEM_freeN(data[i]);
}
+
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
+ }
}
static void ptcache_copy_data(void *from[], void *to[])
{
@@ -1361,7 +1401,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
int ret = 0, error = 0;
/* nothing to read to */
- if(pid->totpoint(pid->calldata) == 0)
+ if(pid->totpoint(pid->calldata, (int)cfra) == 0)
return 0;
if(pid->cache->flag & PTCACHE_READ_INFO) {
@@ -1462,13 +1502,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf)) {
ptcache_file_init_pointers(pf);
totpoint = pf->totpoint;
- index = pf->data_types & BPHYS_DATA_INDEX ? &pf->data.index : &i;
+ index = pf->data_types & (1<<BPHYS_DATA_INDEX) ? &pf->data.index : &i;
}
}
else {
/* fall back to old cache file format */
use_old = 1;
- totpoint = pid->totpoint(pid->calldata);
+ totpoint = pid->totpoint(pid->calldata, (int) cfra);
}
}
if(pf2) {
@@ -1481,13 +1521,13 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
else if(pid->read_header(pf2)) {
ptcache_file_init_pointers(pf2);
totpoint2 = pf2->totpoint;
- index2 = pf2->data_types & BPHYS_DATA_INDEX ? &pf2->data.index : &i;
+ index2 = pf2->data_types & (1<<BPHYS_DATA_INDEX) ? &pf2->data.index : &i;
}
}
else {
/* fall back to old cache file format */
use_old = 1;
- totpoint2 = pid->totpoint(pid->calldata);
+ totpoint2 = pid->totpoint(pid->calldata, (int) cfra);
}
}
@@ -1500,7 +1540,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(!error)
{
if(pf && pid->read_stream) {
- if(totpoint != pid->totpoint(pid->calldata))
+ if(totpoint != pid->totpoint(pid->calldata, (int) cfra))
error = 1;
else
{
@@ -1510,7 +1550,8 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
}
- totpoint = MIN2(totpoint, pid->totpoint(pid->calldata));
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint = MIN2(totpoint, pid->totpoint(pid->calldata, (int) cfra));
if(!error)
{
@@ -1539,7 +1580,7 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
if(!error)
{
if(pf2 && pid->read_stream) {
- if(totpoint2 != pid->totpoint(pid->calldata))
+ if(totpoint2 != pid->totpoint(pid->calldata, (int) cfra))
error = 1;
else
{
@@ -1549,7 +1590,8 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
}
}
- totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata));
+ if((pid->data_types & (1<<BPHYS_DATA_INDEX)) == 0)
+ totpoint2 = MIN2(totpoint2, pid->totpoint(pid->calldata, (int) cfra));
if(!error)
{
@@ -1621,31 +1663,31 @@ int BKE_ptcache_read_cache(PTCacheID *pid, float cfra, float frs_sec)
return (error ? 0 : ret);
}
/* TODO for later */
-//static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
-//{
-// int i, *index;
-//
-// if(pm->index_array) {
-// MEM_freeN(pm->index_array);
-// pm->index_array = NULL;
-// }
-//
-// if(!pm->data[BPHYS_DATA_INDEX])
-// return;
-//
-// pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
-// index = pm->data[BPHYS_DATA_INDEX];
-//
-// for(i=0; i<pm->totpoint; i++, index++)
-// pm->index_array[*index] = i;
-//}
+static void ptcache_make_index_array(PTCacheMem *pm, int totpoint)
+{
+ int i, *index;
+
+ if(pm->index_array) {
+ MEM_freeN(pm->index_array);
+ pm->index_array = NULL;
+ }
+
+ if(!pm->data[BPHYS_DATA_INDEX])
+ return;
+
+ pm->index_array = MEM_callocN(totpoint * sizeof(int), "PTCacheMem index_array");
+ index = pm->data[BPHYS_DATA_INDEX];
+
+ for(i=0; i<pm->totpoint; i++, index++)
+ pm->index_array[*index] = i + 1;
+}
/* writes cache to disk or memory */
int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
{
PointCache *cache = pid->cache;
PTCacheFile *pf= NULL, *pf2= NULL;
int i;
- int totpoint = pid->totpoint(pid->calldata);
+ int totpoint = pid->totpoint(pid->calldata, cfra);
int add = 0, overwrite = 0;
if(totpoint == 0 || cfra < 0
@@ -1690,7 +1732,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
return 0;
pf->type = pid->type;
- pf->totpoint = cfra ? totpoint : pid->totwrite(pid->calldata);
+ pf->totpoint = cfra ? pid->totwrite(pid->calldata, cfra) : totpoint;
pf->data_types = cfra ? pid->data_types : pid->info_types;
if(!ptcache_file_write_header_begin(pf) || !pid->write_header(pf)) {
@@ -1707,7 +1749,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
else
for(i=0; i<totpoint; i++) {
if(pid->write_elem) {
- int write = pid->write_elem(i, pid->calldata, pf->cur);
+ int write = pid->write_elem(i, pid->calldata, pf->cur, cfra);
if(write) {
if(!ptcache_file_write_data(pf)) {
ptcache_file_close(pf);
@@ -1727,7 +1769,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pf2->data_types = pid->data_types;
}
ptcache_file_seek_pointers(i, pf2);
- pid->write_elem(i, pid->calldata, pf2->cur);
+ pid->write_elem(i, pid->calldata, pf2->cur, cfra);
if(!ptcache_file_write_data(pf2)) {
ptcache_file_close(pf);
ptcache_file_close(pf2);
@@ -1773,7 +1815,7 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
pm = MEM_callocN(sizeof(PTCacheMem), "Pointcache mem");
- pm->totpoint = pid->totwrite(pid->calldata);
+ pm->totpoint = pid->totwrite(pid->calldata, cfra);
pm->data_types = cfra ? pid->data_types : pid->info_types;
ptcache_alloc_data(pm);
@@ -1781,20 +1823,20 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
for(i=0; i<totpoint; i++) {
if(pid->write_elem) {
- int write = pid->write_elem(i, pid->calldata, pm->cur);
+ int write = pid->write_elem(i, pid->calldata, pm->cur, cfra);
if(write) {
BKE_ptcache_mem_incr_pointers(pm);
/* newly born particles have to be copied to previous cached frame */
if(overwrite && write == 2) {
pm2 = cache->mem_cache.last;
- BKE_ptcache_mem_seek_pointers(i, pm2);
- pid->write_elem(i, pid->calldata, pm2->cur);
+ if(BKE_ptcache_mem_seek_pointers(i, pm2))
+ pid->write_elem(i, pid->calldata, pm2->cur, cfra);
}
}
}
}
- //ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
pm->frame = cfra;
BLI_addtail(&cache->mem_cache, pm);
@@ -1899,15 +1941,15 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
if(mode == PTCACHE_CLEAR_ALL) {
pid->cache->last_exact = 0;
for(; pm; pm=pm->next)
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
BLI_freelistN(&pid->cache->mem_cache);
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
link = pm;
+ ptcache_free_data(pm);
pm = pm->next;
- ptcache_free_data(link->data);
BLI_freelinkN(&pid->cache->mem_cache, link);
}
else
@@ -1929,7 +1971,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next) {
if(pm->frame == cfra) {
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
BLI_freelinkN(&pid->cache->mem_cache, pm);
break;
}
@@ -2214,11 +2256,8 @@ void BKE_ptcache_free_mem(ListBase *mem_cache)
PTCacheMem *pm = mem_cache->first;
if(pm) {
- for(; pm; pm=pm->next) {
- ptcache_free_data(pm->data);
- if(pm->index_array)
- MEM_freeN(pm->index_array);
- }
+ for(; pm; pm=pm->next)
+ ptcache_free_data(pm);
BLI_freelistN(mem_cache);
}
@@ -2587,7 +2626,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
cache->flag |= PTCACHE_DISK_CACHE;
- ptcache_free_data(pm->data);
+ ptcache_free_data(pm);
MEM_freeN(pm);
ptcache_file_close(pf);
@@ -2597,7 +2636,7 @@ void BKE_ptcache_disk_to_mem(PTCacheID *pid)
BKE_ptcache_mem_incr_pointers(pm);
}
- //ptcache_make_index_array(pm, pid->totpoint(pid->calldata));
+ ptcache_make_index_array(pm, pid->totpoint(pid->calldata, cfra));
BLI_addtail(&pid->cache->mem_cache, pm);
@@ -2813,16 +2852,14 @@ void BKE_ptcache_update_info(PTCacheID *pid)
}
else {
PTCacheMem *pm = cache->mem_cache.first;
- float framesize = 0.0f, bytes = 0.0f;
- int mb;
-
- if(pm)
- framesize = (float)ptcache_pid_old_elemsize(pid) * (float)pm->totpoint;
+ float bytes = 0.0f;
+ int i, mb;
- for(; pm; pm=pm->next)
+ for(; pm; pm=pm->next) {
+ for(i=0; i<BPHYS_TOT_DATA; i++)
+ bytes += pm->data[i] ? MEM_allocN_len(pm->data[i]) : 0.0f;
totframes++;
-
- bytes = totframes * framesize;
+ }
mb = (bytes > 1024.0f * 1024.0f);