[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16214] trunk/blender/source/blender: New things for particle effectors:

Janne Karhu jhkarh at utu.fi
Thu Aug 21 23:12:27 CEST 2008


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. @@




More information about the Bf-blender-cvs mailing list