Revision: 16214
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16214
Author:   jhk
Date:     2008-08-21 23:12:27 +0200 (Thu, 21 Aug 2008)

Log Message:
-----------
New things for particle effectors:
- For newtonian particles a "self effect" button in particle extras makes the 
particles be effected by themselves if a particle effector is defined for this 
system, currently this is a brute force method so things start getting slow 
with more than ~100 particles, but this will hopefully change in the future.
- Two new effector types: charge and a Lennard-Jones potential based force 
(inter-molecular forces for example).
   -Charge is similar to spherical field except it changes behavior 
(attract/repulse) based on the effected particles charge field 
(negative/positive) like real particles with a charge.
   -The Lennard-Jones field is a very short range force with a behavior 
determined by the sizes of the effector and effected particle. At a distance 
smaller than the combined sizes the field is very repulsive and after that 
distance it's attractive. It tries to keep the particles at an equilibrium 
distance from each other. Particles need to be at a close proximity to each 
other to be effected by this field at all.
- Particle systems can now have two effector fields (two slots in the fields 
panel). This allows to create particles which for example have both a charge 
and a Lennard-Jones potential.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_effect.h
    trunk/blender/source/blender/blenkernel/intern/effect.c
    trunk/blender/source/blender/blenkernel/intern/ipo.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/blenloader/intern/writefile.c
    trunk/blender/source/blender/makesdna/DNA_ipo_types.h
    trunk/blender/source/blender/makesdna/DNA_object_force.h
    trunk/blender/source/blender/makesdna/DNA_particle_types.h
    trunk/blender/source/blender/src/buttons_object.c
    trunk/blender/source/blender/src/editipo.c
    trunk/blender/source/blender/src/editipo_lib.c

Modified: trunk/blender/source/blender/blenkernel/BKE_effect.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_effect.h        2008-08-21 
21:04:42 UTC (rev 16213)
+++ trunk/blender/source/blender/blenkernel/BKE_effect.h        2008-08-21 
21:12:27 UTC (rev 16214)
@@ -66,7 +66,7 @@
 void                   pdDoEffectors(struct ListBase *lb, float *opco, float 
*force, float *speed, float cur_time, float loc_time, unsigned int flags);
 
 /* required for particle_system.c */
-void do_physical_effector(Object *ob, float *opco, short type, float 
force_val, float distance, float falloff, float size, float damp, float 
*eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, 
struct RNG *rng, float noise_factor);
+void do_physical_effector(Object *ob, float *opco, short type, float 
force_val, float distance, float falloff, float size, float damp, float 
*eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, 
struct RNG *rng, float noise_factor, float charge, float pa_size);
 float effector_falloff(struct PartDeflect *pd, float *eff_velocity, float 
*vec_to_part);
 
 

Modified: trunk/blender/source/blender/blenkernel/intern/effect.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/effect.c     2008-08-21 
21:04:42 UTC (rev 16213)
+++ trunk/blender/source/blender/blenkernel/intern/effect.c     2008-08-21 
21:12:27 UTC (rev 16214)
@@ -332,7 +332,10 @@
 {
        float eff_dir[3], temp[3];
        float falloff=1.0, fac, r_fac;
-       
+
+       if(pd->forcefield==PFIELD_LENNARDJ)
+               return falloff; /* Lennard-Jones field has it's own falloff 
built in */
+
        VecCopyf(eff_dir,eff_velocity);
        Normalize(eff_dir);
 
@@ -369,7 +372,7 @@
        return falloff;
 }
 
-void do_physical_effector(Object *ob, float *opco, short type, float 
force_val, float distance, float falloff, float size, float damp, float 
*eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, 
struct RNG *rng, float noise_factor)
+void do_physical_effector(Object *ob, float *opco, short type, float 
force_val, float distance, float falloff, float size, float damp, float 
*eff_velocity, float *vec_to_part, float *velocity, float *field, int planar, 
struct RNG *rng, float noise_factor, float charge, float pa_size)
 {
        float mag_vec[3]={0,0,0};
        float temp[3], temp2[3];
@@ -442,14 +445,44 @@
                        VecMulf(mag_vec,damp*1.9f*(float)sqrt(force_val));
                        VecSubf(field,field,mag_vec);
                        break;
-               case PFIELD_NUCLEAR:
-                       /*pow here is root of cosine expression below*/
-                       //rad=(float)pow(2.0,-1.0/power)*distance/size;
-                       //VECCOPY(mag_vec,vec_to_part);
-                       //Normalize(mag_vec);
-                       
//VecMulf(mag_vec,(float)cos(3.0*M_PI/2.0*(1.0-1.0/(pow(rad,power)+1.0)))/(rad+0.2f));
-                       //VECADDFAC(field,field,mag_vec,force_val);
+               case PFIELD_CHARGE:
+                       if(planar)
+                               Projf(mag_vec,vec_to_part,eff_vel);
+                       else
+                               VecCopyf(mag_vec,vec_to_part);
+
+                       VecMulf(mag_vec,charge*force_val*falloff);
+                       VecAddf(field,field,mag_vec);
                        break;
+               case PFIELD_LENNARDJ:
+               {
+                       float fac;
+
+                       if(planar) {
+                               Projf(mag_vec,vec_to_part,eff_vel);
+                               distance = VecLength(mag_vec);
+                       }
+                       else
+                               VecCopyf(mag_vec,vec_to_part);
+
+                       /* at this distance the field is 60 times weaker than 
maximum */
+                       if(distance > 2.22 * (size+pa_size))
+                               break;
+
+                       fac = pow((size+pa_size)/distance,6.0);
+                       
+                       fac = - fac * (1.0 - fac) / distance;
+
+                       /* limit the repulsive term drastically to avoid huge 
forces */
+                       fac = ((fac>2.0) ? 2.0 : fac);
+
+                       /* 0.003715 is the fac value at 2.22 times 
(size+pa_size),
+                          substracted to avoid discontinuity at the border
+                       */
+                       VecMulf(mag_vec, force_val * (fac-0.0037315));
+                       VecAddf(field,field,mag_vec);
+                       break;
+               }
        }
 }
 
@@ -518,7 +551,7 @@
                        VECCOPY(field, force);
                        do_physical_effector(ob, opco, 
pd->forcefield,pd->f_strength,distance,
                                                                
falloff,pd->f_dist,pd->f_damp,ob->obmat[2],vec_to_part,
-                                                               
speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise);
+                                                               
speed,force,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise, 0.0f, 0.0f);
                        
                        // for softbody backward compatibility
                        if(flags & PE_WIND_AS_SPEED){

Modified: trunk/blender/source/blender/blenkernel/intern/ipo.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/ipo.c        2008-08-21 
21:04:42 UTC (rev 16213)
+++ trunk/blender/source/blender/blenkernel/intern/ipo.c        2008-08-21 
21:12:27 UTC (rev 16214)
@@ -182,7 +182,7 @@
        PART_EMIT_FREQ, PART_EMIT_LIFE, PART_EMIT_VEL, PART_EMIT_AVE, 
PART_EMIT_SIZE,
        PART_AVE, PART_SIZE, PART_DRAG, PART_BROWN, PART_DAMP, PART_LENGTH, 
PART_CLUMP,
     PART_GRAV_X, PART_GRAV_Y, PART_GRAV_Z, PART_KINK_AMP, PART_KINK_FREQ, 
PART_KINK_SHAPE,
-       PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD
+       PART_BB_TILT, PART_PD_FSTR, PART_PD_FFALL, PART_PD_FMAXD, 
PART_PD2_FSTR, PART_PD2_FFALL, PART_PD2_FMAXD
 };
 
 
@@ -1614,6 +1614,12 @@
                        poin= (part->pd?(&(part->pd->f_power)):NULL); break;
                case PART_PD_FMAXD:
                        poin= (part->pd?(&(part->pd->maxdist)):NULL); break;
+               case PART_PD2_FSTR:
+                       poin= (part->pd2?(&(part->pd2->f_strength)):NULL); 
break;
+               case PART_PD2_FFALL:
+                       poin= (part->pd2?(&(part->pd2->f_power)):NULL); break;
+               case PART_PD2_FMAXD:
+                       poin= (part->pd2?(&(part->pd2->maxdist)):NULL); break;
                }
        }
 

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c   2008-08-21 
21:04:42 UTC (rev 16213)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c   2008-08-21 
21:12:27 UTC (rev 16214)
@@ -320,8 +320,14 @@
 /************************************************/
 void psys_free_settings(ParticleSettings *part)
 {
-       if(part->pd)
+       if(part->pd) {
                MEM_freeN(part->pd);
+               part->pd = NULL;
+       }
+       if(part->pd2) {
+               MEM_freeN(part->pd2);
+               part->pd2 = NULL;
+       }
 }
 
 void free_hair(ParticleSystem *psys, int softbody)
@@ -3015,6 +3021,7 @@
        
        partn= copy_libblock(part);
        if(partn->pd) partn->pd= MEM_dupallocN(part->pd);
+       if(partn->pd2) partn->pd2= MEM_dupallocN(part->pd2);
        
        return partn;
 }

Modified: trunk/blender/source/blender/blenkernel/intern/particle_system.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle_system.c    
2008-08-21 21:04:42 UTC (rev 16213)
+++ trunk/blender/source/blender/blenkernel/intern/particle_system.c    
2008-08-21 21:12:27 UTC (rev 16214)
@@ -2206,6 +2206,9 @@
        return 1;
 }
 
+/************************************************/
+/*                     Effectors                                               
        */
+/************************************************/
 static void do_texture_effector(Tex *tex, short mode, short is_2d, float 
nabla, short object, float *pa_co, float obmat[4][4], float force_val, float 
falloff, float *field)
 {
        TexResult result[4];
@@ -2323,10 +2326,11 @@
 
                for(i=0; epsys; epsys=epsys->next,i++){
                        type=0;
-                       if(epsys!=psys){
+                       if(epsys!=psys || (psys->part->flag & 
PART_SELF_EFFECT)){
                                epart=epsys->part;
 
-                               if(epsys->part->pd && 
epsys->part->pd->forcefield)
+                               if((epsys->part->pd && 
epsys->part->pd->forcefield)
+                                       || (epsys->part->pd2 && 
epsys->part->pd2->forcefield))
                                        type=PSYS_EC_PARTICLE;
 
                                if(epart->type==PART_REACTOR) {
@@ -2575,35 +2579,31 @@
        ListBase *lb=&psys->effectors;
        ParticleEffectorCache *ec;
        float distance, vec_to_part[3];
-       float falloff;
+       float falloff, charge = 0.0f;
        int p;
 
        /* check all effector objects for interaction */
        if(lb->first){
+               if(psys->part->pd && psys->part->pd->forcefield==PFIELD_CHARGE){
+                       /* Only the charge of the effected particle is used for 
+                          interaction, not fall-offs. If the fall-offs aren't 
the      
+                          same this will be unphysical, but for animation this 
        
+                          could be the wanted behavior. If you want physical
+                          correctness the fall-off should be spherical 2.0 
anyways.
+                        */
+                       charge = psys->part->pd->f_strength;
+               }
+               if(psys->part->pd2 && 
psys->part->pd2->forcefield==PFIELD_CHARGE){
+                       charge += psys->part->pd2->f_strength;
+               }
                for(ec = lb->first; ec; ec= ec->next){
                        eob= ec->ob;
                        if(ec->type & PSYS_EC_EFFECTOR){
                                pd=eob->pd;
                                if(psys->part->type!=PART_HAIR && 
psys->part->integrator)
                                        where_is_object_time(eob,cfra);
-                               /* Get IPO force strength and fall off values 
here */
-                               //if (has_ipo_code(eob->ipo, OB_PD_FSTR))
-                               //      force_val = IPO_GetFloatValue(eob->ipo, 
OB_PD_FSTR, cfra);
-                               //else 
-                               //      force_val = pd->f_strength;
-                               
-                               //if (has_ipo_code(eob->ipo, OB_PD_FFALL)) 
-                               //      ffall_val = IPO_GetFloatValue(eob->ipo, 
OB_PD_FFALL, cfra);
-                               //else 
-                               //      ffall_val = pd->f_power;
 
-                               //if (has_ipo_code(eob->ipo, OB_PD_FMAXD)) 
-                               //      maxdist = IPO_GetFloatValue(eob->ipo, 
OB_PD_FMAXD, cfra);
-                               //else 
-                               //      maxdist = pd->maxdist;
-
                                /* use center of object for distance calculus */
-                               //obloc= eob->obmat[3];
                                VecSubf(vec_to_part, state->co, eob->obmat[3]);
                                distance = VecLength(vec_to_part);
 
@@ -2617,21 +2617,21 @@
                                                                        
pd->f_strength, falloff, force_field);
                                } else {
                                        do_physical_effector(eob, state->co, 
pd->forcefield,pd->f_strength,distance,
-                                                                               
falloff,pd->f_dist,pd->f_damp,eob->obmat[2],vec_to_part,
-                                                                               
pa->state.vel,force_field,pd->flag&PFIELD_PLANAR, pd->rng, pd->f_noise);
+                                                                               
falloff,0.0,pd->f_damp,eob->obmat[2],vec_to_part,
+                                                                               
pa->state.vel,force_field,pd->flag&PFIELD_PLANAR,pd->rng,pd->f_noise,charge,pa->size);
                                }
                        }
                        if(ec->type & PSYS_EC_PARTICLE){
-                               int totepart;
+                               int totepart, i;
                                epsys= 
BLI_findlink(&eob->particlesystem,ec->psys_nbr);
                                epart= epsys->part;
-                               pd= epart->pd;
+                               pd=epart->pd;
                                totepart= epsys->totpart;
                                
                                if(totepart <= 0)
                                        continue;
                                
-                               if(pd->forcefield==PFIELD_HARMONIC){
+                               if(pd && pd->forcefield==PFIELD_HARMONIC){
                                        /* every particle is mapped to only one 
harmonic effector particle */
                                        p= pa_no%epsys->totpart;
                                        totepart= p+1;
@@ -2643,31 +2643,27 @@
                                epsys->lattice=psys_get_lattice(ob,psys);
 
                                for(; p<totepart; p++){
+                                       /* particle skips itself as effector */
+                                       if(epsys==psys && p == pa_no) continue;
+
                                        epa = epsys->particles + p;
                                        estate.time=-1.0;
                                        
if(psys_get_particle_state(eob,epsys,p,&estate,0)){

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to