Effectors on particle hair can now be applied to the children instead

of the parents, with the "Children" button next to Stiffness.
This commit is contained in:
Brecht Van Lommel 2008-02-15 12:54:43 +00:00
parent 113b684e07
commit e63d03afc7
4 changed files with 65 additions and 30 deletions

@ -179,6 +179,7 @@ typedef struct ParticleThreadContext {
float *vg_length, *vg_clump, *vg_kink;
float *vg_rough1, *vg_rough2, *vg_roughe;
float *vg_effector;
} ParticleThreadContext;
typedef struct ParticleThread {

@ -1668,6 +1668,32 @@ 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)
{
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
ParticleKey eff_key;
ParticleData *pa;
VECCOPY(eff_key.co,(ca-1)->co);
VECCOPY(eff_key.vel,(ca-1)->vel);
QUATCOPY(eff_key.rot,(ca-1)->rot);
pa= psys->particles+i;
do_effectors(i, pa, &eff_key, ob, psys, force, vel, dfra, cfra);
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
VecAddf(force, force, vec);
Normalize(force);
if(k < steps) {
VecSubf(vec, (ca+1)->co, ca->co);
*length = VecLength(vec);
}
VECADDFAC(ca->co, (ca-1)->co, force, *length);
}
static int check_path_length(int k, ParticleCacheKey *keys, ParticleCacheKey *state, float max_length, float *cur_length, float length, float *dvec)
{
if(*cur_length + length > max_length){
@ -1859,6 +1885,8 @@ int psys_threads_init_path(ParticleThread *threads, float cfra, int editupdate)
ctx->vg_rough1 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH1);
ctx->vg_rough2 = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGH2);
ctx->vg_roughe = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_ROUGHE);
if(psys->part->flag & PART_CHILD_EFFECT)
ctx->vg_effector = psys_cache_vgroup(ctx->dm,psys,PSYS_VG_EFFECTOR);
}
/* set correct ipo timing */
@ -1886,8 +1914,9 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3];
float branch_begin, branch_end, branch_prob, branchfac, rough_rand;
float pa_rough1, pa_rough2, pa_roughe;
float length, pa_length, pa_clump, pa_kink;
float length, pa_length, pa_clump, pa_kink, pa_effector;
float max_length = 1.0f, cur_length = 0.0f;
float eff_length, eff_vec[3];
int k, cpa_num, guided=0;
short cpa_from;
@ -2000,6 +2029,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
pa_rough1=ptex.rough;
pa_rough2=ptex.rough;
pa_roughe=ptex.rough;
pa_effector= 1.0f;
if(ctx->vg_length)
pa_length*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_length);
@ -2013,16 +2043,17 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
pa_rough2*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_rough2);
if(ctx->vg_roughe)
pa_roughe*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_roughe);
if(ctx->vg_effector)
pa_effector*=psys_interpolate_value_from_verts(ctx->dm,cpa_from,cpa_num,cpa_fuv,ctx->vg_effector);
/* create the child path */
for(k=0,state=keys; k<=ctx->steps; k++,state++){
t=(float)k/(float)ctx->steps;
if(ctx->between){
int w=0;
state->co[0] = state->co[1] = state->co[2] = 0.0f;
state->vel[0] = state->vel[1] = state->vel[2] = 0.0f;
state->rot[0] = state->rot[1] = state->rot[2] = state->rot[3] = 0.0f;
//QUATCOPY(state->rot,key[0]->rot);
@ -2051,6 +2082,23 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa,
key[0]++;
}
}
/* apply effectors */
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);
}
else {
VecSubf(eff_vec,(state+1)->co,state->co);
eff_length= VecLength(eff_vec);
}
}
}
for(k=0,state=keys; k<=ctx->steps; k++,state++){
t=(float)k/(float)ctx->steps;
if(ctx->totparent){
if(i>=ctx->totparent)
@ -2322,8 +2370,10 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda
if(ma && (psys->part->draw & PART_DRAW_MAT_COL))
VECCOPY(col, &ma->r)
if(psys->part->from!=PART_FROM_PARTICLE)
vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
if(psys->part->from!=PART_FROM_PARTICLE) {
if(!(psys->part->flag & PART_CHILD_EFFECT))
vg_effector = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_EFFECTOR);
}
/*---first main loop: create all actual particles' paths---*/
for(i=0,pa=psys->particles; i<totpart; i++, pa++){
@ -2466,29 +2516,8 @@ 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(edit==0 && k) {
float force[3] = {0.0f,0.0f,0.0f}, vel[3] = {0.0f,0.0f,0.0f};
ParticleKey eff_key;
VECCOPY(eff_key.co,(ca-1)->co);
VECCOPY(eff_key.vel,(ca-1)->vel);
QUATCOPY(eff_key.rot,(ca-1)->rot);
do_effectors(i, pa, &eff_key, ob, psys, force, vel, dfra, cfra);
VecMulf(force, effector*pow((float)k / (float)steps, 100.0f * psys->part->eff_hair) / (float)steps);
VecAddf(force, force, vec);
Normalize(force);
if(k < steps) {
VecSubf(vec, (ca+1)->co, ca->co);
length = VecLength(vec);
}
VECADDFAC(ca->co, (ca-1)->co, force, length);
}
if(!(psys->part->flag & PART_CHILD_EFFECT) && edit==0 && k)
do_path_effectors(ob, psys, i, ca, k, steps, effector, dfra, cfra, &length, vec);
/* apply guide curves to path data */
if(edit==0 && psys->effectors.first && (psys->part->flag & PART_CHILD_GUIDE)==0)

@ -258,6 +258,7 @@ typedef struct ParticleSystem{
#define PART_GRID_INVERT (1<<26)
#define PART_CHILD_EFFECT (1<<27)
#define PART_CHILD_SEAMS (1<<28)
#define PART_CHILD_RENDER (1<<29)
#define PART_CHILD_GUIDE (1<<30)

@ -4182,8 +4182,12 @@ static void object_panel_particle_extra(Object *ob)
buty=butx=160;
uiDefButI(block, NUM, B_PART_DISTR, "Seed:", butx,(buty-=buth),butw,buth, &psys->seed, 0.0, 255.0, 1, 0, "Set an offset in the random table");
if(part->type == PART_HAIR && psys->flag & PSYS_EDITED)
uiDefButF(block, NUM, B_PART_RECALC, "Stiff:", butx,(buty-=buth),butw,buth, &part->eff_hair, 0.0, 1.0, 0, 0, "Hair stiffness for effectors");
if(part->type == PART_HAIR && psys->flag & PSYS_EDITED) {
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_PART_RECALC, "Stiff:", butx,(buty-=buth),(butw*3)/5,buth, &part->eff_hair, 0.0, 1.0, 0, 0, "Hair stiffness for effectors");
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
buty-=buth;