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/particle_system.c')
-rw-r--r--source/blender/blenkernel/intern/particle_system.c428
1 files changed, 237 insertions, 191 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 1931b89af38..dcd3fcd2f89 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -123,11 +123,21 @@ static int get_current_display_percentage(ParticleSystem *psys)
void psys_reset(ParticleSystem *psys, int mode)
{
ParticleSettings *part= psys->part;
- PARTICLE_P;
+ ParticleData *pa;
+ int i;
if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
- if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->edit && psys->edit->edited))) {
- psys_free_particles(psys);
+ if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->flag & PSYS_EDITED))) {
+ if(psys->particles) {
+ if(psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
+
+ for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++)
+ if(pa->hair) MEM_freeN(pa->hair);
+
+ MEM_freeN(psys->particles);
+ psys->particles= NULL;
+ }
psys->totpart= 0;
psys->totkeyed= 0;
@@ -135,17 +145,14 @@ void psys_reset(ParticleSystem *psys, int mode)
if(psys->reactevents.first)
BLI_freelistN(&psys->reactevents);
-
- if(psys->edit && psys->free_edit) {
- psys->free_edit(psys->edit);
- psys->edit = NULL;
- psys->free_edit = NULL;
- }
}
}
else if(mode == PSYS_RESET_CACHE_MISS) {
/* set all particles to be skipped */
- LOOP_PARTICLES
+ ParticleData *pa = psys->particles;
+ int p=0;
+
+ for(; p<psys->totpart; p++, pa++)
pa->flag |= PARS_NO_DISP;
}
@@ -158,7 +165,7 @@ void psys_reset(ParticleSystem *psys, int mode)
psys->totchild= 0;
/* reset path cache */
- psys_free_path_cache(psys, psys->edit);
+ psys_free_path_cache(psys);
/* reset point cache */
psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID;
@@ -167,10 +174,9 @@ void psys_reset(ParticleSystem *psys, int mode)
static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
{
- ParticleData *newpars = NULL;
- BoidParticle *newboids = NULL;
- PARTICLE_P;
- int totpart, totsaved = 0;
+ ParticleData *newpars = 0, *pa;
+ BoidData *newboids = 0;
+ int i, totpart, totsaved = 0;
if(new_totpart<0) {
if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
@@ -183,46 +189,47 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
else
totpart=new_totpart;
- if(totpart && totpart != psys->totpart) {
+ if(totpart) {
newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
-
- if(psys->particles) {
- totsaved=MIN2(psys->totpart,totpart);
- /*save old pars*/
- if(totsaved) {
- memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
-
- if(psys->particles->boid)
- memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle));
- }
- if(psys->particles->keys)
- MEM_freeN(psys->particles->keys);
+ if(psys->part->phystype == PART_PHYS_BOIDS)
+ newboids = MEM_callocN(totpart*sizeof(BoidData), "Boid Data");
+ }
+ if(psys->particles) {
+ totsaved=MIN2(psys->totpart,totpart);
+ /*save old pars*/
+ if(totsaved) {
+ memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
- if(psys->particles->boid)
- MEM_freeN(psys->particles->boid);
+ if(newboids)
+ memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidData));
+ }
- for(p=0, pa=newpars; p<totsaved; p++, pa++) {
- if(pa->keys) {
- pa->keys= NULL;
- pa->totkey= 0;
- }
- }
+ if(psys->particles->keys)
+ MEM_freeN(psys->particles->keys);
- for(p=totsaved, pa=psys->particles+totsaved; p<psys->totpart; p++, pa++)
- if(pa->hair) MEM_freeN(pa->hair);
+ if(psys->particles->boid)
+ MEM_freeN(psys->particles->boid);
- MEM_freeN(psys->particles);
+ for(i=0, pa=newpars; i<totsaved; i++, pa++) {
+ if(pa->keys) {
+ pa->keys= NULL;
+ pa->totkey= 0;
+ }
}
-
- psys->particles=newpars;
- if(newboids) {
- LOOP_PARTICLES
- pa->boid = newboids++;
- }
-
- psys->totpart=totpart;
+ for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++)
+ if(pa->hair) MEM_freeN(pa->hair);
+
+ MEM_freeN(psys->particles);
+ }
+ psys->particles=newpars;
+
+ if(newboids) {
+ pa = psys->particles;
+ pa->boid = newboids;
+ for(i=1, pa++; i<totpart; i++,pa++)
+ pa->boid = (pa-1)->boid + 1;
}
if(psys->child) {
@@ -230,6 +237,8 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
psys->child=0;
psys->totchild=0;
}
+
+ psys->totpart=totpart;
}
static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys)
@@ -276,7 +285,8 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
each original elements can reference its derived elements
*/
Mesh *me= (Mesh*)ob->data;
- PARTICLE_P;
+ ParticleData *pa= 0;
+ int p;
/* CACHE LOCATIONS */
if(!dm->deformedOnly) {
@@ -313,7 +323,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
}
/* cache the verts/faces! */
- LOOP_PARTICLES {
+ for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
if(psys->part->from == PART_FROM_VERT) {
if(nodearray[pa->num])
pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
@@ -333,7 +343,7 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
* should know to use the num or num_dmcache, set the num_dmcache to
* an invalid value, just incase */
- LOOP_PARTICLES
+ for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++)
pa->num_dmcache = -1;
}
}
@@ -1433,11 +1443,12 @@ static void distribute_particles_on_dm(DerivedMesh *finaldm, Scene *scene, Objec
/* ready for future use, to emit particles without geometry */
static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from)
{
- PARTICLE_P;
+ ParticleData *pa;
+ int totpart=psys->totpart, p;
fprintf(stderr,"Shape emission not yet possible!\n");
- LOOP_PARTICLES {
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
pa->foffset= 0.0f;
pa->num= -1;
@@ -1459,11 +1470,12 @@ static void distribute_particles(Scene *scene, Object *ob, ParticleSystem *psys,
distribute_particles_on_shape(ob,psys,from);
if(distr_error){
- PARTICLE_P;
+ ParticleData *pa;
+ int totpart=psys->totpart, p;
fprintf(stderr,"Particle distribution error!\n");
- LOOP_PARTICLES {
+ for(p=0,pa=psys->particles; p<totpart; p++,pa++){
pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
pa->foffset= 0.0f;
pa->num= -1;
@@ -1558,7 +1570,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
Material *ma=0;
//IpoCurve *icu=0; // XXX old animation system
int totpart;
- float rand;
+ float rand,length;
part=psys->part;
@@ -1613,8 +1625,40 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
pa->dietime= pa->time+pa->lifetime;
+ pa->sizemul= BLI_frand();
+
+ rand= BLI_frand();
+
+ /* while loops are to have a spherical distribution (avoid cubic distribution) */
+ if(part->phystype != PART_PHYS_BOIDS) {
+ /* boids store gravity in r_ve, so skip here */
+ length=2.0f;
+ while(length>1.0){
+ pa->r_ve[0]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ve[1]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ve[2]=2.0f*(BLI_frand()-0.5f);
+ length=VecLength(pa->r_ve);
+ }
+ }
+
+ length=2.0f;
+ while(length>1.0){
+ pa->r_ave[0]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ave[1]=2.0f*(BLI_frand()-0.5f);
+ pa->r_ave[2]=2.0f*(BLI_frand()-0.5f);
+ length=VecLength(pa->r_ave);
+ }
+
+ pa->r_rot[0]=2.0f*(BLI_frand()-0.5f);
+ pa->r_rot[1]=2.0f*(BLI_frand()-0.5f);
+ pa->r_rot[2]=2.0f*(BLI_frand()-0.5f);
+ pa->r_rot[3]=2.0f*(BLI_frand()-0.5f);
+
+ NormalQuat(pa->r_rot);
+
if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
- if(ptex.exist < BLI_frand())
+ /* any unique random number will do (r_ave[0]) */
+ if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
pa->flag |= PARS_UNEXIST;
else
pa->flag &= ~PARS_UNEXIST;
@@ -1628,9 +1672,10 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
{
//IpoCurve *icu=0; // XXX old animation system
- PARTICLE_P;
+ ParticleData *pa;
+ int p, totpart=psys->totpart;
- LOOP_PARTICLES
+ for(p=0, pa=psys->particles; p<totpart; p++, pa++)
initialize_particle(pa,p,ob,psys,psmd);
if(psys->part->type != PART_FLUID) {
@@ -1698,39 +1743,10 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
- float q_phase[4], length, r_phase;
+ float q_phase[4];
part=psys->part;
ptex.ivel=1.0;
-
- BLI_srandom(psys->seed + (pa - psys->particles));
-
- /* we need to get every random even if they're not used so that they don't effect eachother */
- /* while loops are to have a spherical distribution (avoid cubic distribution) */
- length=2.0f;
- while(length>1.0){
- r_vel[0]=2.0f*(BLI_frand()-0.5f);
- r_vel[1]=2.0f*(BLI_frand()-0.5f);
- r_vel[2]=2.0f*(BLI_frand()-0.5f);
- length=VecLength(r_vel);
- }
-
- length=2.0f;
- while(length>1.0){
- r_ave[0]=2.0f*(BLI_frand()-0.5f);
- r_ave[1]=2.0f*(BLI_frand()-0.5f);
- r_ave[2]=2.0f*(BLI_frand()-0.5f);
- length=VecLength(r_ave);
- }
-
- r_rot[0]=2.0f*(BLI_frand()-0.5f);
- r_rot[1]=2.0f*(BLI_frand()-0.5f);
- r_rot[2]=2.0f*(BLI_frand()-0.5f);
- r_rot[3]=2.0f*(BLI_frand()-0.5f);
-
- NormalQuat(r_rot);
-
- r_phase = BLI_frand();
if(part->from==PART_FROM_PARTICLE){
Object *tob;
@@ -1741,26 +1757,29 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
if(tob==0)
tob=ob;
- tpsys=BLI_findlink(&tob->particlesystem, psys->target_psys-1);
+ tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
state.time = pa->time;
if(pa->num == -1)
memset(&state, 0, sizeof(state));
else
psys_get_particle_state(scene, tob,tpsys,pa->num,&state,1);
- psys_get_from_key(&state, loc, nor, rot, 0);
+ psys_get_from_key(&state,loc,nor,rot,0);
- QuatMulVecf(rot, vtan);
- QuatMulVecf(rot, utan);
+ QuatMulVecf(rot,vtan);
+ QuatMulVecf(rot,utan);
+ VECCOPY(r_vel,pa->r_ve);
+ VECCOPY(r_rot,pa->r_rot);
+ VECCOPY(r_ave,pa->r_ave);
- VECCOPY(p_vel, state.vel);
+ VECCOPY(p_vel,state.vel);
speed=Normalize(p_vel);
- VecMulf(p_vel, Inpf(r_vel, p_vel));
- VECSUB(p_vel, r_vel, p_vel);
+ VecMulf(p_vel,Inpf(pa->r_ve,p_vel));
+ VECSUB(p_vel,pa->r_ve,p_vel);
Normalize(p_vel);
- VecMulf(p_vel, speed);
+ VecMulf(p_vel,speed);
- VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
+ VECCOPY(pa->fuv,loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
}
else{
/* get precise emitter matrix if particle is born */
@@ -1814,25 +1833,29 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
/* -velocity */
if(part->randfac!=0.0){
- Mat4Mul3Vecfl(ob->obmat,r_vel);
+ VECADD(r_vel,tloc,pa->r_ve);
+ Mat4MulVecfl(ob->obmat,r_vel);
+ VECSUB(r_vel,r_vel,loc);
Normalize(r_vel);
}
/* -angular velocity */
if(part->avemode==PART_AVE_RAND){
- Mat4Mul3Vecfl(ob->obmat,r_ave);
+ VECADD(r_ave,tloc,pa->r_ave);
+ Mat4MulVecfl(ob->obmat,r_ave);
+ VECSUB(r_ave,r_ave,loc);
Normalize(r_ave);
}
/* -rotation */
if(part->randrotfac != 0.0f){
+ QUATCOPY(r_rot,pa->r_rot);
Mat4ToQuat(ob->obmat,rot);
QuatMul(r_rot,r_rot,rot);
}
}
if(part->phystype==PART_PHYS_BOIDS) {
- BoidParticle *bpa = pa->boid;
float dvec[3], q[4], mat[3][3];
VECCOPY(pa->state.co,loc);
@@ -1849,21 +1872,16 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
VECCOPY(pa->state.ave, nor);
}
/* and gravity in r_ve */
- bpa->gravity[0] = bpa->gravity[1] = 0.0f;
- bpa->gravity[2] = -1.0f;
+ pa->r_ve[0] = pa->r_ve[1] = 0.0f;
+ pa->r_ve[2] = -1.0f;
if(part->acc[2]!=0.0f)
- bpa->gravity[2] = part->acc[2];
-
- //pa->r_ve[0] = pa->r_ve[1] = 0.0f;
- //pa->r_ve[2] = -1.0f;
- //if(part->acc[2]!=0.0f)
- // pa->r_ve[2] = part->acc[2];
+ pa->r_ve[2] = part->acc[2];
/* calculate rotation matrix */
- Projf(dvec, r_vel, pa->state.ave);
+ Projf(dvec, pa->r_ve, pa->state.ave);
VecSubf(mat[0], pa->state.ave, dvec);
Normalize(mat[0]);
- VECCOPY(mat[2], r_vel);
+ VECCOPY(mat[2], pa->r_ve);
VecMulf(mat[2], -1.0f);
Normalize(mat[2]);
Crossf(mat[1], mat[2], mat[0]);
@@ -1872,10 +1890,10 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
Mat3ToQuat_is_ok(mat, q);
QuatCopy(pa->state.rot, q);
- bpa->data.health = part->boids->health;
- bpa->data.mode = eBoidMode_InAir;
- bpa->data.state_id = ((BoidState*)part->boids->states.first)->id;
- bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
+ pa->boid->health = part->boids->health;
+ pa->boid->mode = eBoidMode_InAir;
+ pa->boid->state_id = ((BoidState*)part->boids->states.first)->id;
+ pa->boid->acc[0]=pa->boid->acc[1]=pa->boid->acc[2]=0.0f;
}
else {
/* conversion done so now we apply new: */
@@ -1964,8 +1982,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
/* rotation phase */
phasefac = part->phasefac;
- if(part->randphasefac != 0.0f)
- phasefac += part->randphasefac * r_phase;
+ if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */
+ phasefac += part->randphasefac * pa->r_ave[0];
VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase);
/* combine base rotation & phase */
@@ -2003,7 +2021,8 @@ void reset_particle(Scene *scene, ParticleData *pa, ParticleSystem *psys, Partic
pa->state.time = cfra;
-// pa->flag &= ~PARS_STICKY;
+ pa->stick_ob = 0;
+ pa->flag &= ~PARS_STICKY;
}
static void reset_all_particles(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
{
@@ -2069,9 +2088,8 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSystem *kpsys = psys;
ParticleTarget *pt;
- PARTICLE_P;
- ParticleKey *key;
- int totpart = psys->totpart, k, totkeys = psys->totkeyed;
+ ParticleData *pa;
+ int totpart = psys->totpart, i, k, totkeys = psys->totkeyed;
/* no proper targets so let's clear and bail out */
if(psys->totkeyed==0) {
@@ -2083,12 +2101,12 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
if(totpart && psys->particles->totkey != totkeys) {
free_keyed_keys(psys);
- key = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
+ psys->particles->keys = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
+ psys->particles->totkey = totkeys;
- LOOP_PARTICLES {
- pa->keys = key;
+ for(i=1, pa=psys->particles+1; i<totpart; i++,pa++){
+ pa->keys = (pa-1)->keys + totkeys;
pa->totkey = totkeys;
- key += totkeys;
}
}
@@ -2102,23 +2120,22 @@ static void set_keyed_keys(Scene *scene, Object *ob, ParticleSystem *psys)
else
kpsys = BLI_findlink(&ob->particlesystem, pt->psys - 1);
- LOOP_PARTICLES {
- key = pa->keys + k;
- key->time = -1.0; /* use current time */
+ for(i=0,pa=psys->particles; i<totpart; i++, pa++) {
+ (pa->keys + k)->time = -1.0; /* use current time */
- psys_get_particle_state(scene, pt->ob, kpsys, p%kpsys->totpart, key, 1);
+ psys_get_particle_state(scene, pt->ob, kpsys, i%kpsys->totpart, pa->keys + k, 1);
if(psys->flag & PSYS_KEYED_TIMING){
- key->time = pa->time + pt->time;
+ (pa->keys+k)->time = pa->time + pt->time;
if(pt->duration != 0.0f && k+1 < totkeys) {
- copy_particle_key(key+1, key, 1);
- (key+1)->time = pa->time + pt->time + pt->duration;
+ copy_particle_key(pa->keys+k+1, pa->keys+k, 1);
+ (pa->keys+k+1)->time = pa->time + pt->time + pt->duration;
}
}
else if(totkeys > 1)
- key->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
+ (pa->keys+k)->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
else
- key->time = pa->time;
+ pa->keys->time = pa->time;
}
if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f)
@@ -2257,7 +2274,7 @@ void psys_clear_temp_pointcache(ParticleSystem *psys)
if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0)
return;
- BKE_ptcache_free_mem(&psys->pointcache->mem_cache);
+ BKE_ptache_free_mem(psys->pointcache);
}
void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
{
@@ -2273,15 +2290,16 @@ void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra
static void update_particle_tree(ParticleSystem *psys)
{
if(psys) {
- PARTICLE_P;
+ ParticleData *pa = psys->particles;
+ int p, totpart = psys->totpart;
if(!psys->tree || psys->tree_frame != psys->cfra) {
BLI_kdtree_free(psys->tree);
- psys->tree = BLI_kdtree_new(psys->totpart);
+ psys->tree = BLI_kdtree_new(totpart);
- LOOP_PARTICLES {
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
if(pa->flag & (PARS_NO_DISP+PARS_UNEXIST) || pa->alive != PARS_ALIVE)
continue;
@@ -2524,9 +2542,9 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
ListBase *lb=&psys->effectors;
ParticleEffectorCache *ec;
ParticleSettings *part=psys->part;
- PARTICLE_P;
- int totpart;
+ ParticleData *pa;
float vec2[3],loc[3],*co=0;
+ int p,totpart;
for(ec= lb->first; ec; ec= ec->next) {
PartDeflect *pd= ec->ob->pd;
@@ -2550,7 +2568,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa
ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
- LOOP_PARTICLES {
+ for(p=0,pa=psys->particles; p<totpart; p++, pa++){
if(part->from == PART_FROM_PARTICLE) {
VECCOPY(loc, pa->fuv);
}
@@ -3220,7 +3238,7 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
ParticleCollision col;
BVHTreeRayHit hit;
float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
- float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
+ float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z;
int deflections=0, max_deflections=10;
VECCOPY(col.co1, pa->prev_state.co);
@@ -3229,10 +3247,9 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
/* override for boids */
if(part->phystype == PART_PHYS_BOIDS) {
- BoidParticle *bpa = pa->boid;
radius = pa->size;
boid_z = pa->state.co[2];
- skip_ob = bpa->ground;
+ skip_ob = pa->stick_ob;
}
/* 10 iterations to catch multiple deflections */
@@ -3302,7 +3319,12 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
deflections=max_deflections;
/* store for reactors */
- copy_particle_key(&reaction_state, &pa->state, 0);
+ copy_particle_key(&reaction_state,&pa->state,0);
+
+ if(part->flag & PART_STICKY){
+ pa->stick_ob=ob;
+ pa->flag |= PARS_STICKY;
+ }
}
else {
float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
@@ -3390,8 +3412,7 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) {
- BoidParticle *bpa = pa->boid;
- if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {
+ if(pa->boid->mode == eBoidMode_OnLand || co[2] <= boid_z) {
co[2] = boid_z;
vel[2] = 0.0f;
}
@@ -3433,9 +3454,10 @@ static void deflect_particle(Scene *scene, Object *pob, ParticleSystemModifierDa
/* Hair */
/************************************************/
static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra){
- HairKey *key, *root;
- PARTICLE_P;
+ ParticleData *pa;
+ HairKey *key;
int totpart;
+ int i;
Mat4Invert(ob->imat,ob->obmat);
@@ -3446,22 +3468,21 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
totpart=psys->totpart;
/* save new keys for elements if needed */
- LOOP_PARTICLES {
+ for(i=0,pa=psys->particles; i<totpart; i++,pa++) {
/* first time alloc */
if(pa->totkey==0 || pa->hair==NULL) {
pa->hair = MEM_callocN((psys->part->hair_step + 1) * sizeof(HairKey), "HairKeys");
pa->totkey = 0;
}
- key = root = pa->hair;
- key += pa->totkey;
+ key = pa->hair + pa->totkey;
/* convert from global to geometry space */
VecCopyf(key->co, pa->state.co);
Mat4MulVecfl(ob->imat, key->co);
if(pa->totkey) {
- VECSUB(key->co, key->co, root->co);
+ VECSUB(key->co, key->co, pa->hair->co);
psys_vec_rot_to_face(psmd->dm, pa, key->co);
}
@@ -3473,7 +3494,7 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
/* root is always in the origin of hair space so we set it to be so after the last key is saved*/
if(pa->totkey == psys->part->hair_step + 1)
- root->co[0] = root->co[1] = root->co[2] = 0.0f;
+ pa->hair->co[0] = pa->hair->co[1] = pa->hair->co[2] = 0.0f;
}
}
/************************************************/
@@ -3483,14 +3504,14 @@ static void save_hair(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSy
static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra,
float *vg_vel, float *vg_tan, float *vg_rot, float *vg_size)
{
+ ParticleData *pa;
ParticleSettings *part=psys->part;
KDTree *tree=0;
IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
Material *ma=give_current_material(ob,part->omat);
BoidBrainData bbd;
- PARTICLE_P;
float timestep;
- int totpart;
+ int p, totpart;
/* current time */
float ctime, ipotime; // XXX old animation system
/* frame & time changes */
@@ -3519,7 +3540,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
if(part->type==PART_REACTOR)
vg_size=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
- LOOP_PARTICLES {
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
if(pa->flag & PARS_UNEXIST) continue;
/* set correct ipo timing */
@@ -3588,7 +3609,7 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
}
/* main loop: calculate physics for all particles */
- LOOP_PARTICLES {
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
if(pa->flag & (PARS_UNEXIST+PARS_NO_DISP)) continue;
copy_particle_key(&pa->prev_state,&pa->state,1);
@@ -3676,6 +3697,9 @@ static void dynamics_step(Scene *scene, Object *ob, ParticleSystem *psys, Partic
else{
pa->alive=PARS_DEAD;
pa->state.time=pa->dietime;
+
+ if(pa->flag&PARS_STICKY)
+ psys_key_to_object(pa->stick_ob,&pa->state,0);
}
}
else
@@ -3723,29 +3747,52 @@ static void psys_update_path_cache(Scene *scene, Object *ob, ParticleSystemModif
if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED) && ( psys_in_edit_mode(scene, psys) || (part->type==PART_HAIR
|| (part->ren_as == PART_DRAW_PATH && (part->draw_as == PART_DRAW_REND || psys->renderdata))))){
- psys_cache_paths(scene, ob, psys, cfra);
+ psys_cache_paths(scene, ob, psys, cfra, 0);
/* for render, child particle paths are computed on the fly */
if(part->childtype) {
- if(((psys->totchild!=0)) || (psys_in_edit_mode(scene, psys) && (pset->flag&PE_DRAW_PART)))
+ if(((psys->totchild!=0)) || (psys_in_edit_mode(scene, psys) && (pset->flag&PE_SHOW_CHILD)))
if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE))
psys_cache_child_paths(scene, ob, psys, cfra, 0);
}
}
else if(psys->pathcache)
- psys_free_path_cache(psys, NULL);
+ psys_free_path_cache(psys);
+}
+
+/* calculate and store key locations in world coordinates */
+void psys_update_world_cos(Object *ob, ParticleSystem *psys)
+{
+ ParticleSystemModifierData *psmd= psys_get_modifier(ob, psys);
+ ParticleData *pa;
+ ParticleEditKey *key;
+ int i, k, totpart;
+ float hairmat[4][4];
+
+ if(psys==0 || psys->edit==0)
+ return;
+
+ totpart= psys->totpart;
+
+ for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
+ psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
+
+ for(k=0, key=psys->edit->keys[i]; k<pa->totkey; k++, key++) {
+ VECCOPY(key->world_co,key->co);
+ Mat4MulVecfl(hairmat, key->world_co);
+ }
+ }
}
static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
{
ParticleSettings *part = psys->part;
- PARTICLE_P;
- float disp = (float)get_current_display_percentage(psys)/100.0f;
-
- BLI_srandom(psys->seed);
+ ParticleData *pa;
+ int p;
+ float disp = (float)get_current_display_percentage(psys)/50.0f-1.0f;
- LOOP_PARTICLES {
- if(BLI_frand() > disp)
+ for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
+ if(pa->r_rot[0] > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -3761,6 +3808,9 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
psys_init_effectors(scene, ob, part->eff_group, psys);
if(psys->effectors.first)
precalc_effectors(scene, ob,psys,psmd,cfra);
+
+ if(psys_in_edit_mode(scene, psys))
+ psys_update_world_cos(ob, psys);
psys_update_path_cache(scene, ob,psmd,psys,cfra);
}
@@ -3769,14 +3819,13 @@ static void hair_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd
static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *psmd, ParticleSystem *psys, float cfra)
{
ParticleSettings *part=psys->part;
+ ParticleData *pa;
ParticleKey state;
IpoCurve *icu_esize= NULL; //=find_ipocurve(part->ipo,PART_EMIT_SIZE); // XXX old animation system
Material *ma=give_current_material(ob,part->omat);
- PARTICLE_P;
+ int p;
float disp, birthtime, dietime, *vg_size= NULL; // XXX ipotime=cfra
- BLI_srandom(psys->seed);
-
if(part->from!=PART_FROM_PARTICLE)
vg_size= psys_cache_vgroup(psmd->dm,psys,PSYS_VG_SIZE);
@@ -3789,9 +3838,9 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
precalc_effectors(scene, ob,psys,psmd,cfra);
//}
- disp= (float)get_current_display_percentage(psys)/100.0f;
+ disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
- LOOP_PARTICLES {
+ for(p=0, pa=psys->particles; p<psys->totpart; p++,pa++){
#if 0 // XXX old animation system
if((part->flag&PART_ABS_TIME)==0 && part->ipo){
ipotime=100.0f*(cfra-pa->time)/pa->lifetime;
@@ -3838,7 +3887,7 @@ static void cached_step(Scene *scene, Object *ob, ParticleSystemModifierData *ps
psys->lattice= NULL;
}
- if(BLI_frand() > disp)
+ if(pa->r_rot[0] > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -3891,8 +3940,8 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys)
else {
free_hair(psys, 1);
- CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime));
- CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime));
+ CLAMP(part->path_start, part->sta, part->end + part->lifetime);
+ CLAMP(part->path_end, part->sta, part->end + part->lifetime);
}
psys->softflag= 0;
@@ -3901,25 +3950,23 @@ static void psys_changed_type(Object *ob, ParticleSystem *psys)
}
void psys_check_boid_data(ParticleSystem *psys)
{
- BoidParticle *bpa;
- PARTICLE_P;
-
- pa = psys->particles;
+ ParticleData *pa = psys->particles;
+ int p = 1;
if(!pa)
return;
if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) {
if(!pa->boid) {
- bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data");
+ pa->boid = MEM_callocN(psys->totpart * sizeof(BoidData), "Boid Data");
- LOOP_PARTICLES
- pa->boid = bpa++;
+ for(pa++; p<psys->totpart; p++, pa++)
+ pa->boid = (pa-1)->boid + 1;
}
}
else if(pa->boid){
MEM_freeN(pa->boid);
- LOOP_PARTICLES
+ for(; p<psys->totpart; p++, pa++)
pa->boid = NULL;
}
}
@@ -4067,10 +4114,10 @@ static void particles_fluid_step(Scene *scene, Object *ob, ParticleSystem *psys,
static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
{
ParticleSettings *part;
+ ParticleData *pa;
PointCache *cache;
PTCacheID pid;
- PARTICLE_P;
- int totpart, oldtotpart, totchild, oldtotchild;
+ int totpart, oldtotpart, totchild, oldtotchild, p;
float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
int init= 0, distr= 0, alloc= 0, usecache= 0, only_children_changed= 0;
int framenr, framedelta, startframe, endframe;
@@ -4213,7 +4260,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
}
else if(result==PTCACHE_READ_OLD) {
psys->cfra = (float)cache->simframe;
- LOOP_PARTICLES {
+ for(p=0, pa=psys->particles; p<totpart; p++, pa++) {
/* update alive status */
if(pa->time > psys->cfra)
pa->alive = PARS_UNBORN;
@@ -4252,11 +4299,10 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
}
/* set particles to be not calculated TODO: can't work with pointcache */
- disp= (float)get_current_display_percentage(psys)/100.0f;
+ disp= (float)get_current_display_percentage(psys)/50.0f-1.0f;
- BLI_srandom(psys->seed);
- LOOP_PARTICLES {
- if(BLI_frand() > disp)
+ for(p=0, pa=psys->particles; p<totpart; p++,pa++){
+ if(pa->r_rot[0] > disp)
pa->flag |= PARS_NO_DISP;
else
pa->flag &= ~PARS_NO_DISP;
@@ -4293,7 +4339,7 @@ static void system_step(Scene *scene, Object *ob, ParticleSystem *psys, Particle
psys_update_path_cache(scene, ob, psmd, psys,(int)cfra);
}
else if(psys->pathcache)
- psys_free_path_cache(psys, NULL);
+ psys_free_path_cache(psys);
/* cleanup */
if(vg_vel) MEM_freeN(vg_vel);
@@ -4339,7 +4385,7 @@ static void psys_to_softbody(Scene *scene, Object *ob, ParticleSystem *psys)
static int hair_needs_recalc(ParticleSystem *psys)
{
- if((!psys->edit || !psys->edit->edited) &&
+ if((psys->flag & PSYS_EDITED)==0 &&
((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET)) {
return 1;
}