svn merge -r 15392:15551 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender.git] / source / blender / blenkernel / intern / particle_system.c
index 602c13008dfe610a027a9599d5350dca8336575b..f70648965f413a5b9474f12cc2ae1150f1ee8c90 100644 (file)
@@ -3,15 +3,12 @@
  *
  * $Id: particle_system.c $
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -29,7 +26,7 @@
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 #include <stdlib.h>
@@ -171,7 +168,7 @@ static void realloc_particles(Object *ob, ParticleSystem *psys, int new_totpart)
        int i, totpart, totsaved = 0;
 
        if(new_totpart<0) {
-               if(psys->part->distr==PART_DISTR_GRID) {
+               if(psys->part->distr==PART_DISTR_GRID  && psys->part->from != PART_FROM_VERT) {
                        totpart= psys->part->grid_res;
                        totpart*=totpart*totpart;
                }
@@ -1059,7 +1056,7 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
                dm= CDDM_from_mesh((Mesh*)ob->data, ob);
 
                /* special handling of grid distribution */
-               if(part->distr==PART_DISTR_GRID){
+               if(part->distr==PART_DISTR_GRID && from != PART_FROM_VERT){
                        distribute_particles_in_grid(dm,psys);
                        dm->release(dm);
                        return 0;
@@ -1116,7 +1113,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
        if(tot==0){
                no_distr=1;
                if(children){
-                       fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n");
+                       if(G.f & G_DEBUG)
+                               fprintf(stderr,"Particle child distribution error: Nothing to emit from!\n");
                        for(p=0,cpa=psys->child; p<totpart; p++,cpa++){
                                cpa->fuv[0]=cpa->fuv[1]=cpa->fuv[2]=cpa->fuv[3]= 0.0;
                                cpa->foffset= 0.0f;
@@ -1126,7 +1124,8 @@ int psys_threads_init_distribution(ParticleThread *threads, DerivedMesh *finaldm
                        }
                }
                else {
-                       fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
+                       if(G.f & G_DEBUG)
+                               fprintf(stderr,"Particle distribution error: Nothing to emit from!\n");
                        for(p=0,pa=psys->particles; p<totpart; p++,pa++){
                                pa->fuv[0]=pa->fuv[1]=pa->fuv[2]= pa->fuv[3]= 0.0;
                                pa->foffset= 0.0f;
@@ -1601,7 +1600,7 @@ void initialize_particle(ParticleData *pa, int p, Object *ob, ParticleSystem *ps
 
        NormalQuat(pa->r_rot);
 
-       if(part->distr!=PART_DISTR_GRID){
+       if(part->distr!=PART_DISTR_GRID && part->from != PART_FROM_VERT){
                /* any unique random number will do (r_ave[0]) */
                if(ptex.exist < 0.5*(1.0+pa->r_ave[0]))
                        pa->flag |= PARS_UNEXIST;
@@ -1737,9 +1736,8 @@ void reset_particle(ParticleData *pa, ParticleSystem *psys, ParticleSystemModifi
                /* get possible textural influence */
                psys_get_texture(ob,give_current_material(ob,part->omat),psmd,psys,pa,&ptex,MAP_PA_IVEL);
 
-               if(vg_vel){
+               if(vg_vel && pa->num != -1)
                        ptex.ivel*=psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_vel);
-               }
 
                /* particles live in global space so    */
                /* let's convert:                                               */
@@ -2598,6 +2596,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo
        
        for(ec= lb->first; ec; ec= ec->next) {
                PartDeflect *pd= ec->ob->pd;
+               co = NULL;
                
                if(ec->type==PSYS_EC_EFFECTOR && pd->forcefield==PFIELD_GUIDE && ec->ob->type==OB_CURVE 
                        && part->phystype!=PART_PHYS_BOIDS) {
@@ -3772,10 +3771,12 @@ static void boid_brain(BoidVecFunc *bvf, ParticleData *pa, Object *ob, ParticleS
                                near=0;
                                for(n=1; n<neighbours; n++){
                                        if(ptn[n].dist<2.0f*pa->size){
-                                               bvf->Subf(dvec,pa->state.co,pars[ptn[n].index].state.co);
-                                               bvf->Mulf(dvec,(2.0f*pa->size-ptn[n].dist)/ptn[n].dist);
-                                               bvf->Addf(avoid,avoid,dvec);
-                                               near++;
+                                               if(ptn[n].dist!=0.0f) {
+                                                       bvf->Subf(dvec,pa->state.co,pars[ptn[n].index].state.co);
+                                                       bvf->Mulf(dvec,(2.0f*pa->size-ptn[n].dist)/ptn[n].dist);
+                                                       bvf->Addf(avoid,avoid,dvec);
+                                                       near++;
+                                               }
                                        }
                                        /* ptn[] is distance ordered so no need to check others */
                                        else break;
@@ -4514,7 +4515,7 @@ void psys_changed_type(ParticleSystem *psys)
        if(part->from == PART_FROM_PARTICLE) {
                if(part->type != PART_REACTOR)
                        part->from = PART_FROM_FACE;
-               if(part->distr == PART_DISTR_GRID)
+               if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
                        part->distr = PART_DISTR_JIT;
        }
 
@@ -4567,7 +4568,8 @@ static void particles_fluid_step(Object *ob, ParticleSystem *psys, int cfra)
                // ok, start loading
                strcpy(filename, ob->fluidsimSettings->surfdataPath);
                strcat(filename, suffix);
-               BLI_convertstringcode(filename, G.sce, curFrame); // fixed #frame-no 
+               BLI_convertstringcode(filename, G.sce);
+               BLI_convertstringframe(filename, curFrame); // fixed #frame-no 
                strcat(filename, suffix2);
 
                gzf = gzopen(filename, "rb");
@@ -4708,7 +4710,7 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
        oldtotpart = psys->totpart;
        oldtotchild = psys->totchild;
 
-       if(part->distr == PART_DISTR_GRID)
+       if(part->distr == PART_DISTR_GRID && part->from != PART_FROM_VERT)
                totpart = part->grid_res*part->grid_res*part->grid_res;
        else
                totpart = psys->part->totpart;
@@ -4764,6 +4766,9 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
                                psys_update_path_cache(ob,psmd,psys,framenr);
                        }
 
+                       cache->simframe= framenr;
+                       cache->flag |= PTCACHE_SIMULATION_VALID;
+
                        return;
                }
                else if(ob->id.lib || (cache->flag & PTCACHE_BAKED)) {
@@ -4810,9 +4815,20 @@ static void system_step(Object *ob, ParticleSystem *psys, ParticleSystemModifier
                        pa->flag &= ~PARS_NO_DISP;
        }
 
-       /* ok now we're all set so let's go */
-       if(psys->totpart)
-               dynamics_step(ob,psys,psmd,cfra,vg_vel,vg_tan,vg_rot,vg_size);
+       if(psys->totpart) {
+               int dframe, totframesback = 0;
+
+               /* handle negative frame start at the first frame by doing
+                * all the steps before the first frame */
+               if(framenr == startframe && part->sta < startframe)
+                       totframesback = (startframe - (int)part->sta);
+
+               for(dframe=-totframesback; dframe<=0; dframe++) {
+                       /* ok now we're all set so let's go */
+                       dynamics_step(ob,psys,psmd,cfra+dframe,vg_vel,vg_tan,vg_rot,vg_size);
+                       psys->cfra = cfra+dframe;
+               }
+       }
        
        cache->simframe= framenr;
        cache->flag |= PTCACHE_SIMULATION_VALID;