forked from bartvdbraak/blender
Major cleanup of particle render & drawing code. No new features and hopefully no new bugs.
This commit is contained in:
parent
5934757089
commit
e30cb79aaa
@ -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);
|
||||
|
@ -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]);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
@ -3082,34 +3076,36 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
|
||||
/* 4. */
|
||||
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");
|
||||
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");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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,58 +3282,14 @@ 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);
|
||||
}
|
||||
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);
|
||||
|
||||
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]);
|
||||
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,10 +3329,6 @@ 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]);
|
||||
@ -3413,18 +3337,19 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 6. */
|
||||
|
||||
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);
|
||||
|
||||
/* setup gl flags */
|
||||
if(dt > OB_WIRE) {
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
|
||||
@ -3446,9 +3371,11 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
if(totchild && (part->draw&PART_DRAW_PARENT)==0)
|
||||
totpart=0;
|
||||
|
||||
/* 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) {
|
||||
@ -3459,7 +3386,9 @@ 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];
|
||||
@ -3474,6 +3403,8 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
glDrawArrays(GL_LINE_STRIP, 0, path->steps + 1);
|
||||
}
|
||||
|
||||
|
||||
/* restore & clean up */
|
||||
if(dt > OB_WIRE) {
|
||||
if(part->draw&PART_DRAW_MAT_COL)
|
||||
glDisable(GL_COLOR_ARRAY);
|
||||
@ -3485,13 +3416,11 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
cd2=cdata2=0;
|
||||
|
||||
glLineWidth(1.0f);
|
||||
|
||||
/* draw particle edit mode key points*/
|
||||
}
|
||||
|
||||
if(draw_as!=PART_DRAW_PATH){
|
||||
else if(draw_as!=PART_DRAW_CIRC){
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
/* setup created data arrays */
|
||||
if(vdata){
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, vdata);
|
||||
@ -3514,6 +3443,8 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
glColorPointer(3, GL_FLOAT, 0, cdata);
|
||||
}
|
||||
|
||||
|
||||
/* draw created data arrays */
|
||||
switch(draw_as){
|
||||
case PART_DRAW_AXIS:
|
||||
case PART_DRAW_CROSS:
|
||||
@ -3534,7 +3465,6 @@ static void draw_new_particle_system(Base *base, ParticleSystem *psys, int dt)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(vedata){
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
cpack(0xC0C0C0);
|
||||
|
Loading…
Reference in New Issue
Block a user