[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [16807] trunk/blender/source/blender: Patch #17500: fixes: multiple IK's on bone + targetless IK

Joshua Leung aligorith at gmail.com
Mon Sep 29 06:01:35 CEST 2008


Revision: 16807
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=16807
Author:   aligorith
Date:     2008-09-29 06:00:42 +0200 (Mon, 29 Sep 2008)

Log Message:
-----------
Patch #17500: fixes: multiple IK's on bone + targetless IK
Submitted by: Teppo Kansala (teppoka)

See patch report for details of fixes.
https://projects.blender.org/tracker/index.php?func=detail&aid=17500&group_id=9&atid=127

Note: the patch submitter's test files were quite nice, and would be good to have in our regression suite.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/intern/armature.c
    trunk/blender/source/blender/makesdna/DNA_constraint_types.h
    trunk/blender/source/blender/src/drawarmature.c
    trunk/blender/source/blender/src/poseobject.c
    trunk/blender/source/blender/src/transform_conversions.c

Modified: trunk/blender/source/blender/blenkernel/intern/armature.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/armature.c	2008-09-29 03:09:03 UTC (rev 16806)
+++ trunk/blender/source/blender/blenkernel/intern/armature.c	2008-09-29 04:00:42 UTC (rev 16807)
@@ -1573,21 +1573,16 @@
 	
 	/* find IK constraint, and validate it */
 	for(con= pchan_tip->constraints.first; con; con= con->next) {
-		if(con->type==CONSTRAINT_TYPE_KINEMATIC) break;
+		if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+			data=(bKinematicConstraint*)con->data;
+			if (data->flag & CONSTRAINT_IK_AUTO) break;
+			if (data->tar==NULL) continue;
+			if (data->tar->type==OB_ARMATURE && data->subtarget[0]==0) continue;
+			if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0)) break;
+		}
 	}
 	if(con==NULL) return;
 	
-	data=(bKinematicConstraint*)con->data;
-	
-	/* two types of targets */
-	if(data->flag & CONSTRAINT_IK_AUTO);
-	else {
-		if(con->flag & CONSTRAINT_DISABLE) return;	/* checked in editconstraint.c */
-		if(con->enforce == 0.0f) return;
-		if(data->tar==NULL) return;
-		if(data->tar->type==OB_ARMATURE && data->subtarget[0]==0) return;
-	}
-	
 	/* exclude tip from chain? */
 	if(!(data->flag & CONSTRAINT_IK_TIP))
 		pchan_tip= pchan_tip->parent;

Modified: trunk/blender/source/blender/makesdna/DNA_constraint_types.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2008-09-29 03:09:03 UTC (rev 16806)
+++ trunk/blender/source/blender/makesdna/DNA_constraint_types.h	2008-09-29 04:00:42 UTC (rev 16807)
@@ -463,7 +463,9 @@
 /* bKinematicConstraint->flag */
 #define CONSTRAINT_IK_TIP		1
 #define CONSTRAINT_IK_ROT		2
+	/* targetless */
 #define CONSTRAINT_IK_AUTO		4
+	/* autoik */
 #define CONSTRAINT_IK_TEMP		8
 #define CONSTRAINT_IK_STRETCH	16
 #define CONSTRAINT_IK_POS		32

Modified: trunk/blender/source/blender/src/drawarmature.c
===================================================================
--- trunk/blender/source/blender/src/drawarmature.c	2008-09-29 03:09:03 UTC (rev 16806)
+++ trunk/blender/source/blender/src/drawarmature.c	2008-09-29 04:00:42 UTC (rev 16807)
@@ -1301,7 +1301,7 @@
 	bPoseChannel *parchan;
 	
 	for (con= pchan->constraints.first; con; con= con->next) {
-		if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
+		if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) {
 			bKinematicConstraint *data = (bKinematicConstraint*)con->data;
 			int segcount= 0;
 			
@@ -2573,3 +2573,4 @@
 
 /* *************** END Armature drawing ******************* */
 
+

Modified: trunk/blender/source/blender/src/poseobject.c
===================================================================
--- trunk/blender/source/blender/src/poseobject.c	2008-09-29 03:09:03 UTC (rev 16806)
+++ trunk/blender/source/blender/src/poseobject.c	2008-09-29 04:00:42 UTC (rev 16807)
@@ -213,6 +213,8 @@
 	bConstraint *con;
 	Bone *bone;
 	
+	/* No need to check if constraint is active (has influence),
+	 * since all constraints with CONSTRAINT_IK_AUTO are active */
 	for(con= pchan->constraints.first; con; con= con->next) {
 		if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
 			bKinematicConstraint *data= con->data;
@@ -1733,3 +1735,4 @@
 	autokeyframe_pose_cb_func(ob, TFM_ROTATION, 0);
 }
 
+

Modified: trunk/blender/source/blender/src/transform_conversions.c
===================================================================
--- trunk/blender/source/blender/src/transform_conversions.c	2008-09-29 03:09:03 UTC (rev 16806)
+++ trunk/blender/source/blender/src/transform_conversions.c	2008-09-29 04:00:42 UTC (rev 16807)
@@ -397,7 +397,7 @@
 	bConstraint *con= pchan->constraints.first;
 	
 	for(;con; con= con->next) {
-		if(con->type==CONSTRAINT_TYPE_KINEMATIC) {
+		if(con->type==CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) {
 			bKinematicConstraint *data= con->data;
 			
 			if(data->tar==NULL) 
@@ -505,12 +505,17 @@
 					Mat3ToQuat(rmat3, parchan->quat);
 					
 					/* for size, remove rotation */
-					QuatToMat3(parchan->quat, qmat);
-					Mat3Inv(imat, qmat);
-					Mat3MulMat3(smat, rmat3, imat);
-					Mat3ToSize(smat, parchan->size);
+					/* causes problems with some constraints (so apply only if needed) */
+					if (data->flag & CONSTRAINT_IK_STRETCH) {
+						QuatToMat3(parchan->quat, qmat);
+						Mat3Inv(imat, qmat);
+						Mat3MulMat3(smat, rmat3, imat);
+						Mat3ToSize(smat, parchan->size);
+					}
 					
-					VECCOPY(parchan->loc, rmat[3]);
+					/* causes problems with some constraints (e.g. childof), so disable this */
+					/* as it is IK shouldn't affect location directly */
+					/* VECCOPY(parchan->loc, rmat[3]); */
 				}
 				
 			}
@@ -711,7 +716,7 @@
 	
 	/* check if pchan has ik-constraint */
 	for (con= pchan->constraints.first; con; con= con->next) {
-		if (con->type == CONSTRAINT_TYPE_KINEMATIC) {
+		if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce!=0.0)) {
 			bKinematicConstraint *data= con->data;
 			
 			/* only accept if a temporary one (for auto-ik) */
@@ -763,6 +768,7 @@
 		/* clear all temporary lock flags */
 		pchan->ikflag &= ~(BONE_IK_NO_XDOF_TEMP|BONE_IK_NO_YDOF_TEMP|BONE_IK_NO_ZDOF_TEMP);
 		
+		pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
 		/* remove all temporary IK-constraints added */
 		for (con= pchan->constraints.first; con; con= con->next) {
 			if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
@@ -771,9 +777,11 @@
 					BLI_remlink(&pchan->constraints, con);
 					MEM_freeN(con->data);
 					MEM_freeN(con);
-					pchan->constflag &= ~(PCHAN_HAS_IK|PCHAN_HAS_TARGET);
-					break;
+					continue;
 				}
+				pchan->constflag |= PCHAN_HAS_IK;
+				if(data->tar==NULL || (data->tar->type==OB_ARMATURE && data->subtarget[0]==0))
+					pchan->constflag |= PCHAN_HAS_TARGET;
 			}
 		}
 	}
@@ -784,6 +792,7 @@
 {
 	bKinematicConstraint *data;
 	bConstraint *con;
+	bConstraint *targetless = 0;
 	
 	/* Sanity check */
 	if (pchan == NULL) 
@@ -791,23 +800,31 @@
 	
 	/* 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)
-			break;
+		if (con->type==CONSTRAINT_TYPE_KINEMATIC) {
+			bKinematicConstraint *data= con->data;
+			if(data->tar==NULL || (data->tar->type==OB_ARMATURE && data->subtarget[0]==0)) {
+				targetless = con;
+				/* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
+				if (con->enforce!=0.0) {
+					targetless->flag |= CONSTRAINT_IK_AUTO;
+					return 0;
+				}
+			}
+			if ((con->flag & CONSTRAINT_DISABLE)==0 && (con->enforce!=0.0))
+				return 0;
+		}
 	}
 	
-	if (con) {
-		/* but, if this is a targetless IK, we make it auto anyway (for the children loop) */
-		data= has_targetless_ik(pchan);
-		if (data)
-			data->flag |= CONSTRAINT_IK_AUTO;
-		return 0;
-	}
-	
 	con = add_new_constraint(CONSTRAINT_TYPE_KINEMATIC);
 	BLI_addtail(&pchan->constraints, con);
 	pchan->constflag |= (PCHAN_HAS_IK|PCHAN_HAS_TARGET);	/* for draw, but also for detecting while pose solving */
 	data= con->data;
-	data->flag= CONSTRAINT_IK_TIP|CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO;
+	if (targetless) { /* if exists use values from last targetless IK-constraint as base */
+		*data = *((bKinematicConstraint*)targetless->data);
+	}
+	else
+		data->flag= CONSTRAINT_IK_TIP;
+	data->flag |= CONSTRAINT_IK_TEMP|CONSTRAINT_IK_AUTO;
 	VECCOPY(data->grabtarget, pchan->pose_tail);
 	data->rootbone= 1;
 	
@@ -4279,3 +4296,4 @@
 
 
 
+





More information about the Bf-blender-cvs mailing list