From 0a6d2e26a9eaeaf413c78e1f144fdcfe847fa317 Mon Sep 17 00:00:00 2001 From: Janne Karhu Date: Wed, 17 Sep 2008 19:29:44 +0000 Subject: [PATCH] Fix for [#17642] Particule Hair - Vertex Group lenght don't works without Children - This feature had been removed from the code! So this is how things work now: For normal (non-child) hair particles the length vgroup is used if we're not in particle edit mode and if there are no child particles. So for example checking "Parents" in the visualization panel when children are in use will result in full length parent strands, this is a feature so that you can see how the parent's go to predict child behavior better, not a bug :) --- source/blender/blenkernel/intern/particle.c | 62 ++++++++++++--------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 33af6037519..3ff57f55992 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1775,37 +1775,17 @@ static void do_path_effectors(Object *ob, ParticleSystem *psys, int i, ParticleC 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){ - //if(ptime){ - // /* parents need to be calculated fully first so that they don't mess up their children */ - // /* we'll make a note of where we got to though so that they're easy to finish later */ - // state->time=(max_length-*cur_length)/length; - // cache[totpart+p]->time=(float)k; - // } - //} - //else{ VecMulf(dvec, (max_length - *cur_length) / length); VECADD(state->co, (state - 1)->co, dvec); keys->steps = k; /* something over the maximum step value */ return k=100000; - //} } else { *cur_length+=length; return k; } } -static void finalize_path_length(ParticleCacheKey *keys) -{ - ParticleCacheKey *state = keys; - float dvec[3]; - state += state->steps; - - VECSUB(dvec, state->co, (state - 1)->co); - VecMulf(dvec, state->steps); - VECADD(state->co, (state - 1)->co, dvec); -} static void offset_child(ChildParticle *cpa, ParticleKey *par, ParticleKey *child, float flat, float radius) { VECCOPY(child->co,cpa->fuv); @@ -1986,7 +1966,7 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, ParticleCacheKey **cache= psys->childcache; ParticleCacheKey **pcache= psys->pathcache; ParticleCacheKey *state, *par = NULL, *key[4]; - ParticleData *pa; + ParticleData *pa=NULL; ParticleTexture ptex; float *cpa_fuv=0; float co[3], orco[3], ornor[3], t, rough_t, cpa_1st[3], dvec[3]; @@ -2287,10 +2267,6 @@ void psys_thread_create_path(ParticleThread *thread, struct ChildParticle *cpa, get_strand_normal(ctx->ma, ornor, cur_length, state->vel); } } - - /* now let's finalise the interpolated parents that we might have left half done before */ - if(itotparent) - finalize_path_length(keys); } void *exec_child_path_cache(void *data) @@ -2364,6 +2340,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda ParticleCacheKey *ca, **cache=psys->pathcache; ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys); ParticleEditSettings *pset = &G.scene->toolsettings->particle; + ParticleSettings *part = psys->part; ParticleData *pa; ParticleKey keys[4], result, *kkey[2] = {NULL, NULL}; @@ -2389,6 +2366,8 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda float nosel_col[3]; float length, vec[3]; float *vg_effector= NULL, effector=0.0f; + float *vg_length= NULL, pa_length=1.0f, max_length=1.0f, cur_length=0.0f; + float len, dvec[3]; /* we don't have anything valid to create paths from so let's quit here */ if((psys->flag & PSYS_HAIR_DONE)==0 && (psys->flag & PSYS_KEYED)==0) @@ -2440,6 +2419,9 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda 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); + + if(!edit && !psys->totchild) + vg_length = psys_cache_vgroup(psmd->dm, psys, PSYS_VG_LENGTH); } /*---first main loop: create all actual particles' paths---*/ @@ -2453,6 +2435,12 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda if(editupdate && !(pa->flag & PARS_EDIT_RECALC)) continue; else memset(cache[i], 0, sizeof(*cache[i])*(steps+1)); + if(!edit && !psys->totchild) { + pa_length = part->length * (1.0f - part->randlength*pa->r_ave[0]); + if(vg_length) + pa_length *= psys_interpolate_value_from_verts(psmd->dm,part->from,pa->num,pa->fuv,vg_length); + } + cache[i]->steps = steps; if(edit) @@ -2678,6 +2666,27 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda } + if(!edit && !psys->totchild) { + /* check if path needs to be cut before actual end of data points */ + if(k){ + VECSUB(dvec,ca->co,(ca-1)->co); + if(part->flag&PART_ABS_LENGTH) + len=VecLength(dvec); + else + len=1.0f/(float)steps; + + k=check_path_length(k,cache[i],ca,max_length,&cur_length,len,dvec); + } + else{ + /* initialize length calculation */ + if(part->flag&PART_ABS_LENGTH) + max_length= part->abslength*pa_length; + else + max_length= pa_length; + + cur_length= 0.0f; + } + } } } @@ -2690,6 +2699,9 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda if(vg_effector) MEM_freeN(vg_effector); + + if(vg_length) + MEM_freeN(vg_length); } /************************************************/ /* Particle Key handling */