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