diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4e9096b9768..bf1329128e3 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -369,6 +369,72 @@ static float linetriangle(float p1[3], float p2[3], float v0[3], float v1[3], fl return t; } +static void get_vortex(float opco[], float opno[], float speed[], float cur_time, unsigned int par_layer) +{ + /* Particle vortex code */ + /* Modifies the force on a particle according to its */ + /* distance from mesh vertices set to attract / repel */ + Object *ob; + Base *base; + float vect_to_vert[3]; + float force_vec[3]; + float f_force, distance; + float obloc[3]; + float force_val, ffall_val; + short cur_frame; + + /* Cycle through objects, get total of (1/(vortex_strength * dist^vortex_power)) */ + /* Check for min distance here? */ + base = G.scene->base.first; + while (base) { + if(base->lay & par_layer) { + ob= base->object; + if(ob->pd && ob->pd->forcefield & 2) { + + /* Need to set r.cfra for paths (investigate, ton) */ + cur_frame = G.scene->r.cfra; + G.scene->r.cfra = (short)cur_time; + where_is_object_time(ob, cur_time); + G.scene->r.cfra = cur_frame; + + /* only use center of object */ + obloc[0] = ob->obmat[3][0]; + obloc[1] = ob->obmat[3][1]; + obloc[2] = ob->obmat[3][2]; + + /* Get IPO force strength and fall off values here */ + if (has_ipo_code(ob->ipo, OB_PD_FSTR)) + force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, cur_time); + else + force_val = ob->pd->f_strength; + + if (has_ipo_code(ob->ipo, OB_PD_FFALL)) + ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, cur_time); + else + ffall_val = ob->pd->f_power; + + /* Now calculate the vortex force */ + VecSubf(vect_to_vert, obloc, opco); + + distance = Normalise(vect_to_vert); + + Crossf(force_vec, ob->obmat[2], vect_to_vert); + Normalise(force_vec); + + /* Limit minimum distance to vertex so that */ + /* the force is not too big */ + if (distance < 0.001) distance = 0.001; + f_force = (force_val)*(1/(100 * pow((double)distance, (double)ffall_val))); + speed[0] -= (force_vec[0] * f_force ); + speed[1] -= (force_vec[1] * f_force ); + speed[2] -= (force_vec[2] * f_force ); + + } + } + base = base->next; + } +} + static void get_forcefield(float opco[], float force[], float cur_time, unsigned int par_layer) { /* Particle gravity code */ @@ -388,7 +454,7 @@ static void get_forcefield(float opco[], float force[], float cur_time, unsigned while (base) { if(base->lay & par_layer) { ob= base->object; - if(ob->pd && ob->pd->forcefield) { + if(ob->pd && ob->pd->forcefield & 1) { /* Need to set r.cfra for paths (investigate, ton) */ cur_frame = G.scene->r.cfra; @@ -723,7 +789,7 @@ void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float * Particle *pa, *opa = NULL; float damp, deltalife, life; float cur_time; - float opco[3], opno[3], npco[3], npno[3], new_force[3]; + float opco[3], opno[3], npco[3], npno[3], new_force[3], new_speed[3]; int b, rt1, rt2, deflected, deflection, finish_defs, def_count; int last_ob, last_fc, same_fc; @@ -761,15 +827,19 @@ void make_particle_keys(int depth, int nr, PartEff *paf, Particle *part, float * new_force[0] = force[0]; new_force[1] = force[1]; new_force[2] = force[2]; + new_speed[0] = 0.0; + new_speed[1] = 0.0; + new_speed[2] = 0.0; /* Check force field */ cur_time = pa->time; get_forcefield(opco, new_force, cur_time, par_layer); + get_vortex(opco, opa->no, new_speed, cur_time, par_layer); /* new location */ - pa->co[0]= opa->co[0] + deltalife*opa->no[0]; - pa->co[1]= opa->co[1] + deltalife*opa->no[1]; - pa->co[2]= opa->co[2] + deltalife*opa->no[2]; + pa->co[0]= opa->co[0] + deltalife * (opa->no[0] + new_speed[0] + 0.5*new_force[0]); + pa->co[1]= opa->co[1] + deltalife * (opa->no[1] + new_speed[1] + 0.5*new_force[1]); + pa->co[2]= opa->co[2] + deltalife * (opa->no[2] + new_speed[2] + 0.5*new_force[2]); /* new speed */ pa->no[0]= opa->no[0] + deltalife*new_force[0]; diff --git a/source/blender/src/buttons_object.c b/source/blender/src/buttons_object.c index 5cbddbc4ff0..c185e704039 100644 --- a/source/blender/src/buttons_object.c +++ b/source/blender/src/buttons_object.c @@ -1251,7 +1251,7 @@ static void editing_panel_deflectors(Object *ob) uiBlock *block; block= uiNewBlock(&curarea->uiblocks, "editing_panel_deflectors", UI_EMBOSS, UI_HELV, curarea->win); - if(uiNewPanel(curarea, block, "Particle Interaction", "Effects", 0, 0, 190, 204)==0) return; + if(uiNewPanel(curarea, block, "Particle Interaction", "Effects", 0, 0, 300, 204)==0) return; /* should become button, option? */ if(ob->pd==NULL) { @@ -1261,16 +1261,18 @@ static void editing_panel_deflectors(Object *ob) if(ob->pd) { uiBlockBeginAlign(block); - uiDefButS(block, TOG|BIT|0, B_DIFF, "Force field", 10,160,150,20, &ob->pd->forcefield, 0, 0, 0, 0, "Object center attracts or repels particles"); - uiDefButF(block, NUM, B_DIFF, "Strength", 10,140,150,20, &ob->pd->f_strength, -100, 100, 100, 0, "Strength of force field"); - uiDefButF(block, NUM, B_DIFF, "Fall-off", 10,120,150,20, &ob->pd->f_power, 0, 10, 100, 0, "Falloff power (real gravitational fallof = 2)"); + uiDefButS(block, TOG|BIT|0, B_DIFF, "Force field", 10,160,200,20, &ob->pd->forcefield, 0, 0, 0, 0, "Object center attracts or repels particles"); + uiDefButS(block, TOG|BIT|1, B_DIFF, "Vortex field", 10,140,200,20, &ob->pd->forcefield, 0, 0, 0, 0, "Particles swirl around Z-axis of the object"); + + uiDefButF(block, NUM, B_DIFF, "Strength: ", 10,120,200,20, &ob->pd->f_strength, -100, 1000, 1000, 0, "Strength of force field"); + uiDefButF(block, NUM, B_DIFF, "Fall-off: ", 10,100,200,20, &ob->pd->f_power, 0, 10, 100, 0, "Falloff power (real gravitational fallof = 2)"); /* only meshes collide now */ if(ob->type==OB_MESH) { uiBlockBeginAlign(block); - uiDefButS(block, TOG|BIT|0, B_DIFF, "Deflection",10,80,150,20, &ob->pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); - uiDefButF(block, NUM, B_DIFF, "Surface damping", 10,60,150,20, &ob->pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision"); - uiDefButF(block, NUM, B_DIFF, "Random damping", 10,40,150,20, &ob->pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping"); - uiDefButF(block, NUM, B_DIFF, "Permeability", 10,30,150,20, &ob->pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh"); + uiDefButS(block, TOG|BIT|0, B_DIFF, "Deflection",10,70,200,20, &ob->pd->deflect, 0, 0, 0, 0, "Deflects particles based on collision"); + uiDefButF(block, NUM, B_DIFF, "Damping: ", 10,50,200,20, &ob->pd->pdef_damp, 0.0, 1.0, 10, 0, "Amount of damping during particle collision"); + uiDefButF(block, NUM, B_DIFF, "Rnd Damping: ", 10,30,200,20, &ob->pd->pdef_rdamp, 0.0, 1.0, 10, 0, "Random variation of damping"); + uiDefButF(block, NUM, B_DIFF, "Permeability: ", 10,10,200,20, &ob->pd->pdef_perm, 0.0, 1.0, 10, 0, "Chance that the particle will pass through the mesh"); } } }