Bug fix & new feature;

http://www.blender3d.org/cms/Particle_duplicators.443.0.html

Static particle systems now can also duplicate children (Dupli Vert).
Even ipo's for children are evaluated correctly then, nice stuff :)
This commit is contained in:
Ton Roosendaal 2004-10-14 22:20:42 +00:00
parent 9b82ff3d00
commit 61f738e0f3
3 changed files with 143 additions and 86 deletions

@ -272,6 +272,27 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir) /* returns OK
return 1;
}
static Object *new_dupli_object(ListBase *lb, Object *ob, Object *par)
{
Object *newob;
newob= MEM_mallocN(sizeof(Object), "newobj dupli");
memcpy(newob, ob, sizeof(Object));
newob->flag |= OB_FROMDUPLI;
newob->id.newid= (ID *)par; /* store duplicator */
/* only basis-ball gets displist */
if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= NULL;
if(ob!=par) { // dupliverts, particle
newob->parent= NULL;
newob->track= NULL;
}
BLI_addtail(lb, newob);
return newob;
}
void frames_duplilist(Object *ob)
{
extern int enable_cu_speed; /* object.c */
@ -304,18 +325,10 @@ void frames_duplilist(Object *ob)
else ok= 0;
}
if(ok) {
newob= MEM_mallocN(sizeof(Object), "newobobj dupli");
memcpy(newob, ob, sizeof(Object));
/*only the basis-ball gets a displist */
if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= 0;
newob= new_dupli_object(&duplilist, ob, ob);
BLI_addtail(&duplilist, newob);
do_ob_ipo(newob);
where_is_object(newob);
newob->flag |= OB_FROMDUPLI;
newob->id.newid= (ID *)ob; /* store duplicator */
}
}
@ -370,14 +383,7 @@ void vertex_duplilist(Scene *sce, Object *par)
VecSubf(vec, vec, pmat[3]);
VecAddf(vec, vec, ob->obmat[3]);
newob= MEM_mallocN(sizeof(Object), "newobj dupli");
memcpy(newob, ob, sizeof(Object));
newob->flag |= OB_FROMDUPLI;
newob->id.newid= (ID *)par; /* keep duplicator */
/* only basis-ball gets displist */
if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= 0;
newob= new_dupli_object(&duplilist, ob, par);
VECCOPY(newob->obmat[3], vec);
if(par->transflag & OB_DUPLIROT) {
@ -391,12 +397,6 @@ void vertex_duplilist(Scene *sce, Object *par)
Mat4MulMat43(newob->obmat, tmat, mat);
}
newob->parent= 0;
newob->track= 0;
/* newob->borig= base; */
BLI_addtail(&duplilist, newob);
VECCOPY(pvec, vec);
}
@ -444,39 +444,62 @@ void particle_duplilist(Scene *sce, Object *par, PartEff *paf)
pa= paf->keys;
for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
if(ctime > pa->time) {
if(ctime < pa->time+pa->lifetime) {
newob= MEM_mallocN(sizeof(Object), "newobj dupli");
memcpy(newob, ob, sizeof(Object));
newob->flag |= OB_FROMDUPLI;
newob->id.newid= (ID *)par; /* keep duplicator */
/* only basis-ball gets displist */
if(newob->type==OB_MBALL) newob->disp.first= newob->disp.last= 0;
if(paf->flag & PAF_STATIC) {
float mtime;
where_is_particle(paf, pa, pa->time, vec1);
mtime= pa->time+pa->lifetime+paf->staticstep-1;
for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
newob= new_dupli_object(&duplilist, ob, par);
/* make sure hair grows until the end.. */
if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
/* to give ipos in object correct offset */
where_is_object_time(newob, ctime-pa->time);
where_is_particle(paf, pa, ctime, vec);
Mat4MulVecfl(par->obmat, vec);
if(paf->stype==PAF_VECT) {
where_is_particle(paf, pa, ctime+1.0f, vec1);
where_is_particle(paf, pa, ctime+1, vec1);
Mat4MulVecfl(par->obmat, vec1);
VecSubf(vec1, vec1, vec);
q2= vectoquat(vec1, ob->trackflag, ob->upflag);
QuatToMat3(q2, mat);
Mat4CpyMat4(tmat, newob->obmat);
Mat4MulMat43(newob->obmat, tmat, mat);
}
VECCOPY(newob->obmat[3], vec);
}
}
else { // non static particles
if(ctime > pa->time) {
if(ctime < pa->time+pa->lifetime) {
newob= new_dupli_object(&duplilist, ob, par);
/* to give ipos in object correct offset */
where_is_object_time(newob, ctime-pa->time);
where_is_particle(paf, pa, ctime, vec);
if(paf->stype==PAF_VECT) {
where_is_particle(paf, pa, ctime+1.0f, vec1);
VecSubf(vec1, vec1, vec);
q2= vectoquat(vec1, ob->trackflag, ob->upflag);
newob->parent= 0;
newob->track= 0;
BLI_addtail(&duplilist, newob);
QuatToMat3(q2, mat);
Mat4CpyMat4(tmat, newob->obmat);
Mat4MulMat43(newob->obmat, tmat, mat);
}
VECCOPY(newob->obmat[3], vec);
}
}
}
}

@ -161,8 +161,8 @@ void free_effects(ListBase *lb)
Effect *copy_effect(Effect *eff)
{
Effect *effn;
effn= MEM_dupallocN(eff);
effn= MEM_dupalloc(eff);
if(effn->type==EFF_PARTICLE) ((PartEff *)effn)->keys= 0;
return effn;

@ -949,6 +949,8 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
Particle *pa=0;
HaloRen *har=0;
Material *ma=0;
VertRen *v1= NULL;
VlakRen *vlr;
float xn, yn, zn, imat[3][3], mat[4][4], hasize;
float mtime, ptime, ctime, vec[3], vec1[3], view[3], nor[3];
int a, mat_nr=1;
@ -957,11 +959,11 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
if(pa==NULL || (paf->flag & PAF_ANIMATED)) {
build_particle_system(ob);
pa= paf->keys;
if(pa==0) return;
if(pa==NULL) return;
}
ma= give_render_material(ob, 1);
if(ma==0) ma= &defmaterial;
if(ma==NULL) ma= &defmaterial;
MTC_Mat4MulMat4(mat, ob->obmat, R.viewmat);
MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */
@ -987,7 +989,6 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
/* make sure hair grows until the end.. */
if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
/* watch it: also calc the normal of a particle */
if(paf->stype==PAF_VECT || ma->mode & MA_HALO_SHADE) {
where_is_particle(paf, pa, ctime+1.0, vec);
@ -1004,44 +1005,73 @@ static void render_static_particle_system(Object *ob, PartEff *paf)
if(ma==0) ma= &defmaterial;
}
if(ma->ipo) {
/* correction for lifetime */
ptime= 100.0*(ctime-pa->time)/pa->lifetime;
calc_ipo(ma->ipo, ptime);
execute_ipo((ID *)ma, ma->ipo);
}
hasize= ma->hasize;
if(ma->mode & MA_HALOPUNO) {
xn= pa->no[0];
yn= pa->no[1];
zn= pa->no[2];
/* transpose ! */
nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
Normalise(nor);
VECCOPY(view, vec);
Normalise(view);
zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
if(zn>=0.0) hasize= 0.0;
else hasize*= zn*zn*zn*zn;
}
if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize);
else {
har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0);
if(har && (ma->mode & MA_HALO_SHADE)) {
VecSubf(har->no, vec, vec1);
Normalise(har->no);
har->lay= ob->lay;
if(ma->mode & MA_WIRE) {
if(ctime == pa->time) {
v1= RE_findOrAddVert(R.totvert++);
VECCOPY(v1->co, vec);
}
else {
float cvec[3]={-1.0, 0.0, 0.0};
vlr= RE_findOrAddVlak(R.totvlak++);
vlr->ob= ob;
vlr->v1= v1;
vlr->v2= RE_findOrAddVert(R.totvert++);
vlr->v3= vlr->v2;
vlr->v4= NULL;
v1= vlr->v2; // cycle
VECCOPY(v1->co, vec);
VecSubf(vlr->n, vec, vec1);
Normalise(vlr->n);
VECCOPY(v1->n, vlr->n);
vlr->mat= ma;
vlr->ec= ME_V1V2;
vlr->lay= ob->lay;
}
}
else {
if(ma->ipo) {
/* correction for lifetime */
ptime= 100.0*(ctime-pa->time)/pa->lifetime;
calc_ipo(ma->ipo, ptime);
execute_ipo((ID *)ma, ma->ipo);
}
hasize= ma->hasize;
if(ma->mode & MA_HALOPUNO) {
xn= pa->no[0];
yn= pa->no[1];
zn= pa->no[2];
/* transpose ! */
nor[0]= imat[0][0]*xn+imat[0][1]*yn+imat[0][2]*zn;
nor[1]= imat[1][0]*xn+imat[1][1]*yn+imat[1][2]*zn;
nor[2]= imat[2][0]*xn+imat[2][1]*yn+imat[2][2]*zn;
Normalise(nor);
VECCOPY(view, vec);
Normalise(view);
zn= nor[0]*view[0]+nor[1]*view[1]+nor[2]*view[2];
if(zn>=0.0) hasize= 0.0;
else hasize*= zn*zn*zn*zn;
}
if(paf->stype==PAF_VECT) har= RE_inithalo(ma, vec, vec1, pa->co, hasize, paf->vectsize);
else {
har= RE_inithalo(ma, vec, 0, pa->co, hasize, 0);
if(har && (ma->mode & MA_HALO_SHADE)) {
VecSubf(har->no, vec, vec1);
Normalise(har->no);
har->lay= ob->lay;
}
}
}
VECCOPY(vec1, vec);
}
ma->ren->seed1++;
@ -1254,6 +1284,7 @@ static void init_render_mesh(Object *ob)
if(paf) {
if(paf->flag & PAF_STATIC) render_static_particle_system(ob, paf);
else render_particle_system(ob, paf);
mesh_modifier(ob, 'e'); // end
return;
}
@ -1261,8 +1292,11 @@ static void init_render_mesh(Object *ob)
MTC_Mat4Invert(ob->imat, mat);
MTC_Mat3CpyMat4(imat, ob->imat);
if(me->totvert==0) return;
if(me->totvert==0) {
mesh_modifier(ob, 'e'); // end
return;
}
totvlako= R.totvlak;
totverto= R.totvert;
@ -1743,7 +1777,7 @@ void RE_add_render_lamp(Object *ob, int doshadbuf)
lar->mode &= ~LA_SHAD_RAY;
}
}
lar->org= MEM_dupallocN(lar);
}