4 * $Id: particle_system.c $
6 * ***** BEGIN GPL LICENSE BLOCK *****
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * The Original Code is Copyright (C) 2007 by Janne Karhu.
23 * All rights reserved.
25 * The Original Code is: all of this file.
27 * Contributor(s): none yet.
29 * ***** END GPL LICENSE BLOCK *****
36 #include "MEM_guardedalloc.h"
38 #include "DNA_particle_types.h"
39 #include "DNA_mesh_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_modifier_types.h"
42 #include "DNA_object_force.h"
43 #include "DNA_object_types.h"
44 #include "DNA_material_types.h"
45 #include "DNA_ipo_types.h"
46 #include "DNA_curve_types.h"
47 #include "DNA_group_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_texture_types.h"
52 #include "BLI_jitter.h"
53 #include "BLI_arithb.h"
54 #include "BLI_blenlib.h"
55 #include "BLI_kdtree.h"
56 #include "BLI_kdopbvh.h"
57 #include "BLI_linklist.h"
58 #include "BLI_threads.h"
61 #include "BKE_bad_level_calls.h"
62 #include "BKE_cdderivedmesh.h"
63 #include "BKE_collision.h"
64 #include "BKE_displist.h"
65 #include "BKE_effect.h"
66 #include "BKE_particle.h"
67 #include "BKE_global.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_DerivedMesh.h"
70 #include "BKE_object.h"
71 #include "BKE_material.h"
73 #include "BKE_softbody.h"
74 #include "BKE_depsgraph.h"
75 #include "BKE_lattice.h"
76 #include "BKE_pointcache.h"
78 #include "BKE_modifier.h"
79 #include "BKE_scene.h"
83 #include "BSE_headerbuttons.h"
87 #include "RE_shader_ext.h"
89 /* fluid sim particle import */
90 #ifndef DISABLE_ELBEEM
91 #include "DNA_object_fluidsim.h"
92 #include "LBM_fluidsim.h"
99 #define snprintf _snprintf
103 #endif // DISABLE_ELBEEM
105 /************************************************/
106 /* Reacting to system events */
107 /************************************************/
109 static int get_current_display_percentage(ParticleSystem *psys)
111 ParticleSettings *part=psys->part;
113 if(psys->renderdata || (part->child_nbr && part->childtype))
116 if(part->phystype==PART_PHYS_KEYED){
117 if(psys->flag & PSYS_FIRST_KEYED)
118 return psys->part->disp;
123 return psys->part->disp;
126 void psys_reset(ParticleSystem *psys, int mode)
128 ParticleSettings *part= psys->part;
132 if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
133 if(mode == PSYS_RESET_ALL || !(part->type == PART_HAIR && (psys->flag & PSYS_EDITED))) {
134 if(psys->particles) {
135 if(psys->particles->keys)
136 MEM_freeN(psys->particles->keys);
138 for(i=0, pa=psys->particles; i<psys->totpart; i++, pa++)
139 if(pa->hair) MEM_freeN(pa->hair);
141 MEM_freeN(psys->particles);
142 psys->particles= NULL;
147 psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
149 if(psys->reactevents.first)
150 BLI_freelistN(&psys->reactevents);
153 else if(mode == PSYS_RESET_CACHE_MISS) {
154 /* set all particles to be skipped */
155 ParticleData *pa = psys->particles;
158 for(; p<psys->totpart; p++, pa++)
159 pa->flag |= PARS_NO_DISP;
164 MEM_freeN(psys->child);
170 /* reset path cache */
171 psys_free_path_cache(psys);
173 /* reset point cache */
174 psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID;
175 psys->pointcache->simframe= 0;
178 static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
180 ParticleData *newpars = 0, *pa;
181 int i, totpart, totsaved = 0;
184 if(psys->part->distr==PART_DISTR_GRID && psys->part->from != PART_FROM_VERT) {
185 totpart= psys->part->grid_res;
186 totpart*=totpart*totpart;
189 totpart=psys->part->totpart;
195 newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
196 if(psys->particles) {
197 totsaved=MIN2(psys->totpart,totpart);
200 memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
202 if(psys->particles->keys)
203 MEM_freeN(psys->particles->keys);
205 for(i=0, pa=psys->particles; i<totsaved; i++, pa++)
206 if(pa->keys) pa->keys= NULL;
208 for(i=totsaved, pa=psys->particles+totsaved; i<psys->totpart; i++, pa++)
209 if(pa->hair) MEM_freeN(pa->hair);
211 MEM_freeN(psys->particles);
213 psys->particles=newpars;
216 MEM_freeN(psys->child);
221 psys->totpart=totpart;
224 static int get_psys_child_number(ParticleSystem *psys)
228 if(!psys->part->childtype)
231 if(psys->renderdata) {
232 nbr= psys->part->ren_child_nbr;
233 return get_render_child_particle_number(&G.scene->r, nbr);
236 return psys->part->child_nbr;
239 static int get_psys_tot_child(ParticleSystem *psys)
241 return psys->totpart*get_psys_child_number(psys);
244 static void alloc_child_particles(ParticleSystem *psys, int tot)
247 MEM_freeN(psys->child);
252 if(psys->part->childtype) {
255 psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
259 void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
261 /* use for building derived mesh mapping info:
263 node: the allocated links - total derived mesh element count
264 nodearray: the array of nodes aligned with the base mesh's elements, so
265 each original elements can reference its derived elements
267 Mesh *me= (Mesh*)ob->data;
271 /* CACHE LOCATIONS */
272 if(!dm->deformedOnly) {
273 /* Will use later to speed up subsurf/derivedmesh */
274 LinkNode *node, *nodedmelem, **nodearray;
275 int totdmelem, totelem, i, *origindex;
277 if(psys->part->from == PART_FROM_VERT) {
278 totdmelem= dm->getNumVerts(dm);
279 totelem= me->totvert;
280 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
282 else { /* FROM_FACE/FROM_VOLUME */
283 totdmelem= dm->getNumFaces(dm);
284 totelem= me->totface;
285 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
288 nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems");
289 nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array");
291 for(i=0, node=nodedmelem; i<totdmelem; i++, origindex++, node++) {
292 node->link= SET_INT_IN_POINTER(i);
294 if(*origindex != -1) {
295 if(nodearray[*origindex]) {
297 node->next = nodearray[*origindex];
298 nodearray[*origindex]= node;
301 nodearray[*origindex]= node;
305 /* cache the verts/faces! */
306 for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++) {
307 if(psys->part->from == PART_FROM_VERT) {
308 if(nodearray[pa->num])
309 pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
311 else { /* FROM_FACE/FROM_VOLUME */
312 /* Note that somtimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
313 * but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
314 pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
318 MEM_freeN(nodearray);
319 MEM_freeN(nodedmelem);
322 /* TODO PARTICLE, make the following line unnecessary, each function
323 * should know to use the num or num_dmcache, set the num_dmcache to
324 * an invalid value, just incase */
326 for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++)
327 pa->num_dmcache = -1;
331 static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
334 float min[3], max[3], delta[3], d;
335 MVert *mv, *mvert = dm->getVertDataArray(dm,0);
336 int totvert=dm->getNumVerts(dm), from=psys->part->from;
337 int i, j, k, p, res=psys->part->grid_res, size[3], axis;
341 /* find bounding box of dm */
346 for(i=1; i<totvert; i++, mv++){
347 min[0]=MIN2(min[0],mv->co[0]);
348 min[1]=MIN2(min[1],mv->co[1]);
349 min[2]=MIN2(min[2],mv->co[2]);
351 max[0]=MAX2(max[0],mv->co[0]);
352 max[1]=MAX2(max[1],mv->co[1]);
353 max[2]=MAX2(max[2],mv->co[2]);
356 VECSUB(delta,max,min);
358 /* determine major axis */
359 axis = (delta[0]>=delta[1])?0:((delta[1]>=delta[2])?1:2);
361 d = delta[axis]/(float)res;
364 size[(axis+1)%3]=(int)ceil(delta[(axis+1)%3]/d);
365 size[(axis+2)%3]=(int)ceil(delta[(axis+2)%3]/d);
367 /* float errors grrr.. */
368 size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
369 size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
375 for(i=0,p=0,pa=psys->particles; i<res; i++){
376 for(j=0; j<res; j++){
377 for(k=0; k<res; k++,p++,pa++){
378 pa->fuv[0]=min[0]+(float)i*d;
379 pa->fuv[1]=min[1]+(float)j*d;
380 pa->fuv[2]=min[2]+(float)k*d;
381 pa->flag |= PARS_UNEXIST;
382 pa->loop=0; /* abused in volume calculation */
387 /* enable particles near verts/edges/faces/inside surface */
388 if(from==PART_FROM_VERT){
397 for(i=0,mv=mvert; i<totvert; i++,mv++){
398 VecSubf(vec,mv->co,min);
402 (pa +((int)(vec[0]*(size[0]-1))*res
403 +(int)(vec[1]*(size[1]-1)))*res
404 +(int)(vec[2]*(size[2]-1)))->flag &= ~PARS_UNEXIST;
407 else if(ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)){
408 float co1[3], co2[3];
411 float v1[3], v2[3], v3[3], v4[4], lambda;
412 int a, a1, a2, a0mul, a1mul, a2mul, totface;
413 int amax= from==PART_FROM_FACE ? 3 : 1;
415 totface=dm->getNumFaces(dm);
416 mface=dm->getFaceDataArray(dm,CD_MFACE);
418 for(a=0; a<amax; a++){
419 if(a==0){ a0mul=res*res; a1mul=res; a2mul=1; }
420 else if(a==1){ a0mul=res; a1mul=1; a2mul=res*res; }
421 else{ a0mul=1; a1mul=res*res; a2mul=res; }
423 for(a1=0; a1<size[(a+1)%3]; a1++){
424 for(a2=0; a2<size[(a+2)%3]; a2++){
425 mface=dm->getFaceDataArray(dm,CD_MFACE);
427 pa=psys->particles + a1*a1mul + a2*a2mul;
428 VECCOPY(co1,pa->fuv);
431 co2[a]+=delta[a] + 0.001f*d;
434 /* lets intersect the faces */
435 for(i=0; i<totface; i++,mface++){
436 VECCOPY(v1,mvert[mface->v1].co);
437 VECCOPY(v2,mvert[mface->v2].co);
438 VECCOPY(v3,mvert[mface->v3].co);
440 if(AxialLineIntersectsTriangle(a,co1, co2, v2, v3, v1, &lambda)){
441 if(from==PART_FROM_FACE)
442 (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
443 else /* store number of intersections */
444 (pa+(int)(lambda*size[a])*a0mul)->loop++;
448 VECCOPY(v4,mvert[mface->v4].co);
450 if(AxialLineIntersectsTriangle(a,co1, co2, v4, v1, v3, &lambda)){
451 if(from==PART_FROM_FACE)
452 (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
454 (pa+(int)(lambda*size[a])*a0mul)->loop++;
459 if(from==PART_FROM_VOLUME){
462 for(i=0; i<size[0]; i++){
463 if(in || (pa+i*a0mul)->loop%2)
464 (pa+i*a0mul)->flag &= ~PARS_UNEXIST;
465 /* odd intersections == in->out / out->in */
466 /* even intersections -> in stays same */
467 in=(in + (pa+i*a0mul)->loop) % 2;
475 if(psys->part->flag & PART_GRID_INVERT){
476 for(i=0,pa=psys->particles; i<size[0]; i++){
477 for(j=0; j<size[1]; j++){
478 pa=psys->particles + res*(i*res + j);
479 for(k=0; k<size[2]; k++, pa++){
480 pa->flag ^= PARS_UNEXIST;
487 /* modified copy from rayshade.c */
488 static void hammersley_create(float *out, int n, int seed, float amount)
491 double p, t, offs[2];
494 rng = rng_new(31415926 + n + seed);
495 offs[0]= rng_getDouble(rng) + amount;
496 offs[1]= rng_getDouble(rng) + amount;
499 for (k = 0; k < n; k++) {
501 for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
502 if (kk & 1) /* kk mod 2 = 1 */
505 out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0);
506 out[2*k + 1]= fmod(t + offs[1], 1.0);
510 /* modified copy from effect.c */
511 static void init_mv_jit(float *jit, int num, int seed2, float amount)
514 float *jit2, x, rad1, rad2, rad3;
519 rad1= (float)(1.0/sqrt((float)num));
520 rad2= (float)(1.0/((float)num));
521 rad3= (float)sqrt((float)num)/((float)num);
523 rng = rng_new(31415926 + num + seed2);
526 for(i=0; i<num2; i+=2) {
528 jit[i]= x + amount*rad1*(0.5f - rng_getFloat(rng));
529 jit[i+1]= i/(2.0f*num) + amount*rad1*(0.5f - rng_getFloat(rng));
531 jit[i]-= (float)floor(jit[i]);
532 jit[i+1]-= (float)floor(jit[i+1]);
535 x -= (float)floor(x);
538 jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
540 for (i=0 ; i<4 ; i++) {
541 BLI_jitterate1(jit, jit2, num, rad1);
542 BLI_jitterate1(jit, jit2, num, rad1);
543 BLI_jitterate2(jit, jit2, num, rad2);
549 static void psys_uv_to_w(float u, float v, int quad, float *w)
551 float vert[4][3], co[3];
560 vert[0][0]= 0.0f; vert[0][1]= 0.0f; vert[0][2]= 0.0f;
561 vert[1][0]= 1.0f; vert[1][1]= 0.0f; vert[1][2]= 0.0f;
562 vert[2][0]= 1.0f; vert[2][1]= 1.0f; vert[2][2]= 0.0f;
569 vert[3][0]= 0.0f; vert[3][1]= 1.0f; vert[3][2]= 0.0f;
570 MeanValueWeights(vert, 4, co, w);
573 MeanValueWeights(vert, 3, co, w);
578 static int binary_search_distribution(float *sum, int n, float value)
580 int mid, low=0, high=n;
584 if(sum[mid] <= value && value <= sum[mid+1])
586 else if(sum[mid] > value)
588 else if(sum[mid] < value)
597 /* note: this function must be thread safe, for from == PART_FROM_CHILD */
598 #define ONLY_WORKING_WITH_PA_VERTS 0
599 void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
601 ParticleThreadContext *ctx= thread->ctx;
603 DerivedMesh *dm= ctx->dm;
605 ParticleSettings *part= ctx->psys->part;
606 float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3];
607 float cur_d, min_d, randu, randv;
609 int cfrom= ctx->cfrom;
610 int distr= ctx->distr;
611 int i, intersect, tot;
613 if(from == PART_FROM_VERT) {
614 /* TODO_PARTICLE - use original index */
615 pa->num= ctx->index[p];
617 pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
618 //pa->verts[0] = pa->verts[1] = pa->verts[2] = 0;
620 #if ONLY_WORKING_WITH_PA_VERTS
622 KDTreeNearest ptn[3];
625 psys_particle_on_dm(ctx->ob,ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
626 transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
627 maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
629 for(w=0; w<maxw; w++){
630 pa->verts[w]=ptn->num;
635 else if(from == PART_FROM_FACE || from == PART_FROM_VOLUME) {
638 pa->num = i = ctx->index[p];
639 mface = dm->getFaceData(dm,i,CD_MFACE);
643 ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
644 psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
646 //ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel);
648 case PART_DISTR_RAND:
649 randu= rng_getFloat(thread->rng);
650 randv= rng_getFloat(thread->rng);
651 psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
657 pa->verts[0] = mface->v1;
658 pa->verts[1] = mface->v2;
659 pa->verts[2] = mface->v3;
663 if(from==PART_FROM_VOLUME){
664 MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
666 tot=dm->getNumFaces(dm);
668 psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
678 for(i=0,mface=dm->getFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++){
679 if(i==pa->num) continue;
681 v1=mvert[mface->v1].co;
682 v2=mvert[mface->v2].co;
683 v3=mvert[mface->v3].co;
685 if(LineIntersectsTriangle(co1, co2, v2, v3, v1, &cur_d, 0)){
688 pa->foffset=cur_d*50.0f; /* to the middle of volume */
693 v4=mvert[mface->v4].co;
695 if(LineIntersectsTriangle(co1, co2, v4, v1, v3, &cur_d, 0)){
698 pa->foffset=cur_d*50.0f; /* to the middle of volume */
708 pa->foffset*= ctx->jit[2*(int)ctx->jitoff[i]];
710 case PART_DISTR_RAND:
711 pa->foffset*=BLI_frand();
716 else if(from == PART_FROM_PARTICLE) {
717 //pa->verts[0]=0; /* not applicable */
721 tpa=ctx->tpars+ctx->index[p];
722 pa->num=ctx->index[p];
723 pa->fuv[0]=tpa->fuv[0];
724 pa->fuv[1]=tpa->fuv[1];
725 /* abusing foffset a little for timing in near reaction */
726 pa->foffset=ctx->weight[ctx->index[p]];
727 ctx->weight[ctx->index[p]]+=ctx->maxweight;
729 else if(from == PART_FROM_CHILD) {
732 if(ctx->index[p] < 0) {
734 cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
735 cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
736 cpa->rand[0]=cpa->rand[1]=cpa->rand[2]=0.0f;
740 mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE);
743 // case PART_DISTR_JIT:
745 // psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mf->v4, cpa->fuv);
746 // ctx->jitoff[i]=(float)fmod(ctx->jitoff[i]+ctx->maxweight/ctx->weight[i],(float)ctx->jitlevel);
748 // case PART_DISTR_RAND:
749 randu= rng_getFloat(thread->rng);
750 randv= rng_getFloat(thread->rng);
751 psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
755 cpa->rand[0] = rng_getFloat(thread->rng);
756 cpa->rand[1] = rng_getFloat(thread->rng);
757 cpa->rand[2] = rng_getFloat(thread->rng);
758 cpa->num = ctx->index[p];
761 KDTreeNearest ptn[10];
762 int w,maxw, do_seams;
763 float maxd,mind,dd,totw=0.0;
767 do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);
769 psys_particle_on_dm(ob,dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
770 transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
771 maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
773 maxd=ptn[maxw-1].dist;
777 /* the weights here could be done better */
778 for(w=0; w<maxw; w++){
779 parent[w]=ptn[w].index;
780 pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
781 //pweight[w]= (1.0f - ptn[w].dist*ptn[w].dist/(maxd*maxd));
782 //pweight[w] *= pweight[w];
789 ParticleSeam *seam=ctx->seams;
790 float temp[3],temp2[3],tan[3];
791 float inp,cur_len,min_len=10000.0f;
792 int min_seam=0, near_vert=0;
793 /* find closest seam */
794 for(i=0; i<ctx->totseam; i++, seam++){
795 VecSubf(temp,co1,seam->v0);
796 inp=Inpf(temp,seam->dir)/seam->length2;
798 cur_len=VecLenf(co1,seam->v0);
801 cur_len=VecLenf(co1,seam->v1);
804 VecCopyf(temp2,seam->dir);
806 cur_len=VecLenf(temp,temp2);
811 if(inp<0.0f) near_vert=-1;
812 else if(inp>1.0f) near_vert=1;
816 seam=ctx->seams+min_seam;
818 VecCopyf(temp,seam->v0);
822 VecSubf(tan,co1,seam->v0);
824 VecSubf(tan,co1,seam->v1);
825 VecCopyf(temp,seam->v1);
831 VecCopyf(tan,seam->tan);
832 VecSubf(temp2,co1,temp);
833 if(Inpf(tan,temp2)<0.0f)
836 for(w=0; w<maxw; w++){
837 VecSubf(temp2,ptn[w].co,temp);
838 if(Inpf(tan,temp2)<0.0f){
846 for(w=0,i=0; w<maxw && i<4; w++){
848 cpa->pa[i]=parent[w];
849 cpa->w[i]=pweight[w];
859 if(totw>0.0f) for(w=0; w<4; w++)
862 cpa->parent=cpa->pa[0];
867 void *exec_distribution(void *data)
869 ParticleThread *thread= (ParticleThread*)data;
870 ParticleSystem *psys= thread->ctx->psys;
875 if(thread->ctx->from == PART_FROM_CHILD) {
876 totpart= psys->totchild;
879 for(p=0; p<totpart; p++, cpa++) {
880 if(thread->ctx->skip) /* simplification skip */
881 rng_skip(thread->rng, 5*thread->ctx->skip[p]);
883 if((p+thread->num) % thread->tot == 0)
884 psys_thread_distribute_particle(thread, NULL, cpa, p);
885 else /* thread skip */
886 rng_skip(thread->rng, 5);
890 totpart= psys->totpart;
891 pa= psys->particles + thread->num;
892 for(p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot)
893 psys_thread_distribute_particle(thread, pa, NULL, p);
899 /* not thread safe, but qsort doesn't take userdata argument */
900 static int *COMPARE_ORIG_INDEX = NULL;
901 static int compare_orig_index(const void *p1, const void *p2)
903 int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
904 int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
908 else if(index1 == index2) {
909 /* this pointer comparison appears to make qsort stable for glibc,
910 * and apparently on solaris too, makes the renders reproducable */
922 /* creates a distribution of coordinates on a DerivedMesh */
924 /* 1. lets check from what we are emitting */
925 /* 2. now we know that we have something to emit from so */
926 /* let's calculate some weights */
927 /* 2.1 from even distribution */
928 /* 2.2 and from vertex groups */
929 /* 3. next we determine the indexes of emitting thing that */
930 /* the particles will have */
931 /* 4. let's do jitter if we need it */
932 /* 5. now we're ready to set the indexes & distributions to */
934 /* 6. and we're done! */
936 /* This is to denote functionality that does not yet work with mesh - only derived mesh */
937 int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm, int from)
939 ParticleThreadContext *ctx= threads[0].ctx;
941 ParticleSystem *psys= ctx->psys;
943 ParticleData *pa=0, *tpars= 0;
944 ParticleSettings *part;
945 ParticleSystem *tpsys;
946 ParticleSeam *seams= 0;
947 ChildParticle *cpa=0;
949 DerivedMesh *dm= NULL;
951 int i, seed, p=0, totthread= threads[0].tot;
952 int no_distr=0, cfrom=0;
953 int tot=0, totpart, *index=0, children=0, totseam=0;
955 int jitlevel= 1, distr;
956 float *weight=0,*sum=0,*jitoff=0;
957 float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3];
959 if(ob==0 || psys==0 || psys->part==0)
963 totpart=psys->totpart;
967 if (!finaldm->deformedOnly && !CustomData_has_layer( &finaldm->faceData, CD_ORIGINDEX ) ) {
968 error("Can't paint with the current modifier stack, disable destructive modifiers");
972 BLI_srandom(31415926 + psys->seed);
974 if(from==PART_FROM_CHILD){
975 distr=PART_DISTR_RAND;
976 if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
980 tree=BLI_kdtree_new(totpart);
982 for(p=0,pa=psys->particles; p<totpart; p++,pa++){
983 psys_particle_on_dm(ob,dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
984 transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
985 BLI_kdtree_insert(tree, p, orco, ornor);
988 BLI_kdtree_balance(tree);
990 totpart=get_psys_tot_child(psys);
991 cfrom=from=PART_FROM_FACE;
993 if(part->flag&PART_CHILD_SEAMS){
994 MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE);
995 MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
996 int totedge=dm->getNumEdges(dm);
998 for(p=0, ed=medge; p<totedge; p++,ed++)
1003 ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams");
1004 float temp[3],temp2[3];
1006 for(p=0, ed=medge; p<totedge; p++,ed++){
1007 if(ed->flag&ME_SEAM){
1008 VecCopyf(cur_seam->v0,(mvert+ed->v1)->co);
1009 VecCopyf(cur_seam->v1,(mvert+ed->v2)->co);
1011 VecSubf(cur_seam->dir,cur_seam->v1,cur_seam->v0);
1013 cur_seam->length2=VecLength(cur_seam->dir);
1014 cur_seam->length2*=cur_seam->length2;
1016 temp[0]=(float)((mvert+ed->v1)->no[0]);
1017 temp[1]=(float)((mvert+ed->v1)->no[1]);
1018 temp[2]=(float)((mvert+ed->v1)->no[2]);
1019 temp2[0]=(float)((mvert+ed->v2)->no[0]);
1020 temp2[1]=(float)((mvert+ed->v2)->no[1]);
1021 temp2[2]=(float)((mvert+ed->v2)->no[2]);
1023 VecAddf(cur_seam->nor,temp,temp2);
1024 Normalize(cur_seam->nor);
1026 Crossf(cur_seam->tan,cur_seam->dir,cur_seam->nor);
1028 Normalize(cur_seam->tan);
1038 /* no need to figure out distribution */
1039 int child_nbr= get_psys_child_number(psys);
1041 totpart= get_psys_tot_child(psys);
1042 alloc_child_particles(psys, totpart);
1044 for(i=0; i<child_nbr; i++){
1045 for(p=0; p<psys->totpart; p++,cpa++){
1049 /* create even spherical distribution inside unit sphere */
1050 while(length>=1.0f){
1051 cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
1052 cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
1053 cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
1054 length=VecLength(cpa->fuv);
1057 cpa->rand[0]=BLI_frand();
1058 cpa->rand[1]=BLI_frand();
1059 cpa->rand[2]=BLI_frand();
1069 dm= CDDM_from_mesh((Mesh*)ob->data, ob);
1071 /* special handling of grid distribution */
1072 if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
1073 distribute_particles_in_grid(dm,psys);
1078 /* we need orco for consistent distributions */
1079 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
1083 if(from==PART_FROM_VERT){
1084 MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
1085 float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO);
1086 int totvert = dm->getNumVerts(dm);
1088 tree=BLI_kdtree_new(totvert);
1090 for(p=0; p<totvert; p++){
1092 VECCOPY(co,orcodata[p])
1093 transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1);
1096 VECCOPY(co,mv[p].co)
1097 BLI_kdtree_insert(tree,p,co,NULL);
1100 BLI_kdtree_balance(tree);
1106 case PART_FROM_VERT:
1107 tot = dm->getNumVerts(dm);
1109 case PART_FROM_VOLUME:
1110 case PART_FROM_FACE:
1111 tot = dm->getNumFaces(dm);
1113 case PART_FROM_PARTICLE:
1115 tob=psys->target_ob;
1119 if((tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1))){
1120 tpars=tpsys->particles;
1130 fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n");
1132 for(p=0,cpa=psys->child; p<totpart; p++,cpa++){
1133 cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
1136 cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
1143 fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
1144 for(p=0,pa=psys->particles; p<totpart; p++,pa++){
1145 pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
1151 if(dm != finaldm) dm->release(dm);
1157 weight=MEM_callocN(sizeof(float)*tot, "particle_distribution_weights");
1158 index=MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
1159 sum=MEM_callocN(sizeof(float)*(tot+1), "particle_distribution_sum");
1160 jitoff=MEM_callocN(sizeof(float)*tot, "particle_distribution_jitoff");
1163 if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){
1164 MVert *v1, *v2, *v3, *v4;
1165 float totarea=0.0, co1[3], co2[3], co3[3], co4[3];
1166 float (*orcodata)[3];
1168 orcodata= dm->getVertDataArray(dm, CD_ORCO);
1170 for(i=0; i<tot; i++){
1171 MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
1174 VECCOPY(co1, orcodata[mf->v1]);
1175 VECCOPY(co2, orcodata[mf->v2]);
1176 VECCOPY(co3, orcodata[mf->v3]);
1177 transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1);
1178 transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1);
1179 transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1);
1182 v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
1183 v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
1184 v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
1185 VECCOPY(co1, v1->co);
1186 VECCOPY(co2, v2->co);
1187 VECCOPY(co3, v3->co);
1192 VECCOPY(co4, orcodata[mf->v4]);
1193 transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
1196 v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
1197 VECCOPY(co4, v4->co);
1199 cur= AreaQ3Dfl(co1, co2, co3, co4);
1202 cur= AreaT3Dfl(co1, co2, co3);
1211 for(i=0; i<tot; i++)
1212 weight[i] /= totarea;
1214 maxweight /= totarea;
1216 else if(from==PART_FROM_PARTICLE){
1217 float val=(float)tot/(float)totpart;
1218 for(i=0; i<tot; i++)
1223 float min=1.0f/(float)(MIN2(tot,totpart));
1224 for(i=0; i<tot; i++)
1230 if(ELEM3(from,PART_FROM_VERT,PART_FROM_FACE,PART_FROM_VOLUME)){
1231 float *vweight= psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
1234 if(from==PART_FROM_VERT) {
1236 weight[i]*=vweight[i];
1238 else { /* PART_FROM_FACE / PART_FROM_VOLUME */
1239 for(i=0;i<tot; i++){
1240 MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
1241 tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
1244 tweight += vweight[mf->v4];
1261 totweight += weight[i];
1263 if(totweight > 0.0f)
1264 totweight= 1.0f/totweight;
1268 sum[i+1]= sum[i]+weight[i]*totweight;
1270 if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
1273 for(p=0; p<totpart; p++) {
1275 index[p]= binary_search_distribution(sum, tot, pos);
1276 index[p]= MIN2(tot-1, index[p]);
1277 jitoff[index[p]]= pos;
1283 step= (totpart <= 1)? 0.5: 1.0/(totpart-1);
1284 pos= 1e-16f; /* tiny offset to avoid zero weight face */
1287 for(p=0; p<totpart; p++, pos+=step) {
1288 while((i < tot) && (pos > sum[i+1]))
1291 index[p]= MIN2(tot-1, i);
1293 /* avoid zero weight face */
1294 if(p == totpart-1 && weight[index[p]] == 0.0f)
1295 index[p]= index[p-1];
1297 jitoff[index[p]]= pos;
1303 /* for hair, sort by origindex, allows optimizations in rendering */
1304 if(part->type == PART_HAIR) {
1305 COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
1306 if(COMPARE_ORIG_INDEX)
1307 qsort(index, totpart, sizeof(int), compare_orig_index);
1310 /* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */
1311 if(from==PART_FROM_PARTICLE){
1312 for(i=0; i<tot; i++)
1317 if(distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
1318 jitlevel= part->userjit;
1321 jitlevel= totpart/tot;
1322 if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
1323 if(jitlevel<3) jitlevel= 3;
1324 //if(jitlevel>100) jitlevel= 100;
1327 jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
1329 /* for small amounts of particles we use regular jitter since it looks
1330 * a bit better, for larger amounts we switch to hammersley sequence
1331 * because it is much faster */
1333 init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
1335 hammersley_create(jit, jitlevel+1, psys->seed, part->jitfac);
1336 BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
1342 ctx->totseam= totseam;
1346 ctx->jitlevel= jitlevel;
1347 ctx->jitoff= jitoff;
1348 ctx->weight= weight;
1349 ctx->maxweight= maxweight;
1350 ctx->from= (children)? PART_FROM_CHILD: from;
1357 totpart= psys_render_simplify_distribution(ctx, totpart);
1358 alloc_child_particles(psys, totpart);
1361 if(!children || psys->totchild < 10000)
1364 seed= 31415926 + ctx->psys->seed;
1365 for(i=0; i<totthread; i++) {
1366 threads[i].rng= rng_new(seed);
1367 threads[i].tot= totthread;
1373 static void distribute_particles_on_dm(DerivedMesh *finaldm, Object *ob, ParticleSystem *psys, int from)
1376 ParticleThread *pthreads;
1377 ParticleThreadContext *ctx;
1380 pthreads= psys_threads_create(ob, psys);
1382 if(!psys_threads_init_distribution(pthreads, finaldm, from)) {
1383 psys_threads_free(pthreads);
1387 totthread= pthreads[0].tot;
1389 BLI_init_threads(&threads, exec_distribution, totthread);
1391 for(i=0; i<totthread; i++)
1392 BLI_insert_thread(&threads, &pthreads[i]);
1394 BLI_end_threads(&threads);
1397 exec_distribution(&pthreads[0]);
1399 psys_calc_dmcache(ob, finaldm, psys);
1401 ctx= pthreads[0].ctx;
1402 if(ctx->dm != finaldm)
1403 ctx->dm->release(ctx->dm);
1405 psys_threads_free(pthreads);
1408 /* ready for future use, to emit particles without geometry */
1409 static void distribute_particles_on_shape(Object *ob, ParticleSystem *psys, int from)
1412 int totpart=psys->totpart, p;
1414 fprintf(stderr,"Shape emission not yet possible!\n");
1416 for(p=0,pa=psys->particles; p<totpart; p++,pa++){
1417 pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
1422 static void distribute_particles(Object *ob, ParticleSystem *psys, int from)
1424 ParticleSystemModifierData *psmd=0;
1426 psmd=psys_get_modifier(ob,psys);
1430 distribute_particles_on_dm(psmd->dm,ob,psys,from);
1435 distribute_particles_on_shape(ob,psys,from);
1439 int totpart=psys->totpart, p;
1441 fprintf(stderr,"Particle distribution error!\n");
1443 for(p=0,pa=psys->particles; p<totpart; p++,pa++){
1444 pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
1451 /* threaded child particle distribution and path caching */
1452 ParticleThread *psys_threads_create(struct Object *ob, struct ParticleSystem *psys)
1454 ParticleThread *threads;
1455 ParticleThreadContext *ctx;
1458 if(G.scene->r.mode & R_FIXED_THREADS)
1459 totthread= G.scene->r.threads;
1461 totthread= BLI_system_thread_count();
1463 threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
1464 ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
1468 ctx->psmd= psys_get_modifier(ob, psys);
1469 ctx->dm= ctx->psmd->dm;
1470 ctx->ma= give_current_material(ob, psys->part->omat);
1472 memset(threads, 0, sizeof(ParticleThread)*totthread);
1474 for(i=0; i<totthread; i++) {
1475 threads[i].ctx= ctx;
1477 threads[i].tot= totthread;
1483 void psys_threads_free(ParticleThread *threads)
1485 ParticleThreadContext *ctx= threads[0].ctx;
1486 int i, totthread= threads[0].tot;
1490 MEM_freeN(ctx->vg_length);
1492 MEM_freeN(ctx->vg_clump);
1494 MEM_freeN(ctx->vg_kink);
1496 MEM_freeN(ctx->vg_rough1);
1498 MEM_freeN(ctx->vg_rough2);
1500 MEM_freeN(ctx->vg_roughe);
1502 if(ctx->psys->lattice){
1504 ctx->psys->lattice=0;
1508 if(ctx->jit) MEM_freeN(ctx->jit);
1509 if(ctx->jitoff) MEM_freeN(ctx->jitoff);
1510 if(ctx->weight) MEM_freeN(ctx->weight);
1511 if(ctx->index) MEM_freeN(ctx->index);
1512 if(ctx->skip) MEM_freeN(ctx->skip);
1513 if(ctx->seams) MEM_freeN(ctx->seams);
1514 //if(ctx->vertpart) MEM_freeN(ctx->vertpart);
1515 BLI_kdtree_free(ctx->tree);
1518 for(i=0; i<totthread; i++) {
1520 rng_free(threads[i].rng);
1521 if(threads[i].rng_path)
1522 rng_free(threads[i].rng_path);
1529 /* set particle parameters that don't change during particle's life */
1530 void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
1532 ParticleSettings *part;
1533 ParticleTexture ptex;
1541 totpart=psys->totpart;
1543 ptex.life=ptex.size=ptex.exist=ptex.length=1.0;
1544 ptex.time=(float)p/(float)totpart;
1546 BLI_srandom(psys->seed+p);
1548 if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){
1549 ma=give_current_material(ob,part->omat);
1551 /* TODO: needs some work to make most blendtypes generally usefull */
1552 psys_get_texture(ob,ma,psmd,psys,pa,&ptex,MAP_PA_INIT);
1555 pa->lifetime= part->lifetime*ptex.life;
1557 if(part->type==PART_HAIR)
1559 else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
1562 //icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME);
1564 // calc_icu(icu,100*ptex.time);
1565 // ptex.time=icu->curval;
1568 pa->time= part->sta + (part->end - part->sta)*ptex.time;
1572 if(part->type==PART_HAIR){
1573 pa->lifetime=100.0f;
1576 icu=find_ipocurve(psys->part->ipo,PART_EMIT_LIFE);
1578 calc_icu(icu,100*ptex.time);
1579 pa->lifetime*=icu->curval;
1582 /* need to get every rand even if we don't use them so that randoms don't affect eachother */
1584 if(part->randlife!=0.0)
1585 pa->lifetime*= 1.0f - part->randlife*rand;
1588 pa->dietime= pa->time+pa->lifetime;
1590 pa->sizemul= BLI_frand();
1594 /* while loops are to have a spherical distribution (avoid cubic distribution) */
1597 pa->r_ve[0]=2.0f*(BLI_frand()-0.5f);
1598 pa->r_ve[1]=2.0f*(BLI_frand()-0.5f);
1599 pa->r_ve[2]=2.0f*(BLI_frand()-0.5f);
1600 length=VecLength(pa->r_ve);
1605 pa->r_ave[0]=2.0f*(BLI_frand()-0.5f);
1606 pa->r_ave[1]=2.0f*(BLI_frand()-0.5f);
1607 pa->r_ave[2]=2.0f*(BLI_frand()-0.5f);
1608 length=VecLength(pa->r_ave);
1611 pa->r_rot[0]=2.0f*(BLI_frand()-0.5f);
1612 pa->r_rot[1]=2.0f*(BLI_frand()-0.5f);
1613 pa->r_rot[2]=2.0f*(BLI_frand()-0.5f);
1614 pa->r_rot[3]=2.0f*(BLI_frand()-0.5f);
1616 NormalQuat(pa->r_rot);
1618 if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
1619 /* any unique random number will do (r_ave[0]) */
1620 if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
1621 pa->flag |= PARS_UNEXIST;
1623 pa->flag &= ~PARS_UNEXIST;
1627 /* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */
1628 /* usage other than straight after distribute has to handle this index by itself - jahka*/
1629 //pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */
1631 static void initialize_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd)
1635 int p, totpart=psys->totpart;
1637 for(p=0, pa=psys->particles; p<totpart; p++, pa++)
1638 initialize_particle(pa,p,ob,psys,psmd);
1640 if(psys->part->type != PART_FLUID) {
1641 icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ);
1643 float time=psys->part->sta, end=psys->part->end;
1644 float v1, v2, a=0.0f, t1,t2, d;
1651 if(v1<0.0f) v1=0.0f;
1653 calc_icu(icu,time+1.0f);
1655 if(v2<0.0f) v2=0.0f;
1657 for(p=0, pa=psys->particles; p<totpart && time<end; p++, pa++){
1658 while(a+0.5f*(v1+v2) < (float)(p+1) && time<end){
1662 calc_icu(icu,time+1.0f);
1667 pa->time=time+((float)(p+1)-a)/v1;
1670 d=(float)sqrt(v1*v1-2.0f*(v2-v1)*(a-(float)(p+1)));
1674 /* the root between 0-1 is the correct one */
1675 if(t1>0.0f && t1<=1.0f)
1682 pa->dietime = pa->time+pa->lifetime;
1683 pa->flag &= ~PARS_UNEXIST;
1685 for(; p<totpart; p++, pa++){
1686 pa->flag |= PARS_UNEXIST;
1691 /* sets particle to the emitter surface with initial velocity & rotation */
1692 void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifierData *psmd, Object *ob,
1693 float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot)
1695 ParticleSettings *part;
1696 ParticleTexture ptex;
1699 float fac, phasefac, nor[3]={0,0,0},loc[3],tloc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
1700 float r_vel[3],r_ave[3],r_rot[4],p_vel[3]={0.0,0.0,0.0};
1701 float x_vec[3]={1.0,0.0,0.0}, utan[3]={0.0,1.0,0.0}, vtan[3]={0.0,0.0,1.0}, rot_vec[3]={0.0,0.0,0.0};
1707 if(part->from==PART_FROM_PARTICLE){
1709 ParticleSystem *tpsys=0;
1712 tob=psys->target_ob;
1716 tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
1718 state.time = pa->time;
1720 memset(&state, 0, sizeof(state));
1722 psys_get_particle_state(tob,tpsys,pa->num,&state,1);
1723 psys_get_from_key(&state,loc,nor,rot,0);
1725 QuatMulVecf(rot,vtan);
1726 QuatMulVecf(rot,utan);
1727 VECCOPY(r_vel,pa->r_ve);
1728 VECCOPY(r_rot,pa->r_rot);
1729 VECCOPY(r_ave,pa->r_ave);
1731 VECCOPY(p_vel,state.vel);
1732 speed=Normalize(p_vel);
1733 VecMulf(p_vel,Inpf(pa->r_ve,p_vel));
1734 VECSUB(p_vel,pa->r_ve,p_vel);
1736 VecMulf(p_vel,speed);
1739 /* get precise emitter matrix if particle is born */
1740 if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= psys->cfra)
1741 where_is_object_time(ob,pa->time);
1743 /* get birth location from object */
1744 psys_particle_on_emitter(ob,psmd,part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
1746 /* save local coordinates for later */
1749 /* get possible textural influence */
1750 psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL);
1752 if(vg_vel && pa->num != -1)
1753 ptex.ivel*=psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_vel);
1755 /* particles live in global space so */
1756 /* let's convert: */
1758 Mat4MulVecfl(ob->obmat,loc);
1761 VECADD(nor,tloc,nor);
1762 Mat4MulVecfl(ob->obmat,nor);
1763 VECSUB(nor,nor,loc);
1767 if(part->tanfac!=0.0){
1768 float phase=vg_rot?2.0f*(psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_rot)-0.5f):0.0f;
1769 VecMulf(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
1770 fac=-(float)sin(M_PI*(part->tanphase+phase));
1771 VECADDFAC(vtan,vtan,utan,fac);
1773 VECADD(vtan,tloc,vtan);
1774 Mat4MulVecfl(ob->obmat,vtan);
1775 VECSUB(vtan,vtan,loc);
1778 VecMulf(utan,Inpf(vtan,nor));
1779 VECSUB(vtan,vtan,utan);
1786 if(part->randfac!=0.0){
1787 VECADD(r_vel,tloc,pa->r_ve);
1788 Mat4MulVecfl(ob->obmat,r_vel);
1789 VECSUB(r_vel,r_vel,loc);
1793 /* -angular velocity */
1794 if(part->avemode==PART_AVE_RAND){
1795 VECADD(r_ave,tloc,pa->r_ave);
1796 Mat4MulVecfl(ob->obmat,r_ave);
1797 VECSUB(r_ave,r_ave,loc);
1802 if(part->randrotfac != 0.0f){
1803 QUATCOPY(r_rot,pa->r_rot);
1804 Mat4ToQuat(ob->obmat,rot);
1805 QuatMul(r_rot,r_rot,rot);
1808 /* conversion done so now we apply new: */
1809 /* -velocity from: */
1813 VECSUB(vel,pa->state.vel,pa->prev_state.vel);
1816 /* *emitter velocity */
1817 if(dtime!=0.0 && part->obfac!=0.0){
1818 VECSUB(vel,loc,pa->state.co);
1819 VecMulf(vel,part->obfac/dtime);
1822 /* *emitter normal */
1823 if(part->normfac!=0.0)
1824 VECADDFAC(vel,vel,nor,part->normfac);
1826 /* *emitter tangent */
1827 if(part->tanfac!=0.0)
1828 VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_tan):1.0f));
1834 if(part->randfac!=0.0)
1835 VECADDFAC(vel,vel,r_vel,part->randfac);
1838 if(part->partfac!=0.0)
1839 VECADDFAC(vel,vel,p_vel,part->partfac);
1841 icu=find_ipocurve(psys->part->ipo,PART_EMIT_VEL);
1843 calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
1844 ptex.ivel*=icu->curval;
1847 VecMulf(vel,ptex.ivel);
1849 VECCOPY(pa->state.vel,vel);
1851 /* -location from emitter */
1852 VECCOPY(pa->state.co,loc);
1855 pa->state.rot[0]=1.0;
1856 pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0.0;
1859 /* create vector into which rotation is aligned */
1860 switch(part->rotmode){
1862 VecCopyf(rot_vec, nor);
1865 VecCopyf(rot_vec, vel);
1867 case PART_ROT_GLOB_X:
1868 case PART_ROT_GLOB_Y:
1869 case PART_ROT_GLOB_Z:
1870 rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
1875 VecCopyf(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
1879 /* create rotation quat */
1880 VecMulf(rot_vec,-1.0);
1881 vectoquat(rot_vec, OB_POSX, OB_POSZ, q2);
1883 /* randomize rotation quat */
1884 if(part->randrotfac!=0.0f)
1885 QuatInterpol(rot, q2, r_rot, part->randrotfac);
1889 /* rotation phase */
1890 phasefac = part->phasefac;
1891 if(part->randphasefac != 0.0f) /* abuse r_ave[0] as a random number */
1892 phasefac += part->randphasefac * pa->r_ave[0];
1893 VecRotToQuat(x_vec, phasefac*(float)M_PI, q_phase);
1895 /* combine base rotation & phase */
1896 QuatMul(pa->state.rot, rot, q_phase);
1899 /* -angular velocity */
1901 pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0;
1904 switch(part->avemode){
1906 VECCOPY(pa->state.ave,vel);
1909 VECCOPY(pa->state.ave,r_ave);
1912 Normalize(pa->state.ave);
1913 VecMulf(pa->state.ave,part->avefac);
1915 icu=find_ipocurve(psys->part->ipo,PART_EMIT_AVE);
1917 calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
1918 VecMulf(pa->state.ave,icu->curval);
1922 pa->dietime = pa->time + pa->lifetime;
1924 if(pa->time >= cfra)
1925 pa->alive = PARS_UNBORN;
1927 pa->state.time = cfra;
1930 pa->flag &= ~PARS_STICKY;
1932 static void reset_all_particles(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float dtime, float cfra, int from)
1935 int p, totpart=psys->totpart;
1936 float *vg_vel=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_VEL);
1937 float *vg_tan=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_TAN);
1938 float *vg_rot=psys_cache_vgroup(psmd->dm,psys,PSYS_VG_ROT);
1940 for(p=from, pa=psys->particles+from; p<totpart; p++, pa++)
1941 reset_particle(pa, psys, psmd, ob, dtime, cfra, vg_vel, vg_tan, vg_rot);
1946 /************************************************/
1947 /* Keyed particles */
1948 /************************************************/
1949 /* a bit of an unintuitive function :) counts objects in a keyed chain and returns 1 if some of them were selected (used in drawing) */
1950 int psys_count_keyed_targets(Object *ob, ParticleSystem *psys)
1952 ParticleSystem *kpsys=psys,*tpsys;
1953 ParticleSettings *tpart;
1954 Object *kob=ob,*tob;
1955 int select=ob->flag&SELECT;
1964 if((tpsys=BLI_findlink(&tob->particlesystem,kpsys->keyed_psys-1))){
1967 if(tpart->phystype==PART_PHYS_KEYED){
1969 for(base=lb.first;base;base=base->next){
1970 if(tob==base->object){
1971 fprintf(stderr,"Error: loop in keyed chain!\n");
1977 base=MEM_callocN(sizeof(Base), "keyed base");
1979 BLI_addtail(&lb,base);
1981 if(tob->flag&SELECT)
1985 tob=tpsys->keyed_ob;
1996 psys->totkeyed=totkeyed;
2001 static void set_keyed_keys(Object *ob, ParticleSystem *psys)
2004 ParticleSystem *kpsys = psys;
2007 int totpart = psys->totpart, i, k, totkeys = psys->totkeyed + 1;
2008 float prevtime, nexttime, keyedtime;
2010 /* no proper targets so let's clear and bail out */
2011 if(psys->totkeyed==0) {
2012 free_keyed_keys(psys);
2013 psys->flag &= ~PSYS_KEYED;
2017 if(totpart && psys->particles->totkey != totkeys) {
2018 free_keyed_keys(psys);
2020 psys->particles->keys = MEM_callocN(psys->totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
2021 psys->particles->totkey = totkeys;
2023 for(i=1, pa=psys->particles+1; i<totpart; i++,pa++){
2024 pa->keys = (pa-1)->keys + totkeys;
2025 pa->totkey = totkeys;
2029 psys->flag &= ~PSYS_KEYED;
2032 for(k=0; k<totkeys; k++) {
2033 for(i=0,pa=psys->particles; i<totpart; i++, pa++) {
2034 if(kpsys->totpart > 0)
2035 psys_get_particle_state(kob, kpsys, i%kpsys->totpart, pa->keys + k, 1);
2038 pa->keys->time = pa->time;
2039 else if(k==totkeys-1)
2040 (pa->keys + k)->time = pa->time + pa->lifetime;
2042 if(psys->flag & PSYS_KEYED_TIME){
2043 prevtime = (pa->keys + k - 1)->time;
2044 nexttime = pa->time + pa->lifetime;
2045 keyedtime = kpsys->part->keyed_time;
2046 (pa->keys + k)->time = (1.0f - keyedtime) * prevtime + keyedtime * nexttime;
2049 (pa->keys+k)->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
2052 if(kpsys->keyed_ob){
2053 kob = kpsys->keyed_ob;
2054 kpsys = BLI_findlink(&kob->particlesystem, kpsys->keyed_psys - 1);
2058 psys->flag |= PSYS_KEYED;
2060 /************************************************/
2062 /************************************************/
2063 static void push_reaction(Object* ob, ParticleSystem *psys, int pa_num, int event, ParticleKey *state)
2066 ParticleSystem *rpsys;
2067 ParticleSettings *rpart;
2069 ListBase *lb=&psys->effectors;
2070 ParticleEffectorCache *ec;
2071 ParticleReactEvent *re;
2073 if(lb->first) for(ec = lb->first; ec; ec= ec->next){
2074 if(ec->type & PSYS_EC_REACTOR){
2075 /* all validity checks already done in add_to_effectors */
2077 rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
2079 if(rpsys->part->reactevent==event){
2080 pa=psys->particles+pa_num;
2081 re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
2083 re->pa_num = pa_num;
2086 re->size = pa->size;
2087 copy_particle_key(&re->state,state,1);
2090 case PART_EVENT_DEATH:
2091 re->time=pa->dietime;
2093 case PART_EVENT_COLLIDE:
2094 re->time=state->time;
2096 case PART_EVENT_NEAR:
2097 re->time=state->time;
2101 BLI_addtail(&rpsys->reactevents, re);
2106 static void react_to_events(ParticleSystem *psys, int pa_num)
2108 ParticleSettings *part=psys->part;
2109 ParticleData *pa=psys->particles+pa_num;
2110 ParticleReactEvent *re=psys->reactevents.first;
2114 for(re=psys->reactevents.first; re; re=re->next){
2116 if(part->from==PART_FROM_PARTICLE){
2117 if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
2118 if(re->event==PART_EVENT_NEAR){
2119 ParticleData *tpa = re->psys->particles+re->pa_num;
2120 float pa_time=tpa->time + pa->foffset*tpa->lifetime;
2121 if(re->time >= pa_time){
2123 pa->dietime=pa->time+pa->lifetime;
2128 pa->dietime=pa->time+pa->lifetime;
2133 dist=VecLenf(pa->state.co, re->state.co);
2134 if(dist <= re->size){
2135 if(pa->alive==PARS_UNBORN){
2137 pa->dietime=pa->time+pa->lifetime;
2140 if(birth || part->flag&PART_REACT_MULTIPLE){
2142 VECSUB(vec,pa->state.co, re->state.co);
2144 VecMulf(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
2145 VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
2146 VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
2149 VecMulf(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
2154 void psys_get_reactor_target(Object *ob, ParticleSystem *psys, Object **target_ob, ParticleSystem **target_psys)
2158 tob=psys->target_ob;
2162 *target_psys=BLI_findlink(&tob->particlesystem,psys->target_psys-1);
2168 /************************************************/
2170 /************************************************/
2172 static void write_particles_to_cache(Object *ob, ParticleSystem *psys, int cfra)
2177 int i, totpart= psys->totpart;
2182 BKE_ptcache_id_from_particles(&pid, ob, psys);
2183 pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_WRITE, cfra);
2187 /* assuming struct consists of tightly packed floats */
2188 for(i=0, pa=psys->particles; i<totpart; i++, pa++)
2189 BKE_ptcache_file_write_floats(pf, (float*)&pa->state, sizeof(ParticleKey)/sizeof(float));
2191 BKE_ptcache_file_close(pf);
2194 static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra)
2199 int i, totpart= psys->totpart;
2204 BKE_ptcache_id_from_particles(&pid, ob, psys);
2205 pf= BKE_ptcache_file_open(&pid, PTCACHE_FILE_READ, cfra);
2209 /* assuming struct consists of tightly packed floats */
2210 for(i=0, pa=psys->particles; i<totpart; i++, pa++) {
2211 if(cfra!=pa->state.time)
2212 copy_particle_key(&pa->prev_state,&pa->state,1);
2213 if(!BKE_ptcache_file_read_floats(pf, (float*)&pa->state, sizeof(ParticleKey)/sizeof(float))) {
2214 BKE_ptcache_file_close(pf);
2219 BKE_ptcache_file_close(pf);
2224 /************************************************/
2226 /************************************************/
2227 static void do_texture_effector(Tex *tex, short mode, short is_2d, float nabla, short object, float *pa_co, float obmat[4][4], float force_val, float falloff, float *field)
2229 TexResult result[4];
2230 float tex_co[3], strength, mag_vec[3];
2232 if(tex==NULL) return;
2234 result[0].nor = result[1].nor = result[2].nor = result[3].nor = 0;
2236 strength= force_val*falloff;///(float)pow((double)distance,(double)power);
2238 VECCOPY(tex_co,pa_co);
2241 float fac=-Inpf(tex_co,obmat[2]);
2242 VECADDFAC(tex_co,tex_co,obmat[2],fac);
2246 VecSubf(tex_co,tex_co,obmat[3]);
2247 Mat4Mul3Vecfl(obmat,tex_co);
2250 hasrgb = multitex_ext(tex, tex_co, NULL,NULL, 1, result);
2252 if(hasrgb && mode==PFIELD_TEX_RGB){
2253 mag_vec[0]= (0.5f-result->tr)*strength;
2254 mag_vec[1]= (0.5f-result->tg)*strength;
2255 mag_vec[2]= (0.5f-result->tb)*strength;
2261 multitex_ext(tex, tex_co, NULL,NULL, 1, result+1);
2265 multitex_ext(tex, tex_co, NULL,NULL, 1, result+2);
2269 multitex_ext(tex, tex_co, NULL,NULL, 1, result+3);
2271 if(mode==PFIELD_TEX_GRAD || !hasrgb){ /* if we dont have rgb fall back to grad */
2272 mag_vec[0]= (result[0].tin-result[1].tin)*strength;
2273 mag_vec[1]= (result[0].tin-result[2].tin)*strength;
2274 mag_vec[2]= (result[0].tin-result[3].tin)*strength;
2276 else{ /*PFIELD_TEX_CURL*/
2277 float dbdy,dgdz,drdz,dbdx,dgdx,drdy;
2279 dbdy= result[2].tb-result[0].tb;
2280 dgdz= result[3].tg-result[0].tg;
2281 drdz= result[3].tr-result[0].tr;
2282 dbdx= result[1].tb-result[0].tb;
2283 dgdx= result[1].tg-result[0].tg;
2284 drdy= result[2].tr-result[0].tr;
2286 mag_vec[0]=(dbdy-dgdz)*strength;
2287 mag_vec[1]=(drdz-dbdx)*strength;
2288 mag_vec[2]=(dgdx-drdy)*strength;
2293 float fac=-Inpf(mag_vec,obmat[2]);
2294 VECADDFAC(mag_vec,mag_vec,obmat[2],fac);
2297 VecAddf(field,field,mag_vec);
2299 static void add_to_effectors(ListBase *lb, Object *ob, Object *obsrc, ParticleSystem *psys)
2301 ParticleEffectorCache *ec;
2302 PartDeflect *pd= ob->pd;
2305 if(pd && ob != obsrc){
2306 if(pd->forcefield == PFIELD_GUIDE) {
2307 if(ob->type==OB_CURVE) {
2308 Curve *cu= ob->data;
2309 if(cu->flag & CU_PATH) {
2310 if(cu->path==NULL || cu->path->data==NULL)
2311 makeDispListCurveTypes(ob, 0);
2312 if(cu->path && cu->path->data) {
2313 type |= PSYS_EC_EFFECTOR;
2318 else if(pd->forcefield)
2320 type |= PSYS_EC_EFFECTOR;
2324 if(pd && pd->deflect)
2325 type |= PSYS_EC_DEFLECT;
2328 ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
2333 ec->rng = rng_new(1);
2334 rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer()))); // use better seed
2336 BLI_addtail(lb, ec);
2341 /* add particles as different effectors */
2342 if(ob->particlesystem.first){
2343 ParticleSystem *epsys=ob->particlesystem.first;
2344 ParticleSettings *epart=0;
2347 for(i=0; epsys; epsys=epsys->next,i++){
2349 if(epsys!=psys || (psys->part->flag & PART_SELF_EFFECT)){
2352 if((epsys->part->pd && epsys->part->pd->forcefield)
2353 || (epsys->part->pd2 && epsys->part->pd2->forcefield))
2355 type=PSYS_EC_PARTICLE;
2358 if(epart->type==PART_REACTOR) {
2359 tob=epsys->target_ob;
2362 if(BLI_findlink(&tob->particlesystem,epsys->target_psys-1)==psys)
2363 type|=PSYS_EC_REACTOR;
2367 ec= MEM_callocN(sizeof(ParticleEffectorCache), "effector cache");
2371 ec->rng = rng_new(1);
2372 rng_srandom(ec->rng, (unsigned int)(ceil(PIL_check_seconds_timer())));
2374 BLI_addtail(lb, ec);
2382 static void psys_init_effectors_recurs(Object *ob, Object *obsrc, ParticleSystem *psys, ListBase *listb, int level)
2386 unsigned int layer= obsrc->lay;
2388 if(level>MAX_DUPLI_RECUR) return;
2390 if(ob->lay & layer) {
2391 if(ob->pd || ob->particlesystem.first)
2392 add_to_effectors(listb, ob, obsrc, psys);
2395 group= ob->dup_group;
2396 for(go= group->gobject.first; go; go= go->next)
2397 psys_init_effectors_recurs(go->ob, obsrc, psys, listb, level+1);
2402 void psys_init_effectors(Object *obsrc, Group *group, ParticleSystem *psys)
2404 ListBase *listb= &psys->effectors;
2407 listb->first=listb->last=0;
2412 for(go= group->gobject.first; go; go= go->next)
2413 psys_init_effectors_recurs(go->ob, obsrc, psys, listb, 0);
2416 for(base = G.scene->base.first; base; base= base->next)
2417 psys_init_effectors_recurs(base->object, obsrc, psys, listb, 0);
2421 void psys_end_effectors(ParticleSystem *psys)
2424 ec->ob is not valid in here anymore! - dg
2426 ListBase *lb=&psys->effectors;
2428 ParticleEffectorCache *ec;
2429 for(ec= lb->first; ec; ec= ec->next){
2431 MEM_freeN(ec->distances);
2434 MEM_freeN(ec->locations);
2437 MEM_freeN(ec->face_minmax);
2440 MEM_freeN(ec->vert_cos);
2443 BLI_kdtree_free(ec->tree);
2454 static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemModifierData *psmd, float cfra)
2456 ListBase *lb=&psys->effectors;
2457 ParticleEffectorCache *ec;
2458 ParticleSettings *part=psys->part;
2460 float vec2[3],loc[3],*co=0;
2461 int p,totpart,totvert;
2463 for(ec= lb->first; ec; ec= ec->next) {
2464 PartDeflect *pd= ec->ob->pd;
2467 if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE
2468 && part->phystype!=PART_PHYS_BOIDS) {
2471 where_on_path(ec->ob, 0.0, vec, vec2);
2473 Mat4MulVecfl(ec->ob->obmat,vec);
2474 Mat4Mul3Vecfl(ec->ob->obmat,vec2);
2476 QUATCOPY(ec->firstloc,vec);
2477 VECCOPY(ec->firstdir,vec2);
2479 totpart=psys->totpart;
2482 ec->distances=MEM_callocN(totpart*sizeof(float),"particle distances");
2483 ec->locations=MEM_callocN(totpart*3*sizeof(float),"particle locations");
2485 for(p=0,pa=psys->particles; p<totpart; p++, pa++){
2486 psys_particle_on_emitter(ob,psmd,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,loc,0,0,0,0,0);
2487 Mat4MulVecfl(ob->obmat,loc);
2488 ec->distances[p]=VecLenf(loc,vec);
2489 VECSUB(loc,loc,vec);
2490 VECCOPY(ec->locations+3*p,loc);
2494 else if(ec->type==PSYS_EC_PARTICLE){
2495 Object *eob = ec->ob;
2496 ParticleSystem *epsys = BLI_findlink(&eob->particlesystem,ec->psys_nbr);
2497 ParticleSettings *epart = epsys->part;
2499 int p, totepart = epsys->totpart;
2501 if(psys->part->phystype==PART_PHYS_BOIDS){
2506 if(pd->forcefield==PFIELD_FORCE && totepart){
2509 tree=BLI_kdtree_new(totepart);
2512 for(p=0, epa=epsys->particles; p<totepart; p++,epa++)
2513 if(epa->alive==PARS_ALIVE && psys_get_particle_state(eob,epsys,p,&state,0))
2514 BLI_kdtree_insert(tree, p, state.co, NULL);
2516 BLI_kdtree_balance(tree);
2521 else if(ec->type==PSYS_EC_DEFLECT) {
2522 CollisionModifierData *collmd = ( CollisionModifierData * ) ( modifiers_findByType ( ec->ob, eModifierType_Collision ) );
2524 collision_move_object(collmd, 1.0, 0.0);
2530 /* calculate forces that all effectors apply to a particle*/
2531 void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra)
2534 ParticleSystem *epsys;
2535 ParticleSettings *epart;
2539 ListBase *lb=&psys->effectors;
2540 ParticleEffectorCache *ec;
2541 float distance, vec_to_part[3];
2542 float falloff, charge = 0.0f;
2545 /* check all effector objects for interaction */
2547 if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){
2548 /* Only the charge of the effected particle is used for
2549 interaction, not fall-offs. If the fall-offs aren't the
2550 same this will be unphysical, but for animation this
2551 could be the wanted behavior. If you want physical
2552 correctness the fall-off should be spherical 2.0 anyways.
2554 charge = psys->part->pd->f_strength;
2556 if(psys->part->pd2 && psys->part->pd2->forcefield==PFIELD_CHARGE){
2557 charge += psys->part->pd2->f_strength;
2559 for(ec = lb->first; ec; ec= ec->next){
2561 if(ec->type & PSYS_EC_EFFECTOR){
2563 if(psys->part->type!=PART_HAIR && psys->part->integrator)
2564 where_is_object_time(eob,cfra);
2566 /* use center of object for distance calculus */
2567 VecSubf(vec_to_part, state->co, eob->obmat[3]);
2568 distance = VecLength(vec_to_part);
2570 falloff=effector_falloff(pd,eob->obmat[2],vec_to_part);
2573 ; /* don't do anything */
2574 else if(pd->forcefield==PFIELD_TEXTURE) {
2575 do_texture_effector(pd->tex, pd->tex_mode, pd->flag&PFIELD_TEX_2D, pd->tex_nabla,
2576 pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
2577 pd->f_strength, falloff, force_field);
2579 do_physical_effector(eob, state->co, pd->forcefield,pd->f_strength,distance,
2580 falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
2581 state->vel,force_field,pd->flag&PFIELD_PLANAR,ec->rng,pd->f_noise,charge,pa->size);
2584 if(ec->type & PSYS_EC_PARTICLE){
2586 epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
2589 totepart= epsys->totpart;
2594 if(pd && pd->forcefield==PFIELD_HARMONIC){
2595 /* every particle is mapped to only one harmonic effector particle */
2596 p= pa_no%epsys->totpart;
2603 epsys->lattice=psys_get_lattice(ob,psys);
2605 for(; p<totepart; p++){
2606 /* particle skips itself as effector */
2607 if(epsys==psys && p == pa_no) continue;
2609 epa = epsys->particles + p;
2611 if(psys_get_particle_state(eob,epsys,p,&estate,0)){
2612 VECSUB(vec_to_part, state->co, estate.co);
2613 distance = VecLength(vec_to_part);
2615 for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) {
2616 if(pd==NULL || pd->forcefield==0) continue;
2618 falloff=effector_falloff(pd,estate.vel,vec_to_part);
2621 ; /* don't do anything */
2623 do_physical_effector(eob, state->co, pd->forcefield,pd->f_strength,distance,
2624 falloff,epart->size,pd->f_damp,estate.vel,vec_to_part,
2625 state->vel,force_field,0, ec->rng, pd->f_noise,charge,pa->size);
2628 else if(pd && pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){
2629 /* first step after key release */
2630 psys_get_particle_state(eob,epsys,p,&estate,1);
2631 VECADD(vel,vel,estate.vel);
2632 /* TODO: add rotation handling here too */
2645 /************************************************/
2646 /* Newtonian physics */
2647 /************************************************/
2648 /* gathers all forces that effect particles and calculates a new state for the particle */
2649 static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, ParticleSystem *psys, ParticleSettings *part, float timestep, float dfra, float cfra)
2651 ParticleKey states[5], tkey;
2652 float force[3],tvel[3],dx[4][3],dv[4][3];
2653 float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=psys->cfra;
2656 /* maintain angular velocity */
2657 VECCOPY(pa->state.ave,pa->prev_state.ave);
2659 if(part->flag & PART_SIZEMASS)
2662 switch(part->integrator){
2663 case PART_INT_EULER:
2666 case PART_INT_MIDPOINT:
2674 copy_particle_key(states,&pa->state,1);
2676 for(i=0; i<steps; i++){
2677 force[0]=force[1]=force[2]=0.0;
2678 tvel[0]=tvel[1]=tvel[2]=0.0;
2680 if(part->type != PART_HAIR)
2681 do_effectors(pa_no,pa,states+i,ob,psys,states->co,force,tvel,dfra,fra);
2683 /* calculate air-particle interaction */
2684 if(part->dragfac!=0.0f){
2685 fac=-part->dragfac*pa->size*pa->size*VecLength(states[i].vel);
2686 VECADDFAC(force,force,states[i].vel,fac);
2689 /* brownian force */
2690 if(part->brownfac!=0.0){
2691 force[0]+=(BLI_frand()-0.5f)*part->brownfac;
2692 force[1]+=(BLI_frand()-0.5f)*part->brownfac;
2693 force[2]+=(BLI_frand()-0.5f)*part->brownfac;
2696 /* force to acceleration*/
2697 VecMulf(force,1.0f/pa_mass);
2699 /* add global acceleration (gravitation) */
2700 VECADD(force,force,part->acc);
2702 /* calculate next state */
2703 VECADD(states[i].vel,states[i].vel,tvel);
2705 switch(part->integrator){
2706 case PART_INT_EULER:
2707 VECADDFAC(pa->state.co,states->co,states->vel,dtime);
2708 VECADDFAC(pa->state.vel,states->vel,force,dtime);
2710 case PART_INT_MIDPOINT:
2712 VECADDFAC(states[1].co,states->co,states->vel,dtime*0.5f);
2713 VECADDFAC(states[1].vel,states->vel,force,dtime*0.5f);
2714 fra=psys->cfra+0.5f*dfra;
2717 VECADDFAC(pa->state.co,states->co,states[1].vel,dtime);
2718 VECADDFAC(pa->state.vel,states->vel,force,dtime);
2724 VECCOPY(dx[0],states->vel);
2725 VecMulf(dx[0],dtime);
2726 VECCOPY(dv[0],force);
2727 VecMulf(dv[0],dtime);
2729 VECADDFAC(states[1].co,states->co,dx[0],0.5f);
2730 VECADDFAC(states[1].vel,states->vel,dv[0],0.5f);
2731 fra=psys->cfra+0.5f*dfra;
2734 VECADDFAC(dx[1],states->vel,dv[0],0.5f);
2735 VecMulf(dx[1],dtime);
2736 VECCOPY(dv[1],force);
2737 VecMulf(dv[1],dtime);
2739 VECADDFAC(states[2].co,states->co,dx[1],0.5f);
2740 VECADDFAC(states[2].vel,states->vel,dv[1],0.5f);
2743 VECADDFAC(dx[2],states->vel,dv[1],0.5f);
2744 VecMulf(dx[2],dtime);
2745 VECCOPY(dv[2],force);
2746 VecMulf(dv[2],dtime);
2748 VECADD(states[3].co,states->co,dx[2]);
2749 VECADD(states[3].vel,states->vel,dv[2]);
2753 VECADD(dx[3],states->vel,dv[2]);
2754 VecMulf(dx[3],dtime);
2755 VECCOPY(dv[3],force);
2756 VecMulf(dv[3],dtime);
2758 VECADDFAC(pa->state.co,states->co,dx[0],1.0f/6.0f);
2759 VECADDFAC(pa->state.co,pa->state.co,dx[1],1.0f/3.0f);
2760 VECADDFAC(pa->state.co,pa->state.co,dx[2],1.0f/3.0f);
2761 VECADDFAC(pa->state.co,pa->state.co,dx[3],1.0f/6.0f);
2763 VECADDFAC(pa->state.vel,states->vel,dv[0],1.0f/6.0f);
2764 VECADDFAC(pa->state.vel,pa->state.vel,dv[1],1.0f/3.0f);
2765 VECADDFAC(pa->state.vel,pa->state.vel,dv[2],1.0f/3.0f);
2766 VECADDFAC(pa->state.vel,pa->state.vel,dv[3],1.0f/6.0f);
2772 /* damp affects final velocity */
2773 if(part->dampfac!=0.0)
2774 VecMulf(pa->state.vel,1.0f-part->dampfac);
2776 /* finally we do guides */
2777 time=(cfra-pa->time)/pa->lifetime;
2778 CLAMP(time,0.0,1.0);
2780 VECCOPY(tkey.co,pa->state.co);
2781 VECCOPY(tkey.vel,pa->state.vel);
2782 tkey.time=pa->state.time;
2784 if(part->type != PART_HAIR) {
2785 if(do_guide(&tkey,pa_no,time,&psys->effectors)) {
2786 VECCOPY(pa->state.co,tkey.co);
2787 /* guides don't produce valid velocity */
2788 VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
2789 VecMulf(pa->state.vel,1.0f/dtime);
2790 pa->state.time=tkey.time;
2794 static void rotate_particle(ParticleSettings *part, ParticleData *pa, float dfra, float timestep)
2796 float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep;
2798 if((part->flag & PART_ROT_DYN)==0){
2799 if(part->avemode==PART_AVE_SPIN){
2801 float len1 = VecLength(pa->prev_state.vel);
2802 float len2 = VecLength(pa->state.vel);
2804 if(len1==0.0f || len2==0.0f)
2805 pa->state.ave[0]=pa->state.ave[1]=pa->state.ave[2]=0.0f;
2807 Crossf(pa->state.ave,pa->prev_state.vel,pa->state.vel);
2808 Normalize(pa->state.ave);
2809 angle=Inpf(pa->prev_state.vel,pa->state.vel)/(len1*len2);
2810 VecMulf(pa->state.ave,saacos(angle)/dtime);
2813 VecRotToQuat(pa->state.vel,dtime*part->avefac,rot2);
2817 rotfac=VecLength(pa->state.ave);
2818 if(rotfac==0.0){ /* QuatOne (in VecRotToQuat) doesn't give unit quat [1,0,0,0]?? */
2820 rot1[1]=rot1[2]=rot1[3]=0;
2823 VecRotToQuat(pa->state.ave,rotfac*dtime,rot1);
2825 QuatMul(pa->state.rot,rot1,pa->prev_state.rot);
2826 QuatMul(pa->state.rot,rot2,pa->state.rot);
2828 /* keep rotation quat in good health */
2829 NormalQuat(pa->state.rot);
2832 /* convert from triangle barycentric weights to quad mean value weights */
2833 static void intersect_dm_quad_weights(float *v1, float *v2, float *v3, float *v4, float *w)
2835 float co[3], vert[4][3];
2837 VECCOPY(vert[0], v1);
2838 VECCOPY(vert[1], v2);
2839 VECCOPY(vert[2], v3);
2840 VECCOPY(vert[3], v4);
2842 co[0]= v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3];
2843 co[1]= v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3];
2844 co[2]= v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3];
2846 MeanValueWeights(vert, 4, co, w);
2849 /* check intersection with a derivedmesh */
2850 int psys_intersect_dm(Object *ob, DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_w,
2851 float *face_minmax, float *pa_minmax, float radius, float *ipoint)
2855 int i, totface, intersect=0;
2856 float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3],p_max[3];
2857 float cur_ipoint[3];
2860 psys_disable_all(ob);
2862 dm=mesh_get_derived_final(ob,0);
2864 mesh_get_derived_deform(ob,0);
2866 psys_enable_all(ob);
2875 INIT_MINMAX(p_min,p_max);
2876 DO_MINMAX(co1,p_min,p_max);
2877 DO_MINMAX(co2,p_min,p_max);
2880 VECCOPY(p_min,pa_minmax);
2881 VECCOPY(p_max,pa_minmax+3);
2884 totface=dm->getNumFaces(dm);
2885 mface=dm->getFaceDataArray(dm,CD_MFACE);
2886 mvert=dm->getVertDataArray(dm,CD_MVERT);
2888 /* lets intersect the faces */
2889 for(i=0; i<totface; i++,mface++){
2891 VECCOPY(v1,vert_cos+3*mface->v1);
2892 VECCOPY(v2,vert_cos+3*mface->v2);
2893 VECCOPY(v3,vert_cos+3*mface->v3);