diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 1008abb3da0..bd809a00ef0 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5253,7 +5253,7 @@ static DerivedMesh * particleInstanceModifier_applyModifier( MVert *mvert, *orig_mvert; int i,totvert, totpart=0, totface, maxvert, maxface, first_particle=0; short track=ob->trackflag%3, trackneg; - float max_co=0.0, min_co=0.0, temp_co[3]; + float max_co=0.0, min_co=0.0, temp_co[3], cross[3]; trackneg=((ob->trackflag>2)?1:0); @@ -5332,15 +5332,29 @@ static DerivedMesh * particleInstanceModifier_applyModifier( if(trackneg) state.time=1.0f-state.time; psys_get_particle_on_path(pimd->ob,psys,first_particle + i/totvert,&state,1); + + mv->co[0] = 0.0; + + Normalize(state.vel); + + if(state.vel[0] < -0.9999 || state.vel[0] > 0.9999) { + state.rot[0] = 1.0; + state.rot[1] = state.rot[2] = state.rot[3] = 0.0f; + } + else { + /* a cross product of state.vel and a unit vector in x-direction */ + cross[0] = 0.0f; + cross[1] = -state.vel[2]; + cross[2] = state.vel[1]; + + /* state.vel[0] is the only component surviving from a dot product with a vector in x-direction*/ + VecRotToQuat(cross,saacos(state.vel[0]),state.rot); + } } else{ state.time=-1.0; psys_get_particle_state(pimd->ob,psys,i/totvert,&state,1); - } - - /*displace vertice to path location*/ - if(pimd->flag & eParticleInstanceFlag_Path) - mv->co[0]=0.0; + } QuatMulVecf(state.rot,mv->co); VECADD(mv->co,mv->co,state.co); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 9cfc7e9dafe..5b92eb12d4f 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -776,7 +776,7 @@ static void weighted_particle_vector(float *v1, float *v2, float *v3, float *v4, vec[1]= weights[0]*v1[1] + weights[1]*v2[1] + weights[2]*v3[1] + weights[3]*v4[1]; vec[2]= weights[0]*v1[2] + weights[1]*v2[2] + weights[2]*v3[2] + weights[3]*v4[2]; } -static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result) +static void interpolate_particle(short type, ParticleKey keys[4], float dt, ParticleKey *result, int velocity) { float t[4]; @@ -788,18 +788,20 @@ static void interpolate_particle(short type, ParticleKey keys[4], float dt, Part weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, result->co); - //if(ve){ - // if(dt>0.999f){ - // set_four_ipo(dt+0.001f,t,ipo_type); - // weighted_particle_vector(key0->co,key1->co,key2->co,key3->co,t,temp); - // VECSUB(ve,temp,co); - // } - // else{ - // set_four_ipo(dt-0.001f,t,ipo_type); - // weighted_particle_vector(key0->co,key1->co,key2->co,key3->co,t,temp); - // VECSUB(ve,co,temp); - // } - //} + if(velocity){ + float temp[3]; + + if(dt>0.999f){ + set_four_ipo(dt-0.001f, t, type); + weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp); + VECSUB(result->vel, result->co, temp); + } + else{ + set_four_ipo(dt+0.001f, t, type); + weighted_particle_vector(keys[0].co, keys[1].co, keys[2].co, keys[3].co, t, temp); + VECSUB(result->vel, temp, result->co); + } + } } } @@ -2426,7 +2428,7 @@ void psys_cache_paths(Object *ob, ParticleSystem *psys, float cfra, int editupda /* now we should have in chronologiacl order k1<=k2<=t<=k3<=k4 with keytime between [0,1]->[k2,k3] (k1 & k4 used for cardinal & bspline interpolation)*/ interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */ : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL) - ,keys, keytime, &result); + ,keys, keytime, &result, 0); /* the velocity needs to be converted back from cubic interpolation */ if(psys->flag & PSYS_KEYED){ @@ -3371,7 +3373,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle interpolate_particle((psys->flag & PSYS_KEYED) ? -1 /* signal for cubic interpolation */ : ((psys->part->flag & PART_HAIR_BSPLINE) ? KEY_BSPLINE : KEY_CARDINAL) - ,keys, keytime, state); + ,keys, keytime, state, 1); /* the velocity needs to be converted back from cubic interpolation */ if(psys->flag & PSYS_KEYED){ @@ -3381,6 +3383,7 @@ void psys_get_particle_on_path(Object *ob, ParticleSystem *psys, int p, Particle if((pa->flag & PARS_REKEY)==0) { psys_mat_hair_to_global(ob, psmd->dm, part->from, pa, hairmat); Mat4MulVecfl(hairmat, state->co); + Mat4Mul3Vecfl(hairmat, state->vel); if(psys->effectors.first && (part->flag & PART_CHILD_GUIDE)==0) { do_guide(state, p, state->time, &psys->effectors);