[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12889] trunk/blender/source/blender: == Auto-IK ==

Joshua Leung aligorith at gmail.com
Sat Dec 15 08:35:17 CET 2007


Revision: 12889
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12889
Author:   aligorith
Date:     2007-12-15 08:35:16 +0100 (Sat, 15 Dec 2007)

Log Message:
-----------
== Auto-IK ==
-- Peach request (from wiki feature request list) --

When translating a bone using Auto-IK, you can now use the ScrollWheel on the Mouse or the Page Up/Down keys to adjust the chain length. 

Notes:
* Up decreases the length, while Down increases it.
* The previously used chain-length is stored per scene
* Currently, it might be too sensitive. Also, it would help to have some kind of indication of the current chain-length somewhere...
* The chain length specified this way determines the MAXIMUM chain length possible for all chains (if 0, then the default chain-length is used). Chains are clamped to have a chain length which does not exceed the default chain length. This restriction may be removed following further feedback...

Modified Paths:
--------------
    trunk/blender/source/blender/include/transform.h
    trunk/blender/source/blender/makesdna/DNA_constraint_types.h
    trunk/blender/source/blender/makesdna/DNA_scene_types.h
    trunk/blender/source/blender/src/transform.c
    trunk/blender/source/blender/src/transform_conversions.c

Modified: trunk/blender/source/blender/include/transform.h
===================================================================
--- trunk/blender/source/blender/include/transform.h	2007-12-14 17:47:58 UTC (rev 12888)
+++ trunk/blender/source/blender/include/transform.h	2007-12-15 07:35:16 UTC (rev 12889)
@@ -230,7 +230,7 @@
 		// for manipulator exceptions, like scaling using center point, drawing help lines
 #define T_USES_MANIPULATOR	(1 << 7)
 
-/* restrictions flags */
+	/* restrictions flags */
 #define T_ALL_RESTRICTIONS	((1 << 8)|(1 << 9)|(1 << 10))
 #define T_NO_CONSTRAINT		(1 << 8)
 #define T_NULL_ONE			(1 << 9)
@@ -239,14 +239,17 @@
 #define T_PROP_EDIT			(1 << 11)
 #define T_PROP_CONNECTED	(1 << 12)
 
-/* if MMB is pressed or not */
+	/* if MMB is pressed or not */
 #define	T_MMB_PRESSED		(1 << 13)
 
 #define T_V3D_ALIGN			(1 << 14)
-#define T_2D_EDIT			(1 << 15) /* for 2d views like uv or ipo */
+	/* for 2d views like uv or ipo */
+#define T_2D_EDIT			(1 << 15) 
 #define T_CLIP_UV			(1 << 16)
 
 #define T_FREE_CUSTOMDATA	(1 << 17)
+	/* auto-ik is on */
+#define T_AUTOIK			(1 << 18)
 
 /* ******************************************************************************** */
 
@@ -375,6 +378,8 @@
 void add_tdi_poin(float *poin, float *old, float delta);
 void special_aftertrans_update(TransInfo *t);
 
+void transform_autoik_update(TransInfo *t, short mode);
+
 /* auto-keying stuff used by special_aftertrans_update */
 void autokeyframe_ob_cb_func(struct Object *ob, int tmode);
 void autokeyframe_pose_cb_func(struct Object *ob, int tmode, short targetless_ik);
@@ -458,3 +463,4 @@
 
 #endif
 
+

Modified: trunk/blender/source/blender/makesdna/DNA_constraint_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2007-12-14 17:47:58 UTC (rev 12888)
+++ trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2007-12-15 07:35:16 UTC (rev 12889)
@@ -126,7 +126,8 @@
 	Object		*tar;
 	short		iterations;		/* Maximum number of iterations to try */
 	short		flag;			/* Like CONSTRAINT_IK_TIP */
-	int			rootbone;	/* index to rootbone, if zero go all the way to mother bone */
+	short		rootbone;		/* index to rootbone, if zero go all the way to mother bone */
+	short		max_rootbone;	/* for auto-ik, maximum length of chain */
 	char		subtarget[32];	/* String to specify sub-object target */
 
 	Object		*poletar;			/* Pole vector target */

Modified: trunk/blender/source/blender/makesdna/DNA_scene_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_scene_types.h	2007-12-14 17:47:58 UTC (rev 12888)
+++ trunk/blender/source/blender/makesdna/DNA_scene_types.h	2007-12-15 07:35:16 UTC (rev 12889)
@@ -363,7 +363,8 @@
 	short uvcalc_mapalign;
 	short uvcalc_flag;
 
-	short pad2;
+	/* Auto-IK */
+	short autoik_chainlen;
 
 	/* Image Paint (8 byte aligned please!) */
 	struct ImagePaintSettings imapaint;

Modified: trunk/blender/source/blender/src/transform.c
===================================================================
--- trunk/blender/source/blender/src/transform.c	2007-12-14 17:47:58 UTC (rev 12888)
+++ trunk/blender/source/blender/src/transform.c	2007-12-15 07:35:16 UTC (rev 12889)
@@ -815,7 +815,10 @@
 			break;
 		case PAGEUPKEY:
 		case WHEELDOWNMOUSE:
-			if(Trans.flag & T_PROP_EDIT) {
+			if (Trans.flag & T_AUTOIK) {
+				transform_autoik_update(&Trans, 1);
+			}
+			else if(Trans.flag & T_PROP_EDIT) {
 				Trans.propsize*= 1.1f;
 				calculatePropRatio(&Trans);
 			}
@@ -831,7 +834,10 @@
 			break;
 		case PAGEDOWNKEY:
 		case WHEELUPMOUSE:
-			if(Trans.flag & T_PROP_EDIT) {
+			if (Trans.flag & T_AUTOIK) {
+				transform_autoik_update(&Trans, -1);
+			}
+			else if (Trans.flag & T_PROP_EDIT) {
 				Trans.propsize*= 0.90909090f;
 				calculatePropRatio(&Trans);
 			}
@@ -4094,3 +4100,4 @@
 }
 
 
+

Modified: trunk/blender/source/blender/src/transform_conversions.c
===================================================================
--- trunk/blender/source/blender/src/transform_conversions.c	2007-12-14 17:47:58 UTC (rev 12888)
+++ trunk/blender/source/blender/src/transform_conversions.c	2007-12-15 07:35:16 UTC (rev 12889)
@@ -695,6 +695,62 @@
 		t->mode= TFM_ROTATION;
 }
 
+
+/* -------- Auto-IK ---------- */
+
+/* adjust pose-channel's auto-ik chainlen */
+static void pchan_autoik_adjust (bPoseChannel *pchan, short chainlen)
+{
+	bConstraint *con;
+	
+	/* don't bother to search if no valid constraints */
+	if ((pchan->constflag & (PCHAN_HAS_IK|PCHAN_HAS_TARGET))==0)
+		return;
+	
+	/* check if pchan has ik-constraint */
+	for (con= pchan->constraints.first; con; con= con->next) {
+		if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
+			bKinematicConstraint *data= con->data;
+			
+			/* only accept if a temporary one (for auto-ik) */
+			if (data->flag & CONSTRAINT_IK_TEMP) {
+				/* chainlen is new chainlen, but is limited by maximum chainlen */
+				if ((chainlen==0) || (chainlen > data->max_rootbone))
+					data->rootbone= data->max_rootbone;
+				else
+					data->rootbone= chainlen;
+				printf("chainlen = %d, max = %d, new = %d\n", chainlen, data->max_rootbone, data->rootbone);
+			}
+		}
+	}
+}
+
+/* change the chain-length of auto-ik */
+void transform_autoik_update (TransInfo *t, short mode)
+{
+	short *chainlen= &G.scene->toolsettings->autoik_chainlen;
+	bPoseChannel *pchan;
+	
+	/* mode determines what change to apply to chainlen */
+	if (mode == 1) {
+		/* mode=1 is from WHEELMOUSEDOWN... increases len */
+		(*chainlen)++;
+	}
+	else if (mode == -1) {
+		/* mode==-1 is from WHEELMOUSEUP... decreases len */
+		if (*chainlen > 0) (*chainlen)--;
+	}
+	
+	/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
+	if (ELEM(NULL, t->poseobj, t->poseobj->pose))
+		return;
+	
+	/* apply to all pose-channels */
+	for (pchan=t->poseobj->pose->chanbase.first; pchan; pchan=pchan->next) {
+		pchan_autoik_adjust(pchan, *chainlen);
+	}	
+}
+
 /* frees temporal IKs */
 static void pose_grab_with_ik_clear(Object *ob)
 {
@@ -722,19 +778,19 @@
 	}
 }
 
-/* adds the IK to pchan */
-static void pose_grab_with_ik_add(bPoseChannel *pchan)
+/* adds the IK to pchan - returns if added */
+static short pose_grab_with_ik_add(bPoseChannel *pchan)
 {
 	bKinematicConstraint *data;
 	bConstraint *con;
 	
-	if (pchan == NULL) { // Sanity check
-		return;
-	}
+	/* Sanity check */
+	if (pchan == NULL) 
+		return 0;
 	
 	/* rule: not if there's already an IK on this channel */
 	for (con= pchan->constraints.first; con; con= con->next)
-		if(con->type==CONSTRAINT_TYPE_KINEMATIC)
+		if (con->type==CONSTRAINT_TYPE_KINEMATIC)
 			break;
 	
 	if (con) {
@@ -742,7 +798,7 @@
 		data= has_targetless_ik(pchan);
 		if (data)
 			data->flag |= CONSTRAINT_IK_AUTO;
-		return;
+		return 0;
 	}
 	
 	con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
@@ -764,73 +820,79 @@
 		data->rootbone++;
 		pchan= pchan->parent;
 	}
+	
+	/* make a copy of maximum chain-length */
+	data->max_rootbone= data->rootbone;
+	
+	return 1;
 }
 
 /* bone is a canditate to get IK, but we don't do it if it has children connected */
-static void pose_grab_with_ik_children(bPose *pose, Bone *bone)
+static short pose_grab_with_ik_children(bPose *pose, Bone *bone)
 {
 	Bone *bonec;
-	int wentdeeper= 0;
+	short wentdeeper=0, added=0;
 
 	/* go deeper if children & children are connected */
-	for(bonec= bone->childbase.first; bonec; bonec= bonec->next) {
-		if(bonec->flag & BONE_CONNECTED) {
+	for (bonec= bone->childbase.first; bonec; bonec= bonec->next) {
+		if (bonec->flag & BONE_CONNECTED) {
 			wentdeeper= 1;
-			pose_grab_with_ik_children(pose, bonec);
+			added+= pose_grab_with_ik_children(pose, bonec);
 		}
 	}
-	if(wentdeeper==0) {
+	if (wentdeeper==0) {
 		bPoseChannel *pchan= get_pose_channel(pose, bone->name);
-		if(pchan)
-			pose_grab_with_ik_add(pchan);
+		if (pchan)
+			added+= pose_grab_with_ik_add(pchan);
 	}
+	
+	return added;
 }
 
 /* main call which adds temporal IK chains */
-static void pose_grab_with_ik(Object *ob)
+static short pose_grab_with_ik(Object *ob)
 {
 	bArmature *arm;
 	bPoseChannel *pchan, *pchansel= NULL;
 	Bone *bonec;
 	
-	if(ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
-		return;
+	if (ob==NULL || ob->pose==NULL || (ob->flag & OB_POSEMODE)==0)
+		return 0;
 		
 	arm = ob->data;
 	
 	/* rule: only one Bone */
-	for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
-		if(pchan->bone->layer & arm->layer) {
-			if(pchan->bone->flag & BONE_SELECTED) {
-				if(pchansel)
+	for (pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
+		if (pchan->bone->layer & arm->layer) {
+			if (pchan->bone->flag & BONE_SELECTED) {
+				if (pchansel)
 					break;
 				pchansel= pchan;
 			}
 		}
 	}
-	if(pchan || pchansel==NULL) return;
+	if (pchan || pchansel==NULL) return 0;
 
 	/* rule: no IK for solitary (unconnected) bone */
-	for(bonec=pchansel->bone->childbase.first; bonec; bonec=bonec->next) {
-		if(bonec->flag & BONE_CONNECTED) {
+	for (bonec=pchansel->bone->childbase.first; bonec; bonec=bonec->next) {
+		if (bonec->flag & BONE_CONNECTED) {
 			break;
 		}
 	}
-	if ((pchansel->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) return;
+	if ((pchansel->bone->flag & BONE_CONNECTED)==0 && (bonec == NULL)) return 0;
 	
 	/* rule: if selected Bone is not a root bone, it gets a temporal IK */
-	if(pchansel->parent) {
+	if (pchansel->parent) {
 		/* only adds if there's no IK yet */
-		pose_grab_with_ik_add(pchansel);
+		return pose_grab_with_ik_add(pchansel);
 	}
 	else {
 		/* rule: go over the children and add IK to the tips */
-		pose_grab_with_ik_children(ob->pose, pchansel->bone);
+		return pose_grab_with_ik_children(ob->pose, pchansel->bone);
 	}
 }	
 
 
-
 /* only called with pose mode active object now */
 static void createTransPose(TransInfo *t, Object *ob)
 {
@@ -838,6 +900,7 @@
 	bPoseChannel *pchan;
 	TransData *td;
 	TransDataExtension *tdx;
+	short ik_on= 0;
 	int i;
 	
 	t->total= 0;
@@ -855,8 +918,10 @@
 	if (!(ob->lay & G.vd->lay)) return;
 
 	/* do we need to add temporal IK chains? */
-	if((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION)
-		pose_grab_with_ik(ob);
+	if ((arm->flag & ARM_AUTO_IK) && t->mode==TFM_TRANSLATION) {
+		ik_on= pose_grab_with_ik(ob);
+		if (ik_on) t->flag |= T_AUTOIK;
+	}
 	
 	/* set flags and count total (warning, can change transform to rotate) */
 	set_pose_transflags(t, ob);
@@ -890,6 +955,8 @@
 	
 	if(td != (t->data+t->total)) printf("Bone selection count error\n");
 	

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list