From f130f16fef38d40ee492ccb4ff1ad0708329ae3c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 12 Sep 2009 16:25:49 +0000 Subject: Use curve radius for paths - use_radius option, off by default for 2.4x files, on by default on new curves. - curve deform modifiers (think tentacles) - follow path (parent mode and constraint) - curve guides - added back Alt+S to scale point radius - Mat3Scale and Mat4Scale arithb.c functions to make a new uniform scale matrix. - TODO, effectors, looks like they have no way to scale from the radius yet. --- source/blender/blenkernel/intern/constraint.c | 33 +++++++++++++++------- source/blender/blenkernel/intern/curve.c | 2 +- source/blender/blenkernel/intern/lattice.c | 13 +++++++-- source/blender/blenkernel/intern/object.c | 11 ++++++-- source/blender/blenkernel/intern/particle.c | 16 ++++++----- source/blender/blenkernel/intern/particle_system.c | 6 ++-- source/blender/blenlib/BLI_arithb.h | 3 ++ source/blender/blenlib/intern/arithb.c | 20 +++++++++++++ source/blender/editors/curve/curve_ops.c | 1 + source/blender/makesdna/DNA_constraint_types.h | 1 + source/blender/makesdna/DNA_curve_types.h | 1 + source/blender/makesrna/intern/rna_constraint.c | 9 ++++-- source/blender/makesrna/intern/rna_curve.c | 5 ++++ 13 files changed, 94 insertions(+), 27 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 6ab9f5844b1..e5c0b3947de 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -1162,7 +1162,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr if (VALID_CONS_TARGET(ct)) { Curve *cu= ct->tar->data; - float q[4], vec[4], dir[3], quat[4], x1; + float q[4], vec[4], dir[3], quat[4], radius, x1; float totmat[4][4]; float curvetime; @@ -1196,7 +1196,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr curvetime= data->offset; // XXX might need a more sensible value } - if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, NULL) ) { + if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) { if (data->followflag & FOLLOWPATH_FOLLOW) { vectoquat(dir, (short) data->trackflag, (short) data->upflag, quat); @@ -1210,6 +1210,14 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr QuatToMat4(quat, totmat); } + + if (data->followflag & FOLLOWPATH_RADIUS) { + float tmat[4][4], rmat[4][4]; + Mat4Scale(tmat, radius); + Mat4MulMat4(rmat, totmat, tmat); + Mat4CpyMat4(totmat, rmat); + } + VECCOPY(totmat[3], vec); Mat4MulSerie(ct->matrix, ct->tar->obmat, totmat, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1227,7 +1235,8 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase /* only evaluate if there is a target */ if (VALID_CONS_TARGET(ct)) { float obmat[4][4]; - float size[3], obsize[3]; + float size[3]; + bFollowPathConstraint *data= con->data; /* get Object local transform (loc/rot/size) to determine transformation from path */ //object_to_mat4(ob, obmat); @@ -1240,13 +1249,17 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase Mat4MulSerie(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL); /* un-apply scaling caused by path */ - Mat4ToSize(cob->matrix, obsize); - if (obsize[0]) - VecMulf(cob->matrix[0], size[0] / obsize[0]); - if (obsize[1]) - VecMulf(cob->matrix[1], size[1] / obsize[1]); - if (obsize[2]) - VecMulf(cob->matrix[2], size[2] / obsize[2]); + if ((data->followflag & FOLLOWPATH_RADIUS)==0) { /* XXX - assume that scale correction means that radius will have some scale error in it - Campbell */ + float obsize[3]; + + Mat4ToSize(cob->matrix, obsize); + if (obsize[0]) + VecMulf(cob->matrix[0], size[0] / obsize[0]); + if (obsize[1]) + VecMulf(cob->matrix[1], size[1] / obsize[1]); + if (obsize[2]) + VecMulf(cob->matrix[2], size[2] / obsize[2]); + } } } diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 2b8c91fcbed..eec3cb73d8a 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -136,7 +136,7 @@ Curve *add_curve(char *name, int type) cu= alloc_libblock(&G.main->curve, ID_CU, name); cu->size[0]= cu->size[1]= cu->size[2]= 1.0; - cu->flag= CU_FRONT+CU_BACK; + cu->flag= CU_FRONT|CU_BACK|CU_PATH_RADIUS; cu->pathlen= 100; cu->resolu= cu->resolv= 12; cu->width= 1.0; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index e2c2723d036..730a12bea09 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -524,7 +524,7 @@ static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp) { Curve *cu= par->data; - float fac, loc[4], dir[3], cent[3]; + float fac, loc[4], dir[3], cent[3], radius; short upflag, index; if(axis==MOD_CURVE_POSX || axis==MOD_CURVE_NEGX) { @@ -579,7 +579,7 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C } #endif // XXX old animation system - if( where_on_path_deform(par, fac, loc, dir, NULL, NULL)) { /* returns OK */ + if( where_on_path_deform(par, fac, loc, dir, NULL, &radius)) { /* returns OK */ float q[4], mat[3][3], quat[4]; if(cd->no_rot_axis) /* set by caller */ @@ -599,7 +599,14 @@ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, C QuatMul(quat, q, quat); } QuatToMat3(quat, mat); - + + if(cu->flag & CU_PATH_RADIUS) { + float tmat[3][3], rmat[3][3]; + Mat3Scale(tmat, radius); + Mat3MulMat3(rmat, mat, tmat); + Mat3CpyMat3(mat, rmat); + } + /* local rotation */ Mat3MulVecfl(mat, cent); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index f04512cffc9..8fe7beeb247 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1646,7 +1646,7 @@ int enable_cu_speed= 1; static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) { Curve *cu; - float q[4], vec[4], dir[3], quat[4], x1, ctime; + float q[4], vec[4], dir[3], quat[4], radius, x1, ctime; float timeoffs = 0.0, sf_orig = 0.0; Mat4One(mat); @@ -1694,7 +1694,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, NULL) ) { + if( where_on_path(par, ctime, vec, dir, NULL, &radius) ) { if(cu->flag & CU_FOLLOW) { vectoquat(dir, ob->trackflag, ob->upflag, quat); @@ -1711,6 +1711,13 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) QuatToMat4(quat, mat); } + if(cu->flag & CU_PATH_RADIUS) { + float tmat[4][4], rmat[4][4]; + Mat4Scale(tmat, radius); + Mat4MulMat4(rmat, mat, tmat); + Mat4CpyMat4(mat, rmat); + } + VECCOPY(mat[3], vec); } diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 404203c4508..2d3e3210afc 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -1932,7 +1932,7 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase ParticleKey key, par; float effect[3]={0.0,0.0,0.0}, distance, f_force, mindist, totforce=0.0; - float guidevec[4], guidedir[3], rot2[4], temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f}; + float guidevec[4], guidedir[3], rot2[4], radius, temp[3], angle, pa_loc[3], pa_zero[3]={0.0f,0.0f,0.0f}; float veffect[3]={0.0,0.0,0.0}, guidetime; effect[0]=effect[1]=effect[2]=0.0; @@ -1975,9 +1975,9 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase } if(pd->flag & PFIELD_GUIDE_PATH_ADD) - where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, NULL); + where_on_path(eob, f_force*guidetime, guidevec, guidedir, NULL, &radius); else - where_on_path(eob, guidetime, guidevec, guidedir, NULL, NULL); + where_on_path(eob, guidetime, guidevec, guidedir, NULL, &radius); Mat4MulVecfl(ec->ob->obmat,guidevec); Mat4Mul3Vecfl(ec->ob->obmat,guidedir); @@ -2007,10 +2007,12 @@ int do_guide(Scene *scene, ParticleKey *state, int pa_num, float time, ListBase /* curve taper */ if(cu->taperobj) VecMulf(pa_loc, calc_taper(scene, cu->taperobj, (int)(f_force*guidetime*100.0), 100)); - /* TODO */ - //else{ - ///* curve size*/ - //} + + else{ /* curve size*/ + if(cu->flag & CU_PATH_RADIUS) { + VecMulf(pa_loc, radius); + } + } par.co[0]=par.co[1]=par.co[2]=0.0f; VECCOPY(key.co,pa_loc); do_prekink(&key, &par, 0, guidetime, pd->kink_freq, pd->kink_shape, pd->kink_amp, pd->kink, pd->kink_axis, 0); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3796e3e0ba5..fb12cfe3147 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -2526,7 +2526,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa ParticleSettings *part=psys->part; PARTICLE_P; int totpart; - float vec2[3],loc[3],*co=0; + float vec2[3],loc[3],radius,*co=0; for(ec= lb->first; ec; ec= ec->next) { PartDeflect *pd= ec->ob->pd; @@ -2536,7 +2536,7 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa && part->phystype!=PART_PHYS_BOIDS) { float vec[4]; - where_on_path(ec->ob, 0.0, vec, vec2, NULL, NULL); + where_on_path(ec->ob, 0.0, vec, vec2, NULL, &radius); Mat4MulVecfl(ec->ob->obmat,vec); Mat4Mul3Vecfl(ec->ob->obmat,vec2); @@ -2544,6 +2544,8 @@ static void precalc_effectors(Scene *scene, Object *ob, ParticleSystem *psys, Pa QUATCOPY(ec->firstloc,vec); VECCOPY(ec->firstdir,vec2); + /* TODO - use 'radius' to adjust the effector */ + totpart=psys->totpart; if(totpart){ diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 40076755fa0..c2d707f60f0 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -320,6 +320,9 @@ void Mat3Clr(float *m); void Mat3One(float m[][3]); void Mat4One(float m[][4]); +void Mat3Scale(float m[][3], float scale); +void Mat4Scale(float m[][4], float scale); + void Mat3Ortho(float mat[][3]); void Mat4Ortho(float mat[][4]); diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 9a05cd75ad0..9e769e19674 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -854,6 +854,26 @@ void Mat3One(float m[][3]) m[2][0]= m[2][1]= 0.0; } +void Mat4Scale(float m[][4], float scale) +{ + + m[0][0]= m[1][1]= m[2][2]= scale; + m[3][3]= 1.0; + m[0][1]= m[0][2]= m[0][3]= 0.0; + m[1][0]= m[1][2]= m[1][3]= 0.0; + m[2][0]= m[2][1]= m[2][3]= 0.0; + m[3][0]= m[3][1]= m[3][2]= 0.0; +} + +void Mat3Scale(float m[][3], float scale) +{ + + m[0][0]= m[1][1]= m[2][2]= scale; + m[0][1]= m[0][2]= 0.0; + m[1][0]= m[1][2]= 0.0; + m[2][0]= m[2][1]= 0.0; +} + void Mat4MulVec( float mat[][4], int *vec) { int x,y; diff --git a/source/blender/editors/curve/curve_ops.c b/source/blender/editors/curve/curve_ops.c index a242e424aa0..8a90dace40b 100644 --- a/source/blender/editors/curve/curve_ops.c +++ b/source/blender/editors/curve/curve_ops.c @@ -234,6 +234,7 @@ void ED_keymap_curve(wmWindowManager *wm) WM_keymap_add_item(keymap, "CURVE_OT_tilt_clear", TKEY, KM_PRESS, KM_ALT, 0); RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", TFM_TILT); + RNA_enum_set(WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", TFM_CURVE_SHRINKFATTEN); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "type", 1); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", HKEY, KM_PRESS, 0, 0)->ptr, "type", 3); RNA_enum_set(WM_keymap_add_item(keymap, "CURVE_OT_handle_type_set", VKEY, KM_PRESS, 0, 0)->ptr, "type", 2); diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h index a92dc836197..70430af3fc8 100644 --- a/source/blender/makesdna/DNA_constraint_types.h +++ b/source/blender/makesdna/DNA_constraint_types.h @@ -453,6 +453,7 @@ typedef enum B_CONSTRAINTCHANNEL_FLAG { /* FollowPath flags */ #define FOLLOWPATH_FOLLOW 0x01 #define FOLLOWPATH_STATIC 0x02 +#define FOLLOWPATH_RADIUS 0x04 /* bTrackToConstraint->flags */ #define TARGET_Z_UP 0x01 diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h index 8473f91a7f7..109a9528de2 100644 --- a/source/blender/makesdna/DNA_curve_types.h +++ b/source/blender/makesdna/DNA_curve_types.h @@ -242,6 +242,7 @@ typedef struct Curve { #define CU_FAST 512 /* Font: no filling inside editmode */ #define CU_RETOPO 1024 #define CU_DS_EXPAND 2048 +#define CU_PATH_RADIUS 4096 /* make use of the path radius if this is enabled (default for new curves) */ /* twist mode */ #define CU_TWIST_Z_UP 0 diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c index 83f3042d8ee..815023ee315 100644 --- a/source/blender/makesrna/intern/rna_constraint.c +++ b/source/blender/makesrna/intern/rna_constraint.c @@ -893,16 +893,21 @@ static void rna_def_constraint_follow_path(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Up Axis", "Axis that points upward."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); - prop= RNA_def_property(srna, "curve_follow", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_curve_follow", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_FOLLOW); RNA_def_property_ui_text(prop, "Follow Curve", "Object will follow the heading and banking of the curve."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); // TODO: do we need to do some special trickery to get offset sane for this? - prop= RNA_def_property(srna, "fixed_position", PROP_BOOLEAN, PROP_NONE); + prop= RNA_def_property(srna, "use_fixed_position", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_STATIC); RNA_def_property_ui_text(prop, "Fixed Position", "Object will stay locked to a single point somewhere along the length of the curve regardless of time."); RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); + + prop= RNA_def_property(srna, "use_curve_radius", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "followflag", FOLLOWPATH_RADIUS); + RNA_def_property_ui_text(prop, "Curve Radius", "Objects scale by the curve radius."); + RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update"); } static void rna_def_constraint_stretch_to(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index d09546231d5..da4abe81f24 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -426,6 +426,11 @@ static void rna_def_path(BlenderRNA *brna, StructRNA *srna) RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_OFFS_PATHDIST); RNA_def_property_ui_text(prop, "Offset Path Distance", "Children will use TimeOffs value as path distance offset."); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); + + prop= RNA_def_property(srna, "use_radius", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", CU_PATH_RADIUS); + RNA_def_property_ui_text(prop, "Radius", "Option for paths: apply the curve radius with path following it and deforming."); + RNA_def_property_update(prop, 0, "rna_Curve_update_data"); } static void rna_def_nurbs(BlenderRNA *brna, StructRNA *srna) -- cgit v1.2.3