diff options
author | Joshua Leung <aligorith@gmail.com> | 2009-11-01 14:29:40 +0300 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2009-11-01 14:29:40 +0300 |
commit | 2068eaf1b7f7729198ad865f69fa3bd11d7a9edc (patch) | |
tree | cc15c3d1e3d68ff8f8ca47a353b3b1e51dee52ea /source/blender/editors/object/object_constraint.c | |
parent | cb45db0336aa7a090c5edc0f8b6f62d334c72baa (diff) |
Rigging Goodies: Spline IK Constraint
At last, this commit introduces the Spline IK Constraint to Blender. Spline IK is a constraint that makes n bones follow the shape of a specified curve.
Simply add a chain of bones, add a curve, add a Spline IK Constraint to the tip bone and set the number of bones in the chain to make it work. Or, try the following test file:
http://download.blender.org/ftp/incoming/250_splineik_spine01.blend
Screenshots of this in action (as proof):
http://download.blender.org/ftp/incoming/b250_splineik_001_before.png
http://download.blender.org/ftp/incoming/b250_splineik_001_after.png
I've implemented this in a similar way to how standard IK solvers are done. However, this code is currently not an IK plugin, since I imagine that it would be useful to be able to combine the 2 types of IK. This can be easily changed though :)
Finally, a few notes on what to expect still:
* Constraint blending currently doesn't affect this. Getting that to work correctly will take a bit more work still.
* Options for not affecting the root joint (to make it easier to attach the chain to a stump or whatever), and non-uniform scaling options have yet to be added. I've marked the places where they can be added though
* Control over the twisting of the chain still needs investigation.
Have fun!
Diffstat (limited to 'source/blender/editors/object/object_constraint.c')
-rw-r--r-- | source/blender/editors/object/object_constraint.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 8c0da354938..15ec8d6116d 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -327,7 +327,7 @@ static void test_constraints (Object *owner, const char substring[]) /* clear disabled-flag first */ curcon->flag &= ~CONSTRAINT_DISABLE; - + if (curcon->type == CONSTRAINT_TYPE_KINEMATIC) { bKinematicConstraint *data = curcon->data; @@ -395,6 +395,26 @@ static void test_constraints (Object *owner, const char substring[]) if (data->lockflag+3==data->trackflag) curcon->flag |= CONSTRAINT_DISABLE; } + else if (curcon->type == CONSTRAINT_TYPE_SPLINEIK) { + bSplineIKConstraint *data = curcon->data; + + /* if the number of points does not match the amount required by the chain length, + * free the points array and request a rebind... + */ + if ( (data->points == NULL) || + (!(data->flag & CONSTRAINT_SPLINEIK_NO_ROOT) && (data->numpoints != data->chainlen+1)) || + ( (data->flag & CONSTRAINT_SPLINEIK_NO_ROOT) && (data->numpoints != data->chainlen)) ) + { + /* free the points array */ + if (data->points) { + MEM_freeN(data->points); + data->points = NULL; + } + + /* clear the bound flag, forcing a rebind next time this is evaluated */ + data->flag &= ~CONSTRAINT_SPLINEIK_BOUND; + } + } /* Check targets for constraints */ if (cti && cti->get_constraint_targets) { @@ -414,7 +434,7 @@ static void test_constraints (Object *owner, const char substring[]) } /* target checks for specific constraints */ - if (ELEM(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) { + if (ELEM3(curcon->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO, CONSTRAINT_TYPE_SPLINEIK)) { if (ct->tar) { if (ct->tar->type != OB_CURVE) { ct->tar= NULL; @@ -855,7 +875,7 @@ static int pose_constraints_clear_exec(bContext *C, wmOperator *op) CTX_DATA_BEGIN(C, bPoseChannel*, pchan, selected_pchans) { free_constraints(&pchan->constraints); - pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_CONST); + pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_SPLINEIK|PCHAN_HAS_CONST); } CTX_DATA_END; @@ -947,6 +967,7 @@ static short get_new_constraint_target(bContext *C, int con_type, Object **tar_o /* curve-based constraints - set the only_curve and only_ob flags */ case CONSTRAINT_TYPE_CLAMPTO: case CONSTRAINT_TYPE_FOLLOWPATH: + case CONSTRAINT_TYPE_SPLINEIK: only_curve= 1; only_ob= 1; add= 0; @@ -1070,6 +1091,10 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase BKE_report(op->reports, RPT_ERROR, "IK Constraint can only be added to Bones."); return OPERATOR_CANCELLED; } + if ( (type == CONSTRAINT_TYPE_SPLINEIK) && ((!pchan) || (list != &pchan->constraints)) ) { + BKE_report(op->reports, RPT_ERROR, "Spline IK Constraint can only be added to Bones."); + return OPERATOR_CANCELLED; + } /* create a new constraint of the type requried, and add it to the active/given constraints list */ con = add_new_constraint(type); @@ -1119,6 +1144,7 @@ static int constraint_add_exec(bContext *C, wmOperator *op, Object *ob, ListBase } /* do type-specific tweaking to the constraint settings */ + // TODO: does action constraint need anything here - i.e. spaceonce? switch (type) { case CONSTRAINT_TYPE_CHILDOF: { |