From 61f738e0f3a96dddd235655db0359ffcaa7105fb Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Thu, 14 Oct 2004 22:20:42 +0000 Subject: [PATCH] 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 :) --- source/blender/blenkernel/intern/anim.c | 109 +++++++++------- source/blender/blenkernel/intern/effect.c | 4 +- .../intern/convertBlenderScene.c | 116 +++++++++++------- 3 files changed, 143 insertions(+), 86 deletions(-) diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 9df3130628a..779baf4e015 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -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; atotpart; 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; ctimestaticstep) { + 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); + } } } } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4249e5eef5b..2ad9f0485f0 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -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; diff --git a/source/blender/renderconverter/intern/convertBlenderScene.c b/source/blender/renderconverter/intern/convertBlenderScene.c index 912d44fee88..28fec81b491 100644 --- a/source/blender/renderconverter/intern/convertBlenderScene.c +++ b/source/blender/renderconverter/intern/convertBlenderScene.c @@ -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); }