forked from bartvdbraak/blender
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:
parent
9b82ff3d00
commit
61f738e0f3
@ -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);
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user