Particle instance modifier works again in path mode. There's still some work to do...
authorJanne Karhu <jhkarh@gmail.com>
Thu, 24 Jan 2008 10:44:21 +0000 (10:44 +0000)
committerJanne Karhu <jhkarh@gmail.com>
Thu, 24 Jan 2008 10:44:21 +0000 (10:44 +0000)
source/blender/blenkernel/intern/modifier.c
source/blender/blenkernel/intern/particle.c

index 1008abb3da07479a93e9060f84f6a72a8b94e529..bd809a00ef00c517263cb989cc48ecafcaf03b41 100644 (file)
@@ -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);
index 9cfc7e9dafe97044253add78190a753e3db28e50..5b92eb12d4fb664112ff39f9b39488c549b2d659 100644 (file)
@@ -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);