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