option to use curve point weights to influence particle effectors.
authorCampbell Barton <ideasman42@gmail.com>
Wed, 21 Apr 2010 11:59:47 +0000 (11:59 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 21 Apr 2010 11:59:47 +0000 (11:59 +0000)
19 files changed:
release/scripts/ui/properties_physics_field.py
source/blender/blenkernel/BKE_anim.h
source/blender/blenkernel/BKE_curve.h
source/blender/blenkernel/intern/anim.c
source/blender/blenkernel/intern/armature.c
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/curve.c
source/blender/blenkernel/intern/displist.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/font.c
source/blender/blenkernel/intern/lattice.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_system.c
source/blender/blenkernel/intern/pointcache.c
source/blender/editors/space_view3d/drawobject.c
source/blender/makesdna/DNA_curve_types.h
source/blender/makesdna/DNA_object_force.h
source/blender/makesrna/intern/rna_object_force.c

index e0be01d..9776643 100644 (file)
@@ -72,6 +72,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel):
             col.prop(field, "guide_free")
             col.prop(field, "falloff_power")
             col.prop(field, "guide_path_add")
+            col.prop(field, "use_guide_path_weight")
 
             if wide_ui:
                 col = split.column()
index 79b4d50..aae2be1 100644 (file)
@@ -63,7 +63,7 @@ void animviz_calc_motionpaths(struct Scene *scene, ListBase *targets);
 void free_path(struct Path *path);
 void calc_curvepath(struct Object *ob);
 int interval_test(int min, int max, int p1, int cycl);
-int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius);
+int where_on_path(struct Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight);
 
 /* ---------------------------------------------------- */
 /* Dupli-Geometry */
index a3232ac..ca45c2f 100644 (file)
@@ -72,7 +72,7 @@ void minmaxNurb( struct Nurb *nu, float *min, float *max);
 void makeknots( struct Nurb *nu, short uv);
 
 void makeNurbfaces(struct Nurb *nu, float *coord_array, int rowstride);
-void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu, int stride);
+void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride);
 void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
 float *make_orco_curve(struct Scene *scene, struct Object *ob);
 float *make_orco_surf( struct Object *ob);
index 10608dc..c6120ac 100644 (file)
@@ -460,6 +460,7 @@ void calc_curvepath(Object *ob)
                interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
                pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa;
                pp->radius= fac1*bevp->radius + fac2*bevpn->radius;
+               pp->weight= fac1*bevp->weight + fac2*bevpn->weight;
                interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2);
                normalize_qt(pp->quat);
                
@@ -491,7 +492,7 @@ int interval_test(int min, int max, int p1, int cycl)
  *     - *vec needs FOUR items!
  *     - ctime is normalized range <0-1>
  */
-int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
+int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius, float *weight)  /* returns OK */
 {
        Curve *cu;
        Nurb *nu;
@@ -587,6 +588,9 @@ int where_on_path(Object *ob, float ctime, float *vec, float *dir, float *quat,
        if(radius)
                *radius= data[0]*p0->radius + data[1]*p1->radius + data[2]*p2->radius + data[3]*p3->radius;
 
+       if(weight)
+               *weight= data[0]*p0->weight + data[1]*p1->weight + data[2]*p2->weight + data[3]*p3->weight;
+
        return 1;
 }
 
index 47f3530..b5b5547 100644 (file)
@@ -1941,7 +1941,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
                }
                
                /* tail endpoint */
-               if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad) ) {
+               if ( where_on_path(ikData->tar, tree->points[index], vec, dir, NULL, &rad, NULL) ) {
                        /* apply curve's object-mode transforms to the position 
                         * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
                         */
@@ -1957,7 +1957,7 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o
                }
                
                /* head endpoint */
-               if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad) ) {
+               if ( where_on_path(ikData->tar, tree->points[index+1], vec, dir, NULL, &rad, NULL) ) {
                        /* apply curve's object-mode transforms to the position 
                         * unless the option to allow curve to be positioned elsewhere is activated (i.e. no root)
                         */
index 9566fa8..c23f34e 100644 (file)
@@ -1242,7 +1242,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr
                                curvetime= data->offset_fac;
                        }
                        
-                       if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) {
+                       if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius, NULL) ) {
                                if (data->followflag & FOLLOWPATH_FOLLOW) {
                                        vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag);
                                        
@@ -3261,7 +3261,7 @@ static void clampto_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *ta
                        }
                        
                        /* 3. position on curve */
-                       if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) {
+                       if (where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL, NULL) ) {
                                unit_m4(totmat);
                                VECCOPY(totmat[3], vec);
                                
index dff936d..a01ee15 100644 (file)
@@ -887,14 +887,14 @@ void makeNurbfaces(Nurb *nu, float *coord_array, int rowstride)
        MEM_freeN(jend);
 }
 
-void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, int resolu, int stride)
+void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride)
 /* coord_array has to be 3*4*pntsu*resolu in size and zero-ed
  * tilt_array and radius_array will be written to if valid */
 {
        BPoint *bp;
        float u, ustart, uend, ustep, sumdiv;
        float *basisu, *sum, *fp;
-       float *coord_fp= coord_array, *tilt_fp= tilt_array, *radius_fp= radius_array;
+       float *coord_fp= coord_array, *tilt_fp= tilt_array, *radius_fp= radius_array, *weight_fp= weight_array;
        int i, len, istart, iend, cycl;
 
        if(nu->knotsu==NULL) return;
@@ -967,6 +967,9 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
                                
                                if (radius_fp)
                                        (*radius_fp) += (*fp) * bp->radius;
+
+                               if (weight_fp)
+                                       (*weight_fp) += (*fp) * bp->weight;
                                
                        }
                }
@@ -975,6 +978,7 @@ void makeNurbcurve(Nurb *nu, float *coord_array, float *tilt_array, float *radiu
                
                if (tilt_fp)    tilt_fp = (float *)(((char *)tilt_fp) + stride);
                if (radius_fp)  radius_fp = (float *)(((char *)radius_fp) + stride);
+               if (weight_fp)  weight_fp = (float *)(((char *)weight_fp) + stride);
                
                u+= ustep;
        }
@@ -1538,7 +1542,7 @@ static void calc_bevel_sin_cos(float x1, float y1, float x2, float y2, float *si
 
 }
 
-static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, int resolu, int stride)
+static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride)
 {
        BezTriple *pprev, *next, *last;
        float fac, dfac, t[4];
@@ -1595,6 +1599,13 @@ static void alfa_bezpart(BezTriple *prevbezt, BezTriple *bezt, Nurb *nu, float *
                        
                        radius_array = (float *)(((char *)radius_array) + stride); 
                }
+
+               if(weight_array) {
+                       /* basic interpolation for now, could copy tilt interp too  */
+                       *weight_array = prevbezt->weight + (bezt->weight - prevbezt->weight)*(3.0f*fac*fac - 2.0f*fac*fac*fac);
+
+                       weight_array = (float *)(((char *)weight_array) + stride);
+               }
        }
 }
 
@@ -1980,7 +1991,7 @@ void makeBevelList(Object *ob)
        float min, inp, x1, x2, y1, y2;
        struct bevelsort *sortdata, *sd, *sd1;
        int a, b, nr, poly, resolu = 0, len = 0;
-       int do_tilt, do_radius;
+       int do_tilt, do_radius, do_weight;
        
        /* this function needs an object, because of tflag and upflag */
        cu= ob->data;
@@ -1999,6 +2010,7 @@ void makeBevelList(Object *ob)
                /* check if we will calculate tilt data */
                do_tilt = CU_DO_TILT(cu, nu);
                do_radius = CU_DO_RADIUS(cu, nu); /* normal display uses the radius, better just to calculate them */
+               do_weight = 1;
                
                /* check we are a single point? also check we are not a surface and that the orderu is sane,
                 * enforced in the UI but can go wrong possibly */
@@ -2028,6 +2040,7 @@ void makeBevelList(Object *ob)
                                        VECCOPY(bevp->vec, bp->vec);
                                        bevp->alfa= bp->alfa;
                                        bevp->radius= bp->radius;
+                                       bevp->weight= bp->weight;
                                        bevp->split_tag= TRUE;
                                        bevp++;
                                        bp++;
@@ -2060,6 +2073,7 @@ void makeBevelList(Object *ob)
                                                VECCOPY(bevp->vec, prevbezt->vec[1]);
                                                bevp->alfa= prevbezt->alfa;
                                                bevp->radius= prevbezt->radius;
+                                               bevp->weight= prevbezt->weight;
                                                bevp->split_tag= TRUE;
                                                bevp->dupe_tag= FALSE;
                                                bevp++;
@@ -2081,6 +2095,7 @@ void makeBevelList(Object *ob)
                                                alfa_bezpart(   prevbezt, bezt, nu,
                                                                                 do_tilt        ? &bevp->alfa : NULL,
                                                                                 do_radius      ? &bevp->radius : NULL,
+                                                                                do_weight      ? &bevp->weight : NULL,
                                                                                 resolu, sizeof(BevPoint));
 
                                                
@@ -2110,6 +2125,7 @@ void makeBevelList(Object *ob)
                                        VECCOPY(bevp->vec, prevbezt->vec[1]);
                                        bevp->alfa= prevbezt->alfa;
                                        bevp->radius= prevbezt->radius;
+                                       bevp->weight= prevbezt->weight;
                                        bl->nr++;
                                }
                        }
@@ -2128,6 +2144,7 @@ void makeBevelList(Object *ob)
                                        makeNurbcurve(  nu, &bevp->vec[0],
                                                                        do_tilt         ? &bevp->alfa : NULL,
                                                                        do_radius       ? &bevp->radius : NULL,
+                                                                       do_weight       ? &bevp->weight : NULL,
                                                                        resolu, sizeof(BevPoint));
                                }
                        }
index c65fac7..ac635e5 100644 (file)
@@ -895,7 +895,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase)
                                data= dl->verts;
                                if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
                                else dl->type= DL_SEGM;
-                               makeNurbcurve(nu, data, NULL, NULL, resolu, 3*sizeof(float));
+                               makeNurbcurve(nu, data, NULL, NULL, NULL, resolu, 3*sizeof(float));
                        }
                        else if(nu->type == CU_POLY) {
                                len= nu->pntsu;
@@ -1598,7 +1598,7 @@ void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase,
                                if(nu->flagu & CU_NURB_CYCLIC) dl->type= DL_POLY;
                                else dl->type= DL_SEGM;
 
-                               makeNurbcurve(nu, data, NULL, NULL, nu->resolu, 3*sizeof(float));
+                               makeNurbcurve(nu, data, NULL, NULL, NULL, nu->resolu, 3*sizeof(float));
                        }
                        else {
                                len= (nu->pntsu*nu->resolu) * (nu->pntsv*nu->resolv);
index 118f488..00659b2 100644 (file)
@@ -222,7 +222,7 @@ static void precalculate_effector(EffectorCache *eff)
                                makeDispListCurveTypes(eff->scene, eff->ob, 0);
 
                        if(cu->path && cu->path->data) {
-                               where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius);
+                               where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
                                mul_m4_v3(eff->ob->obmat, eff->guide_loc);
                                mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
                        }
index 907c848..01f2b57 100644 (file)
@@ -1037,8 +1037,8 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode)
 
                                /* calc the right loc AND the right rot separately */
                                /* vec, tvec need 4 items */
-                               where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL);
-                               where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL);
+                               where_on_path(cu->textoncurve, ctime, vec, tvec, NULL, NULL, NULL);
+                               where_on_path(cu->textoncurve, ctime+dtime, tvec, rotvec, NULL, NULL, NULL);
                                
                                mul_v3_fl(vec, sizefac);
                                
index 8b1ff05..53fa7c1 100644 (file)
@@ -497,7 +497,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
        else ctime1= ctime;
        
        /* vec needs 4 items */
-       if(where_on_path(ob, ctime1, vec, dir, quat, radius)) {
+       if(where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
                
                if(cycl==0) {
                        Path *path= cu->path;
@@ -516,6 +516,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir,
                                VECADD(vec, vec, dvec);
                                if(quat) QUATCOPY(quat, path->data[path->len-1].quat);
                                if(radius) *radius= path->data[path->len-1].radius;
+                               /* weight - not used but could be added */
                        }
                }
                return 1;
index cd86ac0..bad1ebc 100644 (file)
@@ -1760,7 +1760,7 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4])
        
        
        /* vec: 4 items! */
-        if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) {
+        if( where_on_path(par, ctime, vec, dir, NULL, &radius, NULL) ) {
 
                if(cu->flag & CU_FOLLOW) {
                        vec_to_quat( quat,dir, ob->trackflag, ob->upflag);
index c4888de..e1b91b7 100644 (file)
@@ -1985,7 +1985,7 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
 
        float effect[3] = {0.0f, 0.0f, 0.0f}, veffect[3] = {0.0f, 0.0f, 0.0f};
        float guidevec[4], guidedir[3], rot2[4], temp[3];
-       float guidetime, radius, angle, totstrength = 0.0f;
+       float guidetime, radius, weight, angle, totstrength = 0.0f;
        float vec_to_point[3];
 
        if(effectors) for(eff = effectors->first; eff; eff=eff->next) {
@@ -2007,11 +2007,11 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
                cu = (Curve*)eff->ob->data;
 
                if(pd->flag & PFIELD_GUIDE_PATH_ADD) {
-                       if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius)==0)
+                       if(where_on_path(eff->ob, data->strength * guidetime, guidevec, guidedir, NULL, &radius, &weight)==0)
                                return 0;
                }
                else {
-                       if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius)==0)
+                       if(where_on_path(eff->ob, guidetime, guidevec, guidedir, NULL, &radius, &weight)==0)
                                return 0;
                }
 
@@ -2051,10 +2051,14 @@ int do_guides(ListBase *effectors, ParticleKey *state, int index, float time)
                VECCOPY(vec_to_point, key.co);
 
                VECADD(vec_to_point, vec_to_point, guidevec);
+
                //VECSUB(pa_loc,pa_loc,pa_zero);
                VECADDFAC(effect, effect, vec_to_point, data->strength);
                VECADDFAC(veffect, veffect, guidedir, data->strength);
                totstrength += data->strength;
+
+               if(pd->flag & PFIELD_GUIDE_PATH_WEIGHT)
+                       totstrength *= weight;
        }
 
        if(totstrength != 0.0){
index 720bf3b..621850f 100644 (file)
@@ -3687,7 +3687,7 @@ static void system_step(ParticleSimulationData *sim, float cfra)
        PTCacheID pid, *use_cache = NULL;
        PARTICLE_P;
        int oldtotpart;
-       float disp, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0;
+       float disp; /*, *vg_vel= 0, *vg_tan= 0, *vg_rot= 0, *vg_size= 0; */
        int init= 0, emit= 0; //, only_children_changed= 0;
        int framenr, framedelta, startframe = 0, endframe = 100;
 
index ab4750a..8001ba6 100644 (file)
@@ -802,10 +802,12 @@ static int ptcache_compress_read(PTCacheFile *pf, unsigned char *result, unsigne
        int r = 0;
        unsigned char compressed = 0;
        unsigned int in_len;
+#ifdef WITH_LZO
        unsigned int out_len = len;
+       size_t sizeOfIt = 5;
+#endif
        unsigned char *in;
        unsigned char *props = MEM_callocN(16*sizeof(char), "tmp");
-       size_t sizeOfIt = 5;
 
        ptcache_file_read(pf, &compressed, 1, sizeof(unsigned char));
        if(compressed) {
index 3fad63a..95ceb1b 100644 (file)
@@ -5098,13 +5098,13 @@ static void draw_forcefield(Scene *scene, Object *ob, RegionView3D *rv3d)
 
                        /*path end*/
                        setlinestyle(3);
-                       where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL);
+                       where_on_path(ob, 1.0f, guidevec1, guidevec2, NULL, NULL, NULL);
                        UI_ThemeColorBlend(curcol, TH_BACK, 0.5);
                        drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
 
                        /*path beginning*/
                        setlinestyle(0);
-                       where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL);
+                       where_on_path(ob, 0.0f, guidevec1, guidevec2, NULL, NULL, NULL);
                        UI_ThemeColorBlend(curcol, TH_BACK, 0.5);
                        drawcircball(GL_LINE_LOOP, guidevec1, mindist, imat);
                        
index 8241889..bd9ec95 100644 (file)
@@ -55,7 +55,7 @@ struct EditFont;
 typedef struct PathPoint {
        float vec[4]; /* grr, cant get rid of tilt yet */
        float quat[4];
-       float radius;
+       float radius, weight;
 } PathPoint;
 
 /* These two Lines with # tell makesdna this struct can be excluded. */
@@ -80,7 +80,7 @@ typedef struct BevList {
 #
 #
 typedef struct BevPoint {
-       float vec[3], alfa, radius;
+       float vec[3], alfa, radius, weight;
        float sina, cosa;                               /* 2D Only */
        float dir[3], tan[3], quat[4];  /* 3D Only */
        short split_tag, dupe_tag;
index 29a188c..ca8b664 100644 (file)
@@ -330,6 +330,7 @@ typedef struct SoftBody {
 #define PFIELD_VISIBILITY              (1<<13)
 #define PFIELD_DO_LOCATION             (1<<14)
 #define PFIELD_DO_ROTATION             (1<<15)
+#define PFIELD_GUIDE_PATH_WEIGHT (1<<16)       /* apply curve weights */
 
 /* pd->falloff */
 #define PFIELD_FALL_SPHERE             0
index 4cd0929..ee54505 100644 (file)
@@ -1262,6 +1262,11 @@ static void rna_def_field(BlenderRNA *brna)
        RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_ADD);
        RNA_def_property_ui_text(prop, "Additive", "Based on distance/falloff it adds a portion of the entire path");
        RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
+
+       prop= RNA_def_property(srna, "use_guide_path_weight", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_GUIDE_PATH_WEIGHT);
+       RNA_def_property_ui_text(prop, "Weights", "Use curve weights to influence the particle influence along the curve");
+       RNA_def_property_update(prop, 0, "rna_FieldSettings_update");
        
        /* Clump Settings */