Added an option for texture forcefields to use the root location of a particle for its texture coords.

Without this, animating grass would either look like seaweed (with low freq texture)
Or the grass would wrinkle up and get kinks (high freq texture)
This lets you use a high frequency texture while having straight grass.
This commit is contained in:
Campbell Barton 2008-02-19 18:36:50 +00:00
parent 2463e7a32e
commit 97d40faee9
6 changed files with 16 additions and 13 deletions

@ -293,7 +293,7 @@ void psys_particle_on_dm(struct Object *ob, struct DerivedMesh *dm, int from, in
void initialize_particle(struct ParticleData *pa, int p, struct Object *ob, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd);
void reset_particle(struct ParticleData *pa, struct ParticleSystem *psys, struct ParticleSystemModifierData *psmd, struct Object *ob, float dtime, float cfra, float *vg_vel, float *vg_tan, float *vg_rot);
void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Object *ob, struct ParticleSystem *psys, float *force_field, float *vel,float framestep, float cfra);
void do_effectors(int pa_no, struct ParticleData *pa, struct ParticleKey *state, struct Object *ob, struct ParticleSystem *psys, float *texco, float *force_field, float *vel,float framestep, float cfra);
void psys_calc_dmcache(struct Object *ob, struct DerivedMesh *dm, struct ParticleSystem *psys);
int psys_particle_dm_face_lookup(struct Object *ob, struct DerivedMesh *dm, int index, float *fw, struct LinkNode *node);

@ -1682,7 +1682,7 @@ static void do_rough_end(float *loc, float t, float fac, float shape, ParticleKe
VECADD(state->co,state->co,rough);
}
static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float effector, float dfra, float cfra, float *length, float *vec)
static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleCacheKey *ca, int k, int steps, float *rootco, float effector, float dfra, float cfra, float *length, float *vec)
{
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
ParticleKey eff_key;
@ -1693,7 +1693,7 @@ static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleC
QUATCOPY(eff_key.rot,(ca-1)->rot);
pa= psys->particles+i;
do_effectors(i, pa, &eff_key, ob, psys, force, vel, dfra, cfra);
do_effectors(i, pa, &eff_key, ob, psys, rootco, force, vel, dfra, cfra);
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
@ -2102,7 +2102,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
if(part->flag & PART_CHILD_EFFECT) {
for(k=0,state=keys; k<=ctx->steps; k++,state++) {
if(k) {
do_path_effectors(ob, psys, cpa->pa[0], state, k, ctx->steps, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
do_path_effectors(ob, psys, cpa->pa[0], state, k, ctx->steps, keys->co, pa_effector, 0.0f, ctx->cfra, &eff_length, eff_vec);
}
else {
VecSubf(eff_vec,(state+1)->co,state->co);
@ -2527,7 +2527,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
for(k=0, ca=cache[i]; k<=steps; k++, ca++) {
/* apply effectors */
if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k)
do_path_effectors(ob, psys, i, ca, k, steps, effector, dfra, cfra, &length, vec);
do_path_effectors(ob, psys, i, ca, k, steps, cache[i]->co, effector, dfra, cfra, &length, vec);
/* apply guide curves to path data */
if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_GUIDE)==0)

@ -2603,7 +2603,7 @@ static void precalc_effectors(Object *ob, ParticleSystem *psys, ParticleSystemMo
/* calculate forces that all effectors apply to a particle*/
void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, ParticleSystem *psys, float *force_field, float *vel,float framestep, float cfra)
void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, ParticleSystem *psys, float *rootco, float *force_field, float *vel,float framestep, float cfra)
{
Object *eob;
ParticleSystem *epsys;
@ -2650,15 +2650,16 @@ void do_effectors(int pa_no, ParticleData *pa, ParticleKey *state, Object *ob, P
if(falloff<=0.0f)
; /* don't do anything */
else if(pd->forcefield==PFIELD_TEXTURE)
else if(pd->forcefield==PFIELD_TEXTURE) {
do_texture_effector(pd->tex, pd->tex_mode, pd->flag&PFIELD_TEX_2D, pd->tex_nabla,
pd->flag & PFIELD_TEX_OBJECT, state->co, eob->obmat,
pd->flag & PFIELD_TEX_OBJECT, (pd->flag & PFIELD_TEX_ROOTCO) ? rootco : state->co, eob->obmat,
pd->f_strength, falloff, force_field);
else
} else {
do_physical_effector(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);
}
}
if(ec->type & PSYS_EC_PARTICLE){
int totepart;
epsys= BLI_findlink(&eob->particlesystem,ec->psys_nbr);
@ -2757,7 +2758,7 @@ static void apply_particle_forces(int pa_no, ParticleData *pa, Object *ob, Parti
tvel[0]=tvel[1]=tvel[2]=0.0;
/* add effectors */
if(part->type != PART_HAIR)
do_effectors(pa_no,pa,states+i,ob,psys,force,tvel,dfra,fra);
do_effectors(pa_no,pa,states+i,ob,psys,states->co,force,tvel,dfra,fra);
/* calculate air-particle interaction */
if(part->dragfac!=0.0f){

@ -163,6 +163,7 @@ typedef struct SoftBody {
#define PFIELD_USEMIN 256
#define PFIELD_USEMAXR 512
#define PFIELD_USEMINR 1024
#define PFIELD_TEX_ROOTCO 2048
/* pd->falloff */
#define PFIELD_FALL_SPHERE 0

@ -3417,7 +3417,8 @@ static void object_panel_fields(Object *ob)
if(pd->forcefield == PFIELD_TEXTURE){
uiDefIDPoinBut(block, field_testTexture, ID_TE, B_FIELD_CHANGE, "Texture: ", 10, 120, 140, 20, &pd->tex, "Texture to use as force");
uiDefButBitS(block, TOG, PFIELD_TEX_OBJECT, B_FIELD_CHANGE, "Use Object Co", 10,100,140,20, &pd->flag, 0.0, 0, 0, 0, "Use object/global coordinates for texture");
uiDefButBitS(block, TOG, PFIELD_TEX_2D, B_FIELD_CHANGE, "2D", 10,80,140,20, &pd->flag, 0.0, 0, 0, 0, "Apply force only in 2d");
uiDefButBitS(block, TOG, PFIELD_TEX_ROOTCO, B_FIELD_CHANGE, "Root TexCo", 10,80,120,20, &pd->flag, 0.0, 0, 0, 0, "Texture coords from root particle locations");
uiDefButBitS(block, TOG, PFIELD_TEX_2D, B_FIELD_CHANGE, "2D", 130,80,20,20, &pd->flag, 0.0, 0, 0, 0, "Apply force only in 2d");
}
else if(pd->forcefield == PFIELD_HARMONIC)
uiDefButF(block, NUM, B_FIELD_CHANGE, "Damp: ", 10,120,140,20, &pd->f_damp, 0, 10, 10, 0, "Damping of the harmonic force");

@ -2268,7 +2268,7 @@ void toolbox_generic( TBitem *generic_menu )
uiBut *but;
TBitem *menu;
int dx=96;
short event, mval[2], tot=0;
short event, mval[2];
long ypos = -5;
tb_mainx= -32;