diff options
-rw-r--r-- | source/blender/blenkernel/BKE_effect.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/effect.c | 53 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/ipo.c | 8 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 9 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 80 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 1 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 1 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_ipo_types.h | 8 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_force.h | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_particle_types.h | 3 | ||||
-rw-r--r-- | source/blender/src/buttons_object.c | 94 | ||||
-rw-r--r-- | source/blender/src/editipo.c | 17 | ||||
-rw-r--r-- | source/blender/src/editipo_lib.c | 3 |
13 files changed, 168 insertions, 115 deletions
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h index 5d3a0fba45f..6475f7a71ac 100644 --- a/source/blender/blenkernel/BKE_effect.h +++ b/source/blender/blenkernel/BKE_effect.h @@ -66,7 +66,7 @@ void pdEndEffectors(struct ListBase *lb); 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); diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index accc16ea940..0842e55a0ea 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -332,7 +332,10 @@ float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part) { 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 @@ float effector_falloff(PartDeflect *pd, float *eff_velocity, float *vec_to_part) 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 @@ void do_physical_effector(Object *ob, float *opco, short type, float force_val, 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 @@ void pdDoEffectors(ListBase *lb, float *opco, float *force, float *speed, float 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){ diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index fe92edfbbd5..4af25ee99e7 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -182,7 +182,7 @@ int part_ar[PART_TOTIPO]= { 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 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type) 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; } } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 643f90637ad..2f4696fc442 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -320,8 +320,14 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys) /************************************************/ 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 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part) partn= copy_libblock(part); if(partn->pd) partn->pd= MEM_dupallocN(part->pd); + if(partn->pd2) partn->pd2= MEM_dupallocN(part->pd2); return partn; } diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 8e5b011211b..ef8373ee977 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2206,6 +2206,9 @@ static int get_particles_from_cache(Object *ob, ParticleSystem *psys, int cfra) 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 @@ static void add_to_effectors(ListBase *lb, Object *ob, Object *obsrc, ParticleSy 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 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P 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 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P 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 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P 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)){ VECSUB(vec_to_part, state->co, estate.co); distance = VecLength(vec_to_part); - - //if(pd->forcefield==PFIELD_HARMONIC){ - // //if(cfra < epa->time + radius){ /* radius is fade-in in ui */ - // // eforce*=(cfra-epa->time)/radius; - // //} - //} - //else{ - // /* Limit minimum distance to effector particle so that */ - // /* the force is not too big */ - // if (distance < 0.001) distance = 0.001f; - //} - falloff=effector_falloff(pd,estate.vel,vec_to_part); + for(i=0, pd = epart->pd; i<2; i++,pd = epart->pd2) { + if(pd==NULL || pd->forcefield==0) continue; - if(falloff<=0.0f) - ; /* don't do anything */ - else - do_physical_effector(eob, state->co, pd->forcefield,pd->f_strength,distance, - falloff,epart->size,pd->f_damp,estate.vel,vec_to_part, - state->vel,force_field,0, pd->rng, pd->f_noise); + falloff=effector_falloff(pd,estate.vel,vec_to_part); + + if(falloff<=0.0f) + ; /* don't do anything */ + else + do_physical_effector(eob, state->co, pd->forcefield,pd->f_strength,distance, + falloff,epart->size,pd->f_damp,estate.vel,vec_to_part, + state->vel,force_field,0, pd->rng, pd->f_noise,charge,pa->size); + } } else if(pd->forcefield==PFIELD_HARMONIC && cfra-framestep <= epa->dietime && cfra>epa->dietime){ /* first step after key release */ diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ba8cdca0a83..a5c30f26008 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -2582,6 +2582,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main) static void direct_link_particlesettings(FileData *fd, ParticleSettings *part) { part->pd= newdataadr(fd, part->pd); + part->pd2= newdataadr(fd, part->pd2); } static void lib_link_particlesystems(FileData *fd, ID *id, ListBase *particles) diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index b462233528a..d596f57990f 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -535,6 +535,7 @@ static void write_particlesettings(WriteData *wd, ListBase *idbase) writestruct(wd, ID_PA, "ParticleSettings", 1, part); if (part->id.properties) IDP_WriteProperty(part->id.properties, wd); writestruct(wd, DATA, "PartDeflect", 1, part->pd); + writestruct(wd, DATA, "PartDeflect", 1, part->pd2); } part= part->id.next; } diff --git a/source/blender/makesdna/DNA_ipo_types.h b/source/blender/makesdna/DNA_ipo_types.h index 03ffef3cd55..1e30f3f7640 100644 --- a/source/blender/makesdna/DNA_ipo_types.h +++ b/source/blender/makesdna/DNA_ipo_types.h @@ -354,8 +354,8 @@ typedef short IPO_Channel; /* ******************** */ /* particle ipos */ -#define PART_TOTIPO 22 -#define PART_TOTNAM 22 +#define PART_TOTIPO 25 +#define PART_TOTNAM 25 #define PART_EMIT_FREQ 1 #define PART_EMIT_LIFE 2 @@ -385,6 +385,10 @@ typedef short IPO_Channel; #define PART_PD_FFALL 21 #define PART_PD_FMAXD 22 +#define PART_PD2_FSTR 23 +#define PART_PD2_FFALL 24 +#define PART_PD2_FMAXD 25 + /* these are IpoCurve specific */ /* **************** IPO ********************* */ diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 5f6ae7c7f06..5900e16d5e8 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -156,8 +156,8 @@ typedef struct SoftBody { #define PFIELD_GUIDE 5 #define PFIELD_TEXTURE 6 #define PFIELD_HARMONIC 7 -#define PFIELD_NUCLEAR 8 -#define PFIELD_MDIPOLE 9 +#define PFIELD_CHARGE 8 +#define PFIELD_LENNARDJ 9 /* pd->flag: various settings */ diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h index 4f62cd084cc..363f0075e23 100644 --- a/source/blender/makesdna/DNA_particle_types.h +++ b/source/blender/makesdna/DNA_particle_types.h @@ -166,6 +166,7 @@ typedef struct ParticleSettings { struct Object *bb_ob; struct Ipo *ipo; struct PartDeflect *pd; + struct PartDeflect *pd2; } ParticleSettings; typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in copy_particlesystem */ @@ -264,6 +265,8 @@ typedef struct ParticleSystem{ /* note, make sure all (runtime) are NULL's in #define PART_CHILD_RENDER (1<<29) #define PART_CHILD_GUIDE (1<<30) +#define PART_SELF_EFFECT (1<<22) + /* part->rotfrom */ #define PART_ROT_KEYS 0 /* interpolate directly from keys */ #define PART_ROT_ZINCR 1 /* same as zdir but done incrementally from previous position */ diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 98476cb5cd3..b0d612456d2 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -3317,6 +3317,7 @@ static void object_panel_fields(Object *ob) uiBut *but; int particles=0; static short actpsys=-1; + static char slot=0; block= uiNewBlock(&curarea->uiblocks, "object_panel_fields", UI_EMBOSS, UI_HELV, curarea->win); if(uiNewPanel(curarea, block, "Fields", "Physics", 0, 0, 318, 204)==0) return; @@ -3338,7 +3339,7 @@ static void object_panel_fields(Object *ob) char *tipstr="Choose field type"; uiBlockBeginAlign(block); - + if(ob->particlesystem.first) { ParticleSystem *psys; char *menustr2= psys_menu_string(ob,1); @@ -3350,8 +3351,16 @@ static void object_panel_fields(Object *ob) if(psys->part->pd==NULL) psys->part->pd= MEM_callocN(sizeof(PartDeflect), "PartDeflect"); - pd= psys->part->pd; + if(psys->part->pd2==NULL) + psys->part->pd2= MEM_callocN(sizeof(PartDeflect), "PartDeflect"); + + pd= ((slot==1) ? psys->part->pd2 : psys->part->pd); particles=1; + + uiDefButC(block, ROW, B_REDR, "", 10, 163, 14, 14, &slot, 3.0, 0, 0, 0, "Edit first particle effector slot"); + uiDefButC(block, ROW, B_REDR, "", 24, 163, 14, 14, &slot, 3.0, 1, 0, 0, "Edit second particle effector slot"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); } else actpsys= -1; /* -1 = object */ @@ -3364,8 +3373,8 @@ static void object_panel_fields(Object *ob) /* setup menu button */ if(particles){ - sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d", - PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC); + sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Charge%%x%d|Lennard-Jones%%x%d", + PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_CHARGE, PFIELD_LENNARDJ); if(pd->forcefield==PFIELD_FORCE) tipstr= "Particle attracts or repels particles (On shared object layers)"; else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of particle Z axis (On shared object layers)"; @@ -3373,11 +3382,11 @@ static void object_panel_fields(Object *ob) } else{ if(ob->type==OB_CURVE) - sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Curve Guide%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d", - PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE); + sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Curve Guide%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d|Charge%%x%d|Lennard-Jones%%x%d", + PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_GUIDE, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE, PFIELD_CHARGE, PFIELD_LENNARDJ); else - sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d", - PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE); + sprintf(menustr, "Field Type%%t|None%%x0|Spherical%%x%d|Wind%%x%d|Vortex%%x%d|Magnetic%%x%d|Harmonic%%x%d|Texture%%x%d|Charge%%x%d|Lennard-Jones%%x%d", + PFIELD_FORCE, PFIELD_WIND, PFIELD_VORTEX, PFIELD_MAGNET, PFIELD_HARMONIC, PFIELD_TEXTURE, PFIELD_CHARGE, PFIELD_LENNARDJ); if(pd->forcefield==PFIELD_FORCE) tipstr= "Object center attracts or repels particles (On shared object layers)"; else if(pd->forcefield==PFIELD_WIND) tipstr= "Constant force applied in direction of Object Z axis (On shared object layers)"; @@ -3392,8 +3401,6 @@ static void object_panel_fields(Object *ob) uiBlockEndAlign(block); uiDefBut(block, LABEL, 0, "",160,180,150,2, NULL, 0.0, 0, 0, 0, ""); - - MEM_freeN(menustr); if(pd->forcefield) { uiBlockBeginAlign(block); @@ -3459,40 +3466,49 @@ static void object_panel_fields(Object *ob) uiBlockEndAlign(block); } else{ - uiDefButS(block, MENU, B_FIELD_DEP, "Fall-off%t|Cone%x2|Tube%x1|Sphere%x0", 160,180,140,20, &pd->falloff, 0.0, 0.0, 0, 0, "Fall-off shape"); - if(pd->falloff==PFIELD_FALL_TUBE) - uiDefBut(block, LABEL, 0, "Longitudinal", 160,160,140,20, NULL, 0.0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButBitS(block, TOG, PFIELD_POSZ, B_FIELD_CHANGE, "Pos", 160,140,40,20, &pd->flag, 0.0, 0, 0, 0, "Effect only in direction of positive Z axis"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 200,140,100,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational falloff = 2)"); - uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use", 160,120,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 200,120,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work"); - uiDefButBitS(block, TOG, PFIELD_USEMIN, B_FIELD_CHANGE, "Use", 160,100,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum distance for the field's fall-off"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 200,100,100,20, &pd->mindist, 0, 1000.0, 10, 0, "Minimum distance for the field's fall-off"); - uiBlockEndAlign(block); - - if(pd->falloff==PFIELD_FALL_TUBE){ - uiDefBut(block, LABEL, 0, "Radial", 160,80,70,20, NULL, 0.0, 0, 0, 0, ""); - uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)"); - uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum radial distance for the field to work"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 200,40,100,20, &pd->maxrad, 0, 1000.0, 10, 0, "Maximum radial distance for the field to work"); - uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum radial distance for the field's fall-off"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 200,20,100,20, &pd->minrad, 0, 1000.0, 10, 0, "Minimum radial distance for the field's fall-off"); - uiBlockEndAlign(block); + if(pd->forcefield==PFIELD_LENNARDJ) { + uiDefBut(block, LABEL, 0, "Fall-off determined", 160,140,140,20, NULL, 0.0, 0, 0, 0, ""); + uiDefBut(block, LABEL, 0, "by particle sizes", 160,120,140,20, NULL, 0.0, 0, 0, 0, ""); } - else if(pd->falloff==PFIELD_FALL_CONE){ - uiDefBut(block, LABEL, 0, "Angular", 160,80,70,20, NULL, 0.0, 0, 0, 0, ""); + else { + uiDefButS(block, MENU, B_FIELD_DEP, "Fall-off%t|Cone%x2|Tube%x1|Sphere%x0", 160,180,140,20, &pd->falloff, 0.0, 0.0, 0, 0, "Fall-off shape"); + if(pd->falloff==PFIELD_FALL_TUBE) + uiDefBut(block, LABEL, 0, "Longitudinal", 160,160,140,20, NULL, 0.0, 0, 0, 0, ""); uiBlockBeginAlign(block); - uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)"); - uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum angle for the field to work"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxAngle: ", 200,40,100,20, &pd->maxrad, 0, 89.0, 10, 0, "Maximum angle for the field to work (in radians)"); - uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum angle for the field's fall-off"); - uiDefButF(block, NUM, B_FIELD_CHANGE, "MinAngle: ", 200,20,100,20, &pd->minrad, 0, 89.0, 10, 0, "Minimum angle for the field's fall-off (in radians)"); + uiDefButBitS(block, TOG, PFIELD_POSZ, B_FIELD_CHANGE, "Pos", 160,140,40,20, &pd->flag, 0.0, 0, 0, 0, "Effect only in direction of positive Z axis"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 200,140,100,20, &pd->f_power, 0, 10, 10, 0, "Falloff power (real gravitational falloff = 2)"); + uiDefButBitS(block, TOG, PFIELD_USEMAX, B_FIELD_CHANGE, "Use", 160,120,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum distance for the field to work"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 200,120,100,20, &pd->maxdist, 0, 1000.0, 10, 0, "Maximum distance for the field to work"); + uiDefButBitS(block, TOG, PFIELD_USEMIN, B_FIELD_CHANGE, "Use", 160,100,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum distance for the field's fall-off"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 200,100,100,20, &pd->mindist, 0, 1000.0, 10, 0, "Minimum distance for the field's fall-off"); uiBlockEndAlign(block); + + if(pd->falloff==PFIELD_FALL_TUBE){ + uiDefBut(block, LABEL, 0, "Radial", 160,80,70,20, NULL, 0.0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)"); + uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum radial distance for the field to work"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxDist: ", 200,40,100,20, &pd->maxrad, 0, 1000.0, 10, 0, "Maximum radial distance for the field to work"); + uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum radial distance for the field's fall-off"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "MinDist: ", 200,20,100,20, &pd->minrad, 0, 1000.0, 10, 0, "Minimum radial distance for the field's fall-off"); + uiBlockEndAlign(block); + } + else if(pd->falloff==PFIELD_FALL_CONE){ + uiDefBut(block, LABEL, 0, "Angular", 160,80,70,20, NULL, 0.0, 0, 0, 0, ""); + uiBlockBeginAlign(block); + uiDefButF(block, NUM, B_FIELD_CHANGE, "Fall-off: ", 160,60,140,20, &pd->f_power_r, 0, 10, 10, 0, "Radial falloff power (real gravitational falloff = 2)"); + uiDefButBitS(block, TOG, PFIELD_USEMAXR, B_FIELD_CHANGE, "Use", 160,40,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a maximum angle for the field to work"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "MaxAngle: ", 200,40,100,20, &pd->maxrad, 0, 89.0, 10, 0, "Maximum angle for the field to work (in radians)"); + uiDefButBitS(block, TOG, PFIELD_USEMINR, B_FIELD_CHANGE, "Use", 160,20,40,20, &pd->flag, 0.0, 0, 0, 0, "Use a minimum angle for the field's fall-off"); + uiDefButF(block, NUM, B_FIELD_CHANGE, "MinAngle: ", 200,20,100,20, &pd->minrad, 0, 89.0, 10, 0, "Minimum angle for the field's fall-off (in radians)"); + uiBlockEndAlign(block); + } } } + } + + MEM_freeN(menustr); } } @@ -4339,6 +4355,8 @@ static void object_panel_particle_extra(Object *ob) uiDefButBitI(block, TOG, PART_CHILD_EFFECT, B_PART_RECALC, "Children", butx+(butw*3)/5,buty,(butw*2)/5,buth, &part->flag, 0, 0, 0, 0, "Apply effectors to children"); uiBlockEndAlign(block); } + else if(part->phystype == PART_PHYS_NEWTON) + uiDefButBitI(block, TOG, PART_SELF_EFFECT, B_PART_RECALC, "Self Effect", butx,(buty-=buth),butw,buth, &part->flag, 0, 0, 0, 0, "Particle effectors effect themselves"); else buty-=buth; diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c index aa7787c5905..cd6aefdb87c 100644 --- a/source/blender/src/editipo.c +++ b/source/blender/src/editipo.c @@ -462,24 +462,7 @@ static void make_part_editipo(SpaceIpo *si) name = getname_part_ei(part_ar[a]); strcpy(ei->name, name); ei->adrcode= part_ar[a]; - - //if(ei->adrcode & MA_MAP1) { - // ei->adrcode-= MA_MAP1; - // ei->adrcode |= texchannel_to_adrcode(si->channel); - //} - //else { - // if(ei->adrcode==MA_MODE) ei->disptype= IPO_DISPBITS; - //} - ei->col= ipo_rainbow(a, PART_TOTIPO); - - //len= strlen(ei->name); - //if(len) { - // if( ei->name[ len-1 ]=='R') ei->col= 0x5050FF; - // else if( ei->name[ len-1 ]=='G') ei->col= 0x50FF50; - // else if( ei->name[ len-1 ]=='B') ei->col= 0xFF7050; - //} - ei->icu= find_ipocurve(si->ipo, ei->adrcode); if(ei->icu) { ei->flag= ei->icu->flag; diff --git a/source/blender/src/editipo_lib.c b/source/blender/src/editipo_lib.c index 7b3d439833e..e1e286e10cf 100644 --- a/source/blender/src/editipo_lib.c +++ b/source/blender/src/editipo_lib.c @@ -103,7 +103,8 @@ char *ic_name_empty[1] ={ "" }; char *fluidsim_ic_names[FLUIDSIM_TOTNAM] = { "Fac-Visc", "Fac-Time", "GravX","GravY","GravZ", "VelX","VelY","VelZ", "Active" }; char *part_ic_names[PART_TOTNAM] = { "E_Freq", "E_Life", "E_Speed", "E_Angular", "E_Size", "Angular", "Size", "Drag", "Brown", "Damp", "Length", "Clump", -"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt", "FStreng", "FFall", "FMaxD"}; +"GravX", "GravY", "GravZ", "KinkAmp", "KinkFreq", "KinkShape", "BBTilt", +"FStreng", "FFall", "FMaxD", "F2Streng", "F2Fall", "F2MaxD"}; /* gets the appropriate icon for the given blocktype */ int geticon_ipo_blocktype(short blocktype) |