[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15697] branches/harmonic-skeleton/source/ blender: First draft for control bones repositioning.

Martin Poirier theeth at yahoo.com
Tue Jul 22 19:44:07 CEST 2008


Revision: 15697
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15697
Author:   theeth
Date:     2008-07-22 19:44:06 +0200 (Tue, 22 Jul 2008)

Log Message:
-----------
First draft for control bones repositioning.
All bones marked as no deform are repositioned after the retarget based on their "linked" bone (linked bone is constraint owner if control bone is a target, parent bone if not).

Arithb:
 Function to make a quat between two normalized vectors

Modified Paths:
--------------
    branches/harmonic-skeleton/source/blender/blenlib/BLI_arithb.h
    branches/harmonic-skeleton/source/blender/blenlib/intern/arithb.c
    branches/harmonic-skeleton/source/blender/src/autoarmature.c

Modified: branches/harmonic-skeleton/source/blender/blenlib/BLI_arithb.h
===================================================================
--- branches/harmonic-skeleton/source/blender/blenlib/BLI_arithb.h	2008-07-22 17:03:44 UTC (rev 15696)
+++ branches/harmonic-skeleton/source/blender/blenlib/BLI_arithb.h	2008-07-22 17:44:06 UTC (rev 15697)
@@ -262,6 +262,7 @@
 void Vec2Copyf(float *v1, float *v2);
 
 void AxisAngleToQuat(float *q, float *axis, float angle);
+void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3]);
 void vectoquat(float *vec, short axis, short upflag, float *q);
 
 float VecAngle2(float *v1, float *v2);

Modified: branches/harmonic-skeleton/source/blender/blenlib/intern/arithb.c
===================================================================
--- branches/harmonic-skeleton/source/blender/blenlib/intern/arithb.c	2008-07-22 17:03:44 UTC (rev 15696)
+++ branches/harmonic-skeleton/source/blender/blenlib/intern/arithb.c	2008-07-22 17:44:06 UTC (rev 15697)
@@ -1335,6 +1335,18 @@
 	}
 }
 
+void RotationBetweenVectorsToQuat(float *q, float v1[3], float v2[3])
+{
+	float axis[3];
+	float angle;
+	
+	Crossf(axis, v1, v2);
+	
+	angle = NormalizedVecAngle2(v1, v2);
+	
+	AxisAngleToQuat(q, axis, angle);
+}
+
 void AxisAngleToQuat(float *q, float *axis, float angle)
 {
 	float nor[3];

Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-07-22 17:03:44 UTC (rev 15696)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-07-22 17:44:06 UTC (rev 15697)
@@ -37,7 +37,9 @@
 #include "PIL_time.h"
 
 #include "DNA_ID.h"
+#include "DNA_action_types.h"
 #include "DNA_armature_types.h"
+#include "DNA_constraint_types.h"
 #include "DNA_mesh_types.h"
 #include "DNA_meshdata_types.h"
 #include "DNA_object_types.h"
@@ -55,6 +57,7 @@
 
 #include "BKE_global.h"
 #include "BKE_utildefines.h"
+#include "BKE_constraint.h"
 
 #include "BIF_editarmature.h"
 #include "BIF_space.h"
@@ -87,6 +90,12 @@
 
 	struct RigNode *head;
 	ReebGraph *link_mesh;
+	
+	ListBase controls;
+	
+	GHash *bones_map;
+	
+	Object *ob;
 } RigGraph;
 
 typedef struct RigNode {
@@ -130,6 +139,13 @@
 	EditBone *bone;
 } RigEdge;
 
+typedef struct RigControl {
+	struct RigControl *next, *prev;
+	EditBone *bone;
+	EditBone *parent;
+	float offset[3];
+} RigControl;
+
 /*******************************************************************************************************/
 
 static void RIG_calculateEdgeAngle(RigEdge *edge_first, RigEdge *edge_second);
@@ -196,6 +212,8 @@
 	}
 	BLI_freelistN(&rg->nodes);
 	
+	BLI_ghash_free(((RigGraph*)rg)->bones_map, NULL, NULL);
+	
 	MEM_freeN(rg);
 }
 
@@ -208,6 +226,8 @@
 	
 	rg->head = NULL;
 	
+	rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp);
+	
 	rg->free_arc = RIG_freeRigArc;
 	rg->free_node = NULL;
 	
@@ -226,6 +246,17 @@
 	return arc;
 }
 
+static RigControl *newRigControl(RigGraph *rg)
+{
+	RigControl *ctrl;
+	
+	ctrl = MEM_callocN(sizeof(RigControl), "rig control");
+	
+	BLI_addtail(&rg->controls, ctrl);
+	
+	return ctrl;
+}
+
 static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3])
 {
 	RigNode *node;
@@ -308,39 +339,121 @@
 	edge_first->angle = saacos(Inpf(vec_first, vec_second));
 }
 
-/*******************************************************************************************************/
+/************************************ CONTROL BONES ****************************************************/
 
-static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node)
+static void RIG_addControlBone(RigGraph *rg, EditBone *bone)
 {
-	EditBone *bone, *last_bone = NULL;
-	RigArc *arc;
-	int contain_head = 0;
-	
-	arc = newRigArc(rg);
-	
-	if (starting_node == NULL)
+	RigControl *ctrl = newRigControl(rg);
+	ctrl->bone = bone;
+}
+
+static void RIG_parentControl(RigControl *ctrl, EditBone *parent)
+{
+	if (parent)
 	{
-		starting_node = newRigNodeHead(rg, arc, root_bone->head);
+		ctrl->parent = parent;
+		
+		VecSubf(ctrl->offset, ctrl->bone->head, ctrl->parent->tail);
 	}
-	else
+}
+
+static void RIG_reconnectControlBones(RigGraph *rg)
+{
+	RigControl *ctrl;
+	
+	for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next)
 	{
-		addRigNodeHead(rg, arc, starting_node);
+		bPoseChannel *pchan;
+		bConstraint *con;
+		int found = 0;
+		
+		/* DO SOME MAGIC HERE */
+		for (pchan= rg->ob->pose->chanbase.first; pchan; pchan= pchan->next)
+		{
+			for (con= pchan->constraints.first; con; con= con->next) 
+			{
+				bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+				ListBase targets = {NULL, NULL};
+				bConstraintTarget *ct;
+				
+				/* constraint targets */
+				if (cti && cti->get_constraint_targets)
+				{
+					cti->get_constraint_targets(con, &targets);
+					
+					for (ct= targets.first; ct; ct= ct->next)
+					{
+						if ((ct->tar == rg->ob) && strcmp(ct->subtarget, ctrl->bone->name) == 0)
+						{
+							/* SET bone parent to bone corresponding to pchan */
+							EditBone *parent = BLI_ghash_lookup(rg->bones_map, pchan->name);
+							
+							RIG_parentControl(ctrl, parent);
+							found = 1;
+						}
+					}
+					
+					if (cti->flush_constraint_targets)
+						cti->flush_constraint_targets(con, &targets, 0);
+				}
+			}
+		}
+
+		/* if not found yet, check parent */		
+		if (found == 0)
+		{
+			RIG_parentControl(ctrl, ctrl->bone->parent);
+		}
 	}
+}
+
+/*******************************************************************************************************/
+
+static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node)
+{
+	EditBone *bone, *last_bone = root_bone;
+	RigArc *arc = NULL;
+	int contain_head = 0;
 	
 	for(bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0))
 	{
 		int nb_children;
 		
-		if (bone->parent && (bone->flag & BONE_CONNECTED) == 0)
+		BLI_ghash_insert(rg->bones_map, bone->name, bone);
+		
+		if ((bone->flag & BONE_NO_DEFORM) == 0)
 		{
-			RIG_addEdgeToArc(arc, bone->head, NULL);
+			if (arc == NULL)
+			{
+				arc = newRigArc(rg);
+				
+				if (starting_node == NULL)
+				{
+					starting_node = newRigNodeHead(rg, arc, root_bone->head);
+				}
+				else
+				{
+					addRigNodeHead(rg, arc, starting_node);
+				}
+			}
+			
+			if (bone->parent && (bone->flag & BONE_CONNECTED) == 0)
+			{
+				RIG_addEdgeToArc(arc, bone->head, NULL);
+			}
+			
+			RIG_addEdgeToArc(arc, bone->tail, bone);
+			
+			last_bone = bone;
+			
+			if (strcmp(bone->name, "head") == 0)
+			{
+				contain_head = 1;
+			}
 		}
-		
-		RIG_addEdgeToArc(arc, bone->tail, bone);
-		
-		if (strcmp(bone->name, "head") == 0)
+		else
 		{
-			contain_head = 1;
+			RIG_addControlBone(rg, bone);
 		}
 		
 		nb_children = countEditBoneChildren(list, bone);
@@ -358,11 +471,10 @@
 			/* arc ends here, break */
 			break;
 		}
-		last_bone = bone;
 	}
 	
 	/* If the loop exited without forking */
-	if (bone == NULL)
+	if (arc != NULL && bone == NULL)
 	{
 		newRigNodeTail(rg, arc, last_bone->tail);
 	}
@@ -480,12 +592,14 @@
 
 /*******************************************************************************************************/
 
-static RigGraph *armatureToGraph(ListBase *list)
+static RigGraph *armatureToGraph(Object *ob, ListBase *list)
 {
 	EditBone *ebone;
 	RigGraph *rg;
  	
 	rg = newRigGraph();
+	
+	rg->ob = ob;
 
 	/* Do the rotations */
 	for (ebone = list->first; ebone; ebone=ebone->next){
@@ -495,6 +609,8 @@
 		}
 	}
 	
+	RIG_reconnectControlBones(rg);
+	
 	BLI_removeDoubleNodes((BGraph*)rg, 0.001);
 	
 	BLI_buildAdjacencyList((BGraph*)rg);
@@ -506,6 +622,57 @@
 
 /************************************ RETARGETTING *****************************************************/
 
+static void repositionControl(RigControl *ctrl, float parent[3], float qrot[4], float resize)
+{
+	float parent_offset[3], tail_offset[3];
+	
+	VecSubf(tail_offset, ctrl->bone->tail, ctrl->bone->head);
+	
+	VECCOPY(parent_offset, ctrl->offset);
+	VecMulf(parent_offset, resize);
+	
+	QuatMulVecf(qrot, parent_offset);
+	QuatMulVecf(qrot, tail_offset);
+	
+	VecAddf(ctrl->bone->head, parent, parent_offset); 
+	VecAddf(ctrl->bone->tail, ctrl->bone->head, tail_offset);
+}
+
+static void repositionBone(RigGraph *rigg, EditBone *bone, float vec0[3], float vec1[3])
+{
+	RigControl *ctrl;
+	float qrot[4], resize = 0;
+	
+	QuatOne(qrot);
+	
+	for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next)
+	{
+		if (ctrl->parent == bone)
+		{
+			if (resize == 0)
+			{
+				float v1[3], v2[3];
+				float l1, l2;
+				
+				VecSubf(v1, bone->tail, bone->head);
+				VecSubf(v2, vec1, vec0);
+				
+				l1 = Normalize(v1);
+				l2 = Normalize(v2);
+
+				resize = l2 / l1;
+				
+				RotationBetweenVectorsToQuat(qrot, v1, v2);
+			}
+			
+			repositionControl(ctrl, vec1, qrot, resize);
+		}
+	}
+	
+	VECCOPY(bone->head, vec0);
+	VECCOPY(bone->tail, vec1);
+}
+
 typedef enum 
 {
 	RETARGET_LENGTH,
@@ -513,7 +680,7 @@
 } RetargetMode; 
 
 static RetargetMode detectArcRetargetMode(RigArc *arc);
-static void retargetArctoArcLength(RigArc *iarc);
+static void retargetArctoArcLength(RigGraph *rigg, RigArc *iarc);
 
 
 static RetargetMode detectArcRetargetMode(RigArc *iarc)
@@ -881,7 +1048,7 @@
 	return 1;
 }
 
-static void retargetArctoArcAggresive(RigArc *iarc)
+static void retargetArctoArcAggresive(RigGraph *rigg, RigArc *iarc)
 {
 	ReebArcIterator iter;
 	RigEdge *edge;
@@ -1195,87 +1362,8 @@
 		
 		MEM_freeN(cost_cube);
 	}	
-	/* GRADIENT DESCENT*/
-	else if (G.scene->toolsettings->skgen_optimisation_method == 2)
-	{
-		RigEdge *previous;
-		float *cost_cube;
-		
-		/* [joint: index][position: -1, 0, +1] */
-		cost_cube = MEM_callocN(sizeof(float) * 3 * nb_joints, "Cost Cube");
-		
-		initArcIterator(&iter, earc, node_start);
 
-		/* init vec_cache */
-		for (i = 0; i < nb_joints; i++)
-		{
-			bucket = peekBucket(&iter, positions[i]);
-			vec_cache[i + 1] = bucket->p;
-		}
 
-		/* init cost cube */
-		for (previous = iarc->edges.first, edge = previous->next, i = 0;
-			 edge;
-			 previous = edge, edge = edge->next, i += 1)
-		{
-			calcGradient(previous, edge, &iter, i, nb_joints, cost_cube, positions, vec_cache);
-		}
-
-		while(1)
-		{
-			float min_gradient = 0;
-			int moving_joint = -1;
-			int move_direction = -1;
-		
-			for (i = 0; i < nb_joints; i++)
-			{
-				if (cost_cube[i * 3] < min_gradient)
-				{
-					min_gradient = cost_cube[i * 3]; 
-					moving_joint = i;
-					move_direction = -1;
-				}
-				
-				if  (cost_cube[i * 3 + 2] < min_gradient)
-				{

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list