Blender V2.61 - r43446

particle_system.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2007 by Janne Karhu.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): Raul Fernandez Hernandez (Farsthary), Stephen Swhitehorn.
00024  *
00025  * Adaptive time step
00026  * Copyright 2011 AutoCRC
00027  *
00028  * ***** END GPL LICENSE BLOCK *****
00029  */
00030 
00036 #include <stddef.h>
00037 
00038 #include <stdlib.h>
00039 #include <math.h>
00040 #include <string.h>
00041 
00042 #ifdef _OPENMP
00043 #include <omp.h>
00044 #endif
00045 
00046 #include "MEM_guardedalloc.h"
00047 
00048 #include "DNA_anim_types.h"
00049 #include "DNA_boid_types.h"
00050 #include "DNA_particle_types.h"
00051 #include "DNA_mesh_types.h"
00052 #include "DNA_meshdata_types.h"
00053 #include "DNA_modifier_types.h"
00054 #include "DNA_object_force.h"
00055 #include "DNA_object_types.h"
00056 #include "DNA_material_types.h"
00057 #include "DNA_curve_types.h"
00058 #include "DNA_group_types.h"
00059 #include "DNA_scene_types.h"
00060 #include "DNA_texture_types.h"
00061 #include "DNA_ipo_types.h" // XXX old animation system stuff... to be removed!
00062 #include "DNA_listBase.h"
00063 
00064 #include "BLI_edgehash.h"
00065 #include "BLI_rand.h"
00066 #include "BLI_jitter.h"
00067 #include "BLI_math.h"
00068 #include "BLI_blenlib.h"
00069 #include "BLI_kdtree.h"
00070 #include "BLI_kdopbvh.h"
00071 #include "BLI_threads.h"
00072 #include "BLI_utildefines.h"
00073 #include "BLI_linklist.h"
00074 
00075 #include "BKE_main.h"
00076 #include "BKE_animsys.h"
00077 #include "BKE_boids.h"
00078 #include "BKE_cdderivedmesh.h"
00079 #include "BKE_collision.h"
00080 #include "BKE_displist.h"
00081 #include "BKE_effect.h"
00082 #include "BKE_particle.h"
00083 #include "BKE_global.h"
00084 
00085 #include "BKE_DerivedMesh.h"
00086 #include "BKE_object.h"
00087 #include "BKE_material.h"
00088 #include "BKE_cloth.h"
00089 #include "BKE_depsgraph.h"
00090 #include "BKE_lattice.h"
00091 #include "BKE_pointcache.h"
00092 #include "BKE_mesh.h"
00093 #include "BKE_modifier.h"
00094 #include "BKE_scene.h"
00095 #include "BKE_bvhutils.h"
00096 
00097 #include "PIL_time.h"
00098 
00099 #include "RE_shader_ext.h"
00100 
00101 /* fluid sim particle import */
00102 #ifdef WITH_MOD_FLUID
00103 #include "DNA_object_fluidsim.h"
00104 #include "LBM_fluidsim.h"
00105 #include <zlib.h>
00106 #include <string.h>
00107 
00108 #endif // WITH_MOD_FLUID
00109 
00110 /************************************************/
00111 /*          Reacting to system events           */
00112 /************************************************/
00113 
00114 static int particles_are_dynamic(ParticleSystem *psys)
00115 {
00116     if(psys->pointcache->flag & PTCACHE_BAKED)
00117         return 0;
00118 
00119     if(psys->part->type == PART_HAIR)
00120         return psys->flag & PSYS_HAIR_DYNAMICS;
00121     else
00122         return ELEM3(psys->part->phystype, PART_PHYS_NEWTON, PART_PHYS_BOIDS, PART_PHYS_FLUID);
00123 }
00124 
00125 static int psys_get_current_display_percentage(ParticleSystem *psys)
00126 {
00127     ParticleSettings *part=psys->part;
00128 
00129     if((psys->renderdata && !particles_are_dynamic(psys)) /* non-dynamic particles can be rendered fully */
00130         || (part->child_nbr && part->childtype) /* display percentage applies to children */
00131         || (psys->pointcache->flag & PTCACHE_BAKING)) /* baking is always done with full amount */
00132         return 100;
00133 
00134     return psys->part->disp;
00135 }
00136 
00137 static int tot_particles(ParticleSystem *psys, PTCacheID *pid)
00138 {
00139     if(pid && psys->pointcache->flag & PTCACHE_EXTERNAL)
00140         return pid->cache->totpoint;
00141     else if(psys->part->distr == PART_DISTR_GRID && psys->part->from != PART_FROM_VERT)
00142         return psys->part->grid_res * psys->part->grid_res * psys->part->grid_res - psys->totunexist;
00143     else
00144         return psys->part->totpart - psys->totunexist;
00145 }
00146 
00147 void psys_reset(ParticleSystem *psys, int mode)
00148 {
00149     PARTICLE_P;
00150 
00151     if(ELEM(mode, PSYS_RESET_ALL, PSYS_RESET_DEPSGRAPH)) {
00152         if(mode == PSYS_RESET_ALL || !(psys->flag & PSYS_EDITED)) {
00153             /* don't free if not absolutely necessary */
00154             if(psys->totpart != tot_particles(psys, NULL)) {
00155                 psys_free_particles(psys);
00156                 psys->totpart= 0;
00157             }
00158 
00159             psys->totkeyed= 0;
00160             psys->flag &= ~(PSYS_HAIR_DONE|PSYS_KEYED);
00161 
00162             if(psys->edit && psys->free_edit) {
00163                 psys->free_edit(psys->edit);
00164                 psys->edit = NULL;
00165                 psys->free_edit = NULL;
00166             }
00167         }
00168     }
00169     else if(mode == PSYS_RESET_CACHE_MISS) {
00170         /* set all particles to be skipped */
00171         LOOP_PARTICLES
00172             pa->flag |= PARS_NO_DISP;
00173     }
00174 
00175     /* reset children */
00176     if(psys->child) {
00177         MEM_freeN(psys->child);
00178         psys->child= NULL;
00179     }
00180 
00181     psys->totchild= 0;
00182 
00183     /* reset path cache */
00184     psys_free_path_cache(psys, psys->edit);
00185 
00186     /* reset point cache */
00187     BKE_ptcache_invalidate(psys->pointcache);
00188 
00189     if(psys->fluid_springs) {
00190         MEM_freeN(psys->fluid_springs);
00191         psys->fluid_springs = NULL;
00192     }
00193 
00194     psys->tot_fluidsprings = psys->alloc_fluidsprings = 0;
00195 }
00196 
00197 static void realloc_particles(ParticleSimulationData *sim, int new_totpart)
00198 {
00199     ParticleSystem *psys = sim->psys;
00200     ParticleSettings *part = psys->part;
00201     ParticleData *newpars = NULL;
00202     BoidParticle *newboids = NULL;
00203     PARTICLE_P;
00204     int totpart, totsaved = 0;
00205 
00206     if(new_totpart<0) {
00207         if(part->distr==PART_DISTR_GRID  && part->from != PART_FROM_VERT) {
00208             totpart= part->grid_res;
00209             totpart*=totpart*totpart;
00210         }
00211         else
00212             totpart=part->totpart;
00213     }
00214     else
00215         totpart=new_totpart;
00216 
00217     if(totpart != psys->totpart) {
00218         if(psys->edit && psys->free_edit) {
00219             psys->free_edit(psys->edit);
00220             psys->edit = NULL;
00221             psys->free_edit = NULL;
00222         }
00223 
00224         if(totpart) {
00225             newpars= MEM_callocN(totpart*sizeof(ParticleData), "particles");
00226             if(newpars == NULL)
00227                 return;
00228 
00229             if(psys->part->phystype == PART_PHYS_BOIDS) {
00230                 newboids= MEM_callocN(totpart*sizeof(BoidParticle), "boid particles");
00231 
00232                 if(newboids == NULL) {
00233                      /* allocation error! */
00234                     if(newpars)
00235                         MEM_freeN(newpars);
00236                     return;
00237                 }
00238             }
00239         }
00240     
00241         if(psys->particles) {
00242             totsaved=MIN2(psys->totpart,totpart);
00243             /*save old pars*/
00244             if(totsaved) {
00245                 memcpy(newpars,psys->particles,totsaved*sizeof(ParticleData));
00246 
00247                 if(psys->particles->boid)
00248                     memcpy(newboids, psys->particles->boid, totsaved*sizeof(BoidParticle));
00249             }
00250 
00251             if(psys->particles->keys)
00252                 MEM_freeN(psys->particles->keys);
00253 
00254             if(psys->particles->boid)
00255                 MEM_freeN(psys->particles->boid);
00256 
00257             for(p=0, pa=newpars; p<totsaved; p++, pa++) {
00258                 if(pa->keys) {
00259                     pa->keys= NULL;
00260                     pa->totkey= 0;
00261                 }
00262             }
00263 
00264             for(p=totsaved, pa=psys->particles+totsaved; p<psys->totpart; p++, pa++)
00265                 if(pa->hair) MEM_freeN(pa->hair);
00266 
00267             MEM_freeN(psys->particles);
00268             psys_free_pdd(psys);
00269         }
00270         
00271         psys->particles=newpars;
00272         psys->totpart=totpart;
00273 
00274         if(newboids) {
00275             LOOP_PARTICLES
00276                 pa->boid = newboids++;
00277         }
00278     }
00279 
00280     if(psys->child) {
00281         MEM_freeN(psys->child);
00282         psys->child=NULL;
00283         psys->totchild=0;
00284     }
00285 }
00286 
00287 static int get_psys_child_number(struct Scene *scene, ParticleSystem *psys)
00288 {
00289     int nbr;
00290 
00291     if(!psys->part->childtype)
00292         return 0;
00293 
00294     if(psys->renderdata)
00295         nbr= psys->part->ren_child_nbr;
00296     else
00297         nbr= psys->part->child_nbr;
00298 
00299     return get_render_child_particle_number(&scene->r, nbr);
00300 }
00301 
00302 static int get_psys_tot_child(struct Scene *scene, ParticleSystem *psys)
00303 {
00304     return psys->totpart*get_psys_child_number(scene, psys);
00305 }
00306 
00307 static void alloc_child_particles(ParticleSystem *psys, int tot)
00308 {
00309     if(psys->child){
00310         /* only re-allocate if we have to */
00311         if(psys->part->childtype && psys->totchild == tot) {
00312             memset(psys->child, 0, tot*sizeof(ChildParticle));
00313             return;
00314         }
00315 
00316         MEM_freeN(psys->child);
00317         psys->child=NULL;
00318         psys->totchild=0;
00319     }
00320 
00321     if(psys->part->childtype) {
00322         psys->totchild= tot;
00323         if(psys->totchild)
00324             psys->child= MEM_callocN(psys->totchild*sizeof(ChildParticle), "child_particles");
00325     }
00326 }
00327 
00328 /************************************************/
00329 /*          Distribution                        */
00330 /************************************************/
00331 
00332 void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys)
00333 {
00334     /* use for building derived mesh mapping info:
00335 
00336        node: the allocated links - total derived mesh element count 
00337        nodearray: the array of nodes aligned with the base mesh's elements, so
00338                   each original elements can reference its derived elements
00339     */
00340     Mesh *me= (Mesh*)ob->data;
00341     PARTICLE_P;
00342     
00343     /* CACHE LOCATIONS */
00344     if(!dm->deformedOnly) {
00345         /* Will use later to speed up subsurf/derivedmesh */
00346         LinkNode *node, *nodedmelem, **nodearray;
00347         int totdmelem, totelem, i, *origindex;
00348 
00349         if(psys->part->from == PART_FROM_VERT) {
00350             totdmelem= dm->getNumVerts(dm);
00351             totelem= me->totvert;
00352             origindex= dm->getVertDataArray(dm, CD_ORIGINDEX);
00353         }
00354         else { /* FROM_FACE/FROM_VOLUME */
00355             totdmelem= dm->getNumFaces(dm);
00356             totelem= me->totface;
00357             origindex= dm->getFaceDataArray(dm, CD_ORIGINDEX);
00358         }
00359     
00360         nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems");
00361         nodearray= MEM_callocN(sizeof(LinkNode *)*totelem, "psys node array");
00362         
00363         for(i=0, node=nodedmelem; i<totdmelem; i++, origindex++, node++) {
00364             node->link= SET_INT_IN_POINTER(i);
00365 
00366             if(*origindex != -1) {
00367                 if(nodearray[*origindex]) {
00368                     /* prepend */
00369                     node->next = nodearray[*origindex];
00370                     nodearray[*origindex]= node;
00371                 }
00372                 else
00373                     nodearray[*origindex]= node;
00374             }
00375         }
00376         
00377         /* cache the verts/faces! */
00378         LOOP_PARTICLES {
00379             if(pa->num < 0) {
00380                 pa->num_dmcache = -1;
00381                 continue;
00382             }
00383 
00384             if(psys->part->from == PART_FROM_VERT) {
00385                 if(nodearray[pa->num])
00386                     pa->num_dmcache= GET_INT_FROM_POINTER(nodearray[pa->num]->link);
00387             }
00388             else { /* FROM_FACE/FROM_VOLUME */
00389                 /* Note that sometimes the pa->num is over the nodearray size, this is bad, maybe there is a better place to fix this,
00390                  * but for now passing NULL is OK. every face will be searched for the particle so its slower - Campbell */
00391                 pa->num_dmcache= psys_particle_dm_face_lookup(ob, dm, pa->num, pa->fuv, pa->num < totelem ? nodearray[pa->num] : NULL);
00392             }
00393         }
00394 
00395         MEM_freeN(nodearray);
00396         MEM_freeN(nodedmelem);
00397     }
00398     else {
00399         /* TODO PARTICLE, make the following line unnecessary, each function
00400          * should know to use the num or num_dmcache, set the num_dmcache to
00401          * an invalid value, just incase */
00402         
00403         LOOP_PARTICLES
00404             pa->num_dmcache = -1;
00405     }
00406 }
00407 
00408 static void distribute_simple_children(Scene *scene, Object *ob, DerivedMesh *finaldm, ParticleSystem *psys)
00409 {
00410     ChildParticle *cpa = NULL;
00411     int i, p;
00412     int child_nbr= get_psys_child_number(scene, psys);
00413     int totpart= get_psys_tot_child(scene, psys);
00414 
00415     alloc_child_particles(psys, totpart);
00416 
00417     cpa = psys->child;
00418     for(i=0; i<child_nbr; i++){
00419         for(p=0; p<psys->totpart; p++,cpa++){
00420             float length=2.0;
00421             cpa->parent=p;
00422                     
00423             /* create even spherical distribution inside unit sphere */
00424             while(length>=1.0f){
00425                 cpa->fuv[0]=2.0f*BLI_frand()-1.0f;
00426                 cpa->fuv[1]=2.0f*BLI_frand()-1.0f;
00427                 cpa->fuv[2]=2.0f*BLI_frand()-1.0f;
00428                 length=len_v3(cpa->fuv);
00429             }
00430 
00431             cpa->num=-1;
00432         }
00433     }
00434     /* dmcache must be updated for parent particles if children from faces is used */
00435     psys_calc_dmcache(ob, finaldm, psys);
00436 }
00437 static void distribute_grid(DerivedMesh *dm, ParticleSystem *psys)
00438 {
00439     ParticleData *pa=NULL;
00440     float min[3], max[3], delta[3], d;
00441     MVert *mv, *mvert = dm->getVertDataArray(dm,0);
00442     int totvert=dm->getNumVerts(dm), from=psys->part->from;
00443     int i, j, k, p, res=psys->part->grid_res, size[3], axis;
00444 
00445     mv=mvert;
00446 
00447     /* find bounding box of dm */
00448     copy_v3_v3(min, mv->co);
00449     copy_v3_v3(max, mv->co);
00450     mv++;
00451 
00452     for(i=1; i<totvert; i++, mv++){
00453         min[0]=MIN2(min[0],mv->co[0]);
00454         min[1]=MIN2(min[1],mv->co[1]);
00455         min[2]=MIN2(min[2],mv->co[2]);
00456 
00457         max[0]=MAX2(max[0],mv->co[0]);
00458         max[1]=MAX2(max[1],mv->co[1]);
00459         max[2]=MAX2(max[2],mv->co[2]);
00460     }
00461 
00462     sub_v3_v3v3(delta, max, min);
00463 
00464     /* determine major axis */
00465     axis = (delta[0]>=delta[1]) ? 0 : ((delta[1]>=delta[2]) ? 1 : 2);
00466      
00467     d = delta[axis]/(float)res;
00468 
00469     size[axis] = res;
00470     size[(axis+1)%3] = (int)ceil(delta[(axis+1)%3]/d);
00471     size[(axis+2)%3] = (int)ceil(delta[(axis+2)%3]/d);
00472 
00473     /* float errors grrr.. */
00474     size[(axis+1)%3] = MIN2(size[(axis+1)%3],res);
00475     size[(axis+2)%3] = MIN2(size[(axis+2)%3],res);
00476 
00477     size[0] = MAX2(size[0], 1);
00478     size[1] = MAX2(size[1], 1);
00479     size[2] = MAX2(size[2], 1);
00480 
00481     /* no full offset for flat/thin objects */
00482     min[0]+= d < delta[0] ? d/2.f : delta[0]/2.f;
00483     min[1]+= d < delta[1] ? d/2.f : delta[1]/2.f;
00484     min[2]+= d < delta[2] ? d/2.f : delta[2]/2.f;
00485 
00486     for(i=0,p=0,pa=psys->particles; i<res; i++){
00487         for(j=0; j<res; j++){
00488             for(k=0; k<res; k++,p++,pa++){
00489                 pa->fuv[0] = min[0] + (float)i*d;
00490                 pa->fuv[1] = min[1] + (float)j*d;
00491                 pa->fuv[2] = min[2] + (float)k*d;
00492                 pa->flag |= PARS_UNEXIST;
00493                 pa->hair_index = 0; /* abused in volume calculation */
00494             }
00495         }
00496     }
00497 
00498     /* enable particles near verts/edges/faces/inside surface */
00499     if(from==PART_FROM_VERT){
00500         float vec[3];
00501 
00502         pa=psys->particles;
00503 
00504         min[0] -= d/2.0f;
00505         min[1] -= d/2.0f;
00506         min[2] -= d/2.0f;
00507 
00508         for(i=0,mv=mvert; i<totvert; i++,mv++){
00509             sub_v3_v3v3(vec,mv->co,min);
00510             vec[0]/=delta[0];
00511             vec[1]/=delta[1];
00512             vec[2]/=delta[2];
00513             (pa +((int)(vec[0]*(size[0]-1))*res
00514                 +(int)(vec[1]*(size[1]-1)))*res
00515                 +(int)(vec[2]*(size[2]-1)))->flag &= ~PARS_UNEXIST;
00516         }
00517     }
00518     else if(ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)){
00519         float co1[3], co2[3];
00520 
00521         MFace *mface= NULL, *mface_array;
00522         float v1[3], v2[3], v3[3], v4[4], lambda;
00523         int a, a1, a2, a0mul, a1mul, a2mul, totface;
00524         int amax= from==PART_FROM_FACE ? 3 : 1;
00525 
00526         totface=dm->getNumFaces(dm);
00527         mface_array= dm->getFaceDataArray(dm,CD_MFACE);
00528         
00529         for(a=0; a<amax; a++){
00530             if(a==0){ a0mul=res*res; a1mul=res; a2mul=1; }
00531             else if(a==1){ a0mul=res; a1mul=1; a2mul=res*res; }
00532             else{ a0mul=1; a1mul=res*res; a2mul=res; }
00533 
00534             for(a1=0; a1<size[(a+1)%3]; a1++){
00535                 for(a2=0; a2<size[(a+2)%3]; a2++){
00536                     mface= mface_array;
00537 
00538                     pa = psys->particles + a1*a1mul + a2*a2mul;
00539                     copy_v3_v3(co1, pa->fuv);
00540                     co1[a] -= d < delta[a] ? d/2.f : delta[a]/2.f;
00541                     copy_v3_v3(co2, co1);
00542                     co2[a] += delta[a] + 0.001f*d;
00543                     co1[a] -= 0.001f*d;
00544                     
00545                     /* lets intersect the faces */
00546                     for(i=0; i<totface; i++,mface++){
00547                         copy_v3_v3(v1, mvert[mface->v1].co);
00548                         copy_v3_v3(v2, mvert[mface->v2].co);
00549                         copy_v3_v3(v3, mvert[mface->v3].co);
00550 
00551                         if(isect_axial_line_tri_v3(a, co1, co2, v2, v3, v1, &lambda)){
00552                             if(from==PART_FROM_FACE)
00553                                 (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
00554                             else /* store number of intersections */
00555                                 (pa+(int)(lambda*size[a])*a0mul)->hair_index++;
00556                         }
00557                         
00558                         if(mface->v4){
00559                             copy_v3_v3(v4, mvert[mface->v4].co);
00560 
00561                             if(isect_axial_line_tri_v3(a, co1, co2, v4, v1, v3, &lambda)){
00562                                 if(from==PART_FROM_FACE)
00563                                     (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST;
00564                                 else
00565                                     (pa+(int)(lambda*size[a])*a0mul)->hair_index++;
00566                             }
00567                         }
00568                     }
00569 
00570                     if(from==PART_FROM_VOLUME){
00571                         int in=pa->hair_index%2;
00572                         if(in) pa->hair_index++;
00573                         for(i=0; i<size[0]; i++){
00574                             if(in || (pa+i*a0mul)->hair_index%2)
00575                                 (pa+i*a0mul)->flag &= ~PARS_UNEXIST;
00576                             /* odd intersections == in->out / out->in */
00577                             /* even intersections -> in stays same */
00578                             in=(in + (pa+i*a0mul)->hair_index) % 2;
00579                         }
00580                     }
00581                 }
00582             }
00583         }
00584     }
00585 
00586     if(psys->part->flag & PART_GRID_HEXAGONAL) {
00587         for(i=0,p=0,pa=psys->particles; i<res; i++){
00588             for(j=0; j<res; j++){
00589                 for(k=0; k<res; k++,p++,pa++){
00590                     if(j%2)
00591                         pa->fuv[0] += d/2.f;
00592 
00593                     if(k%2) {
00594                         pa->fuv[0] += d/2.f;
00595                         pa->fuv[1] += d/2.f;
00596                     }
00597                 }
00598             }
00599         }
00600     }
00601 
00602     if(psys->part->flag & PART_GRID_INVERT){
00603         for(i=0; i<size[0]; i++){
00604             for(j=0; j<size[1]; j++){
00605                 pa=psys->particles + res*(i*res + j);
00606                 for(k=0; k<size[2]; k++, pa++){
00607                     pa->flag ^= PARS_UNEXIST;
00608                 }
00609             }
00610         }
00611     }
00612 
00613     if(psys->part->grid_rand > 0.f) {
00614         float rfac = d * psys->part->grid_rand;
00615         for(p=0,pa=psys->particles; p<psys->totpart; p++,pa++){
00616             if(pa->flag & PARS_UNEXIST)
00617                 continue;
00618 
00619             pa->fuv[0] += rfac * (PSYS_FRAND(p + 31) - 0.5f);
00620             pa->fuv[1] += rfac * (PSYS_FRAND(p + 32) - 0.5f);
00621             pa->fuv[2] += rfac * (PSYS_FRAND(p + 33) - 0.5f);
00622         }
00623     }
00624 }
00625 
00626 /* modified copy from rayshade.c */
00627 static void hammersley_create(float *out, int n, int seed, float amount)
00628 {
00629     RNG *rng;
00630     double p, t, offs[2];
00631     int k, kk;
00632 
00633     rng = rng_new(31415926 + n + seed);
00634     offs[0]= rng_getDouble(rng) + (double)amount;
00635     offs[1]= rng_getDouble(rng) + (double)amount;
00636     rng_free(rng);
00637 
00638     for (k = 0; k < n; k++) {
00639         t = 0;
00640         for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1)
00641             if (kk & 1) /* kk mod 2 = 1 */
00642                 t += p;
00643 
00644         out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0);
00645         out[2*k + 1]= fmod(t + offs[1], 1.0);
00646     }
00647 }
00648 
00649 /* modified copy from effect.c */
00650 static void init_mv_jit(float *jit, int num, int seed2, float amount)
00651 {
00652     RNG *rng;
00653     float *jit2, x, rad1, rad2, rad3;
00654     int i, num2;
00655 
00656     if(num==0) return;
00657 
00658     rad1= (float)(1.0f/sqrtf((float)num));
00659     rad2= (float)(1.0f/((float)num));
00660     rad3= (float)sqrt((float)num)/((float)num);
00661 
00662     rng = rng_new(31415926 + num + seed2);
00663     x= 0;
00664         num2 = 2 * num;
00665     for(i=0; i<num2; i+=2) {
00666     
00667         jit[i]= x + amount*rad1*(0.5f - rng_getFloat(rng));
00668         jit[i+1]= i/(2.0f*num) + amount*rad1*(0.5f - rng_getFloat(rng));
00669         
00670         jit[i]-= (float)floor(jit[i]);
00671         jit[i+1]-= (float)floor(jit[i+1]);
00672         
00673         x+= rad3;
00674         x -= (float)floor(x);
00675     }
00676 
00677     jit2= MEM_mallocN(12 + 2*sizeof(float)*num, "initjit");
00678 
00679     for (i=0 ; i<4 ; i++) {
00680         BLI_jitterate1(jit, jit2, num, rad1);
00681         BLI_jitterate1(jit, jit2, num, rad1);
00682         BLI_jitterate2(jit, jit2, num, rad2);
00683     }
00684     MEM_freeN(jit2);
00685     rng_free(rng);
00686 }
00687 
00688 static void psys_uv_to_w(float u, float v, int quad, float *w)
00689 {
00690     float vert[4][3], co[3];
00691 
00692     if(!quad) {
00693         if(u+v > 1.0f)
00694             v= 1.0f-v;
00695         else
00696             u= 1.0f-u;
00697     }
00698 
00699     vert[0][0]= 0.0f; vert[0][1]= 0.0f; vert[0][2]= 0.0f;
00700     vert[1][0]= 1.0f; vert[1][1]= 0.0f; vert[1][2]= 0.0f;
00701     vert[2][0]= 1.0f; vert[2][1]= 1.0f; vert[2][2]= 0.0f;
00702 
00703     co[0]= u;
00704     co[1]= v;
00705     co[2]= 0.0f;
00706 
00707     if(quad) {
00708         vert[3][0]= 0.0f; vert[3][1]= 1.0f; vert[3][2]= 0.0f;
00709         interp_weights_poly_v3( w,vert, 4, co);
00710     }
00711     else {
00712         interp_weights_poly_v3( w,vert, 3, co);
00713         w[3]= 0.0f;
00714     }
00715 }
00716 
00717 /* Find the index in "sum" array before "value" is crossed. */
00718 static int distribute_binary_search(float *sum, int n, float value)
00719 {
00720     int mid, low=0, high=n;
00721 
00722     if(value == 0.f)
00723         return 0;
00724 
00725     while(low <= high) {
00726         mid= (low + high)/2;
00727         
00728         if(sum[mid] < value && value <= sum[mid+1])
00729             return mid;
00730         
00731         if(sum[mid] >= value)
00732             high= mid - 1;
00733         else if(sum[mid] < value)
00734             low= mid + 1;
00735         else
00736             return mid;
00737     }
00738 
00739     return low;
00740 }
00741 
00742 /* the max number if calls to rng_* funcs within psys_thread_distribute_particle
00743  * be sure to keep up to date if this changes */
00744 #define PSYS_RND_DIST_SKIP 2
00745 
00746 /* note: this function must be thread safe, for from == PART_FROM_CHILD */
00747 #define ONLY_WORKING_WITH_PA_VERTS 0
00748 static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, ChildParticle *cpa, int p)
00749 {
00750     ParticleThreadContext *ctx= thread->ctx;
00751     Object *ob= ctx->sim.ob;
00752     DerivedMesh *dm= ctx->dm;
00753     float *v1, *v2, *v3, *v4, nor[3], orco1[3], co1[3], co2[3], nor1[3];
00754     float cur_d, min_d, randu, randv;
00755     int from= ctx->from;
00756     int cfrom= ctx->cfrom;
00757     int distr= ctx->distr;
00758     int i, intersect, tot;
00759     int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
00760 
00761     if(from == PART_FROM_VERT) {
00762         /* TODO_PARTICLE - use original index */
00763         pa->num= ctx->index[p];
00764         pa->fuv[0] = 1.0f;
00765         pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
00766 
00767 #if ONLY_WORKING_WITH_PA_VERTS
00768         if(ctx->tree){
00769             KDTreeNearest ptn[3];
00770             int w, maxw;
00771 
00772             psys_particle_on_dm(ctx->dm,from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co1,0,0,0,orco1,0);
00773             transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
00774             maxw = BLI_kdtree_find_n_nearest(ctx->tree,3,orco1,NULL,ptn);
00775 
00776             for(w=0; w<maxw; w++){
00777                 pa->verts[w]=ptn->num;
00778             }
00779         }
00780 #endif
00781     }
00782     else if(from == PART_FROM_FACE || from == PART_FROM_VOLUME) {
00783         MFace *mface;
00784 
00785         pa->num = i = ctx->index[p];
00786         mface = dm->getFaceData(dm,i,CD_MFACE);
00787         
00788         switch(distr){
00789         case PART_DISTR_JIT:
00790             if(ctx->jitlevel == 1) {
00791                 if(mface->v4)
00792                     psys_uv_to_w(0.5f, 0.5f, mface->v4, pa->fuv);
00793                 else
00794                     psys_uv_to_w(0.33333f, 0.33333f, mface->v4, pa->fuv);
00795             }
00796             else {
00797                 ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
00798                 psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
00799                 ctx->jitoff[i]++;
00800             }
00801             break;
00802         case PART_DISTR_RAND:
00803             randu= rng_getFloat(thread->rng);
00804             randv= rng_getFloat(thread->rng);
00805             rng_skip_tot -= 2;
00806 
00807             psys_uv_to_w(randu, randv, mface->v4, pa->fuv);
00808             break;
00809         }
00810         pa->foffset= 0.0f;
00811         
00812         /* experimental */
00813         if(from==PART_FROM_VOLUME){
00814             MVert *mvert=dm->getVertDataArray(dm,CD_MVERT);
00815 
00816             tot=dm->getNumFaces(dm);
00817 
00818             psys_interpolate_face(mvert,mface,0,0,pa->fuv,co1,nor,0,0,0,0);
00819 
00820             normalize_v3(nor);
00821             mul_v3_fl(nor,-100.0);
00822 
00823             add_v3_v3v3(co2,co1,nor);
00824 
00825             min_d=2.0;
00826             intersect=0;
00827 
00828             for(i=0,mface=dm->getFaceDataArray(dm,CD_MFACE); i<tot; i++,mface++){
00829                 if(i==pa->num) continue;
00830 
00831                 v1=mvert[mface->v1].co;
00832                 v2=mvert[mface->v2].co;
00833                 v3=mvert[mface->v3].co;
00834 
00835                 if(isect_line_tri_v3(co1, co2, v2, v3, v1, &cur_d, 0)){
00836                     if(cur_d<min_d){
00837                         min_d=cur_d;
00838                         pa->foffset=cur_d*50.0f; /* to the middle of volume */
00839                         intersect=1;
00840                     }
00841                 }
00842                 if(mface->v4){
00843                     v4=mvert[mface->v4].co;
00844 
00845                     if(isect_line_tri_v3(co1, co2, v4, v1, v3, &cur_d, 0)){
00846                         if(cur_d<min_d){
00847                             min_d=cur_d;
00848                             pa->foffset=cur_d*50.0f; /* to the middle of volume */
00849                             intersect=1;
00850                         }
00851                     }
00852                 }
00853             }
00854             if(intersect==0)
00855                 pa->foffset=0.0;
00856             else switch(distr){
00857                 case PART_DISTR_JIT:
00858                     pa->foffset*= ctx->jit[p%(2*ctx->jitlevel)];
00859                     break;
00860                 case PART_DISTR_RAND:
00861                     pa->foffset*=BLI_frand();
00862                     break;
00863             }
00864         }
00865     }
00866     else if(from == PART_FROM_CHILD) {
00867         MFace *mf;
00868 
00869         if(ctx->index[p] < 0) {
00870             cpa->num=0;
00871             cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]=0.0f;
00872             cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
00873             return;
00874         }
00875 
00876         mf= dm->getFaceData(dm, ctx->index[p], CD_MFACE);
00877 
00878         randu= rng_getFloat(thread->rng);
00879         randv= rng_getFloat(thread->rng);
00880         rng_skip_tot -= 2;
00881 
00882         psys_uv_to_w(randu, randv, mf->v4, cpa->fuv);
00883 
00884         cpa->num = ctx->index[p];
00885 
00886         if(ctx->tree){
00887             KDTreeNearest ptn[10];
00888             int w,maxw;//, do_seams;
00889             float maxd /*, mind,dd */, totw= 0.0f;
00890             int parent[10];
00891             float pweight[10];
00892 
00893             psys_particle_on_dm(dm,cfrom,cpa->num,DMCACHE_ISCHILD,cpa->fuv,cpa->foffset,co1,nor1,NULL,NULL,orco1,NULL);
00894             transform_mesh_orco_verts((Mesh*)ob->data, &orco1, 1, 1);
00895             maxw = BLI_kdtree_find_n_nearest(ctx->tree,4,orco1,NULL,ptn);
00896 
00897             maxd=ptn[maxw-1].dist;
00898             /* mind=ptn[0].dist; */ /* UNUSED */
00899             
00900             /* the weights here could be done better */
00901             for(w=0; w<maxw; w++){
00902                 parent[w]=ptn[w].index;
00903                 pweight[w]=(float)pow(2.0,(double)(-6.0f*ptn[w].dist/maxd));
00904             }
00905             for(;w<10; w++){
00906                 parent[w]=-1;
00907                 pweight[w]=0.0f;
00908             }
00909 
00910             for(w=0,i=0; w<maxw && i<4; w++){
00911                 if(parent[w]>=0){
00912                     cpa->pa[i]=parent[w];
00913                     cpa->w[i]=pweight[w];
00914                     totw+=pweight[w];
00915                     i++;
00916                 }
00917             }
00918             for(;i<4; i++){
00919                 cpa->pa[i]=-1;
00920                 cpa->w[i]=0.0f;
00921             }
00922 
00923             if(totw>0.0f) for(w=0; w<4; w++)
00924                 cpa->w[w]/=totw;
00925 
00926             cpa->parent=cpa->pa[0];
00927         }
00928     }
00929 
00930     if(rng_skip_tot > 0) /* should never be below zero */
00931         rng_skip(thread->rng, rng_skip_tot);
00932 }
00933 
00934 static void *distribute_threads_exec_cb(void *data)
00935 {
00936     ParticleThread *thread= (ParticleThread*)data;
00937     ParticleSystem *psys= thread->ctx->sim.psys;
00938     ParticleData *pa;
00939     ChildParticle *cpa;
00940     int p, totpart;
00941 
00942     if(thread->ctx->from == PART_FROM_CHILD) {
00943         totpart= psys->totchild;
00944         cpa= psys->child;
00945 
00946         for(p=0; p<totpart; p++, cpa++) {
00947             if(thread->ctx->skip) /* simplification skip */
00948                 rng_skip(thread->rng, PSYS_RND_DIST_SKIP * thread->ctx->skip[p]);
00949 
00950             if((p+thread->num) % thread->tot == 0)
00951                 distribute_threads_exec(thread, NULL, cpa, p);
00952             else /* thread skip */
00953                 rng_skip(thread->rng, PSYS_RND_DIST_SKIP);
00954         }
00955     }
00956     else {
00957         totpart= psys->totpart;
00958         pa= psys->particles + thread->num;
00959         for(p=thread->num; p<totpart; p+=thread->tot, pa+=thread->tot)
00960             distribute_threads_exec(thread, pa, NULL, p);
00961     }
00962 
00963     return 0;
00964 }
00965 
00966 /* not thread safe, but qsort doesn't take userdata argument */
00967 static int *COMPARE_ORIG_INDEX = NULL;
00968 static int distribute_compare_orig_index(const void *p1, const void *p2)
00969 {
00970     int index1 = COMPARE_ORIG_INDEX[*(const int*)p1];
00971     int index2 = COMPARE_ORIG_INDEX[*(const int*)p2];
00972 
00973     if(index1 < index2)
00974         return -1;
00975     else if(index1 == index2) {
00976         /* this pointer comparison appears to make qsort stable for glibc,
00977          * and apparently on solaris too, makes the renders reproducable */
00978         if(p1 < p2)
00979             return -1;
00980         else if(p1 == p2)
00981             return 0;
00982         else
00983             return 1;
00984     }
00985     else
00986         return 1;
00987 }
00988 
00989 static void distribute_invalid(Scene *scene, ParticleSystem *psys, int from)
00990 {
00991     if(from == PART_FROM_CHILD) {
00992         ChildParticle *cpa;
00993         int p, totchild = get_psys_tot_child(scene, psys);
00994 
00995         if(psys->child && totchild) {
00996             for(p=0,cpa=psys->child; p<totchild; p++,cpa++){
00997                 cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
00998                 cpa->foffset= 0.0f;
00999                 cpa->parent=0;
01000                 cpa->pa[0]=cpa->pa[1]=cpa->pa[2]=cpa->pa[3]=0;
01001                 cpa->num= -1;
01002             }
01003         }
01004     }
01005     else {
01006         PARTICLE_P;
01007         LOOP_PARTICLES {
01008             pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
01009             pa->foffset= 0.0f;
01010             pa->num= -1;
01011         }
01012     }
01013 }
01014 
01015 /* Creates a distribution of coordinates on a DerivedMesh   */
01016 /* This is to denote functionality that does not yet work with mesh - only derived mesh */
01017 static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, DerivedMesh *finaldm, int from)
01018 {
01019     ParticleThreadContext *ctx= threads[0].ctx;
01020     Object *ob= ctx->sim.ob;
01021     ParticleSystem *psys= ctx->sim.psys;
01022     ParticleData *pa=0, *tpars= 0;
01023     ParticleSettings *part;
01024     ParticleSeam *seams= 0;
01025     KDTree *tree=0;
01026     DerivedMesh *dm= NULL;
01027     float *jit= NULL;
01028     int i, seed, p=0, totthread= threads[0].tot;
01029     int cfrom=0;
01030     int totelem=0, totpart, *particle_element=0, children=0, totseam=0;
01031     int jitlevel= 1, distr;
01032     float *element_weight=NULL,*element_sum=NULL,*jitter_offset=NULL, *vweight=NULL;
01033     float cur, maxweight=0.0, tweight, totweight, inv_totweight, co[3], nor[3], orco[3], ornor[3];
01034     
01035     if(ELEM3(NULL, ob, psys, psys->part))
01036         return 0;
01037 
01038     part=psys->part;
01039     totpart=psys->totpart;
01040     if(totpart==0)
01041         return 0;
01042 
01043     if (!finaldm->deformedOnly && !finaldm->getFaceDataArray(finaldm, CD_ORIGINDEX)) {
01044         printf("Can't create particles with the current modifier stack, disable destructive modifiers\n");
01045 // XXX      error("Can't paint with the current modifier stack, disable destructive modifiers");
01046         return 0;
01047     }
01048 
01049     /* First handle special cases */
01050     if(from == PART_FROM_CHILD) {
01051         /* Simple children */
01052         if(part->childtype != PART_CHILD_FACES) {
01053             BLI_srandom(31415926 + psys->seed + psys->child_seed);
01054             distribute_simple_children(scene, ob, finaldm, psys);
01055             return 0;
01056         }
01057     }
01058     else {
01059         /* Grid distribution */
01060         if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
01061             BLI_srandom(31415926 + psys->seed);
01062             dm= CDDM_from_mesh((Mesh*)ob->data, ob);
01063             distribute_grid(dm,psys);
01064             dm->release(dm);
01065             return 0;
01066         }
01067     }
01068     
01069     /* Create trees and original coordinates if needed */
01070     if(from == PART_FROM_CHILD) {
01071         distr=PART_DISTR_RAND;
01072         BLI_srandom(31415926 + psys->seed + psys->child_seed);
01073         dm= finaldm;
01074         children=1;
01075 
01076         tree=BLI_kdtree_new(totpart);
01077 
01078         for(p=0,pa=psys->particles; p<totpart; p++,pa++){
01079             psys_particle_on_dm(dm,part->from,pa->num,pa->num_dmcache,pa->fuv,pa->foffset,co,nor,0,0,orco,ornor);
01080             transform_mesh_orco_verts((Mesh*)ob->data, &orco, 1, 1);
01081             BLI_kdtree_insert(tree, p, orco, ornor);
01082         }
01083 
01084         BLI_kdtree_balance(tree);
01085 
01086         totpart = get_psys_tot_child(scene, psys);
01087         cfrom = from = PART_FROM_FACE;
01088     }
01089     else {
01090         distr = part->distr;
01091         BLI_srandom(31415926 + psys->seed);
01092         
01093         dm= CDDM_from_mesh((Mesh*)ob->data, ob);
01094 
01095         /* we need orco for consistent distributions */
01096         DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
01097 
01098         if(from == PART_FROM_VERT) {
01099             MVert *mv= dm->getVertDataArray(dm, CD_MVERT);
01100             float (*orcodata)[3]= dm->getVertDataArray(dm, CD_ORCO);
01101             int totvert = dm->getNumVerts(dm);
01102 
01103             tree=BLI_kdtree_new(totvert);
01104 
01105             for(p=0; p<totvert; p++) {
01106                 if(orcodata) {
01107                     copy_v3_v3(co,orcodata[p]);
01108                     transform_mesh_orco_verts((Mesh*)ob->data, &co, 1, 1);
01109                 }
01110                 else
01111                     copy_v3_v3(co,mv[p].co);
01112                 BLI_kdtree_insert(tree,p,co,NULL);
01113             }
01114 
01115             BLI_kdtree_balance(tree);
01116         }
01117     }
01118 
01119     /* Get total number of emission elements and allocate needed arrays */
01120     totelem = (from == PART_FROM_VERT) ? dm->getNumVerts(dm) : dm->getNumFaces(dm);
01121 
01122     if(totelem == 0){
01123         distribute_invalid(scene, psys, children ? PART_FROM_CHILD : 0);
01124 
01125         if(G.f & G_DEBUG)
01126             fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
01127 
01128         if(dm != finaldm) dm->release(dm);
01129         return 0;
01130     }
01131 
01132     element_weight  = MEM_callocN(sizeof(float)*totelem, "particle_distribution_weights");
01133     particle_element= MEM_callocN(sizeof(int)*totpart, "particle_distribution_indexes");
01134     element_sum     = MEM_callocN(sizeof(float)*(totelem+1), "particle_distribution_sum");
01135     jitter_offset   = MEM_callocN(sizeof(float)*totelem, "particle_distribution_jitoff");
01136 
01137     /* Calculate weights from face areas */
01138     if((part->flag&PART_EDISTR || children) && from != PART_FROM_VERT){
01139         MVert *v1, *v2, *v3, *v4;
01140         float totarea=0.f, co1[3], co2[3], co3[3], co4[3];
01141         float (*orcodata)[3];
01142         
01143         orcodata= dm->getVertDataArray(dm, CD_ORCO);
01144 
01145         for(i=0; i<totelem; i++){
01146             MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
01147 
01148             if(orcodata) {
01149                 copy_v3_v3(co1, orcodata[mf->v1]);
01150                 copy_v3_v3(co2, orcodata[mf->v2]);
01151                 copy_v3_v3(co3, orcodata[mf->v3]);
01152                 transform_mesh_orco_verts((Mesh*)ob->data, &co1, 1, 1);
01153                 transform_mesh_orco_verts((Mesh*)ob->data, &co2, 1, 1);
01154                 transform_mesh_orco_verts((Mesh*)ob->data, &co3, 1, 1);
01155                 if(mf->v4) {
01156                     copy_v3_v3(co4, orcodata[mf->v4]);
01157                     transform_mesh_orco_verts((Mesh*)ob->data, &co4, 1, 1);
01158                 }
01159             }
01160             else {
01161                 v1= (MVert*)dm->getVertData(dm,mf->v1,CD_MVERT);
01162                 v2= (MVert*)dm->getVertData(dm,mf->v2,CD_MVERT);
01163                 v3= (MVert*)dm->getVertData(dm,mf->v3,CD_MVERT);
01164                 copy_v3_v3(co1, v1->co);
01165                 copy_v3_v3(co2, v2->co);
01166                 copy_v3_v3(co3, v3->co);
01167                 if(mf->v4) {
01168                     v4= (MVert*)dm->getVertData(dm,mf->v4,CD_MVERT);
01169                     copy_v3_v3(co4, v4->co);
01170                 }
01171             }
01172 
01173             cur = mf->v4 ? area_quad_v3(co1, co2, co3, co4) : area_tri_v3(co1, co2, co3);
01174             
01175             if(cur > maxweight)
01176                 maxweight = cur;
01177 
01178             element_weight[i] = cur;
01179             totarea += cur;
01180         }
01181 
01182         for(i=0; i<totelem; i++)
01183             element_weight[i] /= totarea;
01184 
01185         maxweight /= totarea;
01186     }
01187     else{
01188         float min=1.0f/(float)(MIN2(totelem,totpart));
01189         for(i=0; i<totelem; i++)
01190             element_weight[i]=min;
01191         maxweight=min;
01192     }
01193 
01194     /* Calculate weights from vgroup */
01195     vweight = psys_cache_vgroup(dm,psys,PSYS_VG_DENSITY);
01196 
01197     if(vweight){
01198         if(from==PART_FROM_VERT) {
01199             for(i=0;i<totelem; i++)
01200                 element_weight[i]*=vweight[i];
01201         }
01202         else { /* PART_FROM_FACE / PART_FROM_VOLUME */
01203             for(i=0;i<totelem; i++){
01204                 MFace *mf=dm->getFaceData(dm,i,CD_MFACE);
01205                 tweight = vweight[mf->v1] + vweight[mf->v2] + vweight[mf->v3];
01206                 
01207                 if(mf->v4) {
01208                     tweight += vweight[mf->v4];
01209                     tweight /= 4.0f;
01210                 }
01211                 else {
01212                     tweight /= 3.0f;
01213                 }
01214 
01215                 element_weight[i]*=tweight;
01216             }
01217         }
01218         MEM_freeN(vweight);
01219     }
01220 
01221     /* Calculate total weight of all elements */
01222     totweight= 0.0f;
01223     for(i=0;i<totelem; i++)
01224         totweight += element_weight[i];
01225 
01226     inv_totweight = (totweight > 0.f ? 1.f/totweight : 0.f);
01227 
01228     /* Calculate cumulative weights */
01229     element_sum[0]= 0.0f;
01230     for(i=0; i<totelem; i++)
01231         element_sum[i+1]= element_sum[i] + element_weight[i] * inv_totweight;
01232     
01233     /* Finally assign elements to particles */
01234     if((part->flag&PART_TRAND) || (part->simplify_flag&PART_SIMPLIFY_ENABLE)) {
01235         float pos;
01236 
01237         for(p=0; p<totpart; p++) {
01238             /* In theory element_sum[totelem] should be 1.0, but due to float errors this is not necessarily always true, so scale pos accordingly. */
01239             pos= BLI_frand() * element_sum[totelem];
01240             particle_element[p]= distribute_binary_search(element_sum, totelem, pos);
01241             particle_element[p]= MIN2(totelem-1, particle_element[p]);
01242             jitter_offset[particle_element[p]]= pos;
01243         }
01244     }
01245     else {
01246         double step, pos;
01247         
01248         step= (totpart < 2) ? 0.5 : 1.0/(double)totpart;
01249         pos= 1e-6; /* tiny offset to avoid zero weight face */
01250         i= 0;
01251 
01252         for(p=0; p<totpart; p++, pos+=step) {
01253             while((i < totelem) && (pos > element_sum[i+1]))
01254                 i++;
01255 
01256             particle_element[p]= MIN2(totelem-1, i);
01257 
01258             /* avoid zero weight face */
01259             if(p == totpart-1 && element_weight[particle_element[p]] == 0.0f)
01260                 particle_element[p]= particle_element[p-1];
01261 
01262             jitter_offset[particle_element[p]]= pos;
01263         }
01264     }
01265 
01266     MEM_freeN(element_sum);
01267 
01268     /* For hair, sort by origindex (allows optimizations in rendering), */
01269     /* however with virtual parents the children need to be in random order. */
01270     if(part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0f)) {
01271         COMPARE_ORIG_INDEX = NULL;
01272 
01273         if(from == PART_FROM_VERT) {
01274             if(dm->numVertData)
01275                 COMPARE_ORIG_INDEX= dm->getVertDataArray(dm, CD_ORIGINDEX);
01276         }
01277         else {
01278             if(dm->numFaceData)
01279                 COMPARE_ORIG_INDEX= dm->getFaceDataArray(dm, CD_ORIGINDEX);
01280         }
01281 
01282         if(COMPARE_ORIG_INDEX) {
01283             qsort(particle_element, totpart, sizeof(int), distribute_compare_orig_index);
01284             COMPARE_ORIG_INDEX = NULL;
01285         }
01286     }
01287 
01288     /* Create jittering if needed */
01289     if(distr==PART_DISTR_JIT && ELEM(from,PART_FROM_FACE,PART_FROM_VOLUME)) {
01290         jitlevel= part->userjit;
01291         
01292         if(jitlevel == 0) {
01293             jitlevel= totpart/totelem;
01294             if(part->flag & PART_EDISTR) jitlevel*= 2;  /* looks better in general, not very scietific */
01295             if(jitlevel<3) jitlevel= 3;
01296         }
01297         
01298         jit= MEM_callocN((2+ jitlevel*2)*sizeof(float), "jit");
01299 
01300         /* for small amounts of particles we use regular jitter since it looks
01301          * a bit better, for larger amounts we switch to hammersley sequence 
01302          * because it is much faster */
01303         if(jitlevel < 25)
01304             init_mv_jit(jit, jitlevel, psys->seed, part->jitfac);
01305         else
01306             hammersley_create(jit, jitlevel+1, psys->seed, part->jitfac);
01307         BLI_array_randomize(jit, 2*sizeof(float), jitlevel, psys->seed); /* for custom jit or even distribution */
01308     }
01309 
01310     /* Setup things for threaded distribution */
01311     ctx->tree= tree;
01312     ctx->seams= seams;
01313     ctx->totseam= totseam;
01314     ctx->sim.psys= psys;
01315     ctx->index= particle_element;
01316     ctx->jit= jit;
01317     ctx->jitlevel= jitlevel;
01318     ctx->jitoff= jitter_offset;
01319     ctx->weight= element_weight;
01320     ctx->maxweight= maxweight;
01321     ctx->from= (children)? PART_FROM_CHILD: from;
01322     ctx->cfrom= cfrom;
01323     ctx->distr= distr;
01324     ctx->dm= dm;
01325     ctx->tpars= tpars;
01326 
01327     if(children) {
01328         totpart= psys_render_simplify_distribution(ctx, totpart);
01329         alloc_child_particles(psys, totpart);
01330     }
01331 
01332     if(!children || psys->totchild < 10000)
01333         totthread= 1;
01334     
01335     seed= 31415926 + ctx->sim.psys->seed;
01336     for(i=0; i<totthread; i++) {
01337         threads[i].rng= rng_new(seed);
01338         threads[i].tot= totthread;
01339     }
01340 
01341     return 1;
01342 }
01343 
01344 static void distribute_particles_on_dm(ParticleSimulationData *sim, int from)
01345 {
01346     DerivedMesh *finaldm = sim->psmd->dm;
01347     ListBase threads;
01348     ParticleThread *pthreads;
01349     ParticleThreadContext *ctx;
01350     int i, totthread;
01351 
01352     pthreads= psys_threads_create(sim);
01353 
01354     if(!distribute_threads_init_data(pthreads, sim->scene, finaldm, from)) {
01355         psys_threads_free(pthreads);
01356         return;
01357     }
01358 
01359     totthread= pthreads[0].tot;
01360     if(totthread > 1) {
01361         BLI_init_threads(&threads, distribute_threads_exec_cb, totthread);
01362 
01363         for(i=0; i<totthread; i++)
01364             BLI_insert_thread(&threads, &pthreads[i]);
01365 
01366         BLI_end_threads(&threads);
01367     }
01368     else
01369         distribute_threads_exec_cb(&pthreads[0]);
01370 
01371     psys_calc_dmcache(sim->ob, finaldm, sim->psys);
01372 
01373     ctx= pthreads[0].ctx;
01374     if(ctx->dm != finaldm)
01375         ctx->dm->release(ctx->dm);
01376 
01377     psys_threads_free(pthreads);
01378 }
01379 
01380 /* ready for future use, to emit particles without geometry */
01381 static void distribute_particles_on_shape(ParticleSimulationData *sim, int UNUSED(from))
01382 {
01383     distribute_invalid(sim->scene, sim->psys, 0);
01384 
01385     fprintf(stderr,"Shape emission not yet possible!\n");
01386 }
01387 
01388 static void distribute_particles(ParticleSimulationData *sim, int from)
01389 {
01390     PARTICLE_PSMD;
01391     int distr_error=0;
01392 
01393     if(psmd){
01394         if(psmd->dm)
01395             distribute_particles_on_dm(sim, from);
01396         else
01397             distr_error=1;
01398     }
01399     else
01400         distribute_particles_on_shape(sim, from);
01401 
01402     if(distr_error){
01403         distribute_invalid(sim->scene, sim->psys, from);
01404 
01405         fprintf(stderr,"Particle distribution error!\n");
01406     }
01407 }
01408 
01409 /* threaded child particle distribution and path caching */
01410 ParticleThread *psys_threads_create(ParticleSimulationData *sim)
01411 {
01412     ParticleThread *threads;
01413     ParticleThreadContext *ctx;
01414     int i, totthread;
01415 
01416     if(sim->scene->r.mode & R_FIXED_THREADS)
01417         totthread= sim->scene->r.threads;
01418     else
01419         totthread= BLI_system_thread_count();
01420     
01421     threads= MEM_callocN(sizeof(ParticleThread)*totthread, "ParticleThread");
01422     ctx= MEM_callocN(sizeof(ParticleThreadContext), "ParticleThreadContext");
01423 
01424     ctx->sim = *sim;
01425     ctx->dm= ctx->sim.psmd->dm;
01426     ctx->ma= give_current_material(sim->ob, sim->psys->part->omat);
01427 
01428     memset(threads, 0, sizeof(ParticleThread)*totthread);
01429 
01430     for(i=0; i<totthread; i++) {
01431         threads[i].ctx= ctx;
01432         threads[i].num= i;
01433         threads[i].tot= totthread;
01434     }
01435 
01436     return threads;
01437 }
01438 
01439 void psys_threads_free(ParticleThread *threads)
01440 {
01441     ParticleThreadContext *ctx= threads[0].ctx;
01442     int i, totthread= threads[0].tot;
01443 
01444     /* path caching */
01445     if(ctx->vg_length)
01446         MEM_freeN(ctx->vg_length);
01447     if(ctx->vg_clump)
01448         MEM_freeN(ctx->vg_clump);
01449     if(ctx->vg_kink)
01450         MEM_freeN(ctx->vg_kink);
01451     if(ctx->vg_rough1)
01452         MEM_freeN(ctx->vg_rough1);
01453     if(ctx->vg_rough2)
01454         MEM_freeN(ctx->vg_rough2);
01455     if(ctx->vg_roughe)
01456         MEM_freeN(ctx->vg_roughe);
01457 
01458     if(ctx->sim.psys->lattice){
01459         end_latt_deform(ctx->sim.psys->lattice);
01460         ctx->sim.psys->lattice= NULL;
01461     }
01462 
01463     /* distribution */
01464     if(ctx->jit) MEM_freeN(ctx->jit);
01465     if(ctx->jitoff) MEM_freeN(ctx->jitoff);
01466     if(ctx->weight) MEM_freeN(ctx->weight);
01467     if(ctx->index) MEM_freeN(ctx->index);
01468     if(ctx->skip) MEM_freeN(ctx->skip);
01469     if(ctx->seams) MEM_freeN(ctx->seams);
01470     //if(ctx->vertpart) MEM_freeN(ctx->vertpart);
01471     BLI_kdtree_free(ctx->tree);
01472 
01473     /* threads */
01474     for(i=0; i<totthread; i++) {
01475         if(threads[i].rng)
01476             rng_free(threads[i].rng);
01477         if(threads[i].rng_path)
01478             rng_free(threads[i].rng_path);
01479     }
01480 
01481     MEM_freeN(ctx);
01482     MEM_freeN(threads);
01483 }
01484 
01485 /* set particle parameters that don't change during particle's life */
01486 void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p)
01487 {
01488     ParticleSystem *psys = sim->psys;
01489     ParticleSettings *part = psys->part;
01490     ParticleTexture ptex;
01491 
01492     pa->flag &= ~PARS_UNEXIST;
01493 
01494     if(part->type != PART_FLUID) {
01495         psys_get_texture(sim, pa, &ptex, PAMAP_INIT, 0.f);
01496         
01497         if(ptex.exist < PSYS_FRAND(p+125))
01498             pa->flag |= PARS_UNEXIST;
01499 
01500         pa->time = (part->type == PART_HAIR) ? 0.f : part->sta + (part->end - part->sta)*ptex.time;
01501     }
01502 
01503     pa->hair_index = 0;
01504     /* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */
01505     /* usage other than straight after distribute has to handle this index by itself - jahka*/
01506     //pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */
01507 }
01508 static void initialize_all_particles(ParticleSimulationData *sim)
01509 {
01510     ParticleSystem *psys = sim->psys;
01511     PARTICLE_P;
01512 
01513     psys->totunexist = 0;
01514 
01515     LOOP_PARTICLES {
01516         if((pa->flag & PARS_UNEXIST)==0)
01517             initialize_particle(sim, pa, p);
01518 
01519         if(pa->flag & PARS_UNEXIST)
01520             psys->totunexist++;
01521     }
01522 
01523     /* Free unexisting particles. */
01524     if(psys->totpart && psys->totunexist == psys->totpart) {
01525         if(psys->particles->boid)
01526             MEM_freeN(psys->particles->boid);
01527 
01528         MEM_freeN(psys->particles);
01529         psys->particles = NULL;
01530         psys->totpart = psys->totunexist = 0;
01531     }
01532 
01533     if(psys->totunexist) {
01534         int newtotpart = psys->totpart - psys->totunexist;
01535         ParticleData *npa, *newpars;
01536         
01537         npa = newpars = MEM_callocN(newtotpart * sizeof(ParticleData), "particles");
01538 
01539         for(p=0, pa=psys->particles; p<newtotpart; p++, pa++, npa++) {
01540             while(pa->flag & PARS_UNEXIST)
01541                 pa++;
01542 
01543             memcpy(npa, pa, sizeof(ParticleData));
01544         }
01545 
01546         if(psys->particles->boid)
01547             MEM_freeN(psys->particles->boid);
01548         MEM_freeN(psys->particles);
01549         psys->particles = newpars;
01550         psys->totpart -= psys->totunexist;
01551 
01552         if(psys->particles->boid) {
01553             BoidParticle *newboids = MEM_callocN(psys->totpart * sizeof(BoidParticle), "boid particles");
01554 
01555             LOOP_PARTICLES
01556                 pa->boid = newboids++;
01557 
01558         }
01559     }
01560 }
01561 void psys_get_birth_coordinates(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, float dtime, float cfra)
01562 {
01563     Object *ob = sim->ob;
01564     ParticleSystem *psys = sim->psys;
01565     ParticleSettings *part;
01566     ParticleTexture ptex;
01567     float fac, phasefac, nor[3]={0,0,0},loc[3],vel[3]={0.0,0.0,0.0},rot[4],q2[4];
01568     float r_vel[3],r_ave[3],r_rot[4],vec[3],p_vel[3]={0.0,0.0,0.0};
01569     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};
01570     float q_phase[4];
01571     int p = pa - psys->particles;
01572     part=psys->part;
01573 
01574     /* get birth location from object       */
01575     if(part->tanfac != 0.f)
01576         psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,utan,vtan,0,0);
01577     else
01578         psys_particle_on_emitter(sim->psmd, part->from,pa->num, pa->num_dmcache, pa->fuv,pa->foffset,loc,nor,0,0,0,0);
01579         
01580     /* get possible textural influence */
01581     psys_get_texture(sim, pa, &ptex, PAMAP_IVEL, cfra);
01582 
01583     /* particles live in global space so    */
01584     /* let's convert:                       */
01585     /* -location                            */
01586     mul_m4_v3(ob->obmat, loc);
01587         
01588     /* -normal                              */
01589     mul_mat3_m4_v3(ob->obmat, nor);
01590     normalize_v3(nor);
01591 
01592     /* -tangent                             */
01593     if(part->tanfac!=0.0f){
01594         //float phase=vg_rot?2.0f*(psys_particle_value_from_verts(sim->psmd->dm,part->from,pa,vg_rot)-0.5f):0.0f;
01595         float phase=0.0f;
01596         mul_v3_fl(vtan,-cosf((float)M_PI*(part->tanphase+phase)));
01597         fac= -sinf((float)M_PI*(part->tanphase+phase));
01598         madd_v3_v3fl(vtan, utan, fac);
01599 
01600         mul_mat3_m4_v3(ob->obmat,vtan);
01601 
01602         copy_v3_v3(utan, nor);
01603         mul_v3_fl(utan,dot_v3v3(vtan,nor));
01604         sub_v3_v3(vtan, utan);
01605             
01606         normalize_v3(vtan);
01607     }
01608         
01609 
01610     /* -velocity (boids need this even if there's no random velocity) */
01611     if(part->randfac != 0.0f || (part->phystype==PART_PHYS_BOIDS && pa->boid)){
01612         r_vel[0] = 2.0f * (PSYS_FRAND(p + 10) - 0.5f);
01613         r_vel[1] = 2.0f * (PSYS_FRAND(p + 11) - 0.5f);
01614         r_vel[2] = 2.0f * (PSYS_FRAND(p + 12) - 0.5f);
01615 
01616         mul_mat3_m4_v3(ob->obmat, r_vel);
01617         normalize_v3(r_vel);
01618     }
01619 
01620     /* -angular velocity                    */
01621     if(part->avemode==PART_AVE_RAND){
01622         r_ave[0] = 2.0f * (PSYS_FRAND(p + 13) - 0.5f);
01623         r_ave[1] = 2.0f * (PSYS_FRAND(p + 14) - 0.5f);
01624         r_ave[2] = 2.0f * (PSYS_FRAND(p + 15) - 0.5f);
01625 
01626         mul_mat3_m4_v3(ob->obmat,r_ave);
01627         normalize_v3(r_ave);
01628     }
01629         
01630     /* -rotation                            */
01631     if(part->randrotfac != 0.0f){
01632         r_rot[0] = 2.0f * (PSYS_FRAND(p + 16) - 0.5f);
01633         r_rot[1] = 2.0f * (PSYS_FRAND(p + 17) - 0.5f);
01634         r_rot[2] = 2.0f * (PSYS_FRAND(p + 18) - 0.5f);
01635         r_rot[3] = 2.0f * (PSYS_FRAND(p + 19) - 0.5f);
01636         normalize_qt(r_rot);
01637 
01638         mat4_to_quat(rot,ob->obmat);
01639         mul_qt_qtqt(r_rot,r_rot,rot);
01640     }
01641 
01642     if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
01643         float dvec[3], q[4], mat[3][3];
01644 
01645         copy_v3_v3(state->co,loc);
01646 
01647         /* boids don't get any initial velocity  */
01648         zero_v3(state->vel);
01649 
01650         /* boids store direction in ave */
01651         if(fabsf(nor[2])==1.0f) {
01652             sub_v3_v3v3(state->ave, loc, ob->obmat[3]);
01653             normalize_v3(state->ave);
01654         }
01655         else {
01656             copy_v3_v3(state->ave, nor);
01657         }
01658 
01659         /* calculate rotation matrix */
01660         project_v3_v3v3(dvec, r_vel, state->ave);
01661         sub_v3_v3v3(mat[0], state->ave, dvec);
01662         normalize_v3(mat[0]);
01663         negate_v3_v3(mat[2], r_vel);
01664         normalize_v3(mat[2]);
01665         cross_v3_v3v3(mat[1], mat[2], mat[0]);
01666         
01667         /* apply rotation */
01668         mat3_to_quat_is_ok( q,mat);
01669         copy_qt_qt(state->rot, q);
01670     }
01671     else {
01672         /* conversion done so now we apply new: */
01673         /* -velocity from:                      */
01674 
01675         /*      *reactions                      */
01676         if(dtime > 0.f){
01677             sub_v3_v3v3(vel, pa->state.vel, pa->prev_state.vel);
01678         }
01679 
01680         /*      *emitter velocity               */
01681         if(dtime != 0.f && part->obfac != 0.f){
01682             sub_v3_v3v3(vel, loc, state->co);
01683             mul_v3_fl(vel, part->obfac/dtime);
01684         }
01685         
01686         /*      *emitter normal                 */
01687         if(part->normfac != 0.f)
01688             madd_v3_v3fl(vel, nor, part->normfac);
01689         
01690         /*      *emitter tangent                */
01691         if(sim->psmd && part->tanfac != 0.f)
01692             madd_v3_v3fl(vel, vtan, part->tanfac);
01693 
01694         /*      *emitter object orientation     */
01695         if(part->ob_vel[0] != 0.f) {
01696             normalize_v3_v3(vec, ob->obmat[0]);
01697             madd_v3_v3fl(vel, vec, part->ob_vel[0]);
01698         }
01699         if(part->ob_vel[1] != 0.f) {
01700             normalize_v3_v3(vec, ob->obmat[1]);
01701             madd_v3_v3fl(vel, vec, part->ob_vel[1]);
01702         }
01703         if(part->ob_vel[2] != 0.f) {
01704             normalize_v3_v3(vec, ob->obmat[2]);
01705             madd_v3_v3fl(vel, vec, part->ob_vel[2]);
01706         }
01707 
01708         /*      *texture                        */
01709         /* TODO */
01710 
01711         /*      *random                         */
01712         if(part->randfac != 0.f)
01713             madd_v3_v3fl(vel, r_vel, part->randfac);
01714 
01715         /*      *particle                       */
01716         if(part->partfac != 0.f)
01717             madd_v3_v3fl(vel, p_vel, part->partfac);
01718         
01719         mul_v3_v3fl(state->vel, vel, ptex.ivel);
01720 
01721         /* -location from emitter               */
01722         copy_v3_v3(state->co,loc);
01723 
01724         /* -rotation                            */
01725         unit_qt(state->rot);
01726 
01727         if(part->rotmode){
01728             /* create vector into which rotation is aligned */
01729             switch(part->rotmode){
01730                 case PART_ROT_NOR:
01731                     copy_v3_v3(rot_vec, nor);
01732                     break;
01733                 case PART_ROT_VEL:
01734                     copy_v3_v3(rot_vec, vel);
01735                     break;
01736                 case PART_ROT_GLOB_X:
01737                 case PART_ROT_GLOB_Y:
01738                 case PART_ROT_GLOB_Z:
01739                     rot_vec[part->rotmode - PART_ROT_GLOB_X] = 1.0f;
01740                     break;
01741                 case PART_ROT_OB_X:
01742                 case PART_ROT_OB_Y:
01743                 case PART_ROT_OB_Z:
01744                     copy_v3_v3(rot_vec, ob->obmat[part->rotmode - PART_ROT_OB_X]);
01745                     break;
01746             }
01747             
01748             /* create rotation quat */
01749             negate_v3(rot_vec);
01750             vec_to_quat( q2,rot_vec, OB_POSX, OB_POSZ);
01751 
01752             /* randomize rotation quat */
01753             if(part->randrotfac!=0.0f)
01754                 interp_qt_qtqt(rot, q2, r_rot, part->randrotfac);
01755             else
01756                 copy_qt_qt(rot,q2);
01757 
01758             /* rotation phase */
01759             phasefac = part->phasefac;
01760             if(part->randphasefac != 0.0f)
01761                 phasefac += part->randphasefac * PSYS_FRAND(p + 20);
01762             axis_angle_to_quat( q_phase,x_vec, phasefac*(float)M_PI);
01763 
01764             /* combine base rotation & phase */
01765             mul_qt_qtqt(state->rot, rot, q_phase);
01766         }
01767 
01768         /* -angular velocity                    */
01769 
01770         zero_v3(state->ave);
01771 
01772         if(part->avemode){
01773             switch(part->avemode){
01774                 case PART_AVE_SPIN:
01775                     copy_v3_v3(state->ave, vel);
01776                     break;
01777                 case PART_AVE_RAND:
01778                     copy_v3_v3(state->ave, r_ave);
01779                     break;
01780             }
01781             normalize_v3(state->ave);
01782             mul_v3_fl(state->ave, part->avefac);
01783         }
01784     }
01785 }
01786 /* sets particle to the emitter surface with initial velocity & rotation */
01787 void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime, float cfra)
01788 {
01789     Object *ob = sim->ob;
01790     ParticleSystem *psys = sim->psys;
01791     ParticleSettings *part;
01792     ParticleTexture ptex;
01793     int p = pa - psys->particles;
01794     part=psys->part;
01795     
01796     /* get precise emitter matrix if particle is born */
01797     if(part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
01798         /* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
01799         while(ob) {
01800             BKE_animsys_evaluate_animdata(sim->scene, &ob->id, ob->adt, pa->time, ADT_RECALC_ANIM);
01801             ob = ob->parent;
01802         }
01803         ob = sim->ob;
01804         where_is_object_time(sim->scene, ob, pa->time);
01805     }
01806 
01807     psys_get_birth_coordinates(sim, pa, &pa->state, dtime, cfra);
01808 
01809     if(part->phystype==PART_PHYS_BOIDS && pa->boid) {
01810         BoidParticle *bpa = pa->boid;
01811 
01812         /* and gravity in r_ve */
01813         bpa->gravity[0] = bpa->gravity[1] = 0.0f;
01814         bpa->gravity[2] = -1.0f;
01815         if((sim->scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY)
01816             && sim->scene->physics_settings.gravity[2]!=0.0f)
01817             bpa->gravity[2] = sim->scene->physics_settings.gravity[2];
01818 
01819         bpa->data.health = part->boids->health;
01820         bpa->data.mode = eBoidMode_InAir;
01821         bpa->data.state_id = ((BoidState*)part->boids->states.first)->id;
01822         bpa->data.acc[0]=bpa->data.acc[1]=bpa->data.acc[2]=0.0f;
01823     }
01824 
01825 
01826     if(part->type == PART_HAIR){
01827         pa->lifetime = 100.0f;
01828     }
01829     else{
01830         /* get possible textural influence */
01831         psys_get_texture(sim, pa, &ptex, PAMAP_LIFE, cfra);
01832 
01833         pa->lifetime = part->lifetime * ptex.life;
01834 
01835         if(part->randlife != 0.0f)
01836             pa->lifetime *= 1.0f - part->randlife * PSYS_FRAND(p + 21);
01837     }
01838 
01839     pa->dietime = pa->time + pa->lifetime;
01840 
01841     if(sim->psys->pointcache && sim->psys->pointcache->flag & PTCACHE_BAKED &&
01842         sim->psys->pointcache->mem_cache.first) {
01843         float dietime = psys_get_dietime_from_cache(sim->psys->pointcache, p);
01844         pa->dietime = MIN2(pa->dietime, dietime);
01845     }
01846 
01847     if(pa->time > cfra)
01848         pa->alive = PARS_UNBORN;
01849     else if(pa->dietime <= cfra)
01850         pa->alive = PARS_DEAD;
01851     else
01852         pa->alive = PARS_ALIVE;
01853 
01854     pa->state.time = cfra;
01855 }
01856 static void reset_all_particles(ParticleSimulationData *sim, float dtime, float cfra, int from)
01857 {
01858     ParticleData *pa;
01859     int p, totpart=sim->psys->totpart;
01860     
01861     for(p=from, pa=sim->psys->particles+from; p<totpart; p++, pa++)
01862         reset_particle(sim, pa, dtime, cfra);
01863 }
01864 /************************************************/
01865 /*          Particle targets                    */
01866 /************************************************/
01867 ParticleSystem *psys_get_target_system(Object *ob, ParticleTarget *pt)
01868 {
01869     ParticleSystem *psys = NULL;
01870 
01871     if(pt->ob == NULL || pt->ob == ob)
01872         psys = BLI_findlink(&ob->particlesystem, pt->psys-1);
01873     else
01874         psys = BLI_findlink(&pt->ob->particlesystem, pt->psys-1);
01875 
01876     if(psys)
01877         pt->flag |= PTARGET_VALID;
01878     else
01879         pt->flag &= ~PTARGET_VALID;
01880 
01881     return psys;
01882 }
01883 /************************************************/
01884 /*          Keyed particles                     */
01885 /************************************************/
01886 /* Counts valid keyed targets */
01887 void psys_count_keyed_targets(ParticleSimulationData *sim)
01888 {
01889     ParticleSystem *psys = sim->psys, *kpsys;
01890     ParticleTarget *pt = psys->targets.first;
01891     int keys_valid = 1;
01892     psys->totkeyed = 0;
01893 
01894     for(; pt; pt=pt->next) {
01895         kpsys = psys_get_target_system(sim->ob, pt);
01896 
01897         if(kpsys && kpsys->totpart) {
01898             psys->totkeyed += keys_valid;
01899             if(psys->flag & PSYS_KEYED_TIMING && pt->duration != 0.0f)
01900                 psys->totkeyed += 1;
01901         }
01902         else {
01903             keys_valid = 0;
01904         }
01905     }
01906 
01907     psys->totkeyed *= psys->flag & PSYS_KEYED_TIMING ? 1 : psys->part->keyed_loops;
01908 }
01909 
01910 static void set_keyed_keys(ParticleSimulationData *sim)
01911 {
01912     ParticleSystem *psys = sim->psys;
01913     ParticleSimulationData ksim= {0};
01914     ParticleTarget *pt;
01915     PARTICLE_P;
01916     ParticleKey *key;
01917     int totpart = psys->totpart, k, totkeys = psys->totkeyed;
01918     int keyed_flag = 0;
01919 
01920     ksim.scene= sim->scene;
01921     
01922     /* no proper targets so let's clear and bail out */
01923     if(psys->totkeyed==0) {
01924         free_keyed_keys(psys);
01925         psys->flag &= ~PSYS_KEYED;
01926         return;
01927     }
01928 
01929     if(totpart && psys->particles->totkey != totkeys) {
01930         free_keyed_keys(psys);
01931         
01932         key = MEM_callocN(totpart*totkeys*sizeof(ParticleKey), "Keyed keys");
01933         
01934         LOOP_PARTICLES {
01935             pa->keys = key;
01936             pa->totkey = totkeys;
01937             key += totkeys;
01938         }
01939     }
01940     
01941     psys->flag &= ~PSYS_KEYED;
01942 
01943 
01944     pt = psys->targets.first;
01945     for(k=0; k<totkeys; k++) {
01946         ksim.ob = pt->ob ? pt->ob : sim->ob;
01947         ksim.psys = BLI_findlink(&ksim.ob->particlesystem, pt->psys - 1);
01948         keyed_flag = (ksim.psys->flag & PSYS_KEYED);
01949         ksim.psys->flag &= ~PSYS_KEYED;
01950 
01951         LOOP_PARTICLES {
01952             key = pa->keys + k;
01953             key->time = -1.0; /* use current time */
01954 
01955             psys_get_particle_state(&ksim, p%ksim.psys->totpart, key, 1);
01956 
01957             if(psys->flag & PSYS_KEYED_TIMING){
01958                 key->time = pa->time + pt->time;
01959                 if(pt->duration != 0.0f && k+1 < totkeys) {
01960                     copy_particle_key(key+1, key, 1);
01961                     (key+1)->time = pa->time + pt->time + pt->duration;
01962                 }
01963             }
01964             else if(totkeys > 1)
01965                 key->time = pa->time + (float)k / (float)(totkeys - 1) * pa->lifetime;
01966             else
01967                 key->time = pa->time;
01968         }
01969 
01970         if(psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f)
01971             k++;
01972 
01973         ksim.psys->flag |= keyed_flag;
01974 
01975         pt = (pt->next && pt->next->flag & PTARGET_VALID)? pt->next : psys->targets.first;
01976     }
01977 
01978     psys->flag |= PSYS_KEYED;
01979 }
01980 
01981 /************************************************/
01982 /*          Point Cache                         */
01983 /************************************************/
01984 void psys_make_temp_pointcache(Object *ob, ParticleSystem *psys)
01985 {
01986     PointCache *cache = psys->pointcache;
01987 
01988     if(cache->flag & PTCACHE_DISK_CACHE && cache->mem_cache.first == NULL) {
01989         PTCacheID pid;
01990         BKE_ptcache_id_from_particles(&pid, ob, psys);
01991         cache->flag &= ~PTCACHE_DISK_CACHE;
01992         BKE_ptcache_disk_to_mem(&pid);
01993         cache->flag |= PTCACHE_DISK_CACHE;
01994     }
01995 }
01996 static void psys_clear_temp_pointcache(ParticleSystem *psys)
01997 {
01998     if(psys->pointcache->flag & PTCACHE_DISK_CACHE)
01999         BKE_ptcache_free_mem(&psys->pointcache->mem_cache);
02000 }
02001 void psys_get_pointcache_start_end(Scene *scene, ParticleSystem *psys, int *sfra, int *efra)
02002 {
02003     ParticleSettings *part = psys->part;
02004 
02005     *sfra = MAX2(1, (int)part->sta);
02006     *efra = MIN2((int)(part->end + part->lifetime + 1.0f), scene->r.efra);
02007 }
02008 
02009 /************************************************/
02010 /*          Effectors                           */
02011 /************************************************/
02012 static void psys_update_particle_bvhtree(ParticleSystem *psys, float cfra)
02013 {
02014     if(psys) {
02015         PARTICLE_P;
02016         int totpart = 0;
02017 
02018         if(!psys->bvhtree || psys->bvhtree_frame != cfra) {
02019             LOOP_SHOWN_PARTICLES {
02020                 totpart++;
02021             }
02022             
02023             BLI_bvhtree_free(psys->bvhtree);
02024             psys->bvhtree = BLI_bvhtree_new(totpart, 0.0, 4, 6);
02025 
02026             LOOP_SHOWN_PARTICLES {
02027                 if(pa->alive == PARS_ALIVE) {
02028                     if(pa->state.time == cfra)
02029                         BLI_bvhtree_insert(psys->bvhtree, p, pa->prev_state.co, 1);
02030                     else
02031                         BLI_bvhtree_insert(psys->bvhtree, p, pa->state.co, 1);
02032                 }
02033             }
02034             BLI_bvhtree_balance(psys->bvhtree);
02035 
02036             psys->bvhtree_frame = cfra;
02037         }
02038     }
02039 }
02040 void psys_update_particle_tree(ParticleSystem *psys, float cfra)
02041 {
02042     if(psys) {
02043         PARTICLE_P;
02044         int totpart = 0;
02045 
02046         if(!psys->tree || psys->tree_frame != cfra) {
02047             LOOP_SHOWN_PARTICLES {
02048                 totpart++;
02049             }
02050 
02051             BLI_kdtree_free(psys->tree);
02052             psys->tree = BLI_kdtree_new(psys->totpart);
02053 
02054             LOOP_SHOWN_PARTICLES {
02055                 if(pa->alive == PARS_ALIVE) {
02056                     if(pa->state.time == cfra)
02057                         BLI_kdtree_insert(psys->tree, p, pa->prev_state.co, NULL);
02058                     else
02059                         BLI_kdtree_insert(psys->tree, p, pa->state.co, NULL);
02060                 }
02061             }
02062             BLI_kdtree_balance(psys->tree);
02063 
02064             psys->tree_frame = cfra;
02065         }
02066     }
02067 }
02068 
02069 static void psys_update_effectors(ParticleSimulationData *sim)
02070 {
02071     pdEndEffectors(&sim->psys->effectors);
02072     sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights);
02073     precalc_guides(sim, sim->psys->effectors);
02074 }
02075 
02076 static void integrate_particle(ParticleSettings *part, ParticleData *pa, float dtime, float *external_acceleration, void (*force_func)(void *forcedata, ParticleKey *state, float *force, float *impulse), void *forcedata)
02077 {
02078     ParticleKey states[5];
02079     float force[3],acceleration[3],impulse[3],dx[4][3],dv[4][3],oldpos[3];
02080     float pa_mass= (part->flag & PART_SIZEMASS ? part->mass * pa->size : part->mass);
02081     int i, steps=1;
02082     int integrator = part->integrator;
02083 
02084     copy_v3_v3(oldpos, pa->state.co);
02085     
02086     /* Verlet integration behaves strangely with moving emitters, so do first step with euler. */
02087     if(pa->prev_state.time < 0.f && integrator == PART_INT_VERLET)
02088         integrator = PART_INT_EULER;
02089 
02090     switch(integrator){
02091         case PART_INT_EULER:
02092             steps=1;
02093             break;
02094         case PART_INT_MIDPOINT:
02095             steps=2;
02096             break;
02097         case PART_INT_RK4:
02098             steps=4;
02099             break;
02100         case PART_INT_VERLET:
02101             steps=1;
02102             break;
02103     }
02104 
02105     copy_particle_key(states, &pa->state, 1);
02106 
02107     states->time = 0.f;
02108 
02109     for(i=0; i<steps; i++){
02110         zero_v3(force);
02111         zero_v3(impulse);
02112 
02113         force_func(forcedata, states+i, force, impulse);
02114 
02115         /* force to acceleration*/
02116         mul_v3_v3fl(acceleration, force, 1.0f/pa_mass);
02117 
02118         if(external_acceleration)
02119             add_v3_v3(acceleration, external_acceleration);
02120         
02121         /* calculate next state */
02122         add_v3_v3(states[i].vel, impulse);
02123 
02124         switch(integrator){
02125             case PART_INT_EULER:
02126                 madd_v3_v3v3fl(pa->state.co, states->co, states->vel, dtime);
02127                 madd_v3_v3v3fl(pa->state.vel, states->vel, acceleration, dtime);
02128                 break;
02129             case PART_INT_MIDPOINT:
02130                 if(i==0){
02131                     madd_v3_v3v3fl(states[1].co, states->co, states->vel, dtime*0.5f);
02132                     madd_v3_v3v3fl(states[1].vel, states->vel, acceleration, dtime*0.5f);
02133                     states[1].time = dtime*0.5f;
02134                     /*fra=sim->psys->cfra+0.5f*dfra;*/
02135                 }
02136                 else{
02137                     madd_v3_v3v3fl(pa->state.co, states->co, states[1].vel, dtime);
02138                     madd_v3_v3v3fl(pa->state.vel, states->vel, acceleration, dtime);
02139                 }
02140                 break;
02141             case PART_INT_RK4:
02142                 switch(i){
02143                     case 0:
02144                         copy_v3_v3(dx[0], states->vel);
02145                         mul_v3_fl(dx[0], dtime);
02146                         copy_v3_v3(dv[0], acceleration);
02147                         mul_v3_fl(dv[0], dtime);
02148 
02149                         madd_v3_v3v3fl(states[1].co, states->co, dx[0], 0.5f);
02150                         madd_v3_v3v3fl(states[1].vel, states->vel, dv[0], 0.5f);
02151                         states[1].time = dtime*0.5f;
02152                         /*fra=sim->psys->cfra+0.5f*dfra;*/
02153                         break;
02154                     case 1:
02155                         madd_v3_v3v3fl(dx[1], states->vel, dv[0], 0.5f);
02156                         mul_v3_fl(dx[1], dtime);
02157                         copy_v3_v3(dv[1], acceleration);
02158                         mul_v3_fl(dv[1], dtime);
02159 
02160                         madd_v3_v3v3fl(states[2].co, states->co, dx[1], 0.5f);
02161                         madd_v3_v3v3fl(states[2].vel, states->vel, dv[1], 0.5f);
02162                         states[2].time = dtime*0.5f;
02163                         break;
02164                     case 2:
02165                         madd_v3_v3v3fl(dx[2], states->vel, dv[1], 0.5f);
02166                         mul_v3_fl(dx[2], dtime);
02167                         copy_v3_v3(dv[2], acceleration);
02168                         mul_v3_fl(dv[2], dtime);
02169 
02170                         add_v3_v3v3(states[3].co, states->co, dx[2]);
02171                         add_v3_v3v3(states[3].vel, states->vel, dv[2]);
02172                         states[3].time = dtime;
02173                         /*fra=cfra;*/
02174                         break;
02175                     case 3:
02176                         add_v3_v3v3(dx[3], states->vel, dv[2]);
02177                         mul_v3_fl(dx[3], dtime);
02178                         copy_v3_v3(dv[3], acceleration);
02179                         mul_v3_fl(dv[3], dtime);
02180 
02181                         madd_v3_v3v3fl(pa->state.co, states->co, dx[0], 1.0f/6.0f);
02182                         madd_v3_v3fl(pa->state.co, dx[1], 1.0f/3.0f);
02183                         madd_v3_v3fl(pa->state.co, dx[2], 1.0f/3.0f);
02184                         madd_v3_v3fl(pa->state.co, dx[3], 1.0f/6.0f);
02185 
02186                         madd_v3_v3v3fl(pa->state.vel, states->vel, dv[0], 1.0f/6.0f);
02187                         madd_v3_v3fl(pa->state.vel, dv[1], 1.0f/3.0f);
02188                         madd_v3_v3fl(pa->state.vel, dv[2], 1.0f/3.0f);
02189                         madd_v3_v3fl(pa->state.vel, dv[3], 1.0f/6.0f);
02190                 }
02191                 break;
02192             case PART_INT_VERLET:   /* Verlet integration */
02193                 madd_v3_v3v3fl(pa->state.vel, pa->prev_state.vel, acceleration, dtime);
02194                 madd_v3_v3v3fl(pa->state.co, pa->prev_state.co, pa->state.vel, dtime);
02195 
02196                 sub_v3_v3v3(pa->state.vel, pa->state.co, oldpos);
02197                 mul_v3_fl(pa->state.vel, 1.0f/dtime);
02198                 break;
02199         }
02200     }
02201 }
02202 
02203 /*********************************************************************************************************
02204                     SPH fluid physics 
02205 
02206  In theory, there could be unlimited implementation of SPH simulators
02207 
02208  This code uses in some parts adapted algorithms from the pseudo code as outlined in the Research paper:
02209 
02210  Titled: Particle-based Viscoelastic Fluid Simulation.
02211  Authors: Simon Clavet, Philippe Beaudoin and Pierre Poulin
02212  Website: http://www.iro.umontreal.ca/labs/infographie/papers/Clavet-2005-PVFS/
02213 
02214  Presented at Siggraph, (2005)
02215 
02216 ***********************************************************************************************************/
02217 #define PSYS_FLUID_SPRINGS_INITIAL_SIZE 256
02218 static ParticleSpring *sph_spring_add(ParticleSystem *psys, ParticleSpring *spring)
02219 {
02220     /* Are more refs required? */
02221     if(psys->alloc_fluidsprings == 0 || psys->fluid_springs == NULL) {
02222         psys->alloc_fluidsprings = PSYS_FLUID_SPRINGS_INITIAL_SIZE;
02223         psys->fluid_springs = (ParticleSpring*)MEM_callocN(psys->alloc_fluidsprings * sizeof(ParticleSpring), "Particle Fluid Springs");
02224     }
02225     else if(psys->tot_fluidsprings == psys->alloc_fluidsprings) {
02226         /* Double the number of refs allocated */
02227         psys->alloc_fluidsprings *= 2;
02228         psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs, psys->alloc_fluidsprings * sizeof(ParticleSpring));
02229     }
02230 
02231     memcpy(psys->fluid_springs + psys->tot_fluidsprings, spring, sizeof(ParticleSpring));
02232     psys->tot_fluidsprings++;
02233 
02234     return psys->fluid_springs + psys->tot_fluidsprings - 1;
02235 }
02236 static void sph_spring_delete(ParticleSystem *psys, int j)
02237 {
02238     if (j != psys->tot_fluidsprings - 1)
02239         psys->fluid_springs[j] = psys->fluid_springs[psys->tot_fluidsprings - 1];
02240 
02241     psys->tot_fluidsprings--;
02242 
02243     if (psys->tot_fluidsprings < psys->alloc_fluidsprings/2 && psys->alloc_fluidsprings > PSYS_FLUID_SPRINGS_INITIAL_SIZE){
02244         psys->alloc_fluidsprings /= 2;
02245         psys->fluid_springs = (ParticleSpring*)MEM_reallocN(psys->fluid_springs,  psys->alloc_fluidsprings * sizeof(ParticleSpring));
02246     }
02247 }
02248 static void sph_springs_modify(ParticleSystem *psys, float dtime)
02249 {
02250     SPHFluidSettings *fluid = psys->part->fluid;
02251     ParticleData *pa1, *pa2;
02252     ParticleSpring *spring = psys->fluid_springs;
02253     
02254     float h, d, Rij[3], rij, Lij;
02255     int i;
02256 
02257     float yield_ratio = fluid->yield_ratio;
02258     float plasticity = fluid->plasticity_constant;
02259     /* scale things according to dtime */
02260     float timefix = 25.f * dtime;
02261 
02262     if((fluid->flag & SPH_VISCOELASTIC_SPRINGS)==0 || fluid->spring_k == 0.f)
02263         return;
02264 
02265     /* Loop through the springs */
02266     for(i=0; i<psys->tot_fluidsprings; i++, spring++) {
02267         pa1 = psys->particles + spring->particle_index[0];
02268         pa2 = psys->particles + spring->particle_index[1];
02269 
02270         sub_v3_v3v3(Rij, pa2->prev_state.co, pa1->prev_state.co);
02271         rij = normalize_v3(Rij);
02272 
02273         /* adjust rest length */
02274         Lij = spring->rest_length;
02275         d = yield_ratio * timefix * Lij;
02276 
02277         if (rij > Lij + d) // Stretch
02278             spring->rest_length += plasticity * (rij - Lij - d) * timefix;
02279         else if(rij < Lij - d) // Compress
02280             spring->rest_length -= plasticity * (Lij - d - rij) * timefix;
02281 
02282         h = 4.f*pa1->size;
02283 
02284         if(spring->rest_length > h)
02285             spring->delete_flag = 1;
02286     }
02287 
02288     /* Loop through springs backwaqrds - for efficient delete function */
02289     for (i=psys->tot_fluidsprings-1; i >= 0; i--) {
02290         if(psys->fluid_springs[i].delete_flag)
02291             sph_spring_delete(psys, i);
02292     }
02293 }
02294 static EdgeHash *sph_springhash_build(ParticleSystem *psys)
02295 {
02296     EdgeHash *springhash = NULL;
02297     ParticleSpring *spring;
02298     int i = 0;
02299 
02300     springhash = BLI_edgehash_new();
02301 
02302     for(i=0, spring=psys->fluid_springs; i<psys->tot_fluidsprings; i++, spring++)
02303         BLI_edgehash_insert(springhash, spring->particle_index[0], spring->particle_index[1], SET_INT_IN_POINTER(i+1));
02304 
02305     return springhash;
02306 }
02307 
02308 #define SPH_NEIGHBORS 512
02309 typedef struct SPHNeighbor
02310 {
02311     ParticleSystem *psys;
02312     int index;
02313 } SPHNeighbor;
02314 typedef struct SPHRangeData
02315 {
02316     SPHNeighbor neighbors[SPH_NEIGHBORS];
02317     int tot_neighbors;
02318 
02319     float density, near_density;
02320     float h;
02321 
02322     ParticleSystem *npsys;
02323     ParticleData *pa;
02324 
02325     float massfac;
02326     int use_size;
02327 } SPHRangeData;
02328 typedef struct SPHData {
02329     ParticleSystem *psys[10];
02330     ParticleData *pa;
02331     float mass;
02332     EdgeHash *eh;
02333     float *gravity;
02334     /* Average distance to neighbours (other particles in the support domain),
02335        for calculating the Courant number (adaptive time step). */
02336     int pass;
02337     float element_size;
02338     float flow[3];
02339 
02340     /* Integrator callbacks. This allows different SPH implementations. */
02341     void (*force_cb) (void *sphdata_v, ParticleKey *state, float *force, float *impulse);
02342     void (*density_cb) (void *rangedata_v, int index, float squared_dist);
02343 }SPHData;
02344 
02345 static void sph_density_accum_cb(void *userdata, int index, float squared_dist)
02346 {
02347     SPHRangeData *pfr = (SPHRangeData *)userdata;
02348     ParticleData *npa = pfr->npsys->particles + index;
02349     float q;
02350     float dist;
02351 
02352     if(npa == pfr->pa || squared_dist < FLT_EPSILON)
02353         return;
02354 
02355     /* Ugh! One particle has too many neighbors! If some aren't taken into
02356      * account, the forces will be biased by the tree search order. This
02357      * effectively adds enery to the system, and results in a churning motion.
02358      * But, we have to stop somewhere, and it's not the end of the world.
02359      *  - jahka and z0r
02360      */
02361     if(pfr->tot_neighbors >= SPH_NEIGHBORS)
02362         return;
02363 
02364     pfr->neighbors[pfr->tot_neighbors].index = index;
02365     pfr->neighbors[pfr->tot_neighbors].psys = pfr->npsys;
02366     pfr->tot_neighbors++;
02367 
02368     dist = sqrtf(squared_dist);
02369     q = (1.f - dist/pfr->h) * pfr->massfac;
02370 
02371     if(pfr->use_size)
02372         q *= npa->size;
02373 
02374     pfr->density += q*q;
02375     pfr->near_density += q*q*q;
02376 }
02377 /*
02378  * Find the Courant number for an SPH particle (used for adaptive time step).
02379  */
02380 static void sph_particle_courant(SPHData *sphdata, SPHRangeData *pfr) {
02381     ParticleData *pa, *npa;
02382     int i;
02383     float flow[3], offset[3], dist;
02384 
02385     flow[0] = flow[1] = flow[2] = 0.0f;
02386     dist = 0.0f;
02387     if (pfr->tot_neighbors > 0) {
02388         pa = pfr->pa;
02389         for (i=0; i < pfr->tot_neighbors; i++) {
02390             npa = pfr->neighbors[i].psys->particles + pfr->neighbors[i].index;
02391             sub_v3_v3v3(offset, pa->prev_state.co, npa->prev_state.co);
02392             dist += len_v3(offset);
02393             add_v3_v3(flow, npa->prev_state.vel);
02394         }
02395         dist += sphdata->psys[0]->part->fluid->radius; // TODO: remove this? - z0r
02396         sphdata->element_size = dist / pfr->tot_neighbors;
02397         mul_v3_v3fl(sphdata->flow, flow, 1.0f / pfr->tot_neighbors);
02398     } else {
02399         sphdata->element_size = MAXFLOAT;
02400         VECCOPY(sphdata->flow, flow);
02401     }
02402 }
02403 static void sph_force_cb(void *sphdata_v, ParticleKey *state, float *force, float *UNUSED(impulse))
02404 {
02405     SPHData *sphdata = (SPHData *)sphdata_v;
02406     ParticleSystem **psys = sphdata->psys;
02407     ParticleData *pa = sphdata->pa;
02408     SPHFluidSettings *fluid = psys[0]->part->fluid;
02409     ParticleSpring *spring = NULL;
02410     SPHRangeData pfr;
02411     SPHNeighbor *pfn;
02412     float mass = sphdata->mass;
02413     float *gravity = sphdata->gravity;
02414     EdgeHash *springhash = sphdata->eh;
02415 
02416     float q, u, rij, dv[3];
02417     float pressure, near_pressure;
02418 
02419     float visc = fluid->viscosity_omega;
02420     float stiff_visc = fluid->viscosity_beta * (fluid->flag & SPH_FAC_VISCOSITY ? fluid->viscosity_omega : 1.f);
02421 
02422     float inv_mass = 1.0f/mass;
02423     float spring_constant = fluid->spring_k;
02424     
02425     float h = fluid->radius * (fluid->flag & SPH_FAC_RADIUS ? 4.f*pa->size : 1.f); /* 4.0 seems to be a pretty good value */
02426     float rest_density = fluid->rest_density * (fluid->flag & SPH_FAC_DENSITY ? 4.77f : 1.f); /* 4.77 is an experimentally determined density factor */
02427     float rest_length = fluid->rest_length * (fluid->flag & SPH_FAC_REST_LENGTH ? 2.588f * pa->size : 1.f);
02428 
02429     float stiffness = fluid->stiffness_k;
02430     float stiffness_near_fac = fluid->stiffness_knear * (fluid->flag & SPH_FAC_REPULSION ? fluid->stiffness_k : 1.f);
02431 
02432     ParticleData *npa;
02433     float vec[3];
02434     float vel[3];
02435     float co[3];
02436 
02437     int i, spring_index, index = pa - psys[0]->particles;
02438 
02439     pfr.tot_neighbors = 0;
02440     pfr.density = pfr.near_density = 0.f;
02441     pfr.h = h;
02442     pfr.pa = pa;
02443 
02444     for(i=0; i<10 && psys[i]; i++) {
02445         pfr.npsys = psys[i];
02446         pfr.massfac = psys[i]->part->mass*inv_mass;
02447         pfr.use_size = psys[i]->part->flag & PART_SIZEMASS;
02448 
02449         BLI_bvhtree_range_query(psys[i]->bvhtree, state->co, h, sphdata->density_cb, &pfr);
02450     }
02451 
02452     pressure =  stiffness * (pfr.density - rest_density);
02453     near_pressure = stiffness_near_fac * pfr.near_density;
02454 
02455     pfn = pfr.neighbors;
02456     for(i=0; i<pfr.tot_neighbors; i++, pfn++) {
02457         npa = pfn->psys->particles + pfn->index;
02458 
02459         madd_v3_v3v3fl(co, npa->prev_state.co, npa->prev_state.vel, state->time);
02460 
02461         sub_v3_v3v3(vec, co, state->co);
02462         rij = normalize_v3(vec);
02463 
02464         q = (1.f - rij/h) * pfn->psys->part->mass * inv_mass;
02465 
02466         if(pfn->psys->part->flag & PART_SIZEMASS)
02467             q *= npa->size;
02468 
02469         copy_v3_v3(vel, npa->prev_state.vel);
02470 
02471         /* Double Density Relaxation */
02472         madd_v3_v3fl(force, vec, -(pressure + near_pressure*q)*q);
02473 
02474         /* Viscosity */
02475         if(visc > 0.f   || stiff_visc > 0.f) {      
02476             sub_v3_v3v3(dv, vel, state->vel);
02477             u = dot_v3v3(vec, dv);
02478 
02479             if(u < 0.f && visc > 0.f)
02480                 madd_v3_v3fl(force, vec, 0.5f * q * visc * u );
02481 
02482             if(u > 0.f && stiff_visc > 0.f)
02483                 madd_v3_v3fl(force, vec, 0.5f * q * stiff_visc * u );
02484         }
02485 
02486         if(spring_constant > 0.f) {
02487             /* Viscoelastic spring force */
02488             if (pfn->psys == psys[0] && fluid->flag & SPH_VISCOELASTIC_SPRINGS && springhash) {
02489                 /* BLI_edgehash_lookup appears to be thread-safe. - z0r */
02490                 spring_index = GET_INT_FROM_POINTER(BLI_edgehash_lookup(springhash, index, pfn->index));
02491 
02492                 if(spring_index) {
02493                     spring = psys[0]->fluid_springs + spring_index - 1;
02494 
02495                     madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij/h) * (spring->rest_length - rij));
02496                 }
02497                 else if(fluid->spring_frames == 0 || (pa->prev_state.time-pa->time) <= fluid->spring_frames){
02498                     ParticleSpring temp_spring;
02499                     temp_spring.particle_index[0] = index;
02500                     temp_spring.particle_index[1] = pfn->index;
02501                     temp_spring.rest_length = (fluid->flag & SPH_CURRENT_REST_LENGTH) ? rij : rest_length;
02502                     temp_spring.delete_flag = 0;
02503 
02504                     /* sph_spring_add is not thread-safe. - z0r */
02505                     #pragma omp critical
02506                     sph_spring_add(psys[0], &temp_spring);
02507                 }
02508             }
02509             else {/* PART_SPRING_HOOKES - Hooke's spring force */
02510                 madd_v3_v3fl(force, vec, -10.f * spring_constant * (1.f - rij/h) * (rest_length - rij));
02511             }
02512         }
02513     }
02514     
02515     /* Artificial buoyancy force in negative gravity direction  */
02516     if (fluid->buoyancy > 0.f && gravity)
02517         madd_v3_v3fl(force, gravity, fluid->buoyancy * (pfr.density-rest_density));
02518 
02519     if (sphdata->pass == 0 && psys[0]->part->time_flag & PART_TIME_AUTOSF)
02520         sph_particle_courant(sphdata, &pfr);
02521     sphdata->pass++;
02522 }
02523 
02524 static void sph_solver_init(ParticleSimulationData *sim, SPHData *sphdata) {
02525     ParticleTarget *pt;
02526     int i;
02527 
02528     // Add other coupled particle systems.
02529     sphdata->psys[0] = sim->psys;
02530     for(i=1, pt=sim->psys->targets.first; i<10; i++, pt=(pt?pt->next:NULL))
02531         sphdata->psys[i] = pt ? psys_get_target_system(sim->ob, pt) : NULL;
02532 
02533     if (psys_uses_gravity(sim))
02534         sphdata->gravity = sim->scene->physics_settings.gravity;
02535     else
02536         sphdata->gravity = NULL;
02537     sphdata->eh = sph_springhash_build(sim->psys);
02538 
02539     // These per-particle values should be overridden later, but just for
02540     // completeness we give them default values now.
02541     sphdata->pa = NULL;
02542     sphdata->mass = 1.0f;
02543 
02544     sphdata->force_cb = sph_force_cb;
02545     sphdata->density_cb = sph_density_accum_cb;
02546 }
02547 static void sph_solver_finalise(SPHData *sphdata) {
02548     if (sphdata->eh) {
02549         BLI_edgehash_free(sphdata->eh, NULL);
02550         sphdata->eh = NULL;
02551     }
02552 }
02553 static void sph_integrate(ParticleSimulationData *sim, ParticleData *pa, float dfra, SPHData *sphdata){
02554     ParticleSettings *part = sim->psys->part;
02555     // float timestep = psys_get_timestep(sim); // UNUSED
02556     float pa_mass = part->mass * (part->flag & PART_SIZEMASS ? pa->size : 1.f);
02557     float dtime = dfra*psys_get_timestep(sim);
02558     // int steps = 1; // UNUSED
02559     float effector_acceleration[3];
02560 
02561     sphdata->pa = pa;
02562     sphdata->mass = pa_mass;
02563     sphdata->pass = 0;
02564     //sphdata.element_size and sphdata.flow are set in the callback.
02565 
02566     /* restore previous state and treat gravity & effectors as external acceleration*/
02567     sub_v3_v3v3(effector_acceleration, pa->state.vel, pa->prev_state.vel);
02568     mul_v3_fl(effector_acceleration, 1.f/dtime);
02569 
02570     copy_particle_key(&pa->state, &pa->prev_state, 0);
02571 
02572     integrate_particle(part, pa, dtime, effector_acceleration, sphdata->force_cb, sphdata);
02573 }
02574 
02575 /************************************************/
02576 /*          Basic physics                       */
02577 /************************************************/
02578 typedef struct EfData
02579 {
02580     ParticleTexture ptex;
02581     ParticleSimulationData *sim;
02582     ParticleData *pa;
02583 } EfData;
02584 static void basic_force_cb(void *efdata_v, ParticleKey *state, float *force, float *impulse)
02585 {
02586     EfData *efdata = (EfData *)efdata_v;
02587     ParticleSimulationData *sim = efdata->sim;
02588     ParticleSettings *part = sim->psys->part;
02589     ParticleData *pa = efdata->pa;
02590     EffectedPoint epoint;
02591 
02592     /* add effectors */
02593     pd_point_from_particle(efdata->sim, efdata->pa, state, &epoint);
02594     if(part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)
02595         pdDoEffectors(sim->psys->effectors, sim->colliders, part->effector_weights, &epoint, force, impulse);
02596 
02597     mul_v3_fl(force, efdata->ptex.field);
02598     mul_v3_fl(impulse, efdata->ptex.field);
02599 
02600     /* calculate air-particle interaction */
02601     if(part->dragfac != 0.0f)
02602         madd_v3_v3fl(force, state->vel, -part->dragfac * pa->size * pa->size * len_v3(state->vel));
02603 
02604     /* brownian force */
02605     if(part->brownfac != 0.0f){
02606         force[0] += (BLI_frand()-0.5f) * part->brownfac;
02607         force[1] += (BLI_frand()-0.5f) * part->brownfac;
02608         force[2] += (BLI_frand()-0.5f) * part->brownfac;
02609     }
02610 }
02611 /* gathers all forces that effect particles and calculates a new state for the particle */
02612 static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, float cfra)
02613 {
02614     ParticleSettings *part = sim->psys->part;
02615     ParticleData *pa = sim->psys->particles + p;
02616     ParticleKey tkey;
02617     float dtime=dfra*psys_get_timestep(sim), time;
02618     float *gravity = NULL, gr[3];
02619     EfData efdata;
02620 
02621     psys_get_texture(sim, pa, &efdata.ptex, PAMAP_PHYSICS, cfra);
02622 
02623     efdata.pa = pa;
02624     efdata.sim = sim;
02625 
02626     /* add global acceleration (gravitation) */
02627     if(psys_uses_gravity(sim)
02628         /* normal gravity is too strong for hair so it's disabled by default */
02629         && (part->type != PART_HAIR || part->effector_weights->flag & EFF_WEIGHT_DO_HAIR)) {
02630         zero_v3(gr);
02631         madd_v3_v3fl(gr, sim->scene->physics_settings.gravity, part->effector_weights->global_gravity * efdata.ptex.gravity);
02632         gravity = gr;
02633     }
02634 
02635     /* maintain angular velocity */
02636     copy_v3_v3(pa->state.ave, pa->prev_state.ave);
02637 
02638     integrate_particle(part, pa, dtime, gravity, basic_force_cb, &efdata);
02639 
02640     /* damp affects final velocity */
02641     if(part->dampfac != 0.f)
02642         mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp * 25.f * dtime);
02643 
02644     //copy_v3_v3(pa->state.ave, states->ave);
02645 
02646     /* finally we do guides */
02647     time=(cfra-pa->time)/pa->lifetime;
02648     CLAMP(time, 0.0f, 1.0f);
02649 
02650     copy_v3_v3(tkey.co,pa->state.co);
02651     copy_v3_v3(tkey.vel,pa->state.vel);
02652     tkey.time=pa->state.time;
02653 
02654     if(part->type != PART_HAIR) {
02655         if(do_guides(sim->psys->effectors, &tkey, p, time)) {
02656             copy_v3_v3(pa->state.co,tkey.co);
02657             /* guides don't produce valid velocity */
02658             sub_v3_v3v3(pa->state.vel, tkey.co, pa->prev_state.co);
02659             mul_v3_fl(pa->state.vel,1.0f/dtime);
02660             pa->state.time=tkey.time;
02661         }
02662     }
02663 }
02664 static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, float timestep)
02665 {
02666     float rotfac, rot1[4], rot2[4]={1.0,0.0,0.0,0.0}, dtime=dfra*timestep;
02667 
02668     if((part->flag & PART_ROT_DYN)==0){
02669         if(part->avemode==PART_AVE_SPIN){
02670             float angle;
02671             float len1 = len_v3(pa->prev_state.vel);
02672             float len2 = len_v3(pa->state.vel);
02673 
02674             if(len1==0.0f || len2==0.0f)
02675                 pa->state.ave[0]=pa->state.ave[1]=pa->state.ave[2]=0.0f;
02676             else{
02677                 cross_v3_v3v3(pa->state.ave,pa->prev_state.vel,pa->state.vel);
02678                 normalize_v3(pa->state.ave);
02679                 angle=dot_v3v3(pa->prev_state.vel,pa->state.vel)/(len1*len2);
02680                 mul_v3_fl(pa->state.ave,saacos(angle)/dtime);
02681             }
02682 
02683             axis_angle_to_quat(rot2,pa->state.vel,dtime*part->avefac);
02684         }
02685     }
02686 
02687     rotfac=len_v3(pa->state.ave);
02688     if(rotfac == 0.0f){ /* unit_qt(in VecRotToQuat) doesn't give unit quat [1,0,0,0]?? */
02689         rot1[0]=1.0f;
02690         rot1[1]=rot1[2]=rot1[3]=0;
02691     }
02692     else{
02693         axis_angle_to_quat(rot1,pa->state.ave,rotfac*dtime);
02694     }
02695     mul_qt_qtqt(pa->state.rot,rot1,pa->prev_state.rot);
02696     mul_qt_qtqt(pa->state.rot,rot2,pa->state.rot);
02697 
02698     /* keep rotation quat in good health */
02699     normalize_qt(pa->state.rot);
02700 }
02701 
02702 /************************************************/
02703 /*          Collisions                          */
02704 /************************************************/
02705 #define COLLISION_MAX_COLLISIONS    10
02706 #define COLLISION_MIN_RADIUS 0.001f
02707 #define COLLISION_MIN_DISTANCE 0.0001f
02708 #define COLLISION_ZERO 0.00001f
02709 typedef float (*NRDistanceFunc)(float *p, float radius, ParticleCollisionElement *pce, float *nor);
02710 static float nr_signed_distance_to_plane(float *p, float radius, ParticleCollisionElement *pce, float *nor)
02711 {
02712     float p0[3], e1[3], e2[3], d;
02713 
02714     sub_v3_v3v3(e1, pce->x1, pce->x0);
02715     sub_v3_v3v3(e2, pce->x2, pce->x0);
02716     sub_v3_v3v3(p0, p, pce->x0);
02717 
02718     cross_v3_v3v3(nor, e1, e2);
02719     normalize_v3(nor);
02720 
02721     d = dot_v3v3(p0, nor);
02722 
02723     if(pce->inv_nor == -1) {
02724         if(d < 0.f)
02725             pce->inv_nor = 1;
02726         else
02727             pce->inv_nor = 0;
02728     }
02729 
02730     if(pce->inv_nor == 1) {
02731         negate_v3(nor);
02732         d = -d;
02733     }
02734 
02735     return d - radius;
02736 }
02737 static float nr_distance_to_edge(float *p, float radius, ParticleCollisionElement *pce, float *UNUSED(nor))
02738 {
02739     float v0[3], v1[3], v2[3], c[3];
02740 
02741     sub_v3_v3v3(v0, pce->x1, pce->x0);
02742     sub_v3_v3v3(v1, p, pce->x0);
02743     sub_v3_v3v3(v2, p, pce->x1);
02744 
02745     cross_v3_v3v3(c, v1, v2);
02746 
02747     return fabsf(len_v3(c)/len_v3(v0)) - radius;
02748 }
02749 static float nr_distance_to_vert(float *p, float radius, ParticleCollisionElement *pce, float *UNUSED(nor))
02750 {
02751     return len_v3v3(p, pce->x0) - radius;
02752 }
02753 static void collision_interpolate_element(ParticleCollisionElement *pce, float t, float fac, ParticleCollision *col)
02754 {
02755     /* t is the current time for newton rhapson */
02756     /* fac is the starting factor for current collision iteration */
02757     /* the col->fac's are factors for the particle subframe step start and end during collision modifier step */
02758     float f = fac + t*(1.f-fac);
02759     float mul = col->fac1 + f * (col->fac2-col->fac1);
02760     if(pce->tot > 0) {
02761         madd_v3_v3v3fl(pce->x0, pce->x[0], pce->v[0], mul);
02762 
02763         if(pce->tot > 1) {
02764             madd_v3_v3v3fl(pce->x1, pce->x[1], pce->v[1], mul);
02765 
02766             if(pce->tot > 2)
02767                 madd_v3_v3v3fl(pce->x2, pce->x[2], pce->v[2], mul);
02768         }
02769     }
02770 }
02771 static void collision_point_velocity(ParticleCollisionElement *pce)
02772 {
02773     float v[3];
02774 
02775     copy_v3_v3(pce->vel, pce->v[0]);
02776 
02777     if(pce->tot > 1) {
02778         sub_v3_v3v3(v, pce->v[1], pce->v[0]);
02779         madd_v3_v3fl(pce->vel, v, pce->uv[0]);
02780 
02781         if(pce->tot > 2) {
02782             sub_v3_v3v3(v, pce->v[2], pce->v[0]);
02783             madd_v3_v3fl(pce->vel, v, pce->uv[1]);
02784         }
02785     }
02786 }
02787 static float collision_point_distance_with_normal(float p[3], ParticleCollisionElement *pce, float fac, ParticleCollision *col, float *nor)
02788 {
02789     if(fac >= 0.f)
02790         collision_interpolate_element(pce, 0.f, fac, col);
02791 
02792     switch(pce->tot) {
02793         case 1:
02794         {
02795             sub_v3_v3v3(nor, p, pce->x0);
02796             return normalize_v3(nor);
02797         }
02798         case 2:
02799         {
02800             float u, e[3], vec[3];
02801             sub_v3_v3v3(e, pce->x1, pce->x0);
02802             sub_v3_v3v3(vec, p, pce->x0);
02803             u = dot_v3v3(vec, e) / dot_v3v3(e, e);
02804 
02805             madd_v3_v3v3fl(nor, vec, e, -u);
02806             return normalize_v3(nor);
02807         }
02808         case 3:
02809             return nr_signed_distance_to_plane(p, 0.f, pce, nor);
02810     }
02811     return 0;
02812 }
02813 static void collision_point_on_surface(float p[3], ParticleCollisionElement *pce, float fac, ParticleCollision *col, float *co)
02814 {
02815     collision_interpolate_element(pce, 0.f, fac, col);
02816 
02817     switch(pce->tot) {
02818         case 1:
02819         {
02820             sub_v3_v3v3(co, p, pce->x0);
02821             normalize_v3(co);
02822             madd_v3_v3v3fl(co, pce->x0, co, col->radius);
02823             break;
02824         }
02825         case 2:
02826         {
02827             float u, e[3], vec[3], nor[3];
02828             sub_v3_v3v3(e, pce->x1, pce->x0);
02829             sub_v3_v3v3(vec, p, pce->x0);
02830             u = dot_v3v3(vec, e) / dot_v3v3(e, e);
02831 
02832             madd_v3_v3v3fl(nor, vec, e, -u);
02833             normalize_v3(nor);
02834 
02835             madd_v3_v3v3fl(co, pce->x0, e, pce->uv[0]);
02836             madd_v3_v3fl(co, nor, col->radius);
02837             break;
02838         }
02839         case 3:
02840         {
02841                 float p0[3], e1[3], e2[3], nor[3];
02842 
02843                 sub_v3_v3v3(e1, pce->x1, pce->x0);
02844                 sub_v3_v3v3(e2, pce->x2, pce->x0);
02845                 sub_v3_v3v3(p0, p, pce->x0);
02846 
02847                 cross_v3_v3v3(nor, e1, e2);
02848                 normalize_v3(nor);
02849 
02850                 if(pce->inv_nor == 1)
02851                     negate_v3(nor);
02852 
02853                 madd_v3_v3v3fl(co, pce->x0, nor, col->radius);
02854                 madd_v3_v3fl(co, e1, pce->uv[0]);
02855                 madd_v3_v3fl(co, e2, pce->uv[1]);
02856             break;
02857         }
02858     }
02859 }
02860 /* find first root in range [0-1] starting from 0 */
02861 static float collision_newton_rhapson(ParticleCollision *col, float radius, ParticleCollisionElement *pce, NRDistanceFunc distance_func)
02862 {
02863     float t0, t1, d0, d1, dd, n[3];
02864     int iter;
02865 
02866     pce->inv_nor = -1;
02867 
02868     /* start from the beginning */
02869     t0 = 0.f;
02870     collision_interpolate_element(pce, t0, col->f, col);
02871     d0 = distance_func(col->co1, radius, pce, n);
02872     t1 = 0.001f;
02873     d1 = 0.f;
02874 
02875     for(iter=0; iter<10; iter++) {//, itersum++) {
02876         /* get current location */
02877         collision_interpolate_element(pce, t1, col->f, col);
02878         interp_v3_v3v3(pce->p, col->co1, col->co2, t1);
02879 
02880         d1 = distance_func(pce->p, radius, pce, n);
02881 
02882         /* no movement, so no collision */
02883         if(d1 == d0) {
02884             return -1.f;
02885         }
02886 
02887         /* particle already inside face, so report collision */
02888         if(iter == 0 && d0 < 0.f && d0 > -radius) {
02889             copy_v3_v3(pce->p, col->co1);
02890             copy_v3_v3(pce->nor, n);
02891             pce->inside = 1;
02892             return 0.f;
02893         }
02894         
02895         dd = (t1-t0)/(d1-d0);
02896 
02897         t0 = t1;
02898         d0 = d1;
02899 
02900         t1 -= d1*dd;
02901 
02902         /* particle movin away from plane could also mean a strangely rotating face, so check from end */
02903         if(iter == 0 && t1 < 0.f) {
02904             t0 = 1.f;
02905             collision_interpolate_element(pce, t0, col->f, col);
02906             d0 = distance_func(col->co2, radius, pce, n);
02907             t1 = 0.999f;
02908             d1 = 0.f;
02909 
02910             continue;
02911         }
02912         else if(iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f))
02913             return -1.f;
02914 
02915         if(d1 <= COLLISION_ZERO && d1 >= -COLLISION_ZERO) {
02916             if(t1 >= -COLLISION_ZERO && t1 <= 1.f) {
02917                 if(distance_func == nr_signed_distance_to_plane)
02918                     copy_v3_v3(pce->nor, n);
02919 
02920                 CLAMP(t1, 0.f, 1.f);
02921 
02922                 return t1;
02923             }
02924             else
02925                 return -1.f;
02926         }
02927     }
02928     return -1.0;
02929 }
02930 static int collision_sphere_to_tri(ParticleCollision *col, float radius, ParticleCollisionElement *pce, float *t)
02931 {
02932     ParticleCollisionElement *result = &col->pce;
02933     float ct, u, v;
02934 
02935     pce->inv_nor = -1;
02936     pce->inside = 0;
02937 
02938     ct = collision_newton_rhapson(col, radius, pce, nr_signed_distance_to_plane);
02939 
02940     if(ct >= 0.f && ct < *t && (result->inside==0 || pce->inside==1) ) {
02941         float e1[3], e2[3], p0[3];
02942         float e1e1, e1e2, e1p0, e2e2, e2p0, inv;
02943 
02944         sub_v3_v3v3(e1, pce->x1, pce->x0);
02945         sub_v3_v3v3(e2, pce->x2, pce->x0);
02946         /* XXX: add radius correction here? */
02947         sub_v3_v3v3(p0, pce->p, pce->x0);
02948 
02949         e1e1 = dot_v3v3(e1, e1);
02950         e1e2 = dot_v3v3(e1, e2);
02951         e1p0 = dot_v3v3(e1, p0);
02952         e2e2 = dot_v3v3(e2, e2);
02953         e2p0 = dot_v3v3(e2, p0);
02954 
02955         inv = 1.f/(e1e1 * e2e2 - e1e2 * e1e2);
02956         u = (e2e2 * e1p0 - e1e2 * e2p0) * inv;
02957         v = (e1e1 * e2p0 - e1e2 * e1p0) * inv;
02958 
02959         if(u>=0.f && u<=1.f && v>=0.f && u+v<=1.f) {
02960             *result = *pce;
02961 
02962             /* normal already calculated in pce */
02963 
02964             result->uv[0] = u;
02965             result->uv[1] = v;
02966 
02967             *t = ct;
02968             return 1;
02969         }
02970     }
02971     return 0;
02972 }
02973 static int collision_sphere_to_edges(ParticleCollision *col, float radius, ParticleCollisionElement *pce, float *t)
02974 {
02975     ParticleCollisionElement edge[3], *cur = NULL, *hit = NULL;
02976     ParticleCollisionElement *result = &col->pce;
02977 
02978     float ct;
02979     int i;
02980 
02981     for(i=0; i<3; i++) {
02982         /* in case of a quad, no need to check "edge" that goes through face twice */
02983         if((pce->x[3] && i==2))
02984             continue;
02985 
02986         cur = edge+i;
02987         cur->x[0] = pce->x[i]; cur->x[1] = pce->x[(i+1)%3];
02988         cur->v[0] = pce->v[i]; cur->v[1] = pce->v[(i+1)%3];
02989         cur->tot = 2;
02990         cur->inside = 0;
02991 
02992         ct = collision_newton_rhapson(col, radius, cur, nr_distance_to_edge);
02993 
02994         if(ct >= 0.f && ct < *t) {
02995             float u, e[3], vec[3];
02996 
02997             sub_v3_v3v3(e, cur->x1, cur->x0);
02998             sub_v3_v3v3(vec, cur->p, cur->x0);
02999             u = dot_v3v3(vec, e) / dot_v3v3(e, e);
03000 
03001             if(u < 0.f || u > 1.f)
03002                 break;
03003 
03004             *result = *cur;
03005 
03006             madd_v3_v3v3fl(result->nor, vec, e, -u);
03007             normalize_v3(result->nor);
03008 
03009             result->uv[0] = u;
03010 
03011             
03012             hit = cur;
03013             *t = ct;
03014         }
03015 
03016     }
03017 
03018     return hit != NULL;
03019 }
03020 static int collision_sphere_to_verts(ParticleCollision *col, float radius, ParticleCollisionElement *pce, float *t)
03021 {
03022     ParticleCollisionElement vert[3], *cur = NULL, *hit = NULL;
03023     ParticleCollisionElement *result = &col->pce;
03024 
03025     float ct;
03026     int i;
03027 
03028     for(i=0; i<3; i++) {
03029         /* in case of quad, only check one vert the first time */
03030         if(pce->x[3] && i != 1)
03031             continue;
03032 
03033         cur = vert+i;
03034         cur->x[0] = pce->x[i];
03035         cur->v[0] = pce->v[i];
03036         cur->tot = 1;
03037         cur->inside = 0;
03038 
03039         ct = collision_newton_rhapson(col, radius, cur, nr_distance_to_vert);
03040         
03041         if(ct >= 0.f && ct < *t) {
03042             *result = *cur;
03043 
03044             sub_v3_v3v3(result->nor, cur->p, cur->x0);
03045             normalize_v3(result->nor);
03046 
03047             hit = cur;
03048             *t = ct;
03049         }
03050 
03051     }
03052 
03053     return hit != NULL;
03054 }
03055 /* Callback for BVHTree near test */
03056 void BKE_psys_collision_neartest_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
03057 {
03058     ParticleCollision *col = (ParticleCollision *) userdata;
03059     ParticleCollisionElement pce;
03060     MFace *face = col->md->mfaces + index;
03061     MVert *x = col->md->x;
03062     MVert *v = col->md->current_v;
03063     float t = hit->dist/col->original_ray_length;
03064     int collision = 0;
03065 
03066     pce.x[0] = x[face->v1].co;
03067     pce.x[1] = x[face->v2].co;
03068     pce.x[2] = x[face->v3].co;
03069     pce.x[3] = face->v4 ? x[face->v4].co : NULL;
03070 
03071     pce.v[0] = v[face->v1].co;
03072     pce.v[1] = v[face->v2].co;
03073     pce.v[2] = v[face->v3].co;
03074     pce.v[3] = face->v4 ? v[face->v4].co : NULL;
03075 
03076     pce.tot = 3;
03077     pce.inside = 0;
03078     pce.index = index;
03079 
03080     /* don't collide with same face again */
03081     if(col->hit == col->current && col->pce.index == index && col->pce.tot == 3)
03082         return;
03083 
03084     do
03085     {   
03086         collision = collision_sphere_to_tri(col, ray->radius, &pce, &t);
03087         if(col->pce.inside == 0) {
03088             collision += collision_sphere_to_edges(col, ray->radius, &pce, &t);
03089             collision += collision_sphere_to_verts(col, ray->radius, &pce, &t);
03090         }
03091 
03092         if(collision) {
03093             hit->dist = col->original_ray_length * t;
03094             hit->index = index;
03095                 
03096             collision_point_velocity(&col->pce);
03097 
03098             col->hit = col->current;
03099         }
03100 
03101         pce.x[1] = pce.x[2];
03102         pce.x[2] = pce.x[3];
03103         pce.x[3] = NULL;
03104 
03105         pce.v[1] = pce.v[2];
03106         pce.v[2] = pce.v[3];
03107         pce.v[3] = NULL;
03108 
03109     } while(pce.x[2]);
03110 }
03111 static int collision_detect(ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, ListBase *colliders)
03112 {
03113     ColliderCache *coll;
03114     float ray_dir[3];
03115 
03116     if(colliders->first == NULL)
03117         return 0;
03118 
03119     sub_v3_v3v3(ray_dir, col->co2, col->co1);
03120     hit->index = -1;
03121     hit->dist = col->original_ray_length = len_v3(ray_dir);
03122     col->pce.inside = 0;
03123 
03124     /* even if particle is stationary we want to check for moving colliders */
03125     /* if hit.dist is zero the bvhtree_ray_cast will just ignore everything */
03126     if(hit->dist == 0.0f)
03127         hit->dist = col->original_ray_length = 0.000001f;
03128 
03129     for(coll = colliders->first; coll; coll=coll->next){
03130         /* for boids: don't check with current ground object */
03131         if(coll->ob == col->skip)
03132             continue;
03133 
03134         /* particles should not collide with emitter at birth */
03135         if(coll->ob == col->emitter && pa->time < col->cfra && pa->time >= col->old_cfra)
03136             continue;
03137 
03138         col->current = coll->ob;
03139         col->md = coll->collmd;
03140         col->fac1 = (col->old_cfra - coll->collmd->time_x) / (coll->collmd->time_xnew - coll->collmd->time_x);
03141         col->fac2 = (col->cfra - coll->collmd->time_x) / (coll->collmd->time_xnew - coll->collmd->time_x);
03142 
03143         if(col->md && col->md->bvhtree)
03144             BLI_bvhtree_ray_cast(col->md->bvhtree, col->co1, ray_dir, col->radius, hit, BKE_psys_collision_neartest_cb, col);
03145     }
03146 
03147     return hit->index >= 0;
03148 }
03149 static int collision_response(ParticleData *pa, ParticleCollision *col, BVHTreeRayHit *hit, int kill, int dynamic_rotation)
03150 {
03151     ParticleCollisionElement *pce = &col->pce;
03152     PartDeflect *pd = col->hit->pd;
03153     float co[3];                                        /* point of collision */
03154     float x = hit->dist/col->original_ray_length;       /* location factor of collision between this iteration */
03155     float f = col->f + x * (1.0f - col->f);             /* time factor of collision between timestep */
03156     float dt1 = (f - col->f) * col->total_time;         /* time since previous collision (in seconds) */
03157     float dt2 = (1.0f - f) * col->total_time;           /* time left after collision (in seconds) */
03158     int through = (BLI_frand() < pd->pdef_perm) ? 1 : 0; /* did particle pass through the collision surface? */
03159 
03160     /* calculate exact collision location */
03161     interp_v3_v3v3(co, col->co1, col->co2, x);
03162 
03163     /* particle dies in collision */
03164     if(through == 0 && (kill || pd->flag & PDEFLE_KILL_PART)) {
03165         pa->alive = PARS_DYING;
03166         pa->dietime = col->old_cfra + (col->cfra - col->old_cfra) * f;
03167 
03168         copy_v3_v3(pa->state.co, co);
03169         interp_v3_v3v3(pa->state.vel, pa->prev_state.vel, pa->state.vel, f);
03170         interp_qt_qtqt(pa->state.rot, pa->prev_state.rot, pa->state.rot, f);
03171         interp_v3_v3v3(pa->state.ave, pa->prev_state.ave, pa->state.ave, f);
03172 
03173         /* particle is dead so we don't need to calculate further */
03174         return 0;
03175     }
03176     /* figure out velocity and other data after collision */
03177     else {
03178         float v0[3];    /* velocity directly before collision to be modified into velocity directly after collision */
03179         float v0_nor[3];/* normal component of v0 */
03180         float v0_tan[3];/* tangential component of v0 */
03181         float vc_tan[3];/* tangential component of collision surface velocity */
03182         float v0_dot, vc_dot;
03183         float damp = pd->pdef_damp + pd->pdef_rdamp * 2 * (BLI_frand() - 0.5f);
03184         float frict = pd->pdef_frict + pd->pdef_rfrict * 2 * (BLI_frand() - 0.5f);
03185         float distance, nor[3], dot;
03186 
03187         CLAMP(damp,0.0f, 1.0f);
03188         CLAMP(frict,0.0f, 1.0f);
03189 
03190         /* get exact velocity right before collision */
03191         madd_v3_v3v3fl(v0, col->ve1, col->acc, dt1);
03192                 
03193         /* convert collider velocity from 1/framestep to 1/s TODO: here we assume 1 frame step for collision modifier */
03194         mul_v3_fl(pce->vel, col->inv_timestep);
03195 
03196         /* calculate tangential particle velocity */
03197         v0_dot = dot_v3v3(pce->nor, v0);
03198         madd_v3_v3v3fl(v0_tan, v0, pce->nor, -v0_dot);
03199 
03200         /* calculate tangential collider velocity */
03201         vc_dot = dot_v3v3(pce->nor, pce->vel);
03202         madd_v3_v3v3fl(vc_tan, pce->vel, pce->nor, -vc_dot);
03203 
03204         /* handle friction effects (tangential and angular velocity) */
03205         if(frict > 0.0f) {
03206             /* angular <-> linear velocity */
03207             if(dynamic_rotation) {
03208                 float vr_tan[3], v1_tan[3], ave[3];
03209                     
03210                 /* linear velocity of particle surface */
03211                 cross_v3_v3v3(vr_tan, pce->nor, pa->state.ave);
03212                 mul_v3_fl(vr_tan, pa->size);
03213 
03214                 /* change to coordinates that move with the collision plane */
03215                 sub_v3_v3v3(v1_tan, v0_tan, vc_tan);
03216                         
03217                 /* The resulting velocity is a weighted average of particle cm & surface
03218                     * velocity. This weight (related to particle's moment of inertia) could
03219                     * be made a parameter for angular <-> linear conversion.
03220                     */
03221                 madd_v3_v3fl(v1_tan, vr_tan, -0.4);
03222                 mul_v3_fl(v1_tan, 1.0f/1.4f); /* 1/(1+0.4) */
03223 
03224                 /* rolling friction is around 0.01 of sliding friction (could be made a parameter) */
03225                 mul_v3_fl(v1_tan, 1.0f - 0.01f * frict);
03226 
03227                 /* surface_velocity is opposite to cm velocity */
03228                 negate_v3_v3(vr_tan, v1_tan);
03229 
03230                 /* get back to global coordinates */
03231                 add_v3_v3(v1_tan, vc_tan);
03232 
03233                 /* convert to angular velocity*/
03234                 cross_v3_v3v3(ave, vr_tan, pce->nor);
03235                 mul_v3_fl(ave, 1.0f/MAX2(pa->size, 0.001f));
03236 
03237                 /* only friction will cause change in linear & angular velocity */
03238                 interp_v3_v3v3(pa->state.ave, pa->state.ave, ave, frict);
03239                 interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict);
03240             }
03241             else {
03242                 /* just basic friction (unphysical due to the friction model used in Blender) */
03243                 interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict);
03244             }
03245         }
03246 
03247         /* stickness was possibly added before, so cancel that before calculating new normal velocity */
03248         /* otherwise particles go flying out of the surface because of high reversed sticky velocity */
03249         if(v0_dot < 0.0f) {
03250             v0_dot += pd->pdef_stickness;
03251             if(v0_dot > 0.0f)
03252                 v0_dot = 0.0f;
03253         }
03254 
03255         /* damping and flipping of velocity around normal */
03256         v0_dot *= 1.0f - damp;
03257         vc_dot *= through ? damp : 1.0f;
03258 
03259         /* calculate normal particle velocity */
03260         /* special case for object hitting the particle from behind */
03261         if(through==0 && ((vc_dot>0.0f && v0_dot>0.0f && vc_dot>v0_dot) || (vc_dot<0.0f && v0_dot<0.0f && vc_dot<v0_dot)))
03262             mul_v3_v3fl(v0_nor, pce->nor, vc_dot);
03263         else if(v0_dot > 0.f)
03264             mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? -1.0f : 1.0f) * v0_dot);
03265         else
03266             mul_v3_v3fl(v0_nor, pce->nor, vc_dot + (through ? 1.0f : -1.0f) * v0_dot);
03267 
03268         /* combine components together again */
03269         add_v3_v3v3(v0, v0_nor, v0_tan);
03270 
03271         if(col->boid) {
03272             /* keep boids above ground */
03273             BoidParticle *bpa = pa->boid;
03274             if(bpa->data.mode == eBoidMode_OnLand || co[2] <= col->boid_z) {
03275                 co[2] = col->boid_z;
03276                 v0[2] = 0.0f;
03277             }
03278         }
03279         
03280         /* re-apply acceleration to final location and velocity */
03281         madd_v3_v3v3fl(pa->state.co, co, v0, dt2);
03282         madd_v3_v3fl(pa->state.co, col->acc, 0.5f*dt2*dt2);
03283         madd_v3_v3v3fl(pa->state.vel, v0, col->acc, dt2);
03284 
03285         /* make sure particle stays on the right side of the surface */
03286         if(!through) {
03287             distance = collision_point_distance_with_normal(co, pce, -1.f, col, nor);
03288             
03289             if(distance < col->radius + COLLISION_MIN_DISTANCE)
03290                 madd_v3_v3fl(co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
03291 
03292             dot = dot_v3v3(nor, v0);
03293             if(dot < 0.f)
03294                 madd_v3_v3fl(v0, nor, -dot);
03295 
03296             distance = collision_point_distance_with_normal(pa->state.co, pce, 1.f, col, nor);
03297 
03298             if(distance < col->radius + COLLISION_MIN_DISTANCE)
03299                 madd_v3_v3fl(pa->state.co, nor, col->radius + COLLISION_MIN_DISTANCE - distance);
03300 
03301             dot = dot_v3v3(nor, pa->state.vel);
03302             if(dot < 0.f)
03303                 madd_v3_v3fl(pa->state.vel, nor, -dot);
03304         }
03305 
03306         /* add stickness to surface */
03307         madd_v3_v3fl(pa->state.vel, pce->nor, -pd->pdef_stickness);
03308 
03309         /* set coordinates for next iteration */
03310         copy_v3_v3(col->co1, co);
03311         copy_v3_v3(col->co2, pa->state.co);
03312 
03313         copy_v3_v3(col->ve1, v0);
03314         copy_v3_v3(col->ve2, pa->state.vel);
03315 
03316         col->f = f;
03317     }
03318 
03319     col->prev = col->hit;
03320     col->prev_index = hit->index;
03321 
03322     return 1;
03323 }
03324 static void collision_fail(ParticleData *pa, ParticleCollision *col)
03325 {
03326     /* final chance to prevent total failure, so stick to the surface and hope for the best */
03327     collision_point_on_surface(col->co1, &col->pce, 1.f, col, pa->state.co);
03328 
03329     copy_v3_v3(pa->state.vel, col->pce.vel);
03330     mul_v3_fl(pa->state.vel, col->inv_timestep);
03331 
03332 
03333     /* printf("max iterations\n"); */
03334 }
03335 
03336 /* Particle - Mesh collision detection and response
03337  * Features:
03338  * -friction and damping
03339  * -angular momentum <-> linear momentum
03340  * -high accuracy by re-applying particle acceleration after collision
03341  * -handles moving, rotating and deforming meshes
03342  * -uses Newton-Rhapson iteration to find the collisions
03343  * -handles spherical particles and (nearly) point like particles
03344  */
03345 static void collision_check(ParticleSimulationData *sim, int p, float dfra, float cfra)
03346 {
03347     ParticleSettings *part = sim->psys->part;
03348     ParticleData *pa = sim->psys->particles + p;
03349     ParticleCollision col;
03350     BVHTreeRayHit hit;
03351     int collision_count=0;
03352 
03353     float timestep = psys_get_timestep(sim);
03354 
03355     memset(&col, 0, sizeof(ParticleCollision));
03356 
03357     col.total_time = timestep * dfra;
03358     col.inv_timestep = 1.0f/timestep;
03359 
03360     col.cfra = cfra;
03361     col.old_cfra = sim->psys->cfra;
03362 
03363     /* get acceleration (from gravity, forcefields etc. to be re-applied in collision response) */
03364     sub_v3_v3v3(col.acc, pa->state.vel, pa->prev_state.vel);
03365     mul_v3_fl(col.acc, 1.f/col.total_time);
03366 
03367     /* set values for first iteration */
03368     copy_v3_v3(col.co1, pa->prev_state.co);
03369     copy_v3_v3(col.co2, pa->state.co);
03370     copy_v3_v3(col.ve1, pa->prev_state.vel);
03371     copy_v3_v3(col.ve2, pa->state.vel);
03372     col.f = 0.0f;
03373 
03374     col.radius = ((part->flag & PART_SIZE_DEFL) || (part->phystype == PART_PHYS_BOIDS)) ? pa->size : COLLISION_MIN_RADIUS;
03375 
03376     /* override for boids */
03377     if(part->phystype == PART_PHYS_BOIDS && part->boids->options & BOID_ALLOW_LAND) {
03378         col.boid = 1;
03379         col.boid_z = pa->state.co[2];
03380         col.skip = pa->boid->ground;
03381     }
03382 
03383     /* 10 iterations to catch multiple collisions */
03384     while(collision_count < COLLISION_MAX_COLLISIONS){
03385         if(collision_detect(pa, &col, &hit, sim->colliders)) {
03386             
03387             collision_count++;
03388 
03389             if(collision_count == COLLISION_MAX_COLLISIONS)
03390                 collision_fail(pa, &col);
03391             else if(collision_response(pa, &col, &hit, part->flag & PART_DIE_ON_COL, part->flag & PART_ROT_DYN)==0)
03392                 return;
03393         }
03394         else
03395             return;
03396     }
03397 }
03398 /************************************************/
03399 /*          Hair                                */
03400 /************************************************/
03401 /* check if path cache or children need updating and do it if needed */
03402 static void psys_update_path_cache(ParticleSimulationData *sim, float cfra)
03403 {
03404     ParticleSystem *psys = sim->psys;
03405     ParticleSettings *part = psys->part;
03406     ParticleEditSettings *pset = &sim->scene->toolsettings->particle;
03407     int distr=0, alloc=0, skip=0;
03408 
03409     if((psys->part->childtype && psys->totchild != get_psys_tot_child(sim->scene, psys)) || psys->recalc&PSYS_RECALC_RESET)
03410         alloc=1;
03411 
03412     if(alloc || psys->recalc&PSYS_RECALC_CHILD || (psys->vgroup[PSYS_VG_DENSITY] && (sim->ob && sim->ob->mode & OB_MODE_WEIGHT_PAINT)))
03413         distr=1;
03414 
03415     if(distr){
03416         if(alloc)
03417             realloc_particles(sim, sim->psys->totpart);
03418 
03419         if(get_psys_tot_child(sim->scene, psys)) {
03420             /* don't generate children while computing the hair keys */
03421             if(!(psys->part->type == PART_HAIR) || (psys->flag & PSYS_HAIR_DONE)) {
03422                 distribute_particles(sim, PART_FROM_CHILD);
03423 
03424                 if(part->childtype==PART_CHILD_FACES && part->parents != 0.0f)
03425                     psys_find_parents(sim);
03426             }
03427         }
03428         else
03429             psys_free_children(psys);
03430     }
03431 
03432     if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0)
03433         skip = 1; /* only hair, keyed and baked stuff can have paths */
03434     else if(part->ren_as != PART_DRAW_PATH && !(part->type==PART_HAIR && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)))
03435         skip = 1; /* particle visualization must be set as path */
03436     else if(!psys->renderdata) {
03437         if(part->draw_as != PART_DRAW_REND)
03438             skip = 1; /* draw visualization */
03439         else if(psys->pointcache->flag & PTCACHE_BAKING)
03440             skip = 1; /* no need to cache paths while baking dynamics */
03441         else if(psys_in_edit_mode(sim->scene, psys)) {
03442             if((pset->flag & PE_DRAW_PART)==0)
03443                 skip = 1;
03444             else if(part->childtype==0 && (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED)==0)
03445                 skip = 1; /* in edit mode paths are needed for child particles and dynamic hair */
03446         }
03447     }
03448 
03449     if(!skip) {
03450         psys_cache_paths(sim, cfra);
03451 
03452         /* for render, child particle paths are computed on the fly */
03453         if(part->childtype) {
03454             if(!psys->totchild)
03455                 skip = 1;
03456             else if(psys->part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DONE)==0)
03457                 skip = 1;
03458 
03459             if(!skip)
03460                 psys_cache_child_paths(sim, cfra, 0);
03461         }
03462     }
03463     else if(psys->pathcache)
03464         psys_free_path_cache(psys, NULL);
03465 }
03466 
03467 static void do_hair_dynamics(ParticleSimulationData *sim)
03468 {
03469     ParticleSystem *psys = sim->psys;
03470     DerivedMesh *dm = psys->hair_in_dm;
03471     MVert *mvert = NULL;
03472     MEdge *medge = NULL;
03473     MDeformVert *dvert = NULL;
03474     HairKey *key;
03475     PARTICLE_P;
03476     int totpoint = 0;
03477     int totedge;
03478     int k;
03479     float hairmat[4][4];
03480 
03481     if(!psys->clmd) {
03482         psys->clmd = (ClothModifierData*)modifier_new(eModifierType_Cloth);
03483         psys->clmd->sim_parms->goalspring = 0.0f;
03484         psys->clmd->sim_parms->flags |= CLOTH_SIMSETTINGS_FLAG_GOAL|CLOTH_SIMSETTINGS_FLAG_NO_SPRING_COMPRESS;
03485         psys->clmd->coll_parms->flags &= ~CLOTH_COLLSETTINGS_FLAG_SELF;
03486     }
03487 
03488     /* create a dm from hair vertices */
03489     LOOP_PARTICLES
03490         totpoint += pa->totkey;
03491 
03492     totedge = totpoint;
03493     totpoint += psys->totpart;
03494 
03495     if(dm && (totpoint != dm->getNumVerts(dm) || totedge != dm->getNumEdges(dm))) {
03496         dm->release(dm);
03497         dm = psys->hair_in_dm = NULL;
03498     }
03499 
03500     if(!dm) {
03501         dm = psys->hair_in_dm = CDDM_new(totpoint, totedge, 0);
03502         DM_add_vert_layer(dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
03503     }
03504 
03505     mvert = CDDM_get_verts(dm);
03506     medge = CDDM_get_edges(dm);
03507     dvert = DM_get_vert_data_layer(dm, CD_MDEFORMVERT);
03508 
03509     psys->clmd->sim_parms->vgroup_mass = 1;
03510 
03511     /* make vgroup for pin roots etc.. */
03512     psys->particles->hair_index = 1;
03513     LOOP_PARTICLES {
03514         if(p)
03515             pa->hair_index = (pa-1)->hair_index + (pa-1)->totkey + 1;
03516 
03517         psys_mat_hair_to_object(sim->ob, sim->psmd->dm, psys->part->from, pa, hairmat);
03518 
03519         for(k=0, key=pa->hair; k<pa->totkey; k++,key++) {
03520             
03521             /* create fake root before actual root to resist bending */
03522             if(k==0) {
03523                 float temp[3];
03524                 sub_v3_v3v3(temp, key->co, (key+1)->co);
03525                 copy_v3_v3(mvert->co, key->co);
03526                 add_v3_v3v3(mvert->co, mvert->co, temp);
03527                 mul_m4_v3(hairmat, mvert->co);
03528                 mvert++;
03529 
03530                 medge->v1 = pa->hair_index - 1;
03531                 medge->v2 = pa->hair_index;
03532                 medge++;
03533 
03534                 if(dvert) {
03535                     if(!dvert->totweight) {
03536                         dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight");
03537                         dvert->totweight = 1;
03538                     }
03539 
03540                     dvert->dw->weight = 1.0f;
03541                     dvert++;
03542                 }
03543             }
03544 
03545             copy_v3_v3(mvert->co, key->co);
03546             mul_m4_v3(hairmat, mvert->co);
03547             mvert++;
03548             
03549             if(k) {
03550                 medge->v1 = pa->hair_index + k - 1;
03551                 medge->v2 = pa->hair_index + k;
03552                 medge++;
03553             }
03554 
03555             if(dvert) {
03556                 if(!dvert->totweight) {
03557                     dvert->dw = MEM_callocN (sizeof(MDeformWeight), "deformWeight");
03558                     dvert->totweight = 1;
03559                 }
03560                 /* roots should be 1.0, the rest can be anything from 0.0 to 1.0 */
03561                 dvert->dw->weight = key->weight;
03562                 dvert++;
03563             }
03564         }
03565     }
03566 
03567     if(psys->hair_out_dm)
03568         psys->hair_out_dm->release(psys->hair_out_dm);
03569 
03570     psys->clmd->point_cache = psys->pointcache;
03571     psys->clmd->sim_parms->effector_weights = psys->part->effector_weights;
03572 
03573     psys->hair_out_dm = clothModifier_do(psys->clmd, sim->scene, sim->ob, dm);
03574 
03575     psys->clmd->sim_parms->effector_weights = NULL;
03576 }
03577 static void hair_step(ParticleSimulationData *sim, float cfra)
03578 {
03579     ParticleSystem *psys = sim->psys;
03580     ParticleSettings *part = psys->part;
03581     PARTICLE_P;
03582     float disp = (float)psys_get_current_display_percentage(psys)/100.0f;
03583 
03584     LOOP_PARTICLES {
03585         pa->size = part->size;
03586         if(part->randsize > 0.0f)
03587             pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
03588 
03589         if(PSYS_FRAND(p) > disp)
03590             pa->flag |= PARS_NO_DISP;
03591         else
03592             pa->flag &= ~PARS_NO_DISP;
03593     }
03594 
03595     if(psys->recalc & PSYS_RECALC_RESET) {
03596         /* need this for changing subsurf levels */
03597         psys_calc_dmcache(sim->ob, sim->psmd->dm, psys);
03598 
03599         if(psys->clmd)
03600             cloth_free_modifier(psys->clmd);
03601     }
03602 
03603     /* dynamics with cloth simulation, psys->particles can be NULL with 0 particles [#25519] */
03604     if(psys->part->type==PART_HAIR && psys->flag & PSYS_HAIR_DYNAMICS && psys->particles)
03605         do_hair_dynamics(sim);
03606 
03607     /* following lines were removed r29079 but cause bug [#22811], see report for details */
03608     psys_update_effectors(sim);
03609     psys_update_path_cache(sim, cfra);
03610 
03611     psys->flag |= PSYS_HAIR_UPDATED;
03612 }
03613 
03614 static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
03615 {
03616     Object *ob = sim->ob;
03617     ParticleSystem *psys = sim->psys;
03618     HairKey *key, *root;
03619     PARTICLE_P;
03620 
03621     invert_m4_m4(ob->imat, ob->obmat);
03622     
03623     psys->lattice= psys_get_lattice(sim);
03624 
03625     if(psys->totpart==0) return;
03626     
03627     /* save new keys for elements if needed */
03628     LOOP_PARTICLES {
03629         /* first time alloc */
03630         if(pa->totkey==0 || pa->hair==NULL) {
03631             pa->hair = MEM_callocN((psys->part->hair_step + 1) * sizeof(HairKey), "HairKeys");
03632             pa->totkey = 0;
03633         }
03634 
03635         key = root = pa->hair;
03636         key += pa->totkey;
03637 
03638         /* convert from global to geometry space */
03639         copy_v3_v3(key->co, pa->state.co);
03640         mul_m4_v3(ob->imat, key->co);
03641 
03642         if(pa->totkey) {
03643             sub_v3_v3(key->co, root->co);
03644             psys_vec_rot_to_face(sim->psmd->dm, pa, key->co);
03645         }
03646 
03647         key->time = pa->state.time;
03648 
03649         key->weight = 1.0f - key->time / 100.0f;
03650 
03651         pa->totkey++;
03652 
03653         /* root is always in the origin of hair space so we set it to be so after the last key is saved*/
03654         if(pa->totkey == psys->part->hair_step + 1)
03655             root->co[0] = root->co[1] = root->co[2] = 0.0f;
03656     }
03657 }
03658 
03659 /* Code for an adaptive time step based on the Courant-Friedrichs-Lewy
03660    condition. */
03661 #define MIN_TIMESTEP 1.0f / 101.0f
03662 /* Tolerance of 1.5 means the last subframe neither favours growing nor
03663    shrinking (e.g if it were 1.3, the last subframe would tend to be too
03664    small). */
03665 #define TIMESTEP_EXPANSION_TOLERANCE 1.5f
03666 
03667 /* Calculate the speed of the particle relative to the local scale of the
03668    simulation. This should be called once per particle during a simulation
03669    step, after the velocity has been updated. element_size defines the scale of
03670    the simulation, and is typically the distance to neighbourning particles. */
03671 void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
03672     float dtime, SPHData *sphdata)
03673 {
03674     float relative_vel[3];
03675     float speed;
03676 
03677     sub_v3_v3v3(relative_vel, pa->prev_state.vel, sphdata->flow);
03678     speed = len_v3(relative_vel);
03679     if (sim->courant_num < speed * dtime / sphdata->element_size)
03680         sim->courant_num = speed * dtime / sphdata->element_size;
03681 }
03682 /* Update time step size to suit current conditions. */
03683 float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim,
03684     float t_frac)
03685 {
03686     if (sim->courant_num == 0.0f)
03687         psys->dt_frac = 1.0f;
03688     else
03689         psys->dt_frac *= (psys->part->courant_target / sim->courant_num);
03690     CLAMP(psys->dt_frac, MIN_TIMESTEP, 1.0f);
03691 
03692     /* Sync with frame end if it's close. */
03693     if (t_frac == 1.0f)
03694         return psys->dt_frac;
03695     else if (t_frac + (psys->dt_frac * TIMESTEP_EXPANSION_TOLERANCE) >= 1.0f)
03696         return 1.0f - t_frac;
03697     else
03698         return psys->dt_frac;
03699 }
03700 
03701 /************************************************/
03702 /*          System Core                         */
03703 /************************************************/
03704 /* unbaked particles are calculated dynamically */
03705 static void dynamics_step(ParticleSimulationData *sim, float cfra)
03706 {
03707     ParticleSystem *psys = sim->psys;
03708     ParticleSettings *part=psys->part;
03709     BoidBrainData bbd;
03710     ParticleTexture ptex;
03711     PARTICLE_P;
03712     float timestep;
03713     /* frame & time changes */
03714     float dfra, dtime;
03715     float birthtime, dietime;
03716 
03717     /* where have we gone in time since last time */
03718     dfra= cfra - psys->cfra;
03719 
03720     timestep = psys_get_timestep(sim);
03721     dtime= dfra*timestep;
03722 
03723     if(dfra < 0.0f) {
03724         LOOP_EXISTING_PARTICLES {
03725             psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
03726             pa->size = part->size*ptex.size;
03727             if(part->randsize > 0.0f)
03728                 pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
03729 
03730             reset_particle(sim, pa, dtime, cfra);
03731         }
03732         return;
03733     }
03734 
03735     BLI_srandom(31415926 + (int)cfra + psys->seed);
03736 
03737     psys_update_effectors(sim);
03738 
03739     if(part->type != PART_HAIR)
03740         sim->colliders = get_collider_cache(sim->scene, sim->ob, NULL);
03741 
03742     /* initialize physics type specific stuff */
03743     switch(part->phystype) {
03744         case PART_PHYS_BOIDS:
03745         {
03746             ParticleTarget *pt = psys->targets.first;
03747             bbd.sim = sim;
03748             bbd.part = part;
03749             bbd.cfra = cfra;
03750             bbd.dfra = dfra;
03751             bbd.timestep = timestep;
03752 
03753             psys_update_particle_tree(psys, cfra);
03754 
03755             boids_precalc_rules(part, cfra);
03756 
03757             for(; pt; pt=pt->next) {
03758                 if(pt->ob)
03759                     psys_update_particle_tree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
03760             }
03761             break;
03762         }
03763         case PART_PHYS_FLUID:
03764         {
03765             ParticleTarget *pt = psys->targets.first;
03766             psys_update_particle_bvhtree(psys, cfra);
03767             
03768             for(; pt; pt=pt->next) {  /* Updating others systems particle tree for fluid-fluid interaction */
03769                 if(pt->ob)
03770                     psys_update_particle_bvhtree(BLI_findlink(&pt->ob->particlesystem, pt->psys-1), cfra);
03771             }
03772             break;
03773         }
03774     }
03775     /* initialize all particles for dynamics */
03776     LOOP_SHOWN_PARTICLES {
03777         copy_particle_key(&pa->prev_state,&pa->state,1);
03778 
03779         psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
03780 
03781         pa->size = part->size*ptex.size;
03782         if(part->randsize > 0.0f)
03783             pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
03784 
03785         birthtime = pa->time;
03786         dietime = pa->dietime;
03787 
03788         /* store this, so we can do multiple loops over particles */
03789         pa->state.time = dfra;
03790 
03791         if(dietime <= cfra && psys->cfra < dietime){
03792             /* particle dies some time between this and last step */
03793             pa->state.time = dietime - ((birthtime > psys->cfra) ? birthtime : psys->cfra);
03794             pa->alive = PARS_DYING;
03795         }
03796         else if(birthtime <= cfra && birthtime >= psys->cfra){
03797             /* particle is born some time between this and last step*/
03798             reset_particle(sim, pa, dfra*timestep, cfra);
03799             pa->alive = PARS_ALIVE;
03800             pa->state.time = cfra - birthtime;
03801         }
03802         else if(dietime < cfra){
03803             /* nothing to be done when particle is dead */
03804         }
03805 
03806         /* only reset unborn particles if they're shown or if the particle is born soon*/
03807         if(pa->alive==PARS_UNBORN
03808             && (part->flag & PART_UNBORN || cfra + psys->pointcache->step > pa->time))
03809             reset_particle(sim, pa, dtime, cfra);
03810         else if(part->phystype == PART_PHYS_NO)
03811             reset_particle(sim, pa, dtime, cfra);
03812 
03813         if(ELEM(pa->alive, PARS_ALIVE, PARS_DYING)==0 || (pa->flag & (PARS_UNEXIST|PARS_NO_DISP)))
03814             pa->state.time = -1.f;
03815     }
03816 
03817     switch(part->phystype) {
03818         case PART_PHYS_NEWTON:
03819         {
03820             LOOP_DYNAMIC_PARTICLES {
03821                 /* do global forces & effectors */
03822                 basic_integrate(sim, p, pa->state.time, cfra);
03823     
03824                 /* deflection */
03825                 if(sim->colliders)
03826                     collision_check(sim, p, pa->state.time, cfra);
03827 
03828                 /* rotations */
03829                 basic_rotate(part, pa, pa->state.time, timestep);
03830             }
03831             break;
03832         }
03833         case PART_PHYS_BOIDS:
03834         {
03835             LOOP_DYNAMIC_PARTICLES {
03836                 bbd.goal_ob = NULL;
03837                 
03838                 boid_brain(&bbd, p, pa);
03839 
03840                 if(pa->alive != PARS_DYING) {
03841                     boid_body(&bbd, pa);
03842 
03843                     /* deflection */
03844                     if(sim->colliders)
03845                         collision_check(sim, p, pa->state.time, cfra);
03846                 }
03847             }
03848             break;
03849         }
03850         case PART_PHYS_FLUID:
03851         {
03852             SPHData sphdata;
03853             sph_solver_init(sim, &sphdata);
03854 
03855             #pragma omp parallel for firstprivate (sphdata) private (pa) schedule(dynamic,5)
03856             LOOP_DYNAMIC_PARTICLES {
03857                 /* do global forces & effectors */
03858                 basic_integrate(sim, p, pa->state.time, cfra);
03859 
03860                 /* actual fluids calculations */
03861                 sph_integrate(sim, pa, pa->state.time, &sphdata);
03862 
03863                 if(sim->colliders)
03864                     collision_check(sim, p, pa->state.time, cfra);
03865                 
03866                 /* SPH particles are not physical particles, just interpolation
03867                  * particles,  thus rotation has not a direct sense for them */
03868                 basic_rotate(part, pa, pa->state.time, timestep);  
03869 
03870                 #pragma omp critical
03871                 if (part->time_flag & PART_TIME_AUTOSF)
03872                     update_courant_num(sim, pa, dtime, &sphdata);
03873             }
03874 
03875             sph_springs_modify(psys, timestep);
03876 
03877             sph_solver_finalise(&sphdata);
03878             break;
03879         }
03880     }
03881 
03882     /* finalize particle state and time after dynamics */
03883     LOOP_DYNAMIC_PARTICLES {
03884         if(pa->alive == PARS_DYING){
03885             pa->alive=PARS_DEAD;
03886             pa->state.time=pa->dietime;
03887         }
03888         else
03889             pa->state.time=cfra;
03890     }
03891 
03892     free_collider_cache(&sim->colliders);
03893 }
03894 static void update_children(ParticleSimulationData *sim)
03895 {
03896     if((sim->psys->part->type == PART_HAIR) && (sim->psys->flag & PSYS_HAIR_DONE)==0)
03897     /* don't generate children while growing hair - waste of time */
03898         psys_free_children(sim->psys);
03899     else if(sim->psys->part->childtype) {
03900         if(sim->psys->totchild != get_psys_tot_child(sim->scene, sim->psys))
03901             distribute_particles(sim, PART_FROM_CHILD);
03902         else {
03903             /* Children are up to date, nothing to do. */
03904         }
03905     }
03906     else
03907         psys_free_children(sim->psys);
03908 }
03909 /* updates cached particles' alive & other flags etc..*/
03910 static void cached_step(ParticleSimulationData *sim, float cfra)
03911 {
03912     ParticleSystem *psys = sim->psys;
03913     ParticleSettings *part = psys->part;
03914     ParticleTexture ptex;
03915     PARTICLE_P;
03916     float disp, dietime;
03917 
03918     psys_update_effectors(sim);
03919     
03920     disp= (float)psys_get_current_display_percentage(psys)/100.0f;
03921 
03922     LOOP_PARTICLES {
03923         psys_get_texture(sim, pa, &ptex, PAMAP_SIZE, cfra);
03924         pa->size = part->size*ptex.size;
03925         if(part->randsize > 0.0f)
03926             pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
03927 
03928         psys->lattice= psys_get_lattice(sim);
03929 
03930         dietime = pa->dietime;
03931 
03932         /* update alive status and push events */
03933         if(pa->time > cfra) {
03934             pa->alive = PARS_UNBORN;
03935             if(part->flag & PART_UNBORN && (psys->pointcache->flag & PTCACHE_EXTERNAL) == 0)
03936                 reset_particle(sim, pa, 0.0f, cfra);
03937         }
03938         else if(dietime <= cfra)
03939             pa->alive = PARS_DEAD;
03940         else
03941             pa->alive = PARS_ALIVE;
03942 
03943         if(psys->lattice){
03944             end_latt_deform(psys->lattice);
03945             psys->lattice= NULL;
03946         }
03947 
03948         if(PSYS_FRAND(p) > disp)
03949             pa->flag |= PARS_NO_DISP;
03950         else
03951             pa->flag &= ~PARS_NO_DISP;
03952     }
03953 }
03954 
03955 static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra))
03956 {   
03957     ParticleSystem *psys = sim->psys;
03958     if(psys->particles){
03959         MEM_freeN(psys->particles);
03960         psys->particles = 0;
03961         psys->totpart = 0;
03962     }
03963 
03964     /* fluid sim particle import handling, actual loading of particles from file */
03965     #ifdef WITH_MOD_FLUID
03966     {
03967         FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(sim->ob, eModifierType_Fluidsim);
03968         
03969         if( fluidmd && fluidmd->fss) { 
03970             FluidsimSettings *fss= fluidmd->fss;
03971             ParticleSettings *part = psys->part;
03972             ParticleData *pa=NULL;
03973             char filename[256];
03974             char debugStrBuffer[256];
03975             int  curFrame = sim->scene->r.cfra -1; // warning - sync with derived mesh fsmesh loading
03976             int  p, j, totpart;
03977             int readMask, activeParts = 0, fileParts = 0;
03978             gzFile gzf;
03979     
03980 // XXX          if(ob==G.obedit) // off...
03981 //              return;
03982 
03983             // ok, start loading
03984             BLI_join_dirfile(filename, sizeof(filename), fss->surfdataPath, OB_FLUIDSIM_SURF_PARTICLES_FNAME);
03985 
03986             BLI_path_abs(filename, modifier_path_relbase(sim->ob));
03987 
03988             BLI_path_frame(filename, curFrame, 0); // fixed #frame-no 
03989 
03990             gzf = gzopen(filename, "rb");
03991             if (!gzf) {
03992                 BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer),"readFsPartData::error - Unable to open file for reading '%s' \n", filename); 
03993                 // XXX bad level call elbeemDebugOut(debugStrBuffer);
03994                 return;
03995             }
03996     
03997             gzread(gzf, &totpart, sizeof(totpart));
03998             totpart = (G.rendering)?totpart:(part->disp*totpart)/100;
03999             
04000             part->totpart= totpart;
04001             part->sta=part->end = 1.0f;
04002             part->lifetime = sim->scene->r.efra + 1;
04003     
04004             /* allocate particles */
04005             realloc_particles(sim, part->totpart);
04006     
04007             // set up reading mask
04008             readMask = fss->typeFlags;
04009             
04010             for(p=0, pa=psys->particles; p<totpart; p++, pa++) {
04011                 int ptype=0;
04012     
04013                 gzread(gzf, &ptype, sizeof( ptype )); 
04014                 if(ptype&readMask) {
04015                     activeParts++;
04016     
04017                     gzread(gzf, &(pa->size), sizeof( float )); 
04018     
04019                     pa->size /= 10.0f;
04020     
04021                     for(j=0; j<3; j++) {
04022                         float wrf;
04023                         gzread(gzf, &wrf, sizeof( wrf )); 
04024                         pa->state.co[j] = wrf;
04025                         //fprintf(stderr,"Rj%d ",j);
04026                     }
04027                     for(j=0; j<3; j++) {
04028                         float wrf;
04029                         gzread(gzf, &wrf, sizeof( wrf )); 
04030                         pa->state.vel[j] = wrf;
04031                     }
04032     
04033                     pa->state.ave[0] = pa->state.ave[1] = pa->state.ave[2] = 0.0f;
04034                     pa->state.rot[0] = 1.0;
04035                     pa->state.rot[1] = pa->state.rot[2] = pa->state.rot[3] = 0.0;
04036     
04037                     pa->time = 1.f;
04038                     pa->dietime = sim->scene->r.efra + 1;
04039                     pa->lifetime = sim->scene->r.efra;
04040                     pa->alive = PARS_ALIVE;
04041                     //if(a<25) fprintf(stderr,"FSPARTICLE debug set %s , a%d = %f,%f,%f , life=%f \n", filename, a, pa->co[0],pa->co[1],pa->co[2], pa->lifetime );
04042                 } else {
04043                     // skip...
04044                     for(j=0; j<2*3+1; j++) {
04045                         float wrf; gzread(gzf, &wrf, sizeof( wrf )); 
04046                     }
04047                 }
04048                 fileParts++;
04049             }
04050             gzclose( gzf );
04051     
04052             totpart = psys->totpart = activeParts;
04053             BLI_snprintf(debugStrBuffer,sizeof(debugStrBuffer),"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d  \n", psys->totpart,activeParts,fileParts,readMask);
04054             // bad level call
04055             // XXX elbeemDebugOut(debugStrBuffer);
04056             
04057         } // fluid sim particles done
04058     }
04059     #endif // WITH_MOD_FLUID
04060 }
04061 
04062 static int emit_particles(ParticleSimulationData *sim, PTCacheID *pid, float UNUSED(cfra))
04063 {
04064     ParticleSystem *psys = sim->psys;
04065     int oldtotpart = psys->totpart;
04066     int totpart = tot_particles(psys, pid);
04067 
04068     if(totpart != oldtotpart)
04069         realloc_particles(sim, totpart);
04070 
04071     return totpart - oldtotpart;
04072 }
04073 
04074 /* Calculates the next state for all particles of the system
04075  * In particles code most fra-ending are frames, time-ending are fra*timestep (seconds)
04076  * 1. Emit particles
04077  * 2. Check cache (if used) and return if frame is cached
04078  * 3. Do dynamics
04079  * 4. Save to cache */
04080 static void system_step(ParticleSimulationData *sim, float cfra)
04081 {
04082     ParticleSystem *psys = sim->psys;
04083     ParticleSettings *part = psys->part;
04084     PointCache *cache = psys->pointcache;
04085     PTCacheID ptcacheid, *pid = NULL;
04086     PARTICLE_P;
04087     float disp, cache_cfra = cfra; /*, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; */
04088     int startframe = 0, endframe = 100, oldtotpart = 0;
04089 
04090     /* cache shouldn't be used for hair or "continue physics" */
04091     if(part->type != PART_HAIR && BKE_ptcache_get_continue_physics() == 0) {
04092         psys_clear_temp_pointcache(psys);
04093 
04094         /* set suitable cache range automatically */
04095         if((cache->flag & (PTCACHE_BAKING|PTCACHE_BAKED))==0)
04096             psys_get_pointcache_start_end(sim->scene, psys, &cache->startframe, &cache->endframe);
04097 
04098         pid = &ptcacheid;
04099         BKE_ptcache_id_from_particles(pid, sim->ob, psys);
04100         
04101         BKE_ptcache_id_time(pid, sim->scene, 0.0f, &startframe, &endframe, NULL);
04102 
04103         /* clear everythin on start frame */
04104         if(cfra == startframe) {
04105             BKE_ptcache_id_reset(sim->scene, pid, PTCACHE_RESET_OUTDATED);
04106             BKE_ptcache_validate(cache, startframe);
04107             cache->flag &= ~PTCACHE_REDO_NEEDED;
04108         }
04109         
04110         CLAMP(cache_cfra, startframe, endframe);
04111     }
04112 
04113 /* 1. emit particles and redo particles if needed */
04114     oldtotpart = psys->totpart;
04115     if(emit_particles(sim, pid, cfra) || psys->recalc & PSYS_RECALC_RESET) {
04116         distribute_particles(sim, part->from);
04117         initialize_all_particles(sim);
04118         /* reset only just created particles (on startframe all particles are recreated) */
04119         reset_all_particles(sim, 0.0, cfra, oldtotpart);
04120 
04121         if (psys->fluid_springs) {
04122             MEM_freeN(psys->fluid_springs);
04123             psys->fluid_springs = NULL;
04124         }
04125 
04126         psys->tot_fluidsprings = psys->alloc_fluidsprings = 0;
04127 
04128         /* flag for possible explode modifiers after this system */
04129         sim->psmd->flag |= eParticleSystemFlag_Pars;
04130 
04131         BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_AFTER, cfra);
04132     }
04133 
04134 /* 2. try to read from the cache */
04135     if(pid) {
04136         int cache_result = BKE_ptcache_read(pid, cache_cfra);
04137 
04138         if(ELEM(cache_result, PTCACHE_READ_EXACT, PTCACHE_READ_INTERPOLATED)) {
04139             cached_step(sim, cfra);
04140             update_children(sim);
04141             psys_update_path_cache(sim, cfra);
04142 
04143             BKE_ptcache_validate(cache, (int)cache_cfra);
04144 
04145             if(cache_result == PTCACHE_READ_INTERPOLATED && cache->flag & PTCACHE_REDO_NEEDED)
04146                 BKE_ptcache_write(pid, (int)cache_cfra);
04147 
04148             return;
04149         }
04150         /* Cache is supposed to be baked, but no data was found so bail out */
04151         else if(cache->flag & PTCACHE_BAKED) {
04152             psys_reset(psys, PSYS_RESET_CACHE_MISS);
04153             return;
04154         }
04155         else if(cache_result == PTCACHE_READ_OLD) {
04156             psys->cfra = (float)cache->simframe;
04157             cached_step(sim, psys->cfra);
04158         }
04159 
04160         /* if on second frame, write cache for first frame */
04161         if(psys->cfra == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0))
04162             BKE_ptcache_write(pid, startframe);
04163     }
04164     else
04165         BKE_ptcache_invalidate(cache);
04166 
04167 /* 3. do dynamics */
04168     /* set particles to be not calculated TODO: can't work with pointcache */
04169     disp= (float)psys_get_current_display_percentage(psys)/100.0f;
04170 
04171     LOOP_PARTICLES {
04172         if(PSYS_FRAND(p) > disp)
04173             pa->flag |= PARS_NO_DISP;
04174         else
04175             pa->flag &= ~PARS_NO_DISP;
04176     }
04177 
04178     if(psys->totpart) {
04179         int dframe, totframesback = 0;
04180         float t_frac, dt_frac;
04181 
04182         /* handle negative frame start at the first frame by doing
04183          * all the steps before the first frame */
04184         if((int)cfra == startframe && part->sta < startframe)
04185             totframesback = (startframe - (int)part->sta);
04186 
04187         if (!(part->time_flag & PART_TIME_AUTOSF)) {
04188             /* Constant time step */
04189             psys->dt_frac = 1.0f / (float) (part->subframes + 1);
04190         } else if ((int)cfra == startframe) {
04191             /* Variable time step; use a very conservative value at the start.
04192              * If it doesn't need to be so small, it will quickly grow. */
04193             psys->dt_frac = 1.0;
04194         } else if (psys->dt_frac < MIN_TIMESTEP) {
04195             psys->dt_frac = MIN_TIMESTEP;
04196         }
04197 
04198         for(dframe=-totframesback; dframe<=0; dframe++) {
04199             /* simulate each subframe */
04200             dt_frac = psys->dt_frac;
04201             for (t_frac = dt_frac; t_frac <= 1.0f; t_frac += dt_frac) {
04202                 sim->courant_num = 0.0f;
04203                 dynamics_step(sim, cfra+dframe+t_frac - 1.f);
04204                 psys->cfra = cfra+dframe+t_frac - 1.f;
04205 #if 0
04206                 printf("%f,%f,%f,%f\n", cfra+dframe+t_frac - 1.f, t_frac, dt_frac, sim->courant_num);
04207 #endif
04208                 if (part->time_flag & PART_TIME_AUTOSF)
04209                     dt_frac = update_timestep(psys, sim, t_frac);
04210             }
04211         }
04212     }
04213     
04214 /* 4. only write cache starting from second frame */
04215     if(pid) {
04216         BKE_ptcache_validate(cache, (int)cache_cfra);
04217         if((int)cache_cfra != startframe)
04218             BKE_ptcache_write(pid, (int)cache_cfra);
04219     }
04220 
04221     update_children(sim);
04222 
04223 /* cleanup */
04224     if(psys->lattice){
04225         end_latt_deform(psys->lattice);
04226         psys->lattice= NULL;
04227     }
04228 }
04229 
04230 /* system type has changed so set sensible defaults and clear non applicable flags */
04231 static void psys_changed_type(ParticleSimulationData *sim)
04232 {
04233     ParticleSettings *part = sim->psys->part;
04234     PTCacheID pid;
04235 
04236     BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
04237 
04238     if(part->phystype != PART_PHYS_KEYED)
04239         sim->psys->flag &= ~PSYS_KEYED;
04240 
04241     if(part->type == PART_HAIR) {
04242         if(ELEM4(part->ren_as, PART_DRAW_NOT, PART_DRAW_PATH, PART_DRAW_OB, PART_DRAW_GR)==0)
04243             part->ren_as = PART_DRAW_PATH;
04244 
04245         if(part->distr == PART_DISTR_GRID)
04246             part->distr = PART_DISTR_JIT;
04247 
04248         if(ELEM3(part->draw_as, PART_DRAW_NOT, PART_DRAW_REND, PART_DRAW_PATH)==0)
04249             part->draw_as = PART_DRAW_REND;
04250 
04251         CLAMP(part->path_start, 0.0f, 100.0f);
04252         CLAMP(part->path_end, 0.0f, 100.0f);
04253 
04254         BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
04255     }
04256     else {
04257         free_hair(sim->ob, sim->psys, 1);
04258 
04259         CLAMP(part->path_start, 0.0f, MAX2(100.0f, part->end + part->lifetime));
04260         CLAMP(part->path_end, 0.0f, MAX2(100.0f, part->end + part->lifetime));
04261     }
04262 
04263     psys_reset(sim->psys, PSYS_RESET_ALL);
04264 }
04265 void psys_check_boid_data(ParticleSystem *psys)
04266 {
04267         BoidParticle *bpa;
04268         PARTICLE_P;
04269 
04270         pa = psys->particles;
04271 
04272         if(!pa)
04273             return;
04274 
04275         if(psys->part && psys->part->phystype==PART_PHYS_BOIDS) {
04276             if(!pa->boid) {
04277                 bpa = MEM_callocN(psys->totpart * sizeof(BoidParticle), "Boid Data");
04278 
04279                 LOOP_PARTICLES
04280                     pa->boid = bpa++;
04281             }
04282         }
04283         else if(pa->boid){
04284             MEM_freeN(pa->boid);
04285             LOOP_PARTICLES
04286                 pa->boid = NULL;
04287         }
04288 }
04289 
04290 static void fluid_default_settings(ParticleSettings *part)
04291 {
04292     SPHFluidSettings *fluid = part->fluid;
04293 
04294     fluid->spring_k = 0.f;
04295     fluid->plasticity_constant = 0.1f;
04296     fluid->yield_ratio = 0.1f;
04297     fluid->rest_length = 1.f;
04298     fluid->viscosity_omega = 2.f;
04299     fluid->viscosity_beta = 0.1f;
04300     fluid->stiffness_k = 1.f;
04301     fluid->stiffness_knear = 1.f;
04302     fluid->rest_density = 1.f;
04303     fluid->buoyancy = 0.f;
04304     fluid->radius = 1.f;
04305     fluid->flag |= SPH_FAC_REPULSION|SPH_FAC_DENSITY|SPH_FAC_RADIUS|SPH_FAC_VISCOSITY|SPH_FAC_REST_LENGTH;
04306 }
04307 
04308 static void psys_prepare_physics(ParticleSimulationData *sim)
04309 {
04310     ParticleSettings *part = sim->psys->part;
04311 
04312     if(ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED)) {
04313         PTCacheID pid;
04314         BKE_ptcache_id_from_particles(&pid, sim->ob, sim->psys);
04315         BKE_ptcache_id_clear(&pid, PTCACHE_CLEAR_ALL, 0);
04316     }
04317     else {
04318         free_keyed_keys(sim->psys);
04319         sim->psys->flag &= ~PSYS_KEYED;
04320     }
04321 
04322     if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
04323         BoidState *state;
04324 
04325         part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
04326         boid_default_settings(part->boids);
04327 
04328         state = boid_new_state(part->boids);
04329         BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Separate));
04330         BLI_addtail(&state->rules, boid_new_rule(eBoidRuleType_Flock));
04331 
04332         ((BoidRule*)state->rules.first)->flag |= BOIDRULE_CURRENT;
04333 
04334         state->flag |= BOIDSTATE_CURRENT;
04335         BLI_addtail(&part->boids->states, state);
04336     }
04337     else if(part->phystype == PART_PHYS_FLUID && part->fluid == NULL) {
04338         part->fluid = MEM_callocN(sizeof(SPHFluidSettings), "SPH Fluid Settings");
04339         fluid_default_settings(part);
04340     }
04341 
04342     psys_check_boid_data(sim->psys);
04343 }
04344 static int hair_needs_recalc(ParticleSystem *psys)
04345 {
04346     if(!(psys->flag & PSYS_EDITED) && (!psys->edit || !psys->edit->edited) &&
04347         ((psys->flag & PSYS_HAIR_DONE)==0 || psys->recalc & PSYS_RECALC_RESET || (psys->part->flag & PART_HAIR_REGROW && !psys->edit))) {
04348         return 1;
04349     }
04350 
04351     return 0;
04352 }
04353 
04354 /* main particle update call, checks that things are ok on the large scale and
04355  * then advances in to actual particle calculations depending on particle type */
04356 void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
04357 {
04358     ParticleSimulationData sim= {0};
04359     ParticleSettings *part = psys->part;
04360     float cfra;
04361 
04362     /* drawdata is outdated after ANY change */
04363     if(psys->pdd) psys->pdd->flag &= ~PARTICLE_DRAW_DATA_UPDATED;
04364 
04365     if(!psys_check_enabled(ob, psys))
04366         return;
04367 
04368     cfra= BKE_curframe(scene);
04369 
04370     sim.scene= scene;
04371     sim.ob= ob;
04372     sim.psys= psys;
04373     sim.psmd= psys_get_modifier(ob, psys);
04374 
04375     /* system was already updated from modifier stack */
04376     if(sim.psmd->flag & eParticleSystemFlag_psys_updated) {
04377         sim.psmd->flag &= ~eParticleSystemFlag_psys_updated;
04378         /* make sure it really was updated to cfra */
04379         if(psys->cfra == cfra)
04380             return;
04381     }
04382 
04383     if(!sim.psmd->dm)
04384         return;
04385 
04386     /* execute drivers only, as animation has already been done */
04387     BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, cfra, ADT_RECALC_DRIVERS);
04388 
04389     if(psys->recalc & PSYS_RECALC_TYPE)
04390         psys_changed_type(&sim);
04391 
04392     if(psys->recalc & PSYS_RECALC_RESET)
04393         psys->totunexist = 0;
04394 
04395     /* setup necessary physics type dependent additional data if it doesn't yet exist */
04396     psys_prepare_physics(&sim);
04397 
04398     switch(part->type) {
04399         case PART_HAIR:
04400         {
04401             /* nothing to do so bail out early */
04402             if(psys->totpart == 0 && part->totpart == 0) {
04403                 psys_free_path_cache(psys, NULL);
04404                 free_hair(ob, psys, 0);
04405             }
04406             /* (re-)create hair */
04407             else if(hair_needs_recalc(psys)) {
04408                 float hcfra=0.0f;
04409                 int i, recalc = psys->recalc;
04410 
04411                 free_hair(ob, psys, 0);
04412 
04413                 if(psys->edit && psys->free_edit) {
04414                     psys->free_edit(psys->edit);
04415                     psys->edit = NULL;
04416                     psys->free_edit = NULL;
04417                 }
04418 
04419                 /* first step is negative so particles get killed and reset */
04420                 psys->cfra= 1.0f;
04421 
04422                 for(i=0; i<=part->hair_step; i++){
04423                     hcfra=100.0f*(float)i/(float)psys->part->hair_step;
04424                     if((part->flag & PART_HAIR_REGROW)==0)
04425                         BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, hcfra, ADT_RECALC_ANIM);
04426                     system_step(&sim, hcfra);
04427                     psys->cfra = hcfra;
04428                     psys->recalc = 0;
04429                     save_hair(&sim, hcfra);
04430                 }
04431 
04432                 psys->flag |= PSYS_HAIR_DONE;
04433                 psys->recalc = recalc;
04434             }
04435             else if(psys->flag & PSYS_EDITED)
04436                 psys->flag |= PSYS_HAIR_DONE;
04437 
04438             if(psys->flag & PSYS_HAIR_DONE)
04439                 hair_step(&sim, cfra);
04440             break;
04441         }
04442         case PART_FLUID:
04443         {
04444             particles_fluid_step(&sim, (int)cfra);
04445             break;
04446         }
04447         default:
04448         {
04449             switch(part->phystype) {
04450                 case PART_PHYS_NO:
04451                 case PART_PHYS_KEYED:
04452                 {
04453                     PARTICLE_P;
04454                     float disp = (float)psys_get_current_display_percentage(psys)/100.0f;
04455 
04456                     /* Particles without dynamics haven't been reset yet because they don't use pointcache */
04457                     if(psys->recalc & PSYS_RECALC_RESET)
04458                         psys_reset(psys, PSYS_RESET_ALL);
04459 
04460                     if(emit_particles(&sim, NULL, cfra) || (psys->recalc & PSYS_RECALC_RESET)) {
04461                         free_keyed_keys(psys);
04462                         distribute_particles(&sim, part->from);
04463                         initialize_all_particles(&sim);
04464 
04465                         /* flag for possible explode modifiers after this system */
04466                         sim.psmd->flag |= eParticleSystemFlag_Pars;
04467                     }
04468 
04469                     LOOP_EXISTING_PARTICLES {
04470                         pa->size = part->size;
04471                         if(part->randsize > 0.0f)
04472                             pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1);
04473 
04474                         reset_particle(&sim, pa, 0.0, cfra);
04475 
04476                         if(PSYS_FRAND(p) > disp)
04477                             pa->flag |= PARS_NO_DISP;
04478                         else
04479                             pa->flag &= ~PARS_NO_DISP;
04480                     }
04481 
04482                     if(part->phystype == PART_PHYS_KEYED) {
04483                         psys_count_keyed_targets(&sim);
04484                         set_keyed_keys(&sim);
04485                         psys_update_path_cache(&sim,(int)cfra);
04486                     }
04487                     break;
04488                 }
04489                 default:
04490                 {
04491                     /* the main dynamic particle system step */
04492                     system_step(&sim, cfra);
04493                     break;
04494                 }
04495             }
04496             break;
04497         }
04498     }
04499 
04500     if(psys->cfra < cfra) {
04501         /* make sure emitter is left at correct time (particle emission can change this) */
04502         while(ob) {
04503             BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM);
04504             ob = ob->parent;
04505         }
04506         ob = sim.ob;
04507         where_is_object_time(scene, ob, cfra);
04508     }
04509 
04510     psys->cfra = cfra;
04511     psys->recalc = 0;
04512 
04513     /* save matrix for duplicators, at rendertime the actual dupliobject's matrix is used so don't update! */
04514     if(psys->renderdata==0)
04515         invert_m4_m4(psys->imat, ob->obmat);
04516 }
04517