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 *****
32 #include "BLI_storage.h" /* _LARGEFILE_SOURCE */
38 #include "MEM_guardedalloc.h"
40 #include "DNA_boid_types.h"
41 #include "DNA_particle_types.h"
42 #include "DNA_mesh_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_modifier_types.h"
45 #include "DNA_object_force.h"
46 #include "DNA_object_types.h"
47 #include "DNA_material_types.h"
48 #include "DNA_curve_types.h"
49 #include "DNA_group_types.h"
50 #include "DNA_scene_types.h"
51 #include "DNA_texture_types.h"
52 #include "DNA_ipo_types.h" // XXX old animation system stuff... to be removed!
53 #include "DNA_listBase.h"
56 #include "BLI_jitter.h"
58 #include "BLI_blenlib.h"
59 #include "BLI_kdtree.h"
60 #include "BLI_kdopbvh.h"
61 #include "BLI_listbase.h"
62 #include "BLI_threads.h"
65 #include "BKE_boids.h"
66 #include "BKE_cdderivedmesh.h"
67 #include "BKE_collision.h"
68 #include "BKE_displist.h"
69 #include "BKE_effect.h"
70 #include "BKE_particle.h"
71 #include "BKE_global.h"
72 #include "BKE_utildefines.h"
73 #include "BKE_DerivedMesh.h"
74 #include "BKE_object.h"
75 #include "BKE_material.h"
76 #include "BKE_cloth.h"
77 #include "BKE_depsgraph.h"
78 #include "BKE_lattice.h"
79 #include "BKE_pointcache.h"
81 #include "BKE_modifier.h"
82 #include "BKE_scene.h"
83 #include "BKE_bvhutils.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"
98 #define snprintf _snprintf
102 #endif // DISABLE_ELBEEM
104 /************************************************/
105 /* Reacting to system events */
106 /************************************************/
108 static int get_current_display_percentage(ParticleSystem *psys)
110 ParticleSettings *part=psys->part;
112 if(psys->renderdata || (part->child_nbr && part->childtype)
113 || (psys->pointcache->flag & PTCACHE_BAKING))
116 if(part->phystype==PART_PHYS_KEYED){
117 return psys->part->disp;
120 return psys->part->disp;
123 void psys_reset(ParticleSystem *psys, int mode)
127 if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
128 if(mode == PSYS_RESET_ALL || !(psys->flag & PSYS_EDITED)) {
129 psys_free_particles(psys);
133 psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
135 if(psys->edit && psys->free_edit) {
136 psys->free_edit(psys->edit);
138 psys->free_edit = NULL;
142 else if(mode == PSYS_RESET_CACHE_MISS) {
143 /* set all particles to be skipped */
145 pa->flag |= PARS_NO_DISP;
150 MEM_freeN(psys->child);
156 /* reset path cache */
157 psys_free_path_cache(psys, psys->edit);
159 /* reset point cache */
160 psys->pointcache->flag &= ~PTCACHE_SIMULATION_VALID;
161 psys->pointcache->simframe= 0;
164 static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
166 ParticleSystem *psys = sim->psys;
167 ParticleSettings *part = psys->part;
168 ParticleData *newpars = NULL;
169 BoidParticle *newboids = NULL;
171 int totpart, totsaved = 0;
174 if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT) {
175 totpart= part->grid_res;
176 totpart*=totpart*totpart;
179 totpart=part->totpart;
184 if(totpart && totpart != psys->totpart) {
185 newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
186 if(psys->part->phystype == PART_PHYS_BOIDS)
187 newboids= MEM_callocN(totpart*sizeof(BoidParticle), "boid particles");
189 if(psys->particles) {
190 totsaved=MIN2(psys->totpart,totpart);
193 memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
195 if(psys->particles->boid)
196 memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle));
199 if(psys->particles->keys)
200 MEM_freeN(psys->particles->keys);
202 if(psys->particles->boid)
203 MEM_freeN(psys->particles->boid);
205 for(p=0, pa=newpars; p<totsaved; p++, pa++) {
212 for(p=totsaved, pa=psys->particles+totsaved; p<psys->totpart; p++, pa++)
213 if(pa->hair) MEM_freeN(pa->hair);
215 MEM_freeN(psys->particles);
219 psys->particles=newpars;
220 psys->totpart=totpart;
224 pa->boid = newboids++;
229 MEM_freeN(psys->child);
235 static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys)
239 if(!psys->part->childtype)
242 if(psys->renderdata) {
243 nbr= psys->part->ren_child_nbr;
244 return get_render_child_particle_number(&scene->r, nbr);
247 return psys->part->child_nbr;
250 static int get_psys_tot_child(struct Scene *scene, ParticleSystem *psys)
252 return psys->totpart*get_psys_child_number(scene, psys);
255 static void alloc_child_particles(ParticleSystem *psys, int tot)
258 MEM_freeN(psys->child);
263 if(psys->part->childtype) {
266 psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
270 void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
272 /* use for building derived mesh mapping info:
274 node: the allocated links - total derived mesh element count
275 nodearray: the array of nodes aligned with the base mesh's elements, so
276 each original elements can reference its derived elements
278 Mesh *me= (Mesh*)ob->data;
281 /* CACHE LOCATIONS */
282 if(!dm->deformedOnly) {
283 /* Will use later to speed up subsurf/derivedmesh */
284 LinkNode *node, *nodedmelem, **nodearray;
285 int totdmelem, totelem, i, *origindex;
287 if(psys->part->from == PART_FROM_VERT) {
288 totdmelem= dm->getNumVerts(dm);
289 totelem= me->totvert;
290 origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX);
292 else { /* FROM_FACE/FROM_VOLUME */
293 totdmelem= dm->getNumFaces(dm);
294 totelem= me->totface;
295 origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX);
298 nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems");
299 nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array");
301 for(i=0, node=nodedmelem; i<totdmelem; i++, origindex++, node++) {
302 node->link= SET_INT_IN_POINTER(i);
304 if(*origindex != -1) {
305 if(nodearray[*origindex]) {
307 node->next = nodearray[*origindex];
308 nodearray[*origindex]= node;
311 nodearray[*origindex]= node;
315 /* cache the verts/faces! */
317 if(psys->part->from == PART_FROM_VERT) {
318 if(nodearray[pa->num])
319 pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
321 else { /* FROM_FACE/FROM_VOLUME */
322 /* Note that somtimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
323 * but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
324 pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
328 MEM_freeN(nodearray);
329 MEM_freeN(nodedmelem);
332 /* TODO PARTICLE, make the following line unnecessary, each function
333 * should know to use the num or num_dmcache, set the num_dmcache to
334 * an invalid value, just incase */
337 pa->num_dmcache = -1;
341 static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys)
344 float min[3], max[3], delta[3], d;
345 MVert *mv, *mvert = dm->getVertDataArray(dm,0);
346 int totvert=dm->getNumVerts(dm), from=psys->part->from;
347 int i, j, k, p, res=psys->part->grid_res, size[3], axis;
351 /* find bounding box of dm */
356 for(i=1; i<totvert; i++, mv++){
357 min[0]=MIN2(min[0],mv->co[0]);
358 min[1]=MIN2(min[1],mv->co[1]);
359 min[2]=MIN2(min[2],mv->co[2]);
361 max[0]=MAX2(max[0],mv->co[0]);
362 max[1]=MAX2(max[1],mv->co[1]);
363 max[2]=MAX2(max[2],mv->co[2]);
366 VECSUB(delta,max,min);
368 /* determine major axis */
369 axis = (delta[0]>=delta[1])?0:((delta[1]>=delta[2])?1:2);
371 d = delta[axis]/(float)res;
374 size[(axis+1)%3]=(int)ceil(delta[(axis+1)%3]/d);
375 size[(axis+2)%3]=(int)ceil(delta[(axis+2)%3]/d);
377 /* float errors grrr.. */
378 size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
379 size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
385 for(i=0,p=0,pa=psys->particles; i<res; i++){
386 for(j=0; j<res; j++){
387 for(k=0; k<res; k++,p++,pa++){
388 pa->fuv[0]=min[0]+(float)i*d;
389 pa->fuv[1]=min[1]+(float)j*d;
390 pa->fuv[2]=min[2]+(float)k*d;
391 pa->flag |= PARS_UNEXIST;
392 pa->loop=0; /* abused in volume calculation */
397 /* enable particles near verts/edges/faces/inside surface */
398 if(from==PART_FROM_VERT){
407 for(i=0,mv=mvert; i<totvert; i++,mv++){
408 sub_v3_v3v3(vec,mv->co,min);
412 (pa +((int)(vec[0]*(size[0]-1))*res
413 +(int)(vec[1]*(size[1]-1)))*res
414 +(int)(vec[2]*(size[2]-1)))->flag &= ~PARS_UNEXIST;
417 else if(ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)){
418 float co1[3], co2[3];
421 float v1[3], v2[3], v3[3], v4[4], lambda;
422 int a, a1, a2, a0mul, a1mul, a2mul, totface;
423 int amax= from==PART_FROM_FACE ? 3 : 1;
425 totface=dm->getNumFaces(dm);
426 mface=dm->getFaceDataArray(dm,CD_MFACE);
428 for(a=0; a<amax; a++){
429 if(a==0){ a0mul=res*res; a1mul=res; a2mul=1; }
430 else if(a==1){ a0mul=res; a1mul=1; a2mul=res*res; }
431 else{ a0mul=1; a1mul=res*res; a2mul=res; }
433 for(a1=0; a1<size[(a+1)%3]; a1++){
434 for(a2=0; a2<size[(a+2)%3]; a2++){
435 mface=dm->getFaceDataArray(dm,CD_MFACE);
437 pa=psys->particles + a1*a1mul + a2*a2mul;
438 VECCOPY(co1,pa->fuv);
441 co2[a]+=delta[a] + 0.001f*d;
444 /* lets intersect the faces */
445 for(i=0; i<totface; i++,mface++){
446 VECCOPY(v1,mvert[mface->v1].co);
447 VECCOPY(v2,mvert[mface->v2].co);
448 VECCOPY(v3,mvert[mface->v3].co);
450 if(isect_axial_line_tri_v3(a,co1, co2, v2, v3, v1, &lambda)){
451 if(from==PART_FROM_FACE)
452 (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
453 else /* store number of intersections */
454 (pa+(int)(lambda*size[a])*a0mul)->loop++;
458 VECCOPY(v4,mvert[mface->v4].co);
460 if(isect_axial_line_tri_v3(a,co1, co2, v4, v1, v3, &lambda)){
461 if(from==PART_FROM_FACE)
462 (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
464 (pa+(int)(lambda*size[a])*a0mul)->loop++;
469 if(from==PART_FROM_VOLUME){
472 for(i=0; i<size[0]; i++){
473 if(in || (pa+i*a0mul)->loop%2)
474 (pa+i*a0mul)->flag &= ~PARS_UNEXIST;
475 /* odd intersections == in->out / out->in */
476 /* even intersections -> in stays same */
477 in=(in + (pa+i*a0mul)->loop) % 2;
485 if(psys->part->flag & PART_GRID_INVERT){
486 for(i=0,pa=psys->particles; i<size[0]; i++){
487 for(j=0; j<size[1]; j++){
488 pa=psys->particles + res*(i*res + j);
489 for(k=0; k<size[2]; k++, pa++){
490 pa->flag ^= PARS_UNEXIST;
497 /* modified copy from rayshade.c */
498 static void hammersley_create(float *out, int n, int seed, float amount)
501 double p, t, offs[2];
504 rng = rng_new(31415926 + n + seed);
505 offs[0]= rng_getDouble(rng) + amount;
506 offs[1]= rng_getDouble(rng) + amount;
509 for (k = 0; k < n; k++) {
511 for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
512 if (kk & 1) /* kk mod 2 = 1 */
515 out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0);
516 out[2*k + 1]= fmod(t + offs[1], 1.0);
520 /* modified copy from effect.c */
521 static void init_mv_jit(float *jit, int num, int seed2, float amount)
524 float *jit2, x, rad1, rad2, rad3;
529 rad1= (float)(1.0/sqrt((float)num));
530 rad2= (float)(1.0/((float)num));
531 rad3= (float)sqrt((float)num)/((float)num);
533 rng = rng_new(31415926 + num + seed2);
536 for(i=0; i<num2; i+=2) {
538 jit[i]= x + amount*rad1*(0.5f - rng_getFloat(rng));
539 jit[i+1]= i/(2.0f*num) + amount*rad1*(0.5f - rng_getFloat(rng));
541 jit[i]-= (float)floor(jit[i]);
542 jit[i+1]-= (float)floor(jit[i+1]);
545 x -= (float)floor(x);
548 jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
550 for (i=0 ; i<4 ; i++) {
551 BLI_jitterate1(jit, jit2, num, rad1);
552 BLI_jitterate1(jit, jit2, num, rad1);
553 BLI_jitterate2(jit, jit2, num, rad2);
559 static void psys_uv_to_w(float u, float v, int quad, float *w)
561 float vert[4][3], co[3];
570 vert[0][0]= 0.0f; vert[0][1]= 0.0f; vert[0][2]= 0.0f;
571 vert[1][0]= 1.0f; vert[1][1]= 0.0f; vert[1][2]= 0.0f;
572 vert[2][0]= 1.0f; vert[2][1]= 1.0f; vert[2][2]= 0.0f;
579 vert[3][0]= 0.0f; vert[3][1]= 1.0f; vert[3][2]= 0.0f;
580 interp_weights_poly_v3( w,vert, 4, co);
583 interp_weights_poly_v3( w,vert, 3, co);
588 static int binary_search_distribution(float *sum, int n, float value)
590 int mid, low=0, high=n;
594 if(sum[mid] <= value && value <= sum[mid+1])
596 else if(sum[mid] > value)
598 else if(sum[mid] < value)
607 /* note: this function must be thread safe, for from == PART_FROM_CHILD */
608 #define ONLY_WORKING_WITH_PA_VERTS 0
609 static void psys_thread_distribute_particle(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
611 ParticleThreadContext *ctx= thread->ctx;
612 Object *ob= ctx->sim.ob;
613 DerivedMesh *dm= ctx->dm;
615 /* ParticleSettings *part= ctx->sim.psys->part; */
616 float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3], ornor1[3];
617 float cur_d, min_d, randu, randv;
619 int cfrom= ctx->cfrom;
620 int distr= ctx->distr;
621 int i, intersect, tot;
623 if(from == PART_FROM_VERT) {
624 /* TODO_PARTICLE - use original index */
625 pa->num= ctx->index[p];
627 pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
629 #if ONLY_WORKING_WITH_PA_VERTS
631 KDTreeNearest ptn[3];
634 psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
635 transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
636 maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
638 for(w=0; w<maxw; w++){
639 pa->verts[w]=ptn->num;
644 else if(from == PART_FROM_FACE || from == PART_FROM_VOLUME) {
647 pa->num = i = ctx->index[p];
648 mface = dm->getFaceData(dm,i,CD_MFACE);
652 ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
653 psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
656 case PART_DISTR_RAND:
657 randu= rng_getFloat(thread->rng);
658 randv= rng_getFloat(thread->rng);
659 psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
665 if(from==PART_FROM_VOLUME){
666 MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
668 tot=dm->getNumFaces(dm);
670 psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
673 mul_v3_fl(nor,-100.0);
680 for(i=0,mface=dm->getFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++){
681 if(i==pa->num) continue;
683 v1=mvert[mface->v1].co;
684 v2=mvert[mface->v2].co;
685 v3=mvert[mface->v3].co;
687 if(isect_line_tri_v3(co1, co2, v2, v3, v1, &cur_d, 0)){
690 pa->foffset=cur_d*50.0f; /* to the middle of volume */
695 v4=mvert[mface->v4].co;
697 if(isect_line_tri_v3(co1, co2, v4, v1, v3, &cur_d, 0)){
700 pa->foffset=cur_d*50.0f; /* to the middle of volume */
710 pa->foffset*= ctx->jit[2*(int)ctx->jitoff[i]];
712 case PART_DISTR_RAND:
713 pa->foffset*=BLI_frand();
718 else if(from == PART_FROM_PARTICLE) {
719 tpa=ctx->tpars+ctx->index[p];
720 pa->num=ctx->index[p];
721 pa->fuv[0]=tpa->fuv[0];
722 pa->fuv[1]=tpa->fuv[1];
723 /* abusing foffset a little for timing in near reaction */
724 pa->foffset=ctx->weight[ctx->index[p]];
725 ctx->weight[ctx->index[p]]+=ctx->maxweight;
727 else if(from == PART_FROM_CHILD) {
730 if(ctx->index[p] < 0) {
732 cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
733 cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
737 mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE);
739 randu= rng_getFloat(thread->rng);
740 randv= rng_getFloat(thread->rng);
741 psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
743 cpa->num = ctx->index[p];
746 KDTreeNearest ptn[10];
747 int w,maxw;//, do_seams;
748 float maxd,mind,dd,totw=0.0;
752 /*do_seams= (part->flag&PART_CHILD_SEAMS && ctx->seams);*/
754 psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,0,0,orco1,ornor1);
755 transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
756 //maxw = BLI_kdtree_find_n_nearest(ctx->tree,(do_seams)?10:4,orco1,ornor1,ptn);
757 maxw = BLI_kdtree_find_n_nearest(ctx->tree,4,orco1,ornor1,ptn);
759 maxd=ptn[maxw-1].dist;
763 /* the weights here could be done better */
764 for(w=0; w<maxw; w++){
765 parent[w]=ptn[w].index;
766 pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
773 // ParticleSeam *seam=ctx->seams;
774 // float temp[3],temp2[3],tan[3];
775 // float inp,cur_len,min_len=10000.0f;
776 // int min_seam=0, near_vert=0;
777 // /* find closest seam */
778 // for(i=0; i<ctx->totseam; i++, seam++){
779 // sub_v3_v3v3(temp,co1,seam->v0);
780 // inp=dot_v3v3(temp,seam->dir)/seam->length2;
782 // cur_len=len_v3v3(co1,seam->v0);
784 // else if(inp>1.0f){
785 // cur_len=len_v3v3(co1,seam->v1);
788 // copy_v3_v3(temp2,seam->dir);
789 // mul_v3_fl(temp2,inp);
790 // cur_len=len_v3v3(temp,temp2);
792 // if(cur_len<min_len){
795 // if(inp<0.0f) near_vert=-1;
796 // else if(inp>1.0f) near_vert=1;
800 // seam=ctx->seams+min_seam;
802 // copy_v3_v3(temp,seam->v0);
806 // sub_v3_v3v3(tan,co1,seam->v0);
808 // sub_v3_v3v3(tan,co1,seam->v1);
809 // copy_v3_v3(temp,seam->v1);
812 // normalize_v3(tan);
815 // copy_v3_v3(tan,seam->tan);
816 // sub_v3_v3v3(temp2,co1,temp);
817 // if(dot_v3v3(tan,temp2)<0.0f)
820 // for(w=0; w<maxw; w++){
821 // sub_v3_v3v3(temp2,ptn[w].co,temp);
822 // if(dot_v3v3(tan,temp2)<0.0f){
830 for(w=0,i=0; w<maxw && i<4; w++){
832 cpa->pa[i]=parent[w];
833 cpa->w[i]=pweight[w];
843 if(totw>0.0f) for(w=0; w<4; w++)
846 cpa->parent=cpa->pa[0];
851 static void *exec_distribution(void *data)
853 ParticleThread *thread= (ParticleThread*)data;
854 ParticleSystem *psys= thread->ctx->sim.psys;
859 if(thread->ctx->from == PART_FROM_CHILD) {
860 totpart= psys->totchild;
863 for(p=0; p<totpart; p++, cpa++) {
864 if(thread->ctx->skip) /* simplification skip */
865 rng_skip(thread->rng, 5*thread->ctx->skip[p]);
867 if((p+thread->num) % thread->tot == 0)
868 psys_thread_distribute_particle(thread, NULL, cpa, p);
869 else /* thread skip */
870 rng_skip(thread->rng, 5);
874 totpart= psys->totpart;
875 pa= psys->particles + thread->num;
876 for(p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot)
877 psys_thread_distribute_particle(thread, pa, NULL, p);
883 /* not thread safe, but qsort doesn't take userdata argument */
884 static int *COMPARE_ORIG_INDEX = NULL;
885 static int compare_orig_index(const void *p1, const void *p2)
887 int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
888 int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
892 else if(index1 == index2) {
893 /* this pointer comparison appears to make qsort stable for glibc,
894 * and apparently on solaris too, makes the renders reproducable */
906 /* creates a distribution of coordinates on a DerivedMesh */
908 /* 1. lets check from what we are emitting */
909 /* 2. now we know that we have something to emit from so */
910 /* let's calculate some weights */
911 /* 2.1 from even distribution */
912 /* 2.2 and from vertex groups */
913 /* 3. next we determine the indexes of emitting thing that */
914 /* the particles will have */
915 /* 4. let's do jitter if we need it */
916 /* 5. now we're ready to set the indexes & distributions to */
918 /* 6. and we're done! */
920 /* This is to denote functionality that does not yet work with mesh - only derived mesh */
921 static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
923 ParticleThreadContext *ctx= threads[0].ctx;
924 Object *ob= ctx->sim.ob;
925 ParticleSystem *psys= ctx->sim.psys;
927 ParticleData *pa=0, *tpars= 0;
928 ParticleSettings *part;
929 ParticleSystem *tpsys;
930 ParticleSeam *seams= 0;
931 ChildParticle *cpa=0;
933 DerivedMesh *dm= NULL;
935 int i, seed, p=0, totthread= threads[0].tot;
936 int no_distr=0, cfrom=0;
937 int tot=0, totpart, *index=0, children=0, totseam=0;
939 int jitlevel= 1, distr;
940 float *weight=0,*sum=0,*jitoff=0;
941 float cur, maxweight=0.0, tweight, totweight, co[3], nor[3], orco[3], ornor[3];
943 if(ob==0 || psys==0 || psys->part==0)
947 totpart=psys->totpart;
951 if (!finaldm->deformedOnly && !CustomData_has_layer( &finaldm->faceData, CD_ORIGINDEX ) ) {
952 // XXX error("Can't paint with the current modifier stack, disable destructive modifiers");
956 BLI_srandom(31415926 + psys->seed);
958 if(from==PART_FROM_CHILD){
959 distr=PART_DISTR_RAND;
960 if(part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
964 tree=BLI_kdtree_new(totpart);
966 for(p=0,pa=psys->particles; p<totpart; p++,pa++){
967 psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
968 transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
969 BLI_kdtree_insert(tree, p, orco, ornor);
972 BLI_kdtree_balance(tree);
974 totpart=get_psys_tot_child(scene, psys);
975 cfrom=from=PART_FROM_FACE;
977 //if(part->flag&PART_CHILD_SEAMS){
978 // MEdge *ed, *medge=dm->getEdgeDataArray(dm,CD_MEDGE);
979 // MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
980 // int totedge=dm->getNumEdges(dm);
982 // for(p=0, ed=medge; p<totedge; p++,ed++)
983 // if(ed->flag&ME_SEAM)
987 // ParticleSeam *cur_seam=seams=MEM_callocN(totseam*sizeof(ParticleSeam),"Child Distribution Seams");
988 // float temp[3],temp2[3];
990 // for(p=0, ed=medge; p<totedge; p++,ed++){
991 // if(ed->flag&ME_SEAM){
992 // copy_v3_v3(cur_seam->v0,(mvert+ed->v1)->co);
993 // copy_v3_v3(cur_seam->v1,(mvert+ed->v2)->co);
995 // sub_v3_v3v3(cur_seam->dir,cur_seam->v1,cur_seam->v0);
997 // cur_seam->length2=len_v3(cur_seam->dir);
998 // cur_seam->length2*=cur_seam->length2;
1000 // temp[0]=(float)((mvert+ed->v1)->no[0]);
1001 // temp[1]=(float)((mvert+ed->v1)->no[1]);
1002 // temp[2]=(float)((mvert+ed->v1)->no[2]);
1003 // temp2[0]=(float)((mvert+ed->v2)->no[0]);
1004 // temp2[1]=(float)((mvert+ed->v2)->no[1]);
1005 // temp2[2]=(float)((mvert+ed->v2)->no[2]);
1007 // add_v3_v3v3(cur_seam->nor,temp,temp2);
1008 // normalize_v3(cur_seam->nor);
1010 // cross_v3_v3v3(cur_seam->tan,cur_seam->dir,cur_seam->nor);
1012 // normalize_v3(cur_seam->tan);
1022 /* no need to figure out distribution */
1023 int child_nbr= get_psys_child_number(scene, psys);
1025 totpart= get_psys_tot_child(scene, psys);
1026 alloc_child_particles(psys, totpart);
1028 for(i=0; i<child_nbr; i++){
1029 for(p=0; p<psys->totpart; p++,cpa++){
1033 /* create even spherical distribution inside unit sphere */
1034 while(length>=1.0f){
1035 cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
1036 cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
1037 cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
1038 length=len_v3(cpa->fuv);
1049 dm= CDDM_from_mesh((Mesh*)ob->data, ob);
1051 /* special handling of grid distribution */
1052 if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
1053 distribute_particles_in_grid(dm,psys);
1058 /* we need orco for consistent distributions */
1059 DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
1063 if(from==PART_FROM_VERT){
1064 MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
1065 float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO);
1066 int totvert = dm->getNumVerts(dm);
1068 tree=BLI_kdtree_new(totvert);
1070 for(p=0; p<totvert; p++){
1072 VECCOPY(co,orcodata[p])
1073 transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1);
1076 VECCOPY(co,mv[p].co)
1077 BLI_kdtree_insert(tree,p,co,NULL);
1080 BLI_kdtree_balance(tree);
1086 case PART_FROM_VERT:
1087 tot = dm->getNumVerts(dm);
1089 case PART_FROM_VOLUME:
1090 case PART_FROM_FACE:
1091 tot = dm->getNumFaces(dm);
1093 case PART_FROM_PARTICLE:
1095 tob=psys->target_ob;
1099 if((tpsys=BLI_findlink(&tob->particlesystem,psys->target_psys-1))){
1100 tpars=tpsys->particles;
1110 fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n");
1112 for(p=0,cpa=psys->child; p<totpart; p++,cpa++){
1113 cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
1116 cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
1123 fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
1124 for(p=0,pa=psys->particles; p<totpart; p++,pa++){
1125 pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
1131 if(dm != finaldm) dm->release(dm);
1137 weight=MEM_callocN(sizeof(float)*tot, "particle_distribution_weights");
1138 index=MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
1139 sum=MEM_callocN(sizeof(float)*(tot+1), "particle_distribution_sum");
1140 jitoff=MEM_callocN(sizeof(float)*tot, "particle_distribution_jitoff");
1143 if((part->flag&PART_EDISTR || children) && ELEM(from,PART_FROM_PARTICLE,PART_FROM_VERT)==0){
1144 MVert *v1, *v2, *v3, *v4;
1145 float totarea=0.0, co1[3], co2[3], co3[3], co4[3];
1146 float (*orcodata)[3];
1148 orcodata= dm->getVertDataArray(dm, CD_ORCO);
1150 for(i=0; i<tot; i++){
1151 MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
1154 VECCOPY(co1, orcodata[mf->v1]);
1155 VECCOPY(co2, orcodata[mf->v2]);
1156 VECCOPY(co3, orcodata[mf->v3]);
1157 transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1);
1158 transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1);
1159 transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1);
1162 v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
1163 v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
1164 v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
1165 VECCOPY(co1, v1->co);
1166 VECCOPY(co2, v2->co);
1167 VECCOPY(co3, v3->co);
1172 VECCOPY(co4, orcodata[mf->v4]);
1173 transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
1176 v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
1177 VECCOPY(co4, v4->co);
1179 cur= area_quad_v3(co1, co2, co3, co4);
1182 cur= area_tri_v3(co1, co2, co3);
1191 for(i=0; i<tot; i++)
1192 weight[i] /= totarea;
1194 maxweight /= totarea;
1196 else if(from==PART_FROM_PARTICLE){
1197 float val=(float)tot/(float)totpart;
1198 for(i=0; i<tot; i++)
1203 float min=1.0f/(float)(MIN2(tot,totpart));
1204 for(i=0; i<tot; i++)
1210 if(ELEM3(from,PART_FROM_VERT,PART_FROM_FACE,PART_FROM_VOLUME)){
1211 float *vweight= psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
1214 if(from==PART_FROM_VERT) {
1216 weight[i]*=vweight[i];
1218 else { /* PART_FROM_FACE / PART_FROM_VOLUME */
1219 for(i=0;i<tot; i++){
1220 MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
1221 tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
1224 tweight += vweight[mf->v4];
1241 totweight += weight[i];
1243 if(totweight > 0.0f)
1244 totweight= 1.0f/totweight;
1248 sum[i+1]= sum[i]+weight[i]*totweight;
1250 if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
1253 for(p=0; p<totpart; p++) {
1255 index[p]= binary_search_distribution(sum, tot, pos);
1256 index[p]= MIN2(tot-1, index[p]);
1257 jitoff[index[p]]= pos;
1263 step= (totpart <= 1)? 0.5: 1.0/(totpart-1);
1264 pos= 1e-16f; /* tiny offset to avoid zero weight face */
1267 for(p=0; p<totpart; p++, pos+=step) {
1268 while((i < tot) && (pos > sum[i+1]))
1271 index[p]= MIN2(tot-1, i);
1273 /* avoid zero weight face */
1274 if(p == totpart-1 && weight[index[p]] == 0.0f)
1275 index[p]= index[p-1];
1277 jitoff[index[p]]= pos;
1283 /* for hair, sort by origindex, allows optimizations in rendering */
1284 /* however with virtual parents the children need to be in random order */
1285 if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0)) {
1286 if(from != PART_FROM_PARTICLE) {
1287 COMPARE_ORIG_INDEX = NULL;
1289 if(from == PART_FROM_VERT) {
1291 COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX);
1295 COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
1298 if(COMPARE_ORIG_INDEX) {
1299 qsort(index, totpart, sizeof(int), compare_orig_index);
1300 COMPARE_ORIG_INDEX = NULL;
1305 /* weights are no longer used except for FROM_PARTICLE, which needs them zeroed for indexing */
1306 if(from==PART_FROM_PARTICLE){
1307 for(i=0; i<tot; i++)
1312 if(distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
1313 jitlevel= part->userjit;
1316 jitlevel= totpart/tot;
1317 if(part->flag & PART_EDISTR) jitlevel*= 2; /* looks better in general, not very scietific */
1318 if(jitlevel<3) jitlevel= 3;
1321 jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
1323 /* for small amounts of particles we use regular jitter since it looks
1324 * a bit better, for larger amounts we switch to hammersley sequence
1325 * because it is much faster */
1327 init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
1329 hammersley_create(jit, jitlevel+1, psys->seed, part->jitfac);
1330 BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
1336 ctx->totseam= totseam;
1337 ctx->sim.psys= psys;
1340 ctx->jitlevel= jitlevel;
1341 ctx->jitoff= jitoff;
1342 ctx->weight= weight;
1343 ctx->maxweight= maxweight;
1344 ctx->from= (children)? PART_FROM_CHILD: from;
1351 totpart= psys_render_simplify_distribution(ctx, totpart);
1352 alloc_child_particles(psys, totpart);
1355 if(!children || psys->totchild < 10000)
1358 seed= 31415926 + ctx->sim.psys->seed;
1359 for(i=0; i<totthread; i++) {
1360 threads[i].rng= rng_new(seed);
1361 threads[i].tot= totthread;
1367 static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
1369 DerivedMesh *finaldm = sim->psmd->dm;
1371 ParticleThread *pthreads;
1372 ParticleThreadContext *ctx;
1375 pthreads= psys_threads_create(sim);
1377 if(!psys_threads_init_distribution(pthreads, sim->scene, finaldm, from)) {
1378 psys_threads_free(pthreads);
1382 totthread= pthreads[0].tot;
1384 BLI_init_threads(&threads, exec_distribution, totthread);
1386 for(i=0; i<totthread; i++)
1387 BLI_insert_thread(&threads, &pthreads[i]);
1389 BLI_end_threads(&threads);
1392 exec_distribution(&pthreads[0]);
1394 psys_calc_dmcache(sim->ob, finaldm, sim->psys);
1396 ctx= pthreads[0].ctx;
1397 if(ctx->dm != finaldm)
1398 ctx->dm->release(ctx->dm);
1400 psys_threads_free(pthreads);
1403 /* ready for future use, to emit particles without geometry */
1404 static void distribute_particles_on_shape(ParticleSimulationData *sim, int from)
1406 ParticleSystem *psys = sim->psys;
1409 fprintf(stderr,"Shape emission not yet possible!\n");
1412 pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
1417 static void distribute_particles(ParticleSimulationData *sim, int from)
1424 distribute_particles_on_dm(sim, from);
1429 distribute_particles_on_shape(sim, from);
1432 ParticleSystem *psys = sim->psys;
1435 fprintf(stderr,"Particle distribution error!\n");
1438 pa->fuv[0]=pa->fuv[1]=pa->fuv[2]=pa->fuv[3]= 0.0;
1445 /* threaded child particle distribution and path caching */
1446 ParticleThread *psys_threads_create(ParticleSimulationData *sim)
1448 ParticleThread *threads;
1449 ParticleThreadContext *ctx;
1452 if(sim->scene->r.mode & R_FIXED_THREADS)
1453 totthread= sim->scene->r.threads;
1455 totthread= BLI_system_thread_count();
1457 threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
1458 ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
1461 ctx->dm= ctx->sim.psmd->dm;
1462 ctx->ma= give_current_material(sim->ob, sim->psys->part->omat);
1464 memset(threads, 0, sizeof(ParticleThread)*totthread);
1466 for(i=0; i<totthread; i++) {
1467 threads[i].ctx= ctx;
1469 threads[i].tot= totthread;
1475 void psys_threads_free(ParticleThread *threads)
1477 ParticleThreadContext *ctx= threads[0].ctx;
1478 int i, totthread= threads[0].tot;
1482 MEM_freeN(ctx->vg_length);
1484 MEM_freeN(ctx->vg_clump);
1486 MEM_freeN(ctx->vg_kink);
1488 MEM_freeN(ctx->vg_rough1);
1490 MEM_freeN(ctx->vg_rough2);
1492 MEM_freeN(ctx->vg_roughe);
1494 if(ctx->sim.psys->lattice){
1495 end_latt_deform(ctx->sim.psys->lattice);
1496 ctx->sim.psys->lattice= NULL;
1500 if(ctx->jit) MEM_freeN(ctx->jit);
1501 if(ctx->jitoff) MEM_freeN(ctx->jitoff);
1502 if(ctx->weight) MEM_freeN(ctx->weight);
1503 if(ctx->index) MEM_freeN(ctx->index);
1504 if(ctx->skip) MEM_freeN(ctx->skip);
1505 if(ctx->seams) MEM_freeN(ctx->seams);
1506 //if(ctx->vertpart) MEM_freeN(ctx->vertpart);
1507 BLI_kdtree_free(ctx->tree);
1510 for(i=0; i<totthread; i++) {
1512 rng_free(threads[i].rng);
1513 if(threads[i].rng_path)
1514 rng_free(threads[i].rng_path);
1521 /* set particle parameters that don't change during particle's life */
1522 void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
1524 ParticleSettings *part = sim->psys->part;
1525 ParticleTexture ptex;
1527 //IpoCurve *icu=0; // XXX old animation system
1530 totpart=sim->psys->totpart;
1532 ptex.life=ptex.size=ptex.exist=ptex.length=1.0;
1533 ptex.time=(float)p/(float)totpart;
1535 BLI_srandom(sim->psys->seed + p + 125);
1537 if(part->from!=PART_FROM_PARTICLE && part->type!=PART_FLUID){
1538 ma=give_current_material(sim->ob,part->omat);
1540 /* TODO: needs some work to make most blendtypes generally usefull */
1541 psys_get_texture(sim,ma,pa,&ptex,MAP_PA_INIT);
1544 pa->lifetime= part->lifetime*ptex.life;
1546 if(part->type==PART_HAIR)
1548 //else if(part->type==PART_REACTOR && (part->flag&PART_REACT_STA_END)==0)
1549 // pa->time= 300000.0f; /* max frame */
1551 //icu=find_ipocurve(psys->part->ipo,PART_EMIT_TIME);
1553 // calc_icu(icu,100*ptex.time);
1554 // ptex.time=icu->curval;
1557 pa->time= part->sta + (part->end - part->sta)*ptex.time;
1561 if(part->type==PART_HAIR){
1562 pa->lifetime=100.0f;
1565 #if 0 // XXX old animation system
1566 icu=find_ipocurve(psys->part->ipo,PART_EMIT_LIFE);
1568 calc_icu(icu,100*ptex.time);
1569 pa->lifetime*=icu->curval;
1571 #endif // XXX old animation system
1573 if(part->randlife!=0.0)
1574 pa->lifetime*= 1.0f - part->randlife * BLI_frand();
1577 pa->dietime= pa->time+pa->lifetime;
1579 if(part->type!=PART_HAIR && part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
1580 if(ptex.exist < BLI_frand())
1581 pa->flag |= PARS_UNEXIST;
1583 pa->flag &= ~PARS_UNEXIST;
1587 /* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */
1588 /* usage other than straight after distribute has to handle this index by itself - jahka*/
1589 //pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */
1591 static void initialize_all_particles(ParticleSimulationData *sim)
1593 //IpoCurve *icu=0; // XXX old animation system
1594 ParticleSystem *psys = sim->psys;
1598 initialize_particle(sim, pa, p);
1600 if(psys->part->type != PART_FLUID) {
1601 #if 0 // XXX old animation system
1602 icu=find_ipocurve(psys->part->ipo,PART_EMIT_FREQ);
1604 float time=psys->part->sta, end=psys->part->end;
1605 float v1, v2, a=0.0f, t1,t2, d;
1613 if(v1<0.0f) v1=0.0f;
1615 calc_icu(icu,time+1.0f);
1617 if(v2<0.0f) v2=0.0f;
1619 for(p=0, pa=psys->particles; p<totpart && time<end; p++, pa++){
1620 while(a+0.5f*(v1+v2) < (float)(p+1) && time<end){
1624 calc_icu(icu,time+1.0f);
1629 pa->time=time+((float)(p+1)-a)/v1;
1632 d=(float)sqrt(v1*v1-2.0f*(v2-v1)*(a-(float)(p+1)));
1636 /* the root between 0-1 is the correct one */
1637 if(t1>0.0f && t1<=1.0f)
1644 pa->dietime = pa->time+pa->lifetime;
1645 pa->flag &= ~PARS_UNEXIST;
1647 for(; p<totpart; p++, pa++){
1648 pa->flag |= PARS_UNEXIST;
1651 #endif // XXX old animation system
1654 /* sets particle to the emitter surface with initial velocity & rotation */
1655 void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
1657 Object *ob = sim->ob;
1658 ParticleSystem *psys = sim->psys;
1659 ParticleSettings *part;
1660 ParticleTexture ptex;
1662 //IpoCurve *icu=0; // XXX old animation system
1663 float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
1664 float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3]={0.0,0.0,0.0};
1665 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};
1666 float q_phase[4], r_phase;
1667 int p = pa - psys->particles;
1672 /* we need to get every random even if they're not used so that they don't effect eachother */
1673 r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
1674 r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
1675 r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
1677 r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
1678 r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
1679 r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
1681 r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
1682 r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
1683 r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
1684 r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
1685 normalize_qt(r_rot);
1687 r_phase = PSYS_FRAND(p + 20);
1689 if(part->from==PART_FROM_PARTICLE){
1690 ParticleSimulationData tsim = {sim->scene, psys->target_ob ? psys->target_ob : ob, NULL, NULL};
1693 tsim.psys = BLI_findlink(&tsim.ob->particlesystem, sim->psys->target_psys-1);
1695 state.time = pa->time;
1697 memset(&state, 0, sizeof(state));
1699 psys_get_particle_state(&tsim, pa->num, &state, 1);
1700 psys_get_from_key(&state, loc, nor, rot, 0);
1702 mul_qt_v3(rot, vtan);
1703 mul_qt_v3(rot, utan);
1705 VECCOPY(p_vel, state.vel);
1706 speed=normalize_v3(p_vel);
1707 mul_v3_fl(p_vel, dot_v3v3(r_vel, p_vel));
1708 VECSUB(p_vel, r_vel, p_vel);
1709 normalize_v3(p_vel);
1710 mul_v3_fl(p_vel, speed);
1712 VECCOPY(pa->fuv, loc); /* abusing pa->fuv (not used for "from particle") for storing emit location */
1715 /* get precise emitter matrix if particle is born */
1716 if(part->type!=PART_HAIR && pa->time < cfra && pa->time >= sim->psys->cfra)
1717 where_is_object_time(sim->scene, sim->ob, pa->time);
1719 /* get birth location from object */
1720 if(part->tanfac!=0.0)
1721 psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
1723 psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
1725 /* get possible textural influence */
1726 psys_get_texture(sim, give_current_material(sim->ob,part->omat), pa, &ptex, MAP_PA_IVEL);
1728 //if(vg_vel && pa->num != -1)
1729 // ptex.ivel*=psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_vel);
1731 /* particles live in global space so */
1732 /* let's convert: */
1734 mul_m4_v3(ob->obmat,loc);
1737 mul_mat3_m4_v3(ob->obmat,nor);
1741 if(part->tanfac!=0.0){
1742 //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
1744 mul_v3_fl(vtan,-(float)cos(M_PI*(part->tanphase+phase)));
1745 fac=-(float)sin(M_PI*(part->tanphase+phase));
1746 VECADDFAC(vtan,vtan,utan,fac);
1748 mul_mat3_m4_v3(ob->obmat,vtan);
1751 mul_v3_fl(utan,dot_v3v3(vtan,nor));
1752 VECSUB(vtan,vtan,utan);
1759 if(part->randfac!=0.0){
1760 mul_mat3_m4_v3(ob->obmat,r_vel);
1761 normalize_v3(r_vel);
1764 /* -angular velocity */
1765 if(part->avemode==PART_AVE_RAND){
1766 mul_mat3_m4_v3(ob->obmat,r_ave);
1767 normalize_v3(r_ave);
1771 if(part->randrotfac != 0.0f){
1772 mat4_to_quat(rot,ob->obmat);
1773 mul_qt_qtqt(r_rot,r_rot,rot);
1777 if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
1778 BoidParticle *bpa = pa->boid;
1779 float dvec[3], q[4], mat[3][3];
1781 VECCOPY(pa->state.co,loc);
1783 /* boids don't get any initial velocity */
1784 pa->state.vel[0]=pa->state.vel[1]=pa->state.vel[2]=0.0f;
1786 /* boids store direction in ave */
1787 if(fabs(nor[2])==1.0f) {
1788 sub_v3_v3v3(pa->state.ave, loc, ob->obmat[3]);
1789 normalize_v3(pa->state.ave);
1792 VECCOPY(pa->state.ave, nor);
1794 /* and gravity in r_ve */
1795 bpa->gravity[0] = bpa->gravity[1] = 0.0f;
1796 bpa->gravity[2] = -1.0f;
1797 if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
1798 && sim->scene->physics_settings.gravity[2]!=0.0f)
1799 bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
1801 /* calculate rotation matrix */
1802 project_v3_v3v3(dvec, r_vel, pa->state.ave);
1803 sub_v3_v3v3(mat[0], pa->state.ave, dvec);
1804 normalize_v3(mat[0]);
1805 VECCOPY(mat[2], r_vel);
1806 mul_v3_fl(mat[2], -1.0f);
1807 normalize_v3(mat[2]);
1808 cross_v3_v3v3(mat[1], mat[2], mat[0]);
1810 /* apply rotation */
1811 mat3_to_quat_is_ok( q,mat);
1812 copy_qt_qt(pa->state.rot, q);
1814 bpa->data.health = part->boids->health;
1815 bpa->data.mode = eBoidMode_InAir;
1816 bpa->data.state_id = ((BoidState*)part->boids->states.first)->id;
1817 bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
1820 /* conversion done so now we apply new: */
1821 /* -velocity from: */
1825 VECSUB(vel,pa->state.vel,pa->prev_state.vel);
1828 /* *emitter velocity */
1829 if(dtime!=0.0 && part->obfac!=0.0){
1830 VECSUB(vel,loc,pa->state.co);
1831 mul_v3_fl(vel,part->obfac/dtime);
1834 /* *emitter normal */
1835 if(part->normfac!=0.0)
1836 VECADDFAC(vel,vel,nor,part->normfac);
1838 /* *emitter tangent */
1839 if(sim->psmd && part->tanfac!=0.0)
1840 VECADDFAC(vel,vel,vtan,part->tanfac);
1841 //VECADDFAC(vel,vel,vtan,part->tanfac*(vg_tan?psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_tan):1.0f));
1843 /* *emitter object orientation */
1844 if(part->ob_vel[0]!=0.0) {
1845 VECCOPY(vec, ob->obmat[0]);
1847 VECADDFAC(vel, vel, vec, part->ob_vel[0]);
1849 if(part->ob_vel[1]!=0.0) {
1850 VECCOPY(vec, ob->obmat[1]);
1852 VECADDFAC(vel, vel, vec, part->ob_vel[1]);
1854 if(part->ob_vel[2]!=0.0) {
1855 VECCOPY(vec, ob->obmat[2]);
1857 VECADDFAC(vel, vel, vec, part->ob_vel[2]);
1864 if(part->randfac!=0.0)
1865 VECADDFAC(vel,vel,r_vel,part->randfac);
1868 if(part->partfac!=0.0)
1869 VECADDFAC(vel,vel,p_vel,part->partfac);
1871 //icu=find_ipocurve(psys->part->ipo,PART_EMIT_VEL);
1873 // calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
1874 // ptex.ivel*=icu->curval;
1877 mul_v3_fl(vel,ptex.ivel);
1879 VECCOPY(pa->state.vel,vel);
1881 /* -location from emitter */
1882 VECCOPY(pa->state.co,loc);
1885 pa->state.rot[0]=1.0;
1886 pa->state.rot[1]=pa->state.rot[2]=pa->state.rot[3]=0.0;
1889 /* create vector into which rotation is aligned */
1890 switch(part->rotmode){
1892 copy_v3_v3(rot_vec, nor);
1895 copy_v3_v3(rot_vec, vel);
1897 case PART_ROT_GLOB_X:
1898 case PART_ROT_GLOB_Y:
1899 case PART_ROT_GLOB_Z:
1900 rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
1905 copy_v3_v3(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
1909 /* create rotation quat */
1911 vec_to_quat( q2,rot_vec, OB_POSX, OB_POSZ);
1913 /* randomize rotation quat */
1914 if(part->randrotfac!=0.0f)
1915 interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
1919 /* rotation phase */
1920 phasefac = part->phasefac;
1921 if(part->randphasefac != 0.0f)
1922 phasefac += part->randphasefac * r_phase;
1923 axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI);
1925 /* combine base rotation & phase */
1926 mul_qt_qtqt(pa->state.rot, rot, q_phase);
1929 /* -angular velocity */
1931 pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0;
1934 switch(part->avemode){
1936 VECCOPY(pa->state.ave,vel);
1939 VECCOPY(pa->state.ave,r_ave);
1942 normalize_v3(pa->state.ave);
1943 mul_v3_fl(pa->state.ave,part->avefac);
1945 //icu=find_ipocurve(psys->part->ipo,PART_EMIT_AVE);
1947 // calc_icu(icu,100*((pa->time-part->sta)/(part->end-part->sta)));
1948 // mul_v3_fl(pa->state.ave,icu->curval);
1953 pa->dietime = pa->time + pa->lifetime;
1956 pa->alive = PARS_UNBORN;
1957 else if(pa->dietime <= cfra)
1958 pa->alive = PARS_DEAD;
1960 pa->alive = PARS_ALIVE;
1962 pa->state.time = cfra;
1964 static void reset_all_particles(ParticleSimulationData *sim, float dtime, float cfra, int from)
1967 int p, totpart=sim->psys->totpart;
1968 //float *vg_vel=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_VEL);
1969 //float *vg_tan=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_TAN);
1970 //float *vg_rot=psys_cache_vgroup(sim->psmd->dm,sim->psys,PSYS_VG_ROT);
1972 for(p=from, pa=sim->psys->particles+from; p<totpart; p++, pa++)
1973 reset_particle(sim, pa, dtime, cfra);
1976 // MEM_freeN(vg_vel);
1978 /************************************************/
1979 /* Particle targets */
1980 /************************************************/
1981 ParticleSystem *psys_get_target_system(Object *ob, ParticleTarget *pt)
1983 ParticleSystem *psys = NULL;
1985 if(pt->ob == NULL || pt->ob == ob)
1986 psys = BLI_findlink(&ob->particlesystem, pt->psys-1);
1988 psys = BLI_findlink(&pt->ob->particlesystem, pt->psys-1);
1991 pt->flag |= PTARGET_VALID;
1993 pt->flag &= ~PTARGET_VALID;
1997 /************************************************/
1998 /* Keyed particles */
1999 /************************************************/
2000 /* Counts valid keyed targets */
2001 void psys_count_keyed_targets(ParticleSimulationData *sim)
2003 ParticleSystem *psys = sim->psys, *kpsys;
2004 ParticleTarget *pt = psys->targets.first;
2008 for(; pt; pt=pt->next) {
2009 kpsys = psys_get_target_system(sim->ob, pt);
2011 if(kpsys && kpsys->totpart) {
2012 psys->totkeyed += keys_valid;
2013 if(psys->flag & PSYS_KEYED_TIMING && pt->duration != 0.0f)
2014 psys->totkeyed += 1;
2021 psys->totkeyed *= psys->flag & PSYS_KEYED_TIMING ? 1 : psys->part->keyed_loops;
2024 static void set_keyed_keys(ParticleSimulationData *sim)
2026 ParticleSystem *psys = sim->psys;
2027 ParticleSimulationData ksim = {sim->scene, NULL, NULL, NULL};
2031 int totpart = psys->totpart, k, totkeys = psys->totkeyed;
2033 /* no proper targets so let's clear and bail out */
2034 if(psys->totkeyed==0) {
2035 free_keyed_keys(psys);
2036 psys->flag &= ~PSYS_KEYED;
2040 if(totpart && psys->particles->totkey != totkeys) {
2041 free_keyed_keys(psys);
2043 key = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
2047 pa->totkey = totkeys;
2052 psys->flag &= ~PSYS_KEYED;
2055 pt = psys->targets.first;
2056 for(k=0; k<totkeys; k++) {
2057 ksim.ob = pt->ob ? pt->ob : sim->ob;
2058 ksim.psys = BLI_findlink(&ksim.ob->particlesystem, pt->psys - 1);
2062 key->time = -1.0; /* use current time */
2064 psys_get_particle_state(&ksim, p%ksim.psys->totpart, key, 1);
2066 if(psys->flag & PSYS_KEYED_TIMING){
2067 key->time = pa->time + pt->time;
2068 if(pt->duration != 0.0f && k+1 < totkeys) {
2069 copy_particle_key(key+1, key, 1);
2070 (key+1)->time = pa->time + pt->time + pt->duration;
2073 else if(totkeys > 1)
2074 key->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
2076 key->time = pa->time;
2079 if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f)
2082 pt = (pt->next && pt->next->flag & PTARGET_VALID)? pt->next : psys->targets.first;
2085 psys->flag |= PSYS_KEYED;
2087 /************************************************/
2089 /************************************************/
2090 //static void push_reaction(ParticleSimulationData *sim, int pa_num, int event, ParticleKey *state)
2093 // ParticleSystem *rpsys;
2094 // ParticleSettings *rpart;
2095 // ParticleData *pa;
2096 // ListBase *lb=&sim->psys->effectors;
2097 // ParticleEffectorCache *ec;
2098 // ParticleReactEvent *re;
2100 // if(lb->first) for(ec = lb->first; ec; ec= ec->next){
2101 // if(ec->type & PSYS_EC_REACTOR){
2102 // /* all validity checks already done in add_to_effectors */
2104 // rpsys=BLI_findlink(&rob->particlesystem,ec->psys_nbr);
2105 // rpart=rpsys->part;
2106 // if(rpsys->part->reactevent==event){
2107 // pa=sim->psys->particles+pa_num;
2108 // re= MEM_callocN(sizeof(ParticleReactEvent), "react event");
2110 // re->pa_num = pa_num;
2111 // re->ob = sim->ob;
2112 // re->psys = sim->psys;
2113 // re->size = pa->size;
2114 // copy_particle_key(&re->state,state,1);
2117 // case PART_EVENT_DEATH:
2118 // re->time=pa->dietime;
2120 // case PART_EVENT_COLLIDE:
2121 // re->time=state->time;
2123 // case PART_EVENT_NEAR:
2124 // re->time=state->time;
2128 // BLI_addtail(&rpsys->reactevents, re);
2133 //static void react_to_events(ParticleSystem *psys, int pa_num)
2135 // ParticleSettings *part=psys->part;
2136 // ParticleData *pa=psys->particles+pa_num;
2137 // ParticleReactEvent *re=psys->reactevents.first;
2141 // for(re=psys->reactevents.first; re; re=re->next){
2143 // if(part->from==PART_FROM_PARTICLE){
2144 // if(pa->num==re->pa_num && pa->alive==PARS_UNBORN){
2145 // if(re->event==PART_EVENT_NEAR){
2146 // ParticleData *tpa = re->psys->particles+re->pa_num;
2147 // float pa_time=tpa->time + pa->foffset*tpa->lifetime;
2148 // if(re->time >= pa_time){
2149 // pa->time=pa_time;
2150 // pa->dietime=pa->time+pa->lifetime;
2154 // pa->time=re->time;
2155 // pa->dietime=pa->time+pa->lifetime;
2160 // dist=len_v3v3(pa->state.co, re->state.co);
2161 // if(dist <= re->size){
2162 // if(pa->alive==PARS_UNBORN){
2163 // pa->time=re->time;
2164 // pa->dietime=pa->time+pa->lifetime;
2167 // if(birth || part->flag&PART_REACT_MULTIPLE){
2169 // VECSUB(vec,pa->state.co, re->state.co);
2171 // mul_v3_fl(vec,(float)pow(1.0f-dist/re->size,part->reactshape));
2172 // VECADDFAC(pa->state.vel,pa->state.vel,vec,part->reactfac);
2173 // VECADDFAC(pa->state.vel,pa->state.vel,re->state.vel,part->partfac);
2176 // mul_v3_fl(pa->state.vel,(float)pow(1.0f-dist/re->size,part->reactshape));
2181 //void psys_get_reactor_target(ParticleSimulationData *sim, Object **target_ob, ParticleSystem **target_psys)
2185 // tob = sim->psys->target_ob ? sim->psys->target_ob : sim->ob;
2187 // *target_psys = BLI_findlink(&tob->particlesystem, sim->psys->target_psys-1);
2193 /************************************************/
2195 /************************************************/
2196 void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
2198 PointCache *cache = psys->pointcache;
2201 if((cache->flag & PTCACHE_DISK_CACHE)==0 || cache->mem_cache.first)
2204 BKE_ptcache_id_from_particles(&pid, ob, psys);
2206 BKE_ptcache_disk_to_mem(&pid);
2208 static void psys_clear_temp_pointcache(ParticleSystem *psys)
2210 if((psys->pointcache->flag & PTCACHE_DISK_CACHE)==0)
2213 BKE_ptcache_free_mem(&psys->pointcache->mem_cache);
2215 void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
2217 ParticleSettings *part = psys->part;
2219 *sfra = MAX2(1, (int)part->sta);
2220 *efra = MIN2((int)(part->end + part->lifetime + 1.0), scene->r.efra);
2223 /************************************************/
2225 /************************************************/
2226 void psys_update_particle_tree(ParticleSystem *psys, float cfra)
2231 if(!psys->tree || psys->tree_frame != cfra) {
2233 BLI_kdtree_free(psys->tree);
2235 psys->tree = BLI_kdtree_new(psys->totpart);
2237 LOOP_SHOWN_PARTICLES {
2238 if(pa->alive == PARS_ALIVE) {
2239 if(pa->state.time == cfra)
2240 BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL);
2242 BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
2245 BLI_kdtree_balance(psys->tree);
2247 psys->tree_frame = psys->cfra;
2252 static void psys_update_effectors(ParticleSimulationData *sim)
2254 pdEndEffectors(&sim->psys->effectors);
2255 sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights);
2256 precalc_guides(sim, sim->psys->effectors);
2259 /************************************************/
2260 /* Newtonian physics */
2261 /************************************************/
2262 /* gathers all forces that effect particles and calculates a new state for the particle */
2263 static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra, float cfra)
2265 ParticleSettings *part = sim->psys->part;
2266 ParticleData *pa = sim->psys->particles + p;
2267 EffectedPoint epoint;
2268 ParticleKey states[5], tkey;
2269 float timestep = psys_get_timestep(sim);
2270 float force[3],impulse[3],dx[4][3],dv[4][3],oldpos[3];
2271 float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra;
2274 /* maintain angular velocity */
2275 VECCOPY(pa->state.ave,pa->prev_state.ave);
2276 VECCOPY(oldpos,pa->state.co);
2278 if(part->flag & PART_SIZEMASS)
2281 switch(part->integrator){
2282 case PART_INT_EULER:
2285 case PART_INT_MIDPOINT:
2291 case PART_INT_VERLET:
2296 copy_particle_key(states,&pa->state,1);
2298 for(i=0; i<steps; i++){
2299 force[0]=force[1]=force[2]=0.0;
2300 impulse[0]=impulse[1]=impulse[2]=0.0;
2302 pd_point_from_particle(sim, pa, states+i, &epoint);
2303 if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
2304 pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
2306 /* calculate air-particle interaction */
2307 if(part->dragfac!=0.0f){
2308 fac=-part->dragfac*pa->size*pa->size*len_v3(states[i].vel);
2309 VECADDFAC(force,force,states[i].vel,fac);
2312 /* brownian force */
2313 if(part->brownfac!=0.0){
2314 force[0]+=(BLI_frand()-0.5f)*part->brownfac;
2315 force[1]+=(BLI_frand()-0.5f)*part->brownfac;
2316 force[2]+=(BLI_frand()-0.5f)*part->brownfac;
2319 /* force to acceleration*/
2320 mul_v3_fl(force,1.0f/pa_mass);
2322 /* add global acceleration (gravitation) */
2323 if(sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY
2324 /* normal gravity is too strong for hair so it's disabled by default */
2325 && (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
2327 VECCOPY(gravity, sim->scene->physics_settings.gravity);
2328 mul_v3_fl(gravity, part->effector_weights->global_gravity);
2329 VECADD(force,force,gravity);
2332 /* calculate next state */
2333 VECADD(states[i].vel,states[i].vel,impulse);
2335 switch(part->integrator){
2336 case PART_INT_EULER:
2337 VECADDFAC(pa->state.co,states->co,states->vel,dtime);
2338 VECADDFAC(pa->state.vel,states->vel,force,dtime);
2340 case PART_INT_MIDPOINT:
2342 VECADDFAC(states[1].co,states->co,states->vel,dtime*0.5f);
2343 VECADDFAC(states[1].vel,states->vel,force,dtime*0.5f);
2344 fra=sim->psys->cfra+0.5f*dfra;
2347 VECADDFAC(pa->state.co,states->co,states[1].vel,dtime);
2348 VECADDFAC(pa->state.vel,states->vel,force,dtime);
2354 VECCOPY(dx[0],states->vel);
2355 mul_v3_fl(dx[0],dtime);
2356 VECCOPY(dv[0],force);
2357 mul_v3_fl(dv[0],dtime);
2359 VECADDFAC(states[1].co,states->co,dx[0],0.5f);
2360 VECADDFAC(states[1].vel,states->vel,dv[0],0.5f);
2361 fra=sim->psys->cfra+0.5f*dfra;
2364 VECADDFAC(dx[1],states->vel,dv[0],0.5f);
2365 mul_v3_fl(dx[1],dtime);
2366 VECCOPY(dv[1],force);
2367 mul_v3_fl(dv[1],dtime);
2369 VECADDFAC(states[2].co,states->co,dx[1],0.5f);
2370 VECADDFAC(states[2].vel,states->vel,dv[1],0.5f);
2373 VECADDFAC(dx[2],states->vel,dv[1],0.5f);
2374 mul_v3_fl(dx[2],dtime);
2375 VECCOPY(dv[2],force);
2376 mul_v3_fl(dv[2],dtime);
2378 VECADD(states[3].co,states->co,dx[2]);
2379 VECADD(states[3].vel,states->vel,dv[2]);
2383 VECADD(dx[3],states->vel,dv[2]);
2384 mul_v3_fl(dx[3],dtime);
2385 VECCOPY(dv[3],force);
2386 mul_v3_fl(dv[3],dtime);
2388 VECADDFAC(pa->state.co,states->co,dx[0],1.0f/6.0f);
2389 VECADDFAC(pa->state.co,pa->state.co,dx[1],1.0f/3.0f);
2390 VECADDFAC(pa->state.co,pa->state.co,dx[2],1.0f/3.0f);
2391 VECADDFAC(pa->state.co,pa->state.co,dx[3],1.0f/6.0f);
2393 VECADDFAC(pa->state.vel,states->vel,dv[0],1.0f/6.0f);
2394 VECADDFAC(pa->state.vel,pa->state.vel,dv[1],1.0f/3.0f);
2395 VECADDFAC(pa->state.vel,pa->state.vel,dv[2],1.0f/3.0f);
2396 VECADDFAC(pa->state.vel,pa->state.vel,dv[3],1.0f/6.0f);
2399 case PART_INT_VERLET: /* Verlet integration */
2400 VECADDFAC(pa->state.vel,pa->state.vel,force,dtime);
2401 VECADDFAC(pa->state.co,pa->state.co,pa->state.vel,dtime);
2403 VECSUB(pa->state.vel,pa->state.co,oldpos);
2404 mul_v3_fl(pa->state.vel,1.0f/dtime);
2409 /* damp affects final velocity */
2410 if(part->dampfac!=0.0)
2411 mul_v3_fl(pa->state.vel,1.0f-part->dampfac);
2413 VECCOPY(pa->state.ave, states->ave);
2415 /* finally we do guides */
2416 time=(cfra-pa->time)/pa->lifetime;
2417 CLAMP(time,0.0,1.0);
2419 VECCOPY(tkey.co,pa->state.co);
2420 VECCOPY(tkey.vel,pa->state.vel);
2421 tkey.time=pa->state.time;
2423 if(part->type != PART_HAIR) {
2424 if(do_guides(sim->psys->effectors, &tkey, p, time)) {
2425 VECCOPY(pa->state.co,tkey.co);
2426 /* guides don't produce valid velocity */
2427 VECSUB(pa->state.vel,tkey.co,pa->prev_state.co);
2428 mul_v3_fl(pa->state.vel,1.0f/dtime);
2429 pa->state.time=tkey.time;
2433 static void rotate_particle(ParticleSettings *part, ParticleData *pa, float dfra, float timestep)
2435 float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep;
2437 if((part->flag & PART_ROT_DYN)==0){
2438 if(part->avemode==PART_AVE_SPIN){
2440 float len1 = len_v3(pa->prev_state.vel);
2441 float len2 = len_v3(pa->state.vel);
2443 if(len1==0.0f || len2==0.0f)
2444 pa->state.ave[0]=pa->state.ave[1]=pa->state.ave[2]=0.0f;
2446 cross_v3_v3v3(pa->state.ave,pa->prev_state.vel,pa->state.vel);
2447 normalize_v3(pa->state.ave);
2448 angle=dot_v3v3(pa->prev_state.vel,pa->state.vel)/(len1*len2);
2449 mul_v3_fl(pa->state.ave,saacos(angle)/dtime);
2452 axis_angle_to_quat(rot2,pa->state.vel,dtime*part->avefac);
2456 rotfac=len_v3(pa->state.ave);
2457 if(rotfac==0.0){ /* unit_qt(in VecRotToQuat) doesn't give unit quat [1,0,0,0]?? */
2459 rot1[1]=rot1[2]=rot1[3]=0;
2462 axis_angle_to_quat(rot1,pa->state.ave,rotfac*dtime);
2464 mul_qt_qtqt(pa->state.rot,rot1,pa->prev_state.rot);
2465 mul_qt_qtqt(pa->state.rot,rot2,pa->state.rot);
2467 /* keep rotation quat in good health */
2468 normalize_qt(pa->state.rot);
2471 /* convert from triangle barycentric weights to quad mean value weights */
2472 static void intersect_dm_quad_weights(float *v1, float *v2, float *v3, float *v4, float *w)
2474 float co[3], vert[4][3];
2476 VECCOPY(vert[0], v1);
2477 VECCOPY(vert[1], v2);
2478 VECCOPY(vert[2], v3);
2479 VECCOPY(vert[3], v4);
2481 co[0]= v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2] + v4[0]*w[3];
2482 co[1]= v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2] + v4[1]*w[3];
2483 co[2]= v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2] + v4[2]*w[3];
2485 interp_weights_poly_v3( w,vert, 4, co);
2488 /* check intersection with a derivedmesh */
2489 int psys_intersect_dm(Scene *scene, Object *ob, DerivedMesh *dm, float *vert_cos, float *co1, float* co2, float *min_d, int *min_face, float *min_w,
2490 float *face_minmax, float *pa_minmax, float radius, float *ipoint)
2494 int i, totface, intersect=0;
2495 float cur_d, cur_uv[2], v1[3], v2[3], v3[3], v4[3], min[3], max[3], p_min[3],p_max[3];
2496 float cur_ipoint[3];
2499 psys_disable_all(ob);
2501 dm=mesh_get_derived_final(scene, ob, 0);
2503 dm=mesh_get_derived_deform(scene, ob, 0);
2505 psys_enable_all(ob);
2514 INIT_MINMAX(p_min,p_max);
2515 DO_MINMAX(co1,p_min,p_max);
2516 DO_MINMAX(co2,p_min,p_max);
2519 VECCOPY(p_min,pa_minmax);
2520 VECCOPY(p_max,pa_minmax+3);
2523 totface=dm->getNumFaces(dm);
2524 mface=dm->getFaceDataArray(dm,CD_MFACE);
2525 mvert=dm->getVertDataArray(dm,CD_MVERT);
2527 /* lets intersect the faces */
2528 for(i=0; i<totface; i++,mface++){
2530 VECCOPY(v1,vert_cos+3*mface->v1);
2531 VECCOPY(v2,vert_cos+3*mface->v2);
2532 VECCOPY(v3,vert_cos+3*mface->v3);
2534 VECCOPY(v4,vert_cos+3*mface->v4)
2537 VECCOPY(v1,mvert[mface->v1].co);
2538 VECCOPY(v2,mvert[mface->v2].co);
2539 VECCOPY(v3,mvert[mface->v3].co);
2541 VECCOPY(v4,mvert[mface->v4].co)
2545 INIT_MINMAX(min,max);
2546 DO_MINMAX(v1,min,max);
2547 DO_MINMAX(v2,min,max);
2548 DO_MINMAX(v3,min,max);
2550 DO_MINMAX(v4,min,max)
2551 if(isect_aabb_aabb_v3(min,max,p_min,p_max)==0)
2555 VECCOPY(min, face_minmax+6*i);
2556 VECCOPY(max, face_minmax+6*i+3);
2557 if(isect_aabb_aabb_v3(min,max,p_min,p_max)==0)
2562 if(isect_sweeping_sphere_tri_v3(co1, co2, radius, v2, v3, v1, &cur_d, cur_ipoint)){
2565 VECCOPY(ipoint,cur_ipoint);
2571 if(isect_sweeping_sphere_tri_v3(co1, co2, radius, v4, v1, v3, &cur_d, cur_ipoint)){
2574 VECCOPY(ipoint,cur_ipoint);
2582 if(isect_line_tri_v3(co1, co2, v1, v2, v3, &cur_d, cur_uv)){
2585 min_w[0]= 1.0 - cur_uv[0] - cur_uv[1];
2586 min_w[1]= cur_uv[0];
2587 min_w[2]= cur_uv[1];
2590 intersect_dm_quad_weights(v1, v2, v3, v4, min_w);
2596 if(isect_line_tri_v3(co1, co2, v1, v3, v4, &cur_d, cur_uv)){
2599 min_w[0]= 1.0 - cur_uv[0] - cur_uv[1];
2601 min_w[2]= cur_uv[0];
2602 min_w[3]= cur_uv[1];
2603 intersect_dm_quad_weights(v1, v2, v3, v4, min_w);
2614 void particle_intersect_face(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
2616 ParticleCollision *col = (ParticleCollision *) userdata;
2617 MFace *face = col->md->mfaces + index;
2618 MVert *x = col->md->x;
2619 MVert *v = col->md->current_v;
2620 float vel[3], co1[3], co2[3], uv[2], ipoint[3], temp[3], t;
2622 float *t0, *t1, *t2, *t3;
2623 t0 = x[ face->v1 ].co;
2624 t1 = x[ face->v2 ].co;
2625 t2 = x[ face->v3 ].co;
2626 t3 = face->v4 ? x[ face->v4].co : NULL;
2628 /* calculate average velocity of face */
2629 VECCOPY(vel, v[ face->v1 ].co);
2630 VECADD(vel, vel, v[ face->v2 ].co);
2631 VECADD(vel, vel, v[ face->v3 ].co);
2632 mul_v3_fl(vel, 0.33334f);
2634 /* substract face velocity, in other words convert to
2635 a coordinate system where only the particle moves */
2636 VECADDFAC(co1, col->co1, vel, -col->t);
2637 VECSUB(co2, col->co2, vel);
2641 if(ray->radius == 0.0f) {
2642 if(isect_line_tri_v3(co1, co2, t0, t1, t2, &t, uv)) {
2643 if(t >= 0.0f && t < hit->dist/col->ray_len) {
2644 hit->dist = col->ray_len * t;
2647 /* calculate normal that's facing the particle */
2648 normal_tri_v3( col->nor,t0, t1, t2);
2649 VECSUB(temp, co2, co1);
2650 if(dot_v3v3(col->nor, temp) > 0.0f)
2651 negate_v3(col->nor);
2653 VECCOPY(col->vel,vel);
2655 col->hit_ob = col->ob;
2656 col->hit_md = col->md;
2661 if(isect_sweeping_sphere_tri_v3(co1, co2, ray->radius, t0, t1, t2, &t, ipoint)) {
2662 if(t >=0.0f && t < hit->dist/col->ray_len) {
2663 hit->dist = col->ray_len * t;
2666 interp_v3_v3v3(temp, co1, co2, t);
2668 VECSUB(col->nor, temp, ipoint);
2669 normalize_v3(col->nor);
2671 VECCOPY(col->vel,vel);
2673 col->hit_ob = col->ob;
2674 col->hit_md = col->md;
2685 /* particle - mesh collision code */
2686 /* in addition to basic point to surface collisions handles friction & damping,*/
2687 /* angular momentum <-> linear momentum and swept sphere - mesh collisions */
2688 /* 1. check for all possible deflectors for closest intersection on particle path */
2689 /* 2. if deflection was found kill the particle or calculate new coordinates */
2690 static void deflect_particle(ParticleSimulationData *sim, int p, float dfra, float cfra){
2691 Object *ground_ob = NULL;
2692 ParticleSettings *part = sim->psys->part;
2693 ParticleData *pa = sim->psys->particles + p;
2694 ParticleCollision col;
2695 ColliderCache *coll;
2697 float ray_dir[3], zerovec[3]={0.0,0.0,0.0};
2698 float radius = ((part->flag & PART_SIZE_DEFL)?pa->size:0.0f), boid_z = 0.0f;
2699 float timestep = psys_get_timestep(sim);
2700 int deflections=0, max_deflections=10;
2702 VECCOPY(col.co1, pa->prev_state.co);
2703 VECCOPY(col.co2, pa->state.co);
2706 /* override for boids */
2707 if(part->phystype == PART_PHYS_BOIDS) {
2708 BoidParticle *bpa = pa->boid;
2710 boid_z = pa->state.co[2];
2711 ground_ob = bpa->ground;
2714 /* 10 iterations to catch multiple deflections */
2715 if(sim->colliders) while(deflections < max_deflections){
2718 VECSUB(ray_dir, col.co2, col.co1);
2720 hit.dist = col.ray_len = len_v3(ray_dir);
2722 /* even if particle is stationary we want to check for moving colliders */
2723 /* if hit.dist is zero the bvhtree_ray_cast will just ignore everything */
2724 if(hit.dist == 0.0f)
2725 hit.dist = col.ray_len = 0.000001f;
2727 for(coll = sim->colliders->first; coll; coll=coll->next){
2728 /* for boids: don't check with current ground object */
2729 if(coll->ob == ground_ob)
2732 /* particles should not collide with emitter at birth */
2733 if(coll->ob == sim->ob && pa->time < cfra && pa->time >= sim->psys->cfra)
2737 col.md = coll->collmd;
2739 if(col.md && col.md->bvhtree)
2740 BLI_bvhtree_ray_cast(col.md->bvhtree, col.co1, ray_dir, radius, &hit, particle_intersect_face, &col);
2745 PartDeflect *pd = col.hit_ob->pd;
2746 int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0;
2747 float co[3]; /* point of collision */
2748 float vec[3]; /* movement through collision */
2749 float t = hit.dist/col.ray_len; /* time of collision between this iteration */
2750 float dt = col.t + t * (1.0f - col.t); /* time of collision between frame change*/
2752 interp_v3_v3v3(co, col.co1, col.co2, t);
2753 VECSUB(vec, col.co2, col.co1);
2755 mul_v3_fl(col.vel, 1.0f-col.t);
2757 /* particle dies in collision */
2758 if(through == 0 && (part->flag & PART_DIE_ON_COL || pd->flag & PDEFLE_KILL_PART)) {
2759 pa->alive = PARS_DYING;
2760 pa->dietime = pa->state.time + (cfra - pa->state.time) * dt;
2762 /* we have to add this for dying particles too so that reactors work correctly */
2763 VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
2765 VECCOPY(pa->state.co, co);
2766 interp_v3_v3v3(pa->state.vel, pa->prev_state.vel, pa->state.vel, dt);
2767 interp_qt_qtqt(pa->state.rot, pa->prev_state.rot, pa->state.rot, dt);
2768 interp_v3_v3v3(pa->state.ave, pa->prev_state.ave, pa->state.ave, dt);
2770 /* particle is dead so we don't need to calculate further */
2771 deflections=max_deflections;
2774 float nor_vec[3], tan_vec[3], tan_vel[3], vel[3];
2778 /* get damping & friction factors */
2779 damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_frand() - 0.5f);
2780 CLAMP(damp,0.0,1.0);
2782 frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_frand() - 0.5f);
2783 CLAMP(frict,0.0,1.0);
2785 /* treat normal & tangent components separately */
2786 inp = dot_v3v3(col.nor, vec);
2787 inp_v = dot_v3v3(col.nor, col.vel);
2789 VECADDFAC(tan_vec, vec, col.nor, -inp);
2790 VECADDFAC(tan_vel, col.vel, col.nor, -inp_v);
2791 if((part->flag & PART_ROT_DYN)==0)
2792 interp_v3_v3v3(tan_vec, tan_vec, tan_vel, frict);
2794 VECCOPY(nor_vec, col.nor);
2800 /* special case for object hitting the particle from behind */
2801 if(through==0 && ((inp_v>0 && inp>0 && inp_v>inp) || (inp_v<0 && inp<0 && inp_v<inp)))
2802 mul_v3_fl(nor_vec, inp_v);
2804 mul_v3_fl(nor_vec, inp_v + (through ? 1.0f : -1.0f) * inp);
2806 /* angular <-> linear velocity - slightly more physical and looks even nicer than before */
2807 if(part->flag & PART_ROT_DYN) {
2808 float surface_vel[3], rot_vel[3], friction[3], dave[3], dvel[3];
2810 /* apparent velocity along collision surface */
2811 VECSUB(surface_vel, tan_vec, tan_vel);
2813 /* direction of rolling friction */
2814 cross_v3_v3v3(rot_vel, pa->state.ave, col.nor);
2815 /* convert to current dt */
2816 mul_v3_fl(rot_vel, (timestep*dfra) * (1.0f - col.t));
2817 mul_v3_fl(rot_vel, pa->size);
2819 /* apply sliding friction */
2820 VECSUB(surface_vel, surface_vel, rot_vel);
2821 VECCOPY(friction, surface_vel);
2823 mul_v3_fl(surface_vel, 1.0 - frict);
2824 mul_v3_fl(friction, frict);
2826 /* sliding changes angular velocity */
2827 cross_v3_v3v3(dave, col.nor, friction);
2828 mul_v3_fl(dave, 1.0f/MAX2(pa->size, 0.001));
2830 /* we assume rolling friction is around 0.01 of sliding friction */
2831 mul_v3_fl(rot_vel, 1.0 - frict*0.01);
2833 /* change in angular velocity has to be added to the linear velocity too */
2834 cross_v3_v3v3(dvel, dave, col.nor);
2835 mul_v3_fl(dvel, pa->size);
2836 VECADD(rot_vel, rot_vel, dvel);
2838 VECADD(surface_vel, surface_vel, rot_vel);
2839 VECADD(tan_vec, surface_vel, tan_vel);
2841 /* convert back to normal time */
2842 mul_v3_fl(dave, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
2844 mul_v3_fl(pa->state.ave, 1.0 - frict*0.01);
2845 VECADD(pa->state.ave, pa->state.ave, dave);
2848 /* combine components together again */
2849 VECADD(vec, nor_vec, tan_vec);
2851 /* calculate velocity from collision vector */
2853 mul_v3_fl(vel, 1.0f/MAX2((timestep*dfra) * (1.0f - col.t), 0.00001));
2855 /* make sure we don't hit the current face again */
2856 VECADDFAC(co, co, col.nor, (through ? -0.0001f : 0.0001f));
2858 if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) {
2859 BoidParticle *bpa = pa->boid;
2860 if(bpa->data.mode == eBoidMode_OnLand || co[2] <= boid_z) {