diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_particle.h | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 73 | ||||
-rw-r--r-- | source/blender/render/intern/source/convertblender.c | 934 | ||||
-rw-r--r-- | source/blender/src/drawobject.c | 350 |
4 files changed, 659 insertions, 713 deletions
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index ecc97dd5d3b..5dbfe2fe520 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -188,6 +188,19 @@ typedef struct ParticleThread { int num, tot; } ParticleThread; +typedef struct ParticleBillboardData +{ + struct Object *ob; + float vec[3], vel[3]; + float offset[2]; + float size, tilt, random, time; + int uv[3]; + int lock, num; + int totnum; + short align, uv_split, anim, split_offset; +} +ParticleBillboardData; + /* ----------- functions needed outside particlesystem ---------------- */ /* particle.c */ int count_particles(struct ParticleSystem *psys); @@ -260,6 +273,8 @@ void psys_threads_free(ParticleThread *threads); void psys_thread_distribute_particle(ParticleThread *thread, struct ParticleData *pa, struct ChildParticle *cpa, int p); void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey *keys, int i); +void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]); + /* particle_system.c */ int psys_count_keyed_targets(struct Object *ob, struct ParticleSystem *psys); void psys_get_reactor_target(struct Object *ob, struct ParticleSystem *psys, struct Object **target_ob, struct ParticleSystem **target_psys); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index b1ed165fedd..4eabb82f6cb 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3868,3 +3868,76 @@ void psys_get_dupli_path_transform(Object *ob, ParticleSystem *psys, ParticleSys *scale= len; } + +void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]) +{ + float onevec[3] = {0.0f,0.0f,0.0f}, tvec[3], tvec2[3]; + + xvec[0] = 1.0f; xvec[1] = 0.0f; xvec[2] = 0.0f; + yvec[0] = 0.0f; yvec[1] = 1.0f; yvec[2] = 0.0f; + + if(bb->align < PART_BB_VIEW) + onevec[bb->align]=1.0f; + + if(bb->lock && (bb->align == PART_BB_VIEW)) { + VECCOPY(xvec, bb->ob->obmat[0]); + Normalize(xvec); + + VECCOPY(yvec, bb->ob->obmat[1]); + Normalize(yvec); + + VECCOPY(zvec, bb->ob->obmat[2]); + Normalize(zvec); + } + else if(bb->align == PART_BB_VEL) { + float temp[3]; + + VECCOPY(temp, bb->vel); + Normalize(temp); + + VECSUB(zvec, bb->ob->obmat[3], bb->vec); + + if(bb->lock) { + float fac = -Inpf(zvec, temp); + + VECADDFAC(zvec, zvec, temp, fac); + } + Normalize(zvec); + + Crossf(xvec,temp,zvec); + Normalize(xvec); + + Crossf(yvec,zvec,xvec); + } + else { + VECSUB(zvec, bb->ob->obmat[3], bb->vec); + if(bb->lock) + zvec[bb->align] = 0.0f; + Normalize(zvec); + + if(bb->align < PART_BB_VIEW) + Crossf(xvec, onevec, zvec); + else + Crossf(xvec, bb->ob->obmat[1], zvec); + Normalize(xvec); + + Crossf(yvec,zvec,xvec); + } + + VECCOPY(tvec, xvec); + VECCOPY(tvec2, yvec); + + VecMulf(xvec, cos(bb->tilt * (float)M_PI)); + VecMulf(tvec2, sin(bb->tilt * (float)M_PI)); + VECADD(xvec, xvec, tvec2); + + VecMulf(yvec, cos(bb->tilt * (float)M_PI)); + VecMulf(tvec, -sin(bb->tilt * (float)M_PI)); + VECADD(yvec, yvec, tvec); + + VecMulf(xvec, bb->size); + VecMulf(yvec, bb->size); + + VECADDFAC(center, bb->vec, xvec, bb->offset[0]); + VECADDFAC(center, center, yvec, bb->offset[1]); +}
\ No newline at end of file diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 601acc881de..9e474c19619 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -947,11 +947,17 @@ static Material *give_render_material(Render *re, Object *ob, int nr) /* ------------------------------------------------------------------------- */ /* Particles */ /* ------------------------------------------------------------------------- */ - +typedef struct ParticleStrandData +{ + struct MCol *mcol; + float *orco, *uvco, *surfnor; + float time, adapt_angle, adapt_pix, size; + int totuv, totcol; + int first, line, adapt, override_uv; +} +ParticleStrandData; /* future thread problem... */ -static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, float *orco, float *surfnor, - float *uvco, int totuv, MCol *mcol, int totcol, float *vec, float *vec1, float ctime, - int first, int line, int adapt, float adapt_angle, float adapt_pix, int override_uv) +static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, ParticleStrandData *sd, float *vec, float *vec1) { static VertRen *v1= NULL, *v2= NULL; VlakRen *vlr; @@ -974,11 +980,11 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo float fac; if(ma->strand_ease!=0.0f) { if(ma->strand_ease<0.0f) - fac= pow(ctime, 1.0+ma->strand_ease); + fac= pow(sd->time, 1.0+ma->strand_ease); else - fac= pow(ctime, 1.0/(1.0f-ma->strand_ease)); + fac= pow(sd->time, 1.0/(1.0f-ma->strand_ease)); } - else fac= ctime; + else fac= sd->time; width= ((1.0f-fac)*ma->strand_sta + (fac)*ma->strand_end); @@ -1010,7 +1016,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo flag |= R_STRAND; /* single face line */ - if(line) { + if(sd->line) { vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->flag= flag; vlr->v1= RE_findOrAddVert(obr, obr->totvert++); @@ -1021,25 +1027,25 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo VECCOPY(vlr->v1->co, vec); VecAddf(vlr->v1->co, vlr->v1->co, cross); VECCOPY(vlr->v1->n, nor); - vlr->v1->orco= orco; + vlr->v1->orco= sd->orco; vlr->v1->accum= -1.0f; // accum abuse for strand texco VECCOPY(vlr->v2->co, vec); VecSubf(vlr->v2->co, vlr->v2->co, cross); VECCOPY(vlr->v2->n, nor); - vlr->v2->orco= orco; + vlr->v2->orco= sd->orco; vlr->v2->accum= vlr->v1->accum; VECCOPY(vlr->v4->co, vec1); VecAddf(vlr->v4->co, vlr->v4->co, cross); VECCOPY(vlr->v4->n, nor); - vlr->v4->orco= orco; + vlr->v4->orco= sd->orco; vlr->v4->accum= 1.0f; // accum abuse for strand texco VECCOPY(vlr->v3->co, vec1); VecSubf(vlr->v3->co, vlr->v3->co, cross); VECCOPY(vlr->v3->n, nor); - vlr->v3->orco= orco; + vlr->v3->orco= sd->orco; vlr->v3->accum= vlr->v4->accum; CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); @@ -1047,23 +1053,23 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo vlr->mat= ma; vlr->ec= ME_V2V3; - if(surfnor) { + if(sd->surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - VECCOPY(snor, surfnor); + VECCOPY(snor, sd->surfnor); } - if(uvco){ - for(i=0; i<totuv; i++){ + if(sd->uvco){ + for(i=0; i<sd->totuv; i++){ MTFace *mtf; mtf=RE_vlakren_get_tface(obr,vlr,i,NULL,1); mtf->uv[0][0]=mtf->uv[1][0]= - mtf->uv[2][0]=mtf->uv[3][0]=(uvco+2*i)[0]; + mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0]; mtf->uv[0][1]=mtf->uv[1][1]= - mtf->uv[2][1]=mtf->uv[3][1]=(uvco+2*i)[1]; + mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1]; } - if(override_uv>=0){ + if(sd->override_uv>=0){ MTFace *mtf; - mtf=RE_vlakren_get_tface(obr,vlr,override_uv,NULL,0); + mtf=RE_vlakren_get_tface(obr,vlr,sd->override_uv,NULL,0); mtf->uv[0][0]=mtf->uv[3][0]=0.0f; mtf->uv[1][0]=mtf->uv[2][0]=1.0f; @@ -1072,18 +1078,18 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo mtf->uv[2][1]=mtf->uv[3][1]=1.0f; } } - if(mcol){ - for(i=0; i<totcol; i++){ + if(sd->mcol){ + for(i=0; i<sd->totcol; i++){ MCol *mc; mc=RE_vlakren_get_mcol(obr,vlr,i,NULL,1); - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; } } } /* first two vertices of a strand */ - else if(first) { - if(adapt){ + else if(sd->first) { + if(sd->adapt){ VECCOPY(anor, nor); VECCOPY(avec, vec); second=1; @@ -1095,18 +1101,18 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo VECCOPY(v1->co, vec); VecAddf(v1->co, v1->co, cross); VECCOPY(v1->n, nor); - v1->orco= orco; + v1->orco= sd->orco; v1->accum= -1.0f; // accum abuse for strand texco VECCOPY(v2->co, vec); VecSubf(v2->co, v2->co, cross); VECCOPY(v2->n, nor); - v2->orco= orco; + v2->orco= sd->orco; v2->accum= v1->accum; } /* more vertices & faces to strand */ else { - if(adapt==0 || second){ + if(sd->adapt==0 || second){ vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->flag= flag; vlr->v1= v1; @@ -1118,14 +1124,14 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo v2= vlr->v3; // cycle - if(adapt){ + if(sd->adapt){ second=0; VECCOPY(anor,nor); VECCOPY(avec,vec); } } - else if(adapt){ + else if(sd->adapt){ float dvec[3],pvec[3]; VecSubf(dvec,avec,vec); Projf(pvec,dvec,vec); @@ -1135,7 +1141,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo dx= re->winx*dvec[0]*re->winmat[0][0]/w; dy= re->winy*dvec[1]*re->winmat[1][1]/w; w= sqrt(dx*dx + dy*dy); - if(Inpf(anor,nor)<adapt_angle && w>adapt_pix){ + if(Inpf(anor,nor)<sd->adapt_angle && w>sd->adapt_pix){ vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->flag= flag; vlr->v1= v1; @@ -1157,13 +1163,13 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo VECCOPY(vlr->v4->co, vec); VecAddf(vlr->v4->co, vlr->v4->co, cross); VECCOPY(vlr->v4->n, nor); - vlr->v4->orco= orco; - vlr->v4->accum= -1.0f + 2.0f*ctime; // accum abuse for strand texco + vlr->v4->orco= sd->orco; + vlr->v4->accum= -1.0f + 2.0f*sd->time; // accum abuse for strand texco VECCOPY(vlr->v3->co, vec); VecSubf(vlr->v3->co, vlr->v3->co, cross); VECCOPY(vlr->v3->n, nor); - vlr->v3->orco= orco; + vlr->v3->orco= sd->orco; vlr->v3->accum= vlr->v4->accum; CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); @@ -1171,23 +1177,23 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo vlr->mat= ma; vlr->ec= ME_V2V3; - if(surfnor) { + if(sd->surfnor) { float *snor= RE_vlakren_get_surfnor(obr, vlr, 1); - VECCOPY(snor, surfnor); + VECCOPY(snor, sd->surfnor); } - if(uvco){ - for(i=0; i<totuv; i++){ + if(sd->uvco){ + for(i=0; i<sd->totuv; i++){ MTFace *mtf; mtf=RE_vlakren_get_tface(obr,vlr,i,NULL,1); mtf->uv[0][0]=mtf->uv[1][0]= - mtf->uv[2][0]=mtf->uv[3][0]=(uvco+2*i)[0]; + mtf->uv[2][0]=mtf->uv[3][0]=(sd->uvco+2*i)[0]; mtf->uv[0][1]=mtf->uv[1][1]= - mtf->uv[2][1]=mtf->uv[3][1]=(uvco+2*i)[1]; + mtf->uv[2][1]=mtf->uv[3][1]=(sd->uvco+2*i)[1]; } - if(override_uv>=0){ + if(sd->override_uv>=0){ MTFace *mtf; - mtf=RE_vlakren_get_tface(obr,vlr,override_uv,NULL,0); + mtf=RE_vlakren_get_tface(obr,vlr,sd->override_uv,NULL,0); mtf->uv[0][0]=mtf->uv[3][0]=0.0f; mtf->uv[1][0]=mtf->uv[2][0]=1.0f; @@ -1196,12 +1202,12 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, flo mtf->uv[2][1]=mtf->uv[3][1]=(vlr->v3->accum+1.0f)/2.0f; } } - if(mcol){ - for(i=0; i<totcol; i++){ + if(sd->mcol){ + for(i=0; i<sd->totcol; i++){ MCol *mc; mc=RE_vlakren_get_mcol(obr,vlr,i,NULL,1); - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; - mc[0]=mc[1]=mc[2]=mc[3]=mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; + mc[0]=mc[1]=mc[2]=mc[3]=sd->mcol[i]; } } } @@ -1254,17 +1260,13 @@ static void static_particle_wire(ObjectRen *obr, Material *ma, float *vec, float } } -static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object *bb_ob, float *vec, float *vel, float size, float tilt, short align, - int lock, int p, int totpart, short uv_split, short anim, short split_offset, float random, float pa_time, float offset[2], int uv[3]) + +static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, ParticleBillboardData *bb) { VlakRen *vlr; MTFace *mtf; - float xvec[3]={1.0f,0.0f,0.0f}, yvec[3]={0.0f,1.0f,0.0f}, zvec[3]; - float onevec[3]={0.0f,0.0f,0.0f}, tvec[3],tvec2[3], bb_center[3]; - float uvx=0.0f, uvy=0.0f, uvdx=1.0f, uvdy=1.0f, time=0.0f; - - if(align<PART_BB_VIEW) - onevec[align]=1.0f; + float xvec[3], yvec[3], zvec[3], bb_center[3]; + float uvx = 0.0f, uvy = 0.0f, uvdx = 1.0f, uvdy = 1.0f, time = 0.0f; vlr= RE_findOrAddVlak(obr, obr->totvlak++); vlr->v1= RE_findOrAddVert(obr, obr->totvert++); @@ -1272,74 +1274,23 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object vlr->v3= RE_findOrAddVert(obr, obr->totvert++); vlr->v4= RE_findOrAddVert(obr, obr->totvert++); - if(lock && align==PART_BB_VIEW){ - VECCOPY(xvec,bb_ob->obmat[0]); - Normalize(xvec); - VECCOPY(yvec,bb_ob->obmat[1]); - Normalize(yvec); - VECCOPY(zvec,bb_ob->obmat[2]); - Normalize(zvec); - } - else if(align==PART_BB_VEL){ - float temp[3]; - VECCOPY(temp,vel); - Normalize(temp); - VECSUB(zvec,bb_ob->obmat[3],vec); - if(lock){ - float fac=-Inpf(zvec,temp); - VECADDFAC(zvec,zvec,temp,fac); - } - Normalize(zvec); - Crossf(xvec,temp,zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - else{ - VECSUB(zvec,bb_ob->obmat[3],vec); - if(lock) - zvec[align]=0.0f; - Normalize(zvec); - - if(align<PART_BB_VIEW) - Crossf(xvec,onevec,zvec); - else - Crossf(xvec,bb_ob->obmat[1],zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - - VECCOPY(tvec,xvec); - VECCOPY(tvec2,yvec); - - VecMulf(xvec,cos(tilt*(float)M_PI)); - VecMulf(tvec2,sin(tilt*(float)M_PI)); - VECADD(xvec,xvec,tvec2); - - VecMulf(yvec,cos(tilt*(float)M_PI)); - VecMulf(tvec,-sin(tilt*(float)M_PI)); - VECADD(yvec,yvec,tvec); - - VecMulf(xvec,size); - VecMulf(yvec,size); + psys_make_billboard(bb, xvec, yvec, zvec, bb_center); - VECADDFAC(bb_center,vec,xvec,offset[0]); - VECADDFAC(bb_center,bb_center,yvec,offset[1]); + VECADD(vlr->v1->co, bb_center, xvec); + VECADD(vlr->v1->co, vlr->v1->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v1->co); - VECADD(vlr->v1->co,bb_center,xvec); - VECADD(vlr->v1->co,vlr->v1->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v1->co); + VECSUB(vlr->v2->co, bb_center, xvec); + VECADD(vlr->v2->co, vlr->v2->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v2->co); - VECSUB(vlr->v2->co,bb_center,xvec); - VECADD(vlr->v2->co,vlr->v2->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v2->co); + VECSUB(vlr->v3->co, bb_center, xvec); + VECSUB(vlr->v3->co, vlr->v3->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v3->co); - VECSUB(vlr->v3->co,bb_center,xvec); - VECSUB(vlr->v3->co,vlr->v3->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v3->co); - - VECADD(vlr->v4->co,bb_center,xvec); - VECSUB(vlr->v4->co,vlr->v4->co,yvec); - MTC_Mat4MulVecfl(re->viewmat,vlr->v4->co); + VECADD(vlr->v4->co, bb_center, xvec); + VECSUB(vlr->v4->co, vlr->v4->co, yvec); + MTC_Mat4MulVecfl(re->viewmat, vlr->v4->co); CalcNormFloat4(vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co, vlr->n); VECCOPY(vlr->v1->n,vlr->n); @@ -1350,113 +1301,141 @@ static void particle_billboard(Render *re, ObjectRen *obr, Material *ma, Object vlr->mat= ma; vlr->ec= ME_V2V3; - if(uv_split>1){ - uvdx=uvdy=1.0f/(float)uv_split; - if(anim==PART_BB_ANIM_TIME){ - if(split_offset==PART_BB_OFF_NONE) - time=pa_time; - else if(split_offset==PART_BB_OFF_LINEAR) - time=(float)fmod(pa_time+(float)p/(float)(uv_split*uv_split),1.0f); + if(bb->uv_split > 1){ + uvdx = uvdy = 1.0f / (float)bb->uv_split; + if(bb->anim == PART_BB_ANIM_TIME) { + if(bb->split_offset == PART_BB_OFF_NONE) + time = bb->time; + else if(bb->split_offset == PART_BB_OFF_LINEAR) + time = (float)fmod(bb->time + (float)bb->num / (float)(bb->uv_split * bb->uv_split), 1.0f); else /* split_offset==PART_BB_OFF_RANDOM */ - time=(float)fmod(pa_time+random,1.0f); + time = (float)fmod(bb->time + bb->random, 1.0f); } - else if(anim==PART_BB_ANIM_ANGLE){ - if(align==PART_BB_VIEW){ - time=(float)fmod((tilt+1.0f)/2.0f,1.0); + else if(bb->anim == PART_BB_ANIM_ANGLE) { + if(bb->align == PART_BB_VIEW) { + time = (float)fmod((bb->tilt + 1.0f) / 2.0f, 1.0); } else{ - float axis1[3]={0.0f,0.0f,0.0f}; - float axis2[3]={0.0f,0.0f,0.0f}; - axis1[(align+1)%3]=1.0f; - axis2[(align+2)%3]=1.0f; - if(lock==0){ - zvec[align]=0.0f; + float axis1[3] = {0.0f,0.0f,0.0f}; + float axis2[3] = {0.0f,0.0f,0.0f}; + axis1[(bb->align + 1) % 3] = 1.0f; + axis2[(bb->align + 2) % 3] = 1.0f; + if(bb->lock == 0) { + zvec[bb->align] = 0.0f; Normalize(zvec); } - time=saacos(Inpf(zvec,axis1))/(float)M_PI; - if(Inpf(zvec,axis2)<0.0f) - time=1.0f-time/2.0f; + time = saacos(Inpf(zvec, axis1)) / (float)M_PI; + if(Inpf(zvec, axis2) < 0.0f) + time = 1.0f - time / 2.0f; else - time=time/2.0f; + time = time / 2.0f; } - if(split_offset==PART_BB_OFF_LINEAR) - time=(float)fmod(pa_time+(float)p/(float)(uv_split*uv_split),1.0f); - else if(split_offset==PART_BB_OFF_RANDOM) - time=(float)fmod(pa_time+random,1.0f); + if(bb->split_offset == PART_BB_OFF_LINEAR) + time = (float)fmod(bb->time + (float)bb->num / (float)(bb->uv_split * bb->uv_split), 1.0f); + else if(bb->split_offset == PART_BB_OFF_RANDOM) + time = (float)fmod(bb->time + bb->random, 1.0f); } else{ - if(split_offset==PART_BB_OFF_NONE) - time=0.0f; - else if(split_offset==PART_BB_OFF_LINEAR) - time=(float)fmod((float)p/(float)(uv_split*uv_split),1.0f); + if(bb->split_offset == PART_BB_OFF_NONE) + time = 0.0f; + else if(bb->split_offset == PART_BB_OFF_LINEAR) + time = (float)fmod((float)bb->num /(float)(bb->uv_split * bb->uv_split) , 1.0f); else /* split_offset==PART_BB_OFF_RANDOM */ - time=random; + time = bb->random; } - uvx=uvdx*floor((float)(uv_split*uv_split)*(float)fmod((double)time,(double)uvdx)); - uvy=uvdy*floor((1.0f-time)*(float)uv_split); - if(fmod(time,1.0f/uv_split)==0.0f) - uvy-=uvdy; + uvx = uvdx * floor((float)(bb->uv_split * bb->uv_split) * (float)fmod((double)time, (double)uvdx)); + uvy = uvdy * floor((1.0f - time) * (float)bb->uv_split); + if(fmod(time, 1.0f / bb->uv_split) == 0.0f) + uvy -= uvdy; } /* normal UVs */ - if(uv[0]>=0){ - mtf=RE_vlakren_get_tface(obr,vlr,uv[0],NULL,1); - mtf->uv[0][0]=1.0f; - mtf->uv[0][1]=1.0f; - mtf->uv[1][0]=0.0f; - mtf->uv[1][1]=1.0f; - mtf->uv[2][0]=0.0f; - mtf->uv[2][1]=0.0f; - mtf->uv[3][0]=1.0f; - mtf->uv[3][1]=0.0f; + if(bb->uv[0] >= 0){ + mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[0], NULL, 1); + mtf->uv[0][0] = 1.0f; + mtf->uv[0][1] = 1.0f; + mtf->uv[1][0] = 0.0f; + mtf->uv[1][1] = 1.0f; + mtf->uv[2][0] = 0.0f; + mtf->uv[2][1] = 0.0f; + mtf->uv[3][0] = 1.0f; + mtf->uv[3][1] = 0.0f; } /* time-index UVs */ - if(uv[1]>=0){ - mtf=RE_vlakren_get_tface(obr,vlr,uv[1],NULL,1); - mtf->uv[0][0]=mtf->uv[1][0]=mtf->uv[2][0]=mtf->uv[3][0]=pa_time; - mtf->uv[0][1]=mtf->uv[1][1]=mtf->uv[2][1]=mtf->uv[3][1]=(float)p/(float)totpart; + if(bb->uv[1] >= 0){ + mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[1], NULL, 1); + mtf->uv[0][0] = mtf->uv[1][0] = mtf->uv[2][0] = mtf->uv[3][0] = bb->time; + mtf->uv[0][1] = mtf->uv[1][1] = mtf->uv[2][1] = mtf->uv[3][1] = (float)bb->num/(float)bb->totnum; } /* split UVs */ - if(uv_split>1 && uv[2]>=0){ - mtf=RE_vlakren_get_tface(obr,vlr,uv[2],NULL,1); - mtf->uv[0][0]=uvx+uvdx; - mtf->uv[0][1]=uvy+uvdy; - mtf->uv[1][0]=uvx; - mtf->uv[1][1]=uvy+uvdy; - mtf->uv[2][0]=uvx; - mtf->uv[2][1]=uvy; - mtf->uv[3][0]=uvx+uvdx; - mtf->uv[3][1]=uvy; + if(bb->uv_split > 1 && bb->uv[2] >= 0){ + mtf = RE_vlakren_get_tface(obr, vlr, bb->uv[2], NULL, 1); + mtf->uv[0][0] = uvx + uvdx; + mtf->uv[0][1] = uvy + uvdy; + mtf->uv[1][0] = uvx; + mtf->uv[1][1] = uvy + uvdy; + mtf->uv[2][0] = uvx; + mtf->uv[2][1] = uvy; + mtf->uv[3][0] = uvx + uvdx; + mtf->uv[3][1] = uvy; } } -static void render_new_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, int path, int first, int line, - float time, float *loc, float *loc1, float *orco, float *surfnor, int totuv, float *uvco, - int totcol, MCol *mcol, float size, int seed, int override_uv, - int adapt, float adapt_angle, float adapt_pix) +static void render_new_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Material *ma, ParticleStrandData *sd, float *loc, float *loc1, int seed) { HaloRen *har=0; - if(path){ - if(ma->mode&MA_WIRE) - static_particle_wire(obr, ma, loc, loc1, first, line); - else if(ma->mode & MA_HALO){ - har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, orco, uvco, size, 1.0, seed); - if(har) har->lay= obr->ob->lay; + + if(ma->mode&MA_WIRE) + static_particle_wire(obr, ma, loc, loc1, sd->first, sd->line); + else if(ma->mode & MA_HALO){ + har= RE_inithalo_particle(re, obr, dm, ma, loc, loc1, sd->orco, sd->uvco, sd->size, 1.0, seed); + if(har) har->lay= obr->ob->lay; + } + else + static_particle_strand(re, obr, ma, sd, loc, loc1); +} +static void get_particle_uvco_mcol(short from, DerivedMesh *dm, float *fuv, int num, ParticleStrandData *sd) +{ + int i; + + /* get uvco */ + if(sd->uvco && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) { + for(i=0; i<sd->totuv; i++) { + if(num != DMCACHE_NOTFOUND) { + MFace *mface = dm->getFaceData(dm, num, CD_MFACE); + MTFace *mtface = (MTFace*)CustomData_get_layer_n(&dm->faceData, CD_MTFACE, i); + mtface += num; + + psys_interpolate_uvs(mtface, mface->v4, fuv, sd->uvco + 2 * i); + } + else { + sd->uvco[2*i] = 0.0f; + sd->uvco[2*i + 1] = 0.0f; + } } - else - static_particle_strand(re, obr, ma, orco, surfnor, uvco, totuv, mcol, totcol, loc, loc1, time, first, line, adapt, adapt_angle, adapt_pix, override_uv); } - else{ - har= RE_inithalo_particle(re, obr, dm, ma, loc, NULL, orco, uvco, size, 0.0, seed); - if(har) har->lay= obr->ob->lay; + + /* get mcol */ + if(sd->mcol && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) { + for(i=0; i<sd->totcol; i++) { + if(num != DMCACHE_NOTFOUND) { + MFace *mface = dm->getFaceData(dm, num, CD_MFACE); + MCol *mc = (MCol*)CustomData_get_layer_n(&dm->faceData, CD_MCOL, i); + mc += num * 4; + + psys_interpolate_mcol(mc, mface->v4, fuv, sd->mcol + i); + } + else + memset(&sd->mcol[i], 0, sizeof(MCol)); + } } } static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *psys, int timeoffset) { Object *ob= obr->ob; - Object *tob=0, *bb_ob=re->scene->camera; + Object *tob=0; Material *ma=0; MTFace *mtface; ParticleSystemModifierData *psmd; @@ -1466,19 +1445,20 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem ParticleKey *states=0; ParticleKey state; ParticleCacheKey *cache=0; + ParticleBillboardData bb; + ParticleStrandData sd; StrandBuffer *strandbuf=0; StrandVert *svert=0; StrandBound *sbound= 0; StrandRen *strand=0; RNG *rng= 0; - MCol *mcol= 0; float loc[3],loc1[3],loc0[3],vel[3],mat[4][4],nmat[3][3],co[3],nor[3],time; - float *orco=0,*surfnor=0,*uvco=0, strandlen=0.0f, curlen=0.0f; + float strandlen=0.0f, curlen=0.0f; float hasize, pa_size, pa_time, r_tilt, cfra=bsystem_time(ob,(float)CFRA,0.0); - float adapt_angle=0.0, adapt_pix=0.0, random, simplify[2]; - int i, a, k, max_k=0, totpart, totuv=0, totcol=0, override_uv=-1, dosimplify = 0, dosurfacecache = 0; - int path_possible=0, keys_possible=0, baked_keys=0, totchild=0; - int seed, path_nbr=0, path=0, orco1=0, adapt=0, uv[3]={0,0,0}, num; + float random, simplify[2]; + int i, a, k, max_k=0, totpart, dosimplify = 0, dosurfacecache = 0; + int totchild=0; + int seed, path_nbr=0, orco1=0, num; int totface, *origindex = 0; char **uv_name=0; @@ -1505,6 +1485,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem return 1; } + /* last possibility to bail out! */ psmd= psys_get_modifier(ob,psys); if(!(psmd->modifier.mode & eModifierMode_Render)) return 0; @@ -1513,182 +1494,182 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem totchild = (int)((float)totchild * (float)part->disp / 100.0f); } - psys->flag|=PSYS_DRAWING; + psys->flag |= PSYS_DRAWING; rng= rng_new(psys->seed); - - ma= give_render_material(re, ob, part->omat); - if(part->bb_ob) - bb_ob=part->bb_ob; + totpart=psys->totpart; + + memset(&sd, 0, sizeof(ParticleStrandData)); + sd.override_uv = -1; + +/* 2.1 setup material stff */ + ma= give_render_material(re, ob, part->omat); if(ma->ipo){ calc_ipo(ma->ipo, cfra); execute_ipo((ID *)ma, ma->ipo); } + hasize = ma->hasize; + seed = ma->seed1; + + re->flag |= R_HALO; + RE_set_customdata_names(obr, &psmd->dm->faceData); - totuv=CustomData_number_of_layers(&psmd->dm->faceData,CD_MTFACE); - totcol=CustomData_number_of_layers(&psmd->dm->faceData,CD_MCOL); + sd.totuv = CustomData_number_of_layers(&psmd->dm->faceData, CD_MTFACE); + sd.totcol = CustomData_number_of_layers(&psmd->dm->faceData, CD_MCOL); - if(ma->texco & TEXCO_UV && totuv) { - uvco = MEM_callocN(totuv*2*sizeof(float),"particle_uvs"); + if(ma->texco & TEXCO_UV && sd.totuv) { + sd.uvco = MEM_callocN(sd.totuv * 2 * sizeof(float), "particle_uvs"); if(ma->strand_uvname[0]) { - override_uv= CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,ma->strand_uvname); - override_uv-= CustomData_get_layer_index(&psmd->dm->faceData,CD_MTFACE); + sd.override_uv = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, ma->strand_uvname); + sd.override_uv -= CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE); } } + else + sd.uvco = NULL; - if(totcol) - mcol = MEM_callocN(totcol*sizeof(MCol),"particle_mcols"); + if(sd.totcol) + sd.mcol = MEM_callocN(sd.totcol * sizeof(MCol), "particle_mcols"); - if(part->draw_as==PART_DRAW_BB){ - int first_uv=CustomData_get_layer_index(&psmd->dm->faceData,CD_MTFACE); +/* 2.2 setup billboards */ + if(part->draw_as == PART_DRAW_BB) { + int first_uv = CustomData_get_layer_index(&psmd->dm->faceData, CD_MTFACE); - uv[0]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[0]); - if(uv[0]<0) - uv[0]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE); + bb.uv[0] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[0]); + if(bb.uv[0] < 0) + bb.uv[0] = CustomData_get_active_layer_index(&psmd->dm->faceData, CD_MTFACE); - uv[1]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[1]); - //if(uv[1]<0) - // uv[1]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE); + bb.uv[1] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[1]); - uv[2]=CustomData_get_named_layer_index(&psmd->dm->faceData,CD_MTFACE,psys->bb_uvname[2]); - //if(uv[2]<0) - // uv[2]=CustomData_get_active_layer_index(&psmd->dm->faceData,CD_MTFACE); + bb.uv[2] = CustomData_get_named_layer_index(&psmd->dm->faceData, CD_MTFACE, psys->bb_uvname[2]); - if(first_uv>=0){ - uv[0]-=first_uv; - uv[1]-=first_uv; - uv[2]-=first_uv; + if(first_uv >= 0) { + bb.uv[0] -= first_uv; + bb.uv[1] -= first_uv; + bb.uv[2] -= first_uv; } + + bb.align = part->bb_align; + bb.anim = part->bb_anim; + bb.lock = part->draw & PART_DRAW_BB_LOCK; + bb.ob = (part->bb_ob ? part->bb_ob : re->scene->camera); + bb.offset[0] = part->bb_offset[0]; + bb.offset[1] = part->bb_offset[1]; + bb.split_offset = part->bb_split_offset; + bb.totnum = totpart+totchild; + bb.uv_split = part->bb_uv_split; } - if(part->flag&PART_ABS_TIME && part->ipo){ +/* 2.3 setup time */ + if(part->flag&PART_ABS_TIME && part->ipo) { calc_ipo(part->ipo, cfra); execute_ipo((ID *)part, part->ipo); } - if(part->flag&PART_GLOB_TIME) - cfra=bsystem_time(0,(float)CFRA,0.0); + if(part->flag & PART_GLOB_TIME) + cfra = bsystem_time(0, (float)CFRA, 0.0); - if(part->type==PART_REACTOR){ +/* 2.4 setup reactors */ + if(part->type == PART_REACTOR){ psys_get_reactor_target(ob, psys, &tob, &tpsys); if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ - psmd=psys_get_modifier(tob,tpsys); - tpart=tpsys->part; + psmd = psys_get_modifier(tob,tpsys); + tpart = tpsys->part; } } - - hasize = ma->hasize; - seed = ma->seed1; - - re->flag |= R_HALO; +/* 2.5 setup matrices */ MTC_Mat4MulMat4(mat, ob->obmat, re->viewmat); MTC_Mat4Invert(ob->imat, mat); /* need to be that way, for imat texture */ Mat3CpyMat4(nmat, ob->imat); Mat3Transp(nmat); - totpart=psys->totpart; +/* 2.6 setup strand rendering */ + if(part->draw_as == PART_DRAW_PATH && psys->pathcache){ + path_nbr=(int)pow(2.0,(double) part->ren_step); - if(psys->pathcache){ - path_possible=1; - keys_possible=1; - } - if(part->draw_as==PART_DRAW_PATH){ - if(path_possible){ - path_nbr=(int)pow(2.0,(double) part->ren_step); - //if(part->phystype==PART_PHYS_KEYED && (psys->flag&PSYS_BAKED)==0) - // path_nbr*=psys->totkeyed; - - if(path_nbr) { - if((ma->mode & (MA_HALO|MA_WIRE))==0) { - orco= MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); - set_object_orco(re, psys, orco); - } - path=1; + if(path_nbr) { + if((ma->mode & (MA_HALO|MA_WIRE))==0) { + sd.orco = MEM_mallocN(3*sizeof(float)*(totpart+totchild), "particle orcos"); + set_object_orco(re, psys, sd.orco); } + } - if(part->draw&PART_DRAW_REN_ADAPT) { - adapt=1; - adapt_pix=(float)part->adapt_pix; - adapt_angle=cos((float)part->adapt_angle*(float)(M_PI/180.0)); - } + if(part->draw & PART_DRAW_REN_ADAPT) { + sd.adapt = 1; + sd.adapt_pix = (float)part->adapt_pix; + sd.adapt_angle = cos((float)part->adapt_angle * (float)(M_PI / 180.0)); + } - if(re->r.renderer==R_INTERN && part->draw&PART_DRAW_REN_STRAND) { - strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1)); - strandbuf->ma= ma; - strandbuf->lay= ob->lay; - Mat4CpyMat4(strandbuf->winmat, re->winmat); - strandbuf->winx= re->winx; - strandbuf->winy= re->winy; - strandbuf->maxdepth= 2; - strandbuf->adaptcos= cos((float)part->adapt_angle*(float)(M_PI/180.0)); - strandbuf->overrideuv= override_uv; - strandbuf->minwidth= ma->strand_min; - - if(ma->strand_widthfade == 0.0f) - strandbuf->widthfade= 0.0f; - else if(ma->strand_widthfade >= 1.0f) - strandbuf->widthfade= 2.0f - ma->strand_widthfade; - else - strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f); + if(re->r.renderer==R_INTERN && part->draw&PART_DRAW_REN_STRAND) { + strandbuf= RE_addStrandBuffer(obr, (totpart+totchild)*(path_nbr+1)); + strandbuf->ma= ma; + strandbuf->lay= ob->lay; + Mat4CpyMat4(strandbuf->winmat, re->winmat); + strandbuf->winx= re->winx; + strandbuf->winy= re->winy; + strandbuf->maxdepth= 2; + strandbuf->adaptcos= cos((float)part->adapt_angle*(float)(M_PI/180.0)); + strandbuf->overrideuv= sd.override_uv; + strandbuf->minwidth= ma->strand_min; + + if(ma->strand_widthfade == 0.0f) + strandbuf->widthfade= 0.0f; + else if(ma->strand_widthfade >= 1.0f) + strandbuf->widthfade= 2.0f - ma->strand_widthfade; + else + strandbuf->widthfade= 1.0f/MAX2(ma->strand_widthfade, 1e-5f); - if(part->flag & PART_HAIR_BSPLINE) - strandbuf->flag |= R_STRAND_BSPLINE; - if(ma->mode & MA_STR_B_UNITS) - strandbuf->flag |= R_STRAND_B_UNITS; + if(part->flag & PART_HAIR_BSPLINE) + strandbuf->flag |= R_STRAND_BSPLINE; + if(ma->mode & MA_STR_B_UNITS) + strandbuf->flag |= R_STRAND_B_UNITS; - svert= strandbuf->vert; + svert= strandbuf->vert; - if(re->r.mode & R_SPEED) + if(re->r.mode & R_SPEED) + dosurfacecache= 1; + else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)) + if(ma->amb != 0.0f) dosurfacecache= 1; - else if((re->wrld.mode & WO_AMB_OCC) && (re->wrld.ao_gather_method == WO_AOGATHER_APPROX)) - if(ma->amb != 0.0f) - dosurfacecache= 1; - - totface= psmd->dm->getNumFaces(psmd->dm); - origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX); - if(origindex) { - for(a=0; a<totface; a++) - strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]); - strandbuf->totbound++; - } + + totface= psmd->dm->getNumFaces(psmd->dm); + origindex= psmd->dm->getFaceDataArray(psmd->dm, CD_ORIGINDEX); + if(origindex) { + for(a=0; a<totface; a++) + strandbuf->totbound= MAX2(strandbuf->totbound, origindex[a]); strandbuf->totbound++; - strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound"); - sbound= strandbuf->bound; - sbound->start= sbound->end= 0; } + strandbuf->totbound++; + strandbuf->bound= MEM_callocN(sizeof(StrandBound)*strandbuf->totbound, "StrandBound"); + sbound= strandbuf->bound; + sbound->start= sbound->end= 0; } } - else if(keys_possible && part->draw&PART_DRAW_KEYS){ - path_nbr=part->keys_step; - if(path_nbr==0) - baked_keys=1; - } - if(orco==0){ - orco=MEM_mallocN(3*sizeof(float),"particle orco"); - orco1=1; + if(sd.orco == 0) { + sd.orco = MEM_mallocN(3 * sizeof(float), "particle orco"); + orco1 = 1; } - if(path_nbr==0) - psys->lattice=psys_get_lattice(ob,psys); + if(path_nbr == 0) + psys->lattice = psys_get_lattice(ob, psys); /* 3. start creating renderable things */ for(a=0,pa=pars; a<totpart+totchild; a++, pa++, seed++) { random = rng_getFloat(rng); - + /* setup per particle individual stuff */ if(a<totpart){ if(pa->flag & PARS_UNEXIST) continue; pa_time=(cfra-pa->time)/pa->lifetime; - if((part->flag&PART_ABS_TIME)==0){ - if(ma->ipo){ + if((part->flag&PART_ABS_TIME) == 0) { + if(ma->ipo) { /* correction for lifetime */ - calc_ipo(ma->ipo, 100.0f*pa_time); + calc_ipo(ma->ipo, 100.0f * pa_time); execute_ipo((ID *)ma, ma->ipo); } if(part->ipo){ @@ -1703,51 +1684,25 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* get orco */ if(tpsys && (part->from==PART_FROM_PARTICLE || part->phystype==PART_PHYS_NO)){ tpa=tpsys->particles+pa->num; - psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,orco,0); + psys_particle_on_emitter(psmd,tpart->from,tpa->num,pa->num_dmcache,tpa->fuv,tpa->foffset,co,nor,0,0,sd.orco,0); } else - psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,0); + psys_particle_on_emitter(psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,sd.orco,0); + /* get uvco & mcol */ num= pa->num_dmcache; if(num == DMCACHE_NOTFOUND) if(pa->num < psmd->dm->getNumFaces(psmd->dm)) num= pa->num; - if(uvco && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - for(i=0; i<totuv; i++){ - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i); - mtface+=num; - - psys_interpolate_uvs(mtface,mface->v4,pa->fuv,uvco+2*i); - } - else { - uvco[2*i]= 0.0f; - uvco[2*i + 1]= 0.0f; - } - } - } - if(mcol && ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - for(i=0; i<totcol; i++){ - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i); - mc+=num*4; - - psys_interpolate_mcol(mc,mface->v4,pa->fuv,mcol+i); - } - else - memset(&mcol[i], 0, sizeof(MCol)); - } - } + get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd); - pa_size=pa->size; + pa_size = pa->size; - r_tilt=1.0f+pa->r_ave[0]; + r_tilt = 1.0f + pa->r_ave[0]; - if(path_nbr){ + if(path_nbr) { cache = psys->pathcache[a]; max_k = (int)cache->steps; } @@ -1756,123 +1711,67 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem } else { ChildParticle *cpa= psys->child+a-totpart; + + if(path_nbr) { + cache = psys->childcache[a-totpart]; + + if(cache->steps < 0) + continue; + + max_k = (int)cache->steps; + } - pa_time=psys_get_child_time(psys, cpa, cfra); + pa_time = psys_get_child_time(psys, cpa, cfra); - if((part->flag&PART_ABS_TIME)==0){ - if(ma->ipo){ + if((part->flag & PART_ABS_TIME) == 0) { + if(ma->ipo) { /* correction for lifetime */ - calc_ipo(ma->ipo, 100.0f*pa_time); + calc_ipo(ma->ipo, 100.0f * pa_time); execute_ipo((ID *)ma, ma->ipo); } - if(part->ipo){ + if(part->ipo) { /* correction for lifetime */ - calc_ipo(part->ipo, 100.0f*pa_time); + calc_ipo(part->ipo, 100.0f * pa_time); execute_ipo((ID *)part, part->ipo); } } - pa_size=psys_get_child_size(psys, cpa, cfra, &pa_time); + pa_size = psys_get_child_size(psys, cpa, cfra, &pa_time); - r_tilt=2.0f*cpa->rand[2]; + r_tilt = 2.0f * cpa->rand[2]; - num= cpa->num; + num = cpa->num; /* get orco */ if(part->childtype == PART_CHILD_FACES) { psys_particle_on_emitter(psmd, PART_FROM_FACE, cpa->num,DMCACHE_ISCHILD, - cpa->fuv,cpa->foffset,co,nor,0,0,orco,0); + cpa->fuv,cpa->foffset,co,nor,0,0,sd.orco,0); } else { ParticleData *par = psys->particles + cpa->parent; psys_particle_on_emitter(psmd, part->from, par->num,DMCACHE_ISCHILD,par->fuv, - par->foffset,co,nor,0,0,orco,0); + par->foffset,co,nor,0,0,sd.orco,0); } - if(uvco){ - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ - for(i=0; i<totuv; i++){ - if(part->childtype==PART_CHILD_FACES){ - MFace *mface=psmd->dm->getFaceData(psmd->dm,cpa->num,CD_MFACE); - - mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i); - mtface+=cpa->num; - - psys_interpolate_uvs(mtface,mface->v4,cpa->fuv,uvco+2*i); - } - else{ - uvco[2*i]=uvco[2*i+1]=0.0f; - } - } - } - else if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - ParticleData *parent = psys->particles + cpa->parent; - num= parent->num_dmcache; - - if(num == DMCACHE_NOTFOUND) - if(parent->num < psmd->dm->getNumFaces(psmd->dm)) - num= parent->num; - - for(i=0; i<totuv; i++) { - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - mtface=(MTFace*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MTFACE,i); - mtface+=num; - psys_interpolate_uvs(mtface,mface->v4,parent->fuv,uvco+2*i); - } - else { - uvco[2*i]= 0.0f; - uvco[2*i + 1]= 0.0f; - } - } - } - } - - if(mcol){ - if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){ - for(i=0; i<totcol; i++){ - if(part->childtype==PART_CHILD_FACES){ - MFace *mface=psmd->dm->getFaceData(psmd->dm,cpa->num,CD_MFACE); - MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i); - mc+=cpa->num*4; - - psys_interpolate_mcol(mc,mface->v4,cpa->fuv,mcol+i); - } - else - memset(&mcol[i], 0, sizeof(MCol)); - } - } - else if(ELEM(part->from,PART_FROM_FACE,PART_FROM_VOLUME)){ - ParticleData *parent = psys->particles + cpa->parent; - num= parent->num_dmcache; - - if(num == DMCACHE_NOTFOUND) - if(parent->num < psmd->dm->getNumFaces(psmd->dm)) - num= parent->num; - - for(i=0; i<totcol; i++){ - if(num != DMCACHE_NOTFOUND) { - MFace *mface=psmd->dm->getFaceData(psmd->dm,num,CD_MFACE); - MCol *mc=(MCol*)CustomData_get_layer_n(&psmd->dm->faceData,CD_MCOL,i); - mc+=num*4; - - psys_interpolate_mcol(mc,mface->v4,parent->fuv,mcol+i); - } - else - memset(&mcol[i], 0, sizeof(MCol)); - } - } + /* get uvco & mcol */ + if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES) { + get_particle_uvco_mcol(PART_FROM_FACE, psmd->dm, cpa->fuv, cpa->num, &sd); } + else { + ParticleData *parent = psys->particles + cpa->parent; + num = parent->num_dmcache; - dosimplify= psys_render_simplify_params(psys, cpa, simplify); + if(num == DMCACHE_NOTFOUND) + if(parent->num < psmd->dm->getNumFaces(psmd->dm)) + num = parent->num; - if(path_nbr && psys->childcache) { - cache = psys->childcache[a-totpart]; - max_k = (int)cache->steps; + get_particle_uvco_mcol(part->from, psmd->dm, pa->fuv, num, &sd); } + dosimplify = psys_render_simplify_params(psys, cpa, simplify); + if(strandbuf) { if(origindex[cpa->num]+1 > sbound - strandbuf->bound) { sbound= strandbuf->bound + origindex[cpa->num]+1; @@ -1884,17 +1783,17 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem /* surface normal shading setup */ if(ma->mode_l & MA_STR_SURFDIFF) { Mat3MulVecfl(nmat, nor); - surfnor= nor; + sd.surfnor= nor; } else - surfnor= NULL; + sd.surfnor= NULL; /* strand render setup */ if(strandbuf) { strand= RE_findOrAddStrand(obr, obr->totstrand++); strand->buffer= strandbuf; strand->vert= svert; - VECCOPY(strand->orco, orco); + VECCOPY(strand->orco, sd.orco); if(dosimplify) { float *ssimplify= RE_strandren_get_simplify(obr, strand, 1); @@ -1902,9 +1801,9 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem ssimplify[1]= simplify[1]; } - if(surfnor) { + if(sd.surfnor) { float *snor= RE_strandren_get_surfnor(obr, strand, 1); - VECCOPY(snor, surfnor); + VECCOPY(snor, sd.surfnor); } if(dosurfacecache && num >= 0) { @@ -1912,20 +1811,20 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem *facenum= num; } - if(uvco) { - for(i=0; i<totuv; i++) { - if(i != override_uv) { + if(sd.uvco) { + for(i=0; i<sd.totuv; i++) { + if(i != sd.override_uv) { float *uv= RE_strandren_get_uv(obr, strand, i, NULL, 1); - uv[0]= uvco[2*i]; - uv[1]= uvco[2*i+1]; + uv[0]= sd.uvco[2*i]; + uv[1]= sd.uvco[2*i+1]; } } } - if(mcol) { - for(i=0; i<totcol; i++) { + if(sd.mcol) { + for(i=0; i<sd.totcol; i++) { MCol *mc= RE_strandren_get_mcol(obr, strand, i, NULL, 1); - *mc = mcol[i]; + *mc = sd.mcol[i]; } } @@ -1941,11 +1840,10 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem strandlen += VecLenf((cache+k-1)->co, (cache+k)->co); } - for(k=0; k<=path_nbr; k++){ - if(path_nbr){ + if(path_nbr) { + /* render strands */ + for(k=0; k<=path_nbr; k++){ if(k<=max_k){ - //bti->convert_bake_key(bsys,cache+k,0,(void*)&state); - //copy_particle_key(&state,cache+k,0); VECCOPY(state.co,(cache+k)->co); VECCOPY(state.vel,(cache+k)->vel); } @@ -1955,65 +1853,95 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(k > 0) curlen += VecLenf((cache+k-1)->co, (cache+k)->co); time= curlen/strandlen; - } - else{ - time=0.0f; - state.time=cfra; - if(psys_get_particle_state(ob,psys,a,&state,0)==0) - continue; + + VECCOPY(loc,state.co); + MTC_Mat4MulVecfl(re->viewmat,loc); + + if(strandbuf) { + VECCOPY(svert->co, loc); + svert->strandco= -1.0f + 2.0f*time; + svert++; + strand->totvert++; + } + else{ + sd.first = 0; + sd.time = time; + sd.size = hasize; + + if(k==1){ + sd.first = 1; + sd.time = 0.0f; + VECSUB(loc0,loc1,loc); + VECADD(loc0,loc1,loc0); + } + + if(k) + render_new_particle(re, obr, psmd->dm, ma, &sd, loc, loc1, seed); + + VECCOPY(loc1,loc); + } } + } + else { + /* render normal particles */ + time=0.0f; + state.time=cfra; + if(psys_get_particle_state(ob,psys,a,&state,0)==0) + continue; + VECCOPY(loc,state.co); if(part->draw_as!=PART_DRAW_BB) MTC_Mat4MulVecfl(re->viewmat,loc); - if(part->draw_as==PART_DRAW_LINE) { - VECCOPY(vel,state.vel); - //VECADD(vel,vel,state.co); - MTC_Mat4Mul3Vecfl(re->viewmat,vel); - //VECSUB(vel,vel,loc); - Normalize(vel); - if(part->draw & PART_DRAW_VEL_LENGTH) - VecMulf(vel,VecLength(state.vel)); - VECADDFAC(loc0,loc,vel,-part->draw_line[0]); - VECADDFAC(loc1,loc,vel,part->draw_line[1]); - - render_new_particle(re,obr,psmd->dm,ma,1,0,1,0.0f,loc0,loc1, - orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv,0,0,0); - } - else if(part->draw_as==PART_DRAW_BB) { - VECCOPY(vel,state.vel); - //MTC_Mat4Mul3Vecfl(re->viewmat,vel); - particle_billboard(re,obr,ma,bb_ob,loc,vel,pa_size,part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt), - part->bb_align,part->draw&PART_DRAW_BB_LOCK, - a,totpart+totchild,part->bb_uv_split,part->bb_anim,part->bb_split_offset,random,pa_time,part->bb_offset,uv); - } - else if(strandbuf) { if(svert) { - VECCOPY(svert->co, loc); - svert->strandco= -1.0f + 2.0f*time; - svert++; - strand->totvert++; - } } - else{ - if(k==1){ - VECSUB(loc0,loc1,loc); - VECADD(loc0,loc1,loc0); - render_new_particle(re,obr,psmd->dm,ma,path,1,0,0.0f,loc1,loc0, - orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv, - adapt,adapt_angle,adapt_pix); - } + switch(part->draw_as) { + case PART_DRAW_LINE: + sd.line = 1; + sd.time = 0.0f; + sd.size = hasize; + + VECCOPY(vel,state.vel); + MTC_Mat4Mul3Vecfl(re->viewmat,vel); + Normalize(vel); + + if(part->draw & PART_DRAW_VEL_LENGTH) + VecMulf(vel,VecLength(state.vel)); + + VECADDFAC(loc0,loc,vel,-part->draw_line[0]); + VECADDFAC(loc1,loc,vel,part->draw_line[1]); - if(path_nbr==0 || k) - render_new_particle(re,obr,psmd->dm,ma,path,0,0,time,loc,loc1, - orco,surfnor,totuv,uvco,totcol,mcol,hasize,seed,override_uv, - adapt,adapt_angle,adapt_pix); + render_new_particle(re,obr,psmd->dm,ma,&sd,loc0,loc1,seed); - VECCOPY(loc1,loc); + break; + + case PART_DRAW_BB: + bb.random = random; + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = pa_time; + bb.num = a; + VECCOPY(bb.vec, loc); + VECCOPY(bb.vel, state.vel); + + particle_billboard(re, obr, ma, &bb); + + break; + + default: + { + HaloRen *har=0; + + har = RE_inithalo_particle(re, obr, psmd->dm, ma, loc, NULL, sd.orco, sd.uvco, hasize, 0.0, seed); + + if(har) har->lay= obr->ob->lay; + + break; + } } } if(orco1==0) - orco+=3; + sd.orco+=3; if(re->test_break()) break; @@ -2026,13 +1954,13 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem if(ma) do_mat_ipo(ma); if(orco1) - MEM_freeN(orco); + MEM_freeN(sd.orco); - if(uvco) - MEM_freeN(uvco); + if(sd.uvco) + MEM_freeN(sd.uvco); - if(mcol) - MEM_freeN(mcol); + if(sd.mcol) + MEM_freeN(sd.mcol); if(uv_name) MEM_freeN(uv_name); @@ -2049,7 +1977,7 @@ static int render_new_particle_system(Render *re, ObjectRen *obr, ParticleSystem psys->lattice=0; } - if(path && (ma->mode_l & MA_TANGENT_STR)==0) + if(path_nbr && (ma->mode_l & MA_TANGENT_STR)==0) calc_vertexnormals(re, obr, 0, 0); return 1; diff --git a/source/blender/src/drawobject.c b/source/blender/src/drawobject.c index 2063ac42bb1..c9fffa407ee 100644 --- a/source/blender/src/drawobject.c +++ b/source/blender/src/drawobject.c @@ -2910,6 +2910,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) ParticleData *pars, *pa; ParticleKey state, *states=0; ParticleCacheKey *cache=0; + ParticleBillboardData bb; Material *ma; Object *bb_ob=0; float vel[3], vec[3], vec2[3], imat[4][4], onevec[3]={0.0f,0.0f,0.0f}, bb_center[3]; @@ -2917,8 +2918,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) float cfra=bsystem_time(ob,(float)CFRA,0.0); float *vdata=0, *vedata=0, *cdata=0, *ndata=0, *vd=0, *ved=0, *cd=0, *nd=0, xvec[3], yvec[3], zvec[3]; float ma_r=0.0f, ma_g=0.0f, ma_b=0.0f; - int a, k, k_max=0, totpart, totpoint=0, draw_as, path_nbr=0; - int path_possible=0, keys_possible=0, draw_keys=0, totchild=0; + int a, k, k_max=0, totpart, totpoint=0, draw_as, totchild=0; int select=ob->flag&SELECT, create_cdata=0; GLint polygonmode[2]; char val[32]; @@ -3004,18 +3004,9 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) if(part->flag&PART_GLOB_TIME) cfra=bsystem_time(0,(float)CFRA,0.0); - if(psys->pathcache){ - path_possible=1; - keys_possible=1; - } - if(draw_as==PART_DRAW_PATH && path_possible==0) + if(draw_as==PART_DRAW_PATH && psys->pathcache==NULL) draw_as=PART_DRAW_DOT; - if(draw_as!=PART_DRAW_PATH && keys_possible && part->draw&PART_DRAW_KEYS){ - path_nbr=part->keys_step; - draw_keys=1; - } - /* 3. */ switch(draw_as){ case PART_DRAW_DOT: @@ -3064,12 +3055,15 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) glPointSize(2.0); /* default dot size */ } else if(part->bb_ob) - bb_ob=part->bb_ob; + bb.ob=part->bb_ob; else - bb_ob=G.vd->camera; + bb.ob=G.vd->camera; - if(part->bb_align<PART_BB_VIEW) - onevec[part->bb_align]=1.0f; + bb.align = part->bb_align; + bb.anim = part->bb_anim; + bb.lock = part->draw & PART_DRAW_BB_LOCK; + bb.offset[0] = part->bb_offset[0]; + bb.offset[1] = part->bb_offset[1]; break; case PART_DRAW_PATH: break; @@ -3081,35 +3075,37 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) } /* 4. */ - if(draw_as && draw_as!=PART_DRAW_PATH){ - if(draw_as!=PART_DRAW_CIRC){ - switch(draw_as){ + if(draw_as && draw_as!=PART_DRAW_PATH) { + int tot_vec_size = (totpart + totchild) * 3 * sizeof(float); + + if(draw_as!=PART_DRAW_CIRC) { + switch(draw_as) { case PART_DRAW_AXIS: case PART_DRAW_CROSS: - if(draw_as!=PART_DRAW_CROSS || create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*6*3*sizeof(float), "particle_vdata"); + if(draw_as != PART_DRAW_CROSS || create_cdata) + cdata = MEM_callocN(tot_vec_size * 6, "particle_cdata"); + vdata = MEM_callocN(tot_vec_size * 6, "particle_vdata"); break; case PART_DRAW_LINE: if(create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*2*3*sizeof(float), "particle_vdata"); + cdata = MEM_callocN(tot_vec_size * 2, "particle_cdata"); + vdata = MEM_callocN(tot_vec_size * 2, "particle_vdata"); break; case PART_DRAW_BB: if(create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); - ndata=MEM_callocN((totpart+totchild)*(path_nbr+1)*4*3*sizeof(float), "particle_vdata"); + cdata = MEM_callocN(tot_vec_size * 4, "particle_cdata"); + vdata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); + ndata = MEM_callocN(tot_vec_size * 4, "particle_vdata"); break; default: if(create_cdata) - cdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_cdata"); - vdata=MEM_callocN((totpart+totchild)*(path_nbr+1)*3*sizeof(float), "particle_vdata"); + cdata=MEM_callocN(tot_vec_size, "particle_cdata"); + vdata=MEM_callocN(tot_vec_size, "particle_vdata"); } } - if(part->draw&PART_DRAW_VEL && draw_as!=PART_DRAW_LINE) - vedata=MEM_callocN((totpart+totchild)*2*3*(path_nbr+1)*sizeof(float), "particle_vedata"); + if(part->draw & PART_DRAW_VEL && draw_as != PART_DRAW_LINE) + vedata = MEM_callocN(tot_vec_size * 2, "particle_vedata"); vd=vdata; ved=vedata; @@ -3122,6 +3118,7 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) if(draw_as){ /* 5. */ for(a=0,pa=pars; a<totpart+totchild; a++, pa++){ + /* setup per particle individual stuff */ if(a<totpart){ if(totchild && (part->draw&PART_DRAW_PARENT)==0) continue; if(pa->flag & PARS_NO_DISP || pa->flag & PARS_UNEXIST) continue; @@ -3159,11 +3156,6 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) } r_tilt=1.0f+pa->r_ave[0]; - - if(path_nbr){ - cache=psys->pathcache[a]; - k_max=(int)(cache->steps); - } } else{ ChildParticle *cpa= &psys->child[a-totpart]; @@ -3191,47 +3183,23 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) pa_size=psys_get_child_size(psys,cpa,cfra,0); r_tilt=2.0f*cpa->rand[2]; - if(path_nbr){ - cache=psys->childcache[a-totpart]; - k_max=(int)(cache->steps); - } } if(draw_as!=PART_DRAW_PATH){ - int next_pa=0; - for(k=0; k<=path_nbr; k++){ - if(draw_keys){ - state.time=(float)k/(float)path_nbr; - psys_get_particle_on_path(ob,psys,a,&state,1); - } - else if(path_nbr){ - if(k<=k_max){ - VECCOPY(state.co,(cache+k)->co); - VECCOPY(state.vel,(cache+k)->vel); - QUATCOPY(state.rot,(cache+k)->rot); - } - else - continue; - } - else{ - state.time=cfra; - if(psys_get_particle_state(ob,psys,a,&state,0)==0){ - next_pa=1; - break; - } - } - + state.time=cfra; + if(psys_get_particle_state(ob,psys,a,&state,0)){ + /* create actiual particle data */ switch(draw_as){ case PART_DRAW_DOT: + if(vd){ + VECCOPY(vd,state.co) vd+=3; + } if(cd) { cd[0]=ma_r; cd[1]=ma_g; cd[2]=ma_b; cd+=3; } - if(vd){ - VECCOPY(vd,state.co) vd+=3; - } break; case PART_DRAW_CROSS: case PART_DRAW_AXIS: @@ -3314,59 +3282,15 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) cd[2]=cd[5]=cd[8]=cd[11]=ma_b; cd+=12; } - if(part->draw&PART_DRAW_BB_LOCK && part->bb_align==PART_BB_VIEW){ - VECCOPY(xvec,bb_ob->obmat[0]); - Normalize(xvec); - VECCOPY(yvec,bb_ob->obmat[1]); - Normalize(yvec); - VECCOPY(zvec,bb_ob->obmat[2]); - Normalize(zvec); - } - else if(part->bb_align==PART_BB_VEL){ - float temp[3]; - VECCOPY(temp,state.vel); - Normalize(temp); - VECSUB(zvec,bb_ob->obmat[3],state.co); - if(part->draw&PART_DRAW_BB_LOCK){ - float fac=-Inpf(zvec,temp); - VECADDFAC(zvec,zvec,temp,fac); - } - Normalize(zvec); - Crossf(xvec,temp,zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - else{ - VECSUB(zvec,bb_ob->obmat[3],state.co); - if(part->draw&PART_DRAW_BB_LOCK) - zvec[part->bb_align]=0.0f; - Normalize(zvec); - - if(part->bb_align<PART_BB_VIEW) - Crossf(xvec,onevec,zvec); - else - Crossf(xvec,bb_ob->obmat[1],zvec); - Normalize(xvec); - Crossf(yvec,zvec,xvec); - } - VECCOPY(vec,xvec); - VECCOPY(vec2,yvec); - - VecMulf(xvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VecMulf(vec2,sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VECADD(xvec,xvec,vec2); - - VecMulf(yvec,cos(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VecMulf(vec,-sin(part->bb_tilt*(1.0f-part->bb_rand_tilt*r_tilt)*(float)M_PI)); - VECADD(yvec,yvec,vec); - - VecMulf(xvec,pa_size); - VecMulf(yvec,pa_size); - - VECADDFAC(bb_center,state.co,xvec,part->bb_offset[0]); - VECADDFAC(bb_center,bb_center,yvec,part->bb_offset[1]); + bb.size = pa_size; + bb.tilt = part->bb_tilt * (1.0f - part->bb_rand_tilt * r_tilt); + bb.time = pa_time; + VECCOPY(bb.vec, state.co); + VECCOPY(bb.vel, state.vel); + psys_make_billboard(&bb, xvec, yvec, zvec, bb_center); + VECADD(vd,bb_center,xvec); VECADD(vd,vd,yvec); vd+=3; @@ -3386,6 +3310,10 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) break; } + totpoint++; + + /* additional things to draw for each particle */ + /* (velocity, size and number) */ if(vedata){ VECCOPY(ved,state.co); ved+=3; @@ -3401,15 +3329,12 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) setlinestyle(0); } - totpoint++; - } - if(next_pa) - continue; - if(part->draw&PART_DRAW_NUM && !(G.f & G_RENDER_SHADOW)){ - /* in path drawing state.co is the end point */ - glRasterPos3f(state.co[0], state.co[1], state.co[2]); - sprintf(val," %i",a); - BMF_DrawString(G.font, val); + if(part->draw&PART_DRAW_NUM && !(G.f & G_RENDER_SHADOW)){ + /* in path drawing state.co is the end point */ + glRasterPos3f(state.co[0], state.co[1], state.co[2]); + sprintf(val," %i",a); + BMF_DrawString(G.font, val); + } } } } @@ -3418,51 +3343,39 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) glGetIntegerv(GL_POLYGON_MODE, polygonmode); glDisableClientState(GL_NORMAL_ARRAY); - if(draw_as != PART_DRAW_CIRC){ - if(draw_as==PART_DRAW_PATH){ - ParticleCacheKey **cache, *path; - float *cd2=0,*cdata2=0; - - glEnableClientState(GL_VERTEX_ARRAY); - - if(dt > OB_WIRE) { - glEnableClientState(GL_NORMAL_ARRAY); + if(draw_as==PART_DRAW_PATH){ + ParticleCacheKey **cache, *path; + float *cd2=0,*cdata2=0; - if(part->draw&PART_DRAW_MAT_COL) - glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); - glEnable(GL_LIGHTING); - glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); - glEnable(GL_COLOR_MATERIAL); - } - else { - glDisableClientState(GL_NORMAL_ARRAY); + /* setup gl flags */ + if(dt > OB_WIRE) { + glEnableClientState(GL_NORMAL_ARRAY); - glDisable(GL_COLOR_MATERIAL); - glDisable(GL_LIGHTING); - BIF_ThemeColor(TH_WIRE); - } + if(part->draw&PART_DRAW_MAT_COL) + glEnableClientState(GL_COLOR_ARRAY); - if(totchild && (part->draw&PART_DRAW_PARENT)==0) - totpart=0; + glEnable(GL_LIGHTING); + glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); + glEnable(GL_COLOR_MATERIAL); + } + else { + glDisableClientState(GL_NORMAL_ARRAY); - cache=psys->pathcache; - for(a=0, pa=psys->particles; a<totpart; a++, pa++){ - path=cache[a]; - glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + BIF_ThemeColor(TH_WIRE); + } - if(dt > OB_WIRE) { - glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); - if(part->draw&PART_DRAW_MAT_COL) - glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); - } + if(totchild && (part->draw&PART_DRAW_PARENT)==0) + totpart=0; - glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); - } - - cache=psys->childcache; - for(a=0; a<totchild; a++){ - path=cache[a]; + /* draw actual/parent particles */ + cache=psys->pathcache; + for(a=0, pa=psys->particles; a<totpart; a++, pa++){ + path=cache[a]; + if(path->steps > 0) { glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); if(dt > OB_WIRE) { @@ -3473,68 +3386,85 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt) glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); } + } + + /* draw child particles */ + cache=psys->childcache; + for(a=0; a<totchild; a++){ + path=cache[a]; + glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); if(dt > OB_WIRE) { + glNormalPointer(GL_FLOAT, sizeof(ParticleCacheKey), path->vel); if(part->draw&PART_DRAW_MAT_COL) - glDisable(GL_COLOR_ARRAY); - glDisable(GL_COLOR_MATERIAL); + glColorPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->col); } - if(cdata2) - MEM_freeN(cdata2); - cd2=cdata2=0; + glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1); + } - glLineWidth(1.0f); - /* draw particle edit mode key points*/ + /* restore & clean up */ + if(dt > OB_WIRE) { + if(part->draw&PART_DRAW_MAT_COL) + glDisable(GL_COLOR_ARRAY); + glDisable(GL_COLOR_MATERIAL); } - if(draw_as!=PART_DRAW_PATH){ - glDisableClientState(GL_COLOR_ARRAY); + if(cdata2) + MEM_freeN(cdata2); + cd2=cdata2=0; - if(vdata){ - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, vdata); - } - else - glDisableClientState(GL_VERTEX_ARRAY); + glLineWidth(1.0f); + } + else if(draw_as!=PART_DRAW_CIRC){ + glDisableClientState(GL_COLOR_ARRAY); - if(ndata && dt>OB_WIRE){ - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, ndata); - glEnable(GL_LIGHTING); - } - else{ - glDisableClientState(GL_NORMAL_ARRAY); - glDisable(GL_LIGHTING); - } + /* setup created data arrays */ + if(vdata){ + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, vdata); + } + else + glDisableClientState(GL_VERTEX_ARRAY); - if(cdata){ - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(3, GL_FLOAT, 0, cdata); - } + if(ndata && dt>OB_WIRE){ + glEnableClientState(GL_NORMAL_ARRAY); + glNormalPointer(GL_FLOAT, 0, ndata); + glEnable(GL_LIGHTING); + } + else{ + glDisableClientState(GL_NORMAL_ARRAY); + glDisable(GL_LIGHTING); + } - switch(draw_as){ - case PART_DRAW_AXIS: - case PART_DRAW_CROSS: - glDrawArrays(GL_LINES, 0, 6*totpoint); - break; - case PART_DRAW_LINE: - glDrawArrays(GL_LINES, 0, 2*totpoint); - break; - case PART_DRAW_BB: - if(dt<=OB_WIRE) - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - - glDrawArrays(GL_QUADS, 0, 4*totpoint); - break; - default: - glDrawArrays(GL_POINTS, 0, totpoint); - break; - } + if(cdata){ + glEnableClientState(GL_COLOR_ARRAY); + glColorPointer(3, GL_FLOAT, 0, cdata); } + + /* draw created data arrays */ + switch(draw_as){ + case PART_DRAW_AXIS: + case PART_DRAW_CROSS: + glDrawArrays(GL_LINES, 0, 6*totpoint); + break; + case PART_DRAW_LINE: + glDrawArrays(GL_LINES, 0, 2*totpoint); + break; + case PART_DRAW_BB: + if(dt<=OB_WIRE) + glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); + + glDrawArrays(GL_QUADS, 0, 4*totpoint); + break; + default: + glDrawArrays(GL_POINTS, 0, totpoint); + break; + } } + if(vedata){ glDisableClientState(GL_COLOR_ARRAY); cpack(0xC0C0C0); |