[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12561] trunk/blender/source/blender: Patch #7767: Constraint Subtargets can now target anywhere on a bone, not just the head or tail

Joshua Leung aligorith at gmail.com
Mon Nov 12 05:17:07 CET 2007


Revision: 12561
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12561
Author:   aligorith
Date:     2007-11-12 05:17:03 +0100 (Mon, 12 Nov 2007)

Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/blender/blenkernel/intern/constraint.c
    trunk/blender/source/blender/blenkernel/intern/ipo.c
    trunk/blender/source/blender/blenloader/intern/readfile.c
    trunk/blender/source/blender/makesdna/DNA_constraint_types.h
    trunk/blender/source/blender/makesdna/DNA_ipo_types.h
    trunk/blender/source/blender/src/buttons_object.c
    trunk/blender/source/blender/src/editipo_lib.c

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c	2007-11-12 01:10:58 UTC (rev 12560)
+++ trunk/blender/source/blender/blenkernel/intern/action.c	2007-11-12 04:17:03 UTC (rev 12561)
@@ -305,8 +305,10 @@
 	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 */

Modified: trunk/blender/source/blender/blenkernel/intern/constraint.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/constraint.c	2007-11-12 01:10:58 UTC (rev 12560)
+++ trunk/blender/source/blender/blenkernel/intern/constraint.c	2007-11-12 04:17:03 UTC (rev 12561)
@@ -194,6 +194,11 @@
 							con->enforce = CLAMPIS(icu->curval, 0.0f, 1.0f);
 						}
 							break;
+						case CO_HEADTAIL:
+						{
+							con->headtail = icu->curval;
+						}
+							break;
 					}
 				}
 			}
@@ -224,6 +229,9 @@
 	}
 	
 	/* 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 @@
 
 /* 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 @@
 			 * 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 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 @@
 	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_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 @@
 	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 @@
 		/* 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 @@
 		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:

Modified: trunk/blender/source/blender/blenkernel/intern/ipo.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/ipo.c	2007-11-12 01:10:58 UTC (rev 12560)
+++ trunk/blender/source/blender/blenkernel/intern/ipo.c	2007-11-12 04:17:03 UTC (rev 12561)
@@ -85,7 +85,7 @@
 */
 
 int co_ar[CO_TOTIPO]= {
-	CO_ENFORCE
+	CO_ENFORCE, CO_HEADTAIL
 };
 
 int ob_ar[OB_TOTIPO]= {

Modified: trunk/blender/source/blender/blenloader/intern/readfile.c
===================================================================
--- trunk/blender/source/blender/blenloader/intern/readfile.c	2007-11-12 01:10:58 UTC (rev 12560)
+++ trunk/blender/source/blender/blenloader/intern/readfile.c	2007-11-12 04:17:03 UTC (rev 12561)
@@ -6827,11 +6827,11 @@
 		bConstraint *con;
 		bConstraintTarget *ct;
 		
-		for(ob = main->object.first; ob; ob= ob->id.next) {
-			if(ob->pose) {
-				for(pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
-					for(con=pchan->constraints.first; con; con=con->next) {
-						if(con->type==CONSTRAINT_TYPE_PYTHON) {
+		for (ob = main->object.first; ob; ob= ob->id.next) {
+			if (ob->pose) {
+				for (pchan=ob->pose->chanbase.first; pchan; pchan=pchan->next) {
+					for (con=pchan->constraints.first; con; con=con->next) {
+						if (con->type == CONSTRAINT_TYPE_PYTHON) {
 							bPythonConstraint *data= (bPythonConstraint *)con->data;
 							if (data->tar) {
 								/* version patching needs to be done */
@@ -6849,12 +6849,19 @@
 								strcpy(data->subtarget, "");
 							}
 						}
+						else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
+							bLocateLikeConstraint *data= (bLocateLikeConstraint *)con->data;
+							
+							/* new headtail functionality makes Bone-Tip function obsolete */
+							if (data->flag & LOCLIKE_TIP)
+								con->headtail = 1.0f;
+						}
 					}
 				}
 			}
 			
-			for(con=ob->constraints.first; con; con=con->next) {
-				if(con->type==CONSTRAINT_TYPE_PYTHON) {
+			for (con=ob->constraints.first; con; con=con->next) {
+				if (con->type==CONSTRAINT_TYPE_PYTHON) {
 					bPythonConstraint *data= (bPythonConstraint *)con->data;
 					if (data->tar) {
 						/* version patching needs to be done */
@@ -6872,6 +6879,13 @@
 						strcpy(data->subtarget, "");
 					}
 				}
+				else if (con->type == CONSTRAINT_TYPE_LOCLIKE) {
+					bLocateLikeConstraint *data= (bLocateLikeConstraint *)con->data;
+					
+					/* new headtail functionality makes Bone-Tip function obsolete */
+					if (data->flag & LOCLIKE_TIP)
+						con->headtail = 1.0f;
+				}
 			}
 		}
 	}

Modified: trunk/blender/source/blender/makesdna/DNA_constraint_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2007-11-12 01:10:58 UTC (rev 12560)
+++ trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2007-11-12 04:17:03 UTC (rev 12561)
@@ -64,6 +64,8 @@
 	char		name[30];	/*	Constraint name */
 	
 	float		enforce;	/* 	Amount of influence exherted by constraint (0.0-1.0) */
+	float		headtail;	/*	Point along subtarget bone where the actual target is. 0=head (default for all), 1=tail*/
+	int			pad;
 } bConstraint;
 
 
@@ -116,7 +118,7 @@
 	char subtarget[32];		/* subtarger from previous implentation (version-patch sets this to "" on file-load) */
 } bPythonConstraint;
 
-/* Single-target subobject constraints ---------------------  */
+
 /* Inverse-Kinematics (IK) constraint */
 typedef struct bKinematicConstraint {
 	Object		*tar;
@@ -134,6 +136,8 @@
 	float		grabtarget[3];	/* for target-less IK */
 } bKinematicConstraint;
 
+
+/* Single-target subobject constraints ---------------------  */
 /* Track To Constraint */
 typedef struct bTrackToConstraint {
 	Object		*tar;
@@ -386,6 +390,7 @@
 #define LOCLIKE_X			0x01
 #define LOCLIKE_Y			0x02
 #define LOCLIKE_Z			0x04
+	/* LOCLIKE_TIP is a depreceated option... use headtail=1.0f instead */
 #define LOCLIKE_TIP			0x08
 #define LOCLIKE_X_INVERT	0x10
 #define LOCLIKE_Y_INVERT	0x20

Modified: trunk/blender/source/blender/makesdna/DNA_ipo_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_ipo_types.h	2007-11-12 01:10:58 UTC (rev 12560)
+++ trunk/blender/source/blender/makesdna/DNA_ipo_types.h	2007-11-12 04:17:03 UTC (rev 12561)
@@ -319,10 +319,11 @@
 #define AC_QUAT_Z	28
 
 /* ******************** */
-#define CO_TOTIPO	1	/* Constraint Ipos */
-#define CO_TOTNAM	1
+#define CO_TOTIPO	2	/* Constraint Ipos */
+#define CO_TOTNAM	2
 
 #define CO_ENFORCE	1
+#define CO_HEADTAIL	2

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list