void update( float time ) { if ( ! ( target && active ) ) return; localtime = ctrlTime( time ); int n = 0; while ( n < list.count() ) { Particle & p = list[n]; float deltaTime = ( localtime > p.lasttime ? localtime - p.lasttime : 0 ); //( stop - start ) - p.lasttime + localtime ); p.lifetime += deltaTime; if ( p.lifetime < p.lifespan && p.vertex < target->verts.count() ) { p.position = target->verts[ p.vertex ]; for ( int i = 0; i < 4; i++ ) moveParticle( p, deltaTime/4 ); p.lasttime = localtime; n++; } else list.remove( n ); } if ( emitNode && emitNode->isVisible() && localtime >= emitStart && localtime <= emitStop ) { float emitDelta = ( localtime > emitLast ? localtime - emitLast : 0 ); emitLast = localtime; emitAccu += emitDelta * emitRate; int num = int( emitAccu ); if ( num > 0 ) { emitAccu -= num; while ( num-- > 0 && list.count() < target->verts.count() ) { Particle p; startParticle( p ); list.append( p ); } } } n = 0; while ( n < list.count() ) { Particle & p = list[n]; p.vertex = n; target->verts[ n ] = p.position; if ( n < target->sizes.count() ) sizeParticle( p, target->sizes[n] ); if ( n < target->colors.count() ) colorParticle( p, target->colors[n] ); n++; } target->active = list.count(); target->size = size; }
int advectParticle(pScene sc,pMesh mesh) { pParticle pp; pStream st; pTetra pt1; pPoint ppt; double v[4]; int i,j,k,l,base; if ( ddebug ) printf("advect particles\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); if ( !sc->stream ) return(0); st = sc->stream; if ( mesh->ntet && !hashTetra(mesh) ) return(0); st->xmin = mesh->xmin - mesh->xtra; st->ymin = mesh->ymin - mesh->ytra; st->zmin = mesh->zmin - mesh->ztra; st->xmax = mesh->xmax - mesh->xtra; st->ymax = mesh->ymax - mesh->ytra; st->zmax = mesh->zmax - mesh->ztra; sc->par.cumpertime = 0.0; sc->par.advtim = 0; /* init list */ sc->slist = (GLuint*)calloc(MAX_LST,sizeof(GLuint)); if ( !sc->slist ) return(0); /* point positions */ base = ++mesh->mark; for (i=1; i<=mesh->np; i++) { ppt = &mesh->point[i]; ppt->mark = base; } for (k=1; k<=mesh->ntet; k++) mesh->tetra[k].cpt = 0; l = 1; for (k=1; k<=st->nbstl; k++) { pp = &tp[k]; pp->ct = 0.0; st->listp[l++] = pp->pos[pp->cur][0]; st->listp[l++] = pp->pos[pp->cur][1]; st->listp[l++] = pp->pos[pp->cur][2]; pp->cur = 1; } ++base; l = 1; for (k=1; k<=st->nbstl; k++) { pp = &tp[k]; pp->pos[1][0] = st->listp[l++]; pp->pos[1][1] = st->listp[l++]; pp->pos[1][2] = st->listp[l++]; tp[k].nsdep = locateTetra(mesh,pp->nsdep,++mesh->mark,pp->pos[1],pp->cb); if ( !pp->nsdep ) { for (j=1; j<=mesh->ntet; j++) { pt1 = &mesh->tetra[j]; if ( pt1->mark != mesh->mark && inTetra(mesh,j,pp->pos[1],pp->cb) ) break; } if ( j > mesh->ntet ) continue; else pp->nsdep = j; } pp->norm = field3DInterp(mesh,tp[k].nsdep,tp[k].cb,v); pp->size = sizeTetra(mesh,tp[k].nsdep); if ( pp->size == 0.0 ) pp->step = EPS*sc->dmax; else pp->step = HSIZ * min(pp->size,pp->norm); pp->step = min(0.05*sc->par.dt,pp->step); pp->flag = 1; pp->cur = 1; colorParticle(sc,pp); for (i=2; i<=sc->par.nbpart; i++) { pp->pos[i][0] = pp->pos[1][0]; pp->pos[i][1] = pp->pos[1][1]; pp->pos[i][2] = pp->pos[1][2]; } } return(1); }
void computeTetraParticle(pScene sc,pMesh mesh,int k) { pTetra pt; pStream st; pParticle pp; double dd,cb[4],v[4]; float ux,uy,uz,pos[3],ldt; int cur,nsfin,nsold,nbp; st = sc->stream; pp = &tp[k]; if ( pp->ct > sc->par.pertime ) return; ldt = 0.0; nbp = 0; nsold = pp->nsdep; pos[0] = pp->pos[pp->cur][0]; pos[1] = pp->pos[pp->cur][1]; pos[2] = pp->pos[pp->cur][2]; do { ux = pos[0]; uy = pos[1]; uz = pos[2]; if ( st->typtrack == 1 || !nxtPoint3D(mesh,pp->nsdep,pos,pp->step,v) ) { pos[0] += pp->step*v[0]; pos[1] += pp->step*v[1]; pos[2] += pp->step*v[2]; } if ( pos[0]<st->xmin || pos[0]>st->xmax || pos[1]<st->ymin || pos[1]>st->ymax || pos[2]<st->zmin || pos[2]>st->zmax ) { pp->flag = 0; break; } ux -= pos[0]; uy -= pos[1]; uz -= pos[2]; dd = sqrt(ux*ux + uy*uy + uz*uz) / pp->norm; ldt += dd; pp->ct += dd; if ( pp->ct >= sc->par.pertime ) { pp->flag = 0; sc->par.cumpertime = sc->par.pertime+1.e-06; break; /*return;*/ } else if ( ldt >= sc->par.dt ) { pp->cur = 1 + (pp->cur % sc->par.nbpart); pp->pos[pp->cur][0] = pos[0]; pp->pos[pp->cur][1] = pos[1]; pp->pos[pp->cur][2] = pos[2]; colorParticle(sc,pp); break; /*return;*/ } /* find tet containing p */ nsfin = locateTetra(mesh,pp->nsdep,++mesh->mark,pos,cb); if ( !nsfin ) { pp->flag = 0; break; /*return;*/ } pp->nsdep = nsfin; pt = &mesh->tetra[pp->nsdep]; if ( pt->cpt > MAX_CPT ) break; /* adjust local stepsize */ if ( pp->nsdep != nsold ) { pp->size = sizeTetra(mesh,pp->nsdep); nsold = pp->nsdep; } /* vector field interpolation */ pp->norm = field3DInterp(mesh,pp->nsdep,pp->cb,v); pp->step = HSIZ*min(pp->size,pp->norm); if ( sc->par.maxtime < FLT_MAX ) pp->step = min(0.05*sc->par.dt,pp->step); if ( pp->step == 0.0 ) { pp->flag = 0; return; } nbp++; } while ( ldt <= sc->par.dt ); cur = (pp->cur % MAX_PRT) + 1; pp->pos[cur][0] = pp->pos[pp->cur][0]; pp->pos[cur][1] = pp->pos[pp->cur][1]; pp->pos[cur][2] = pp->pos[pp->cur][2]; pp->cur = cur; colorParticle(sc,pp); }
int createParticle(pScene sc,pMesh mesh) { pParticle pp; pStream st; pMaterial pm; pTetra pt1; pTriangle pt; pPoint ppt; double v[4],cx,cy,cz; int i,j,k,l,nmat,nbp,base; if ( ddebug ) printf("create particles\n"); if ( egal(sc->iso.val[0],sc->iso.val[MAXISO-1]) ) return(0); if ( sc->stream ) { st = sc->stream; if ( st->listp ) free(st->listp); free(sc->stream); } sc->stream = createStream(sc,mesh); sc->par.cumtim = 0.0; sc->par.advtim = 0; assert(sc->stream); st = sc->stream; fprintf(stdout," Creating particles :"); fflush(stdout); st->nbstl = 0; base = ++mesh->mark; pt = &mesh->tria[refitem]; nmat = matRef(sc,pt->ref); pm = &sc->material[nmat]; k = pm->depmat[LTria]; if ( !k || pm->flag ) return(0); /* point positions */ for (i=1; i<=mesh->np; i++) { ppt = &mesh->point[i]; ppt->mark = base; } if ( sc->par.nbpart >= MAX_PRT ) sc->par.nbpart = MAX_PRT; ++base; l = 1; nbp = 0; while ( k != 0 && st->nbstl < MAX_LST-1 ) { pt = &mesh->tria[k]; if ( pt->v[0] ) { cx = cy = cz = 0.0; for (i=0; i<3; i++) { ppt = &mesh->point[pt->v[i]]; cx += 0.33 * ppt->c[0]; cy += 0.33 * ppt->c[1]; cz += 0.33 * ppt->c[2]; ppt->flag = 1; } st->listp[l++] = cx; st->listp[l++] = cy; st->listp[l++] = cz; ++st->nbstl; if ( st->nbstl > MAX_LST-1 ) break; k = pt->nxt; } } fprintf(stdout,"%d\n",st->nbstl); if ( !st->nbstl ) return(0); /* init positions */ tp = calloc((st->nbstl+1),sizeof(Particle)); assert(tp); for (k=1; k<=st->nbstl; k++) tp[k].nsdep = mesh->ntet / 2; for (k=1; k<=mesh->ntet; k++) mesh->tetra[k].cpt = 0; l = 1; for (k=1; k<=st->nbstl; k++) { pp = &tp[k]; pp->pos[1][0] = st->listp[l++]; pp->pos[1][1] = st->listp[l++]; pp->pos[1][2] = st->listp[l++]; tp[k].nsdep = locateTetra(mesh,pp->nsdep,++mesh->mark,pp->pos[1],pp->cb); if ( !pp->nsdep ) { for (j=1; j<=mesh->ntet; j++) { pt1 = &mesh->tetra[j]; if ( pt1->mark != mesh->mark && inTetra(mesh,j,pp->pos[1],pp->cb) ) break; } if ( j > mesh->ntet ) return(0); else pp->nsdep = j; } pp->norm = field3DInterp(mesh,tp[k].nsdep,tp[k].cb,v); pp->size = sizeTetra(mesh,tp[k].nsdep); if ( pp->size == 0.0 ) pp->step = EPS*sc->dmax; else pp->step = HSIZ * min(pp->size,pp->norm); pp->step = min(0.05*sc->par.dt,pp->step); pp->flag = 1; pp->cur = 1; colorParticle(sc,pp); for (i=2; i<=sc->par.nbpart; i++) { pp->pos[i][0] = pp->pos[1][0]; pp->pos[i][1] = pp->pos[1][1]; pp->pos[i][2] = pp->pos[1][2]; } } return(1); }