Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2007-11-12 07:17:03 +0300
committerJoshua Leung <aligorith@gmail.com>2007-11-12 07:17:03 +0300
commit89317afbdfe19da951aeb2fa7764cc2f60b39f4d (patch)
tree4b8b0410ba9ab4c724d24be43a6882725ed972fb /source/blender/blenkernel/intern
parent7f2e43968a917e4512117164a8645756893c93da (diff)
Patch #7767: Constraint Subtargets can now target anywhere on a bone, not just the head or tail
Patch by: Roland Hess (harkyman) For example, a constraint can be sub-targeted at the 50% (or 31.2% or 85% etc.) point of its target bone, giving you enormous rigging flexibility and removing the need for complex contraptions to do such things as: - A bone whose base slides only between to points on a rig (CopyLoc with a variable, animated subtarget point) - Bones that attach to multiple points along another bone (CopyLocs, each with a different head/tail percentage) - Bones that need to stretch to a point midway between specific spots on two other bones (old way: too crazy to mention; new way: stretch bone between points on end bones, then another stretch to the midpoint of the first stretch) It is only used for the constraint types for which it is relevant: CopyLoc, TrackTo, StretchTo and MinMax, TrackTo, and Floor. Notes: - This is accessed by the Head/Tail number-slider. - This value can be animated per constraint - The old "Copy Bone Tail" option for the CopyLoc constraint has been automatically converted to 1.0 Head/Bone values for the affected constraints - In the code, this value is in the bConstraint struct, so it is available for all constraints, even though only a few implement it.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/action.c4
-rw-r--r--source/blender/blenkernel/intern/constraint.c74
-rw-r--r--source/blender/blenkernel/intern/ipo.c2
3 files changed, 34 insertions, 46 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index d202178fc0a..bd5e5d612c6 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -305,8 +305,10 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan
pchan->flag= chan->flag;
con= chan->constraints.first;
- for(pcon= pchan->constraints.first; pcon; pcon= pcon->next)
+ for(pcon= pchan->constraints.first; pcon; pcon= pcon->next) {
pcon->enforce= con->enforce;
+ pcon->headtail= con->headtail;
+ }
}
/* checks for IK constraint, can do more constraints flags later */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index f50cb2c6be0..558c90b37db 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -194,6 +194,11 @@ void do_constraint_channels (ListBase *conbase, ListBase *chanbase, float ctime,
con->enforce = CLAMPIS(icu->curval, 0.0f, 1.0f);
}
break;
+ case CO_HEADTAIL:
+ {
+ con->headtail = icu->curval;
+ }
+ break;
}
}
}
@@ -224,6 +229,9 @@ void unique_constraint_name (bConstraint *con, ListBase *list)
}
/* See if we even need to do this */
+ if (list == NULL)
+ return;
+
for (curcon = list->first; curcon; curcon=curcon->next) {
if (curcon != con) {
if (!strcmp(curcon->name, con->name)) {
@@ -710,7 +718,7 @@ static void contarget_get_lattice_mat (Object *ob, char *substring, float mat[][
/* generic function to get the appropriate matrix for most target cases */
/* The cases where the target can be object data have not been implemented */
-static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to)
+static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][4], short from, short to, float headtail)
{
/* Case OBJECT */
if (!strlen(substring)) {
@@ -744,7 +752,22 @@ static void constraint_target_to_mat4 (Object *ob, char *substring, float mat[][
* PoseChannel by the Armature Object's Matrix to get a worldspace
* matrix.
*/
- Mat4MulMat4(mat, pchan->pose_mat, ob->obmat);
+ if (headtail < 0.000001) {
+ /* skip length interpolation if set to head */
+ Mat4MulMat4(mat, pchan->pose_mat, ob->obmat);
+ }
+ else {
+ float tempmat[4][4], loc[3];
+
+ /* interpolate along length of bone */
+ VecLerpf(loc, pchan->pose_head, pchan->pose_tail, headtail);
+
+ /* use interpolated distance for subtarget */
+ Mat4CpyMat4(tempmat, pchan->pose_mat);
+ VecCopyf(tempmat[3], loc);
+
+ Mat4MulMat4(mat, tempmat, ob->obmat);
+ }
}
else
Mat4CpyMat4(mat, ob->obmat);
@@ -794,7 +817,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
static void default_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
{
if (VALID_CONS_TARGET(ct))
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space);
+ constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
else if (ct)
Mat4One(ct->matrix);
}
@@ -1192,7 +1215,7 @@ static void kinematic_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstra
bKinematicConstraint *data= con->data;
if (VALID_CONS_TARGET(ct))
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space);
+ constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
else if (ct) {
if (data->flag & CONSTRAINT_IK_AUTO) {
Object *ob= cob->ob;
@@ -1564,43 +1587,6 @@ static void loclike_flush_tars (bConstraint *con, ListBase *list, short nocopy)
}
}
-static void loclike_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float ctime)
-{
- bLocateLikeConstraint *data = con->data;
-
- if (VALID_CONS_TARGET(ct)) {
- if (ct->tar->type==OB_ARMATURE && strlen(ct->subtarget)) {
- /* Pose-Channels for the CopyLoc target are handled specially, so that
- * we can support using the bone-tip as an option.
- */
- bPoseChannel *pchan;
- float tmat[4][4];
-
- pchan = get_pose_channel(ct->tar->pose, ct->subtarget);
- if (pchan) {
- Mat4CpyMat4(tmat, pchan->pose_mat);
-
- if (data->flag & LOCLIKE_TIP) {
- VECCOPY(tmat[3], pchan->pose_tail);
- }
-
- Mat4MulMat4(ct->matrix, tmat, ct->tar->obmat);
- }
- else
- Mat4CpyMat4(ct->matrix, ct->tar->obmat);
-
- /* convert matrix space as required */
- constraint_mat_convertspace(ct->tar, pchan, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space);
- }
- else {
- /* get target matrix as is done normally for other constraints */
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space);
- }
- }
- else if (ct)
- Mat4One(ct->matrix);
-}
-
static void loclike_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *targets)
{
bLocateLikeConstraint *data= con->data;
@@ -1644,7 +1630,7 @@ static bConstraintTypeInfo CTI_LOCLIKE = {
loclike_new_data, /* new data */
loclike_get_tars, /* get constraint targets */
loclike_flush_tars, /* flush constraint targets */
- loclike_get_tarmat, /* get target matrix */
+ default_get_tarmat, /* get target matrix */
loclike_evaluate /* evaluate */
};
@@ -1896,7 +1882,7 @@ static void pycon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraintT
/* firstly calculate the matrix the normal way, then let the py-function override
* this matrix if it needs to do so
*/
- constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space);
+ constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
BPY_pyconstraint_target(data, ct);
}
else if (ct)
@@ -1987,7 +1973,7 @@ static void actcon_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstraint
Mat4One(ct->matrix);
/* get the transform matrix of the target */
- constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space);
+ constraint_target_to_mat4(ct->tar, ct->subtarget, tempmat, CONSTRAINT_SPACE_WORLD, ct->space, con->headtail);
/* determine where in transform range target is */
/* data->type is mapped as follows for backwards compatability:
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 107633eda64..83b845a0064 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -85,7 +85,7 @@
*/
int co_ar[CO_TOTIPO]= {
- CO_ENFORCE
+ CO_ENFORCE, CO_HEADTAIL
};
int ob_ar[OB_TOTIPO]= {