[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15216] branches/harmonic-skeleton/source/ blender: First draft for gradient descent optimization for aggressive retargetting (results no go)

Martin Poirier theeth at yahoo.com
Fri Jun 13 23:09:03 CEST 2008


Revision: 15216
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15216
Author:   theeth
Date:     2008-06-13 23:07:46 +0200 (Fri, 13 Jun 2008)

Log Message:
-----------
First draft for gradient descent optimization for aggressive retargetting (results no go)

Modified Paths:
--------------
    branches/harmonic-skeleton/source/blender/include/reeb.h
    branches/harmonic-skeleton/source/blender/src/autoarmature.c
    branches/harmonic-skeleton/source/blender/src/reeb.c

Modified: branches/harmonic-skeleton/source/blender/include/reeb.h
===================================================================
--- branches/harmonic-skeleton/source/blender/include/reeb.h	2008-06-13 12:54:44 UTC (rev 15215)
+++ branches/harmonic-skeleton/source/blender/include/reeb.h	2008-06-13 21:07:46 UTC (rev 15216)
@@ -129,6 +129,7 @@
 void initArcIteratorStart(struct ReebArcIterator *iter, struct ReebArc *arc, struct ReebNode *head, int start);
 struct EmbedBucket * nextBucket(struct ReebArcIterator *iter);
 struct EmbedBucket * nextNBucket(ReebArcIterator *iter, int n);
+struct EmbedBucket * peekBucket(ReebArcIterator *iter, int n);
 struct EmbedBucket * currentBucket(struct ReebArcIterator *iter);
 struct EmbedBucket * previousBucket(struct ReebArcIterator *iter);
 int iteratorStopped(struct ReebArcIterator *iter);

Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-06-13 12:54:44 UTC (rev 15215)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-06-13 21:07:46 UTC (rev 15216)
@@ -539,6 +539,8 @@
 		mode = RETARGET_LENGTH;
 	}
 	
+	mode = RETARGET_AGGRESSIVE;
+	
 	return mode;
 }
 
@@ -553,6 +555,163 @@
 	printf("\n");
 }
 
+static float calcCost(ReebArc *earc, RigEdge *e1, RigEdge *e2, float *vec0, float *vec1, float *vec2, int i0, int i1, int i2)
+{
+	ReebArcIterator iter2;
+	EmbedBucket *bucket = NULL;
+	float max_dist;
+	
+	float vec_second[3], vec_first[3];
+	float angle = e1->angle;
+	float test_angle, length1, length2;
+	float new_cost = 0;
+
+	VecSubf(vec_second, vec2, vec1);
+	length2 = Normalize(vec_second);
+
+	VecSubf(vec_first, vec1, vec0); 
+	length1 = Normalize(vec_first);
+	
+	if (length1 > 0 && length2 > 0)
+	{
+		test_angle = saacos(Inpf(vec_first, vec_second));
+		/* ANGLE COST HERE */
+		new_cost += G.scene->toolsettings->skgen_retarget_angle_weight * fabs((test_angle - angle) / test_angle);
+	}
+	else
+	{
+		new_cost += M_PI;
+	}
+
+	/* LENGTH COST HERE */
+	new_cost += G.scene->toolsettings->skgen_retarget_length_weight * fabs((length1 - e1->length) / e1->length);
+	new_cost += G.scene->toolsettings->skgen_retarget_length_weight * fabs((length2 - e2->length) / e2->length);
+
+	/* calculate maximum distance */
+//	max_dist = 0;
+//	for (initArcIterator2(&iter2, earc, i0, i1), bucket = nextBucket(&iter2);
+//		bucket;
+//		bucket = nextBucket(&iter2))
+//	{
+//		float v1[3], v2[3], c[3];
+//		float dist;
+//		
+//		VecSubf(v1, vec0, vec1);
+//		VecSubf(v2, bucket->p, vec1);
+//
+//		Crossf(c, v1, v2);
+//		
+//		dist = Inpf(c, c) / Inpf(v1, v1);
+//		
+//		max_dist = dist > max_dist ? dist : max_dist;
+//	}
+//	
+//	new_cost += G.scene->toolsettings->skgen_retarget_length_weight * max_dist;
+//	
+//	max_dist = 0;
+//	for (initArcIterator2(&iter2, earc, i1, i2), bucket = nextBucket(&iter2);
+//		bucket;
+//		bucket = nextBucket(&iter2))
+//	{
+//		float v1[3], v2[3], c[3];
+//		float dist;
+//		
+//		VecSubf(v1, vec1, vec2);
+//		VecSubf(v2, bucket->p, vec2);
+//
+//		Crossf(c, v1, v2);
+//		
+//		dist = Inpf(c, c) / Inpf(v1, v1);
+//		
+//		max_dist = dist > max_dist ? dist : max_dist;
+//	}
+//	
+//	new_cost += G.scene->toolsettings->skgen_retarget_length_weight * max_dist;
+
+	return new_cost;
+}
+
+static void calcGradient(RigEdge *e1, RigEdge *e2, ReebArcIterator *iter, int index, int nb_joints, float *cost_cube, int *positions, float **vec_cache)
+{
+	EmbedBucket *bucket = NULL;
+	float *vec0, *vec1, *vec2;
+	float current_cost;
+	int i0, i1, i2;
+	int next_position;
+
+	vec0 = vec_cache[index];
+	vec1 = vec_cache[index + 1];
+	vec2 = vec_cache[index + 2];
+	
+	if (index == 0)
+	{
+		i0 = iter->start;
+	}
+	else
+	{
+		i0 = positions[index - 1];
+	}
+	
+	i1 = positions[index];
+	
+	if (index +1 == nb_joints)
+	{
+		i2 = iter->end;
+	}
+	else
+	{
+		i2 = positions[index + 1];
+	}
+
+
+	current_cost = calcCost(iter->arc, e1, e2, vec0, vec1, vec2, i0, i1, i2);
+	cost_cube[index * 3 + 1] = current_cost;
+	
+	next_position = positions[index] + 1;
+	
+	if (index + 1 < nb_joints && next_position == positions[index + 1])
+	{
+		cost_cube[index * 3 + 2] = 1;
+	}
+	else
+	{
+		bucket = peekBucket(iter, next_position);
+		
+		if (bucket == NULL)
+		{
+			cost_cube[index * 3 + 2] = 1;
+		}
+		else
+		{
+			vec1 = bucket->p;
+			
+			cost_cube[index * 3 + 2] = calcCost(iter->arc, e1, e2, vec0, vec1, vec2, i0, next_position, i2) - current_cost;
+		}
+	}
+
+	next_position = positions[index] - 1;
+	
+	if (index - 1 > -1 && next_position == positions[index - 1])
+	{
+		cost_cube[index * 3] = 1;
+	}
+	else
+	{
+		bucket = peekBucket(iter, next_position);
+		
+		if (bucket == NULL)
+		{
+			cost_cube[index * 3] = 1;
+		}
+		else
+		{
+			vec1 = bucket->p;
+			
+			cost_cube[index * 3] = calcCost(iter->arc, e1, e2, vec0, vec1, vec2, i0, next_position, i2) - current_cost;
+		}
+	}
+}
+
 static void retargetArctoArcAggresive(RigArc *iarc)
 {
 	ReebArcIterator iter;
@@ -598,6 +757,7 @@
 	for (i = 0; i < nb_joints; i++)
 	{
 		positions[i] = i + 1;
+		//positions[i] = (earc->bcount / nb_edges) * (i + 1);
 	}
 	
 	/* init cost cache */
@@ -609,6 +769,7 @@
 	vec_cache[0] = node_start->p;
 	vec_cache[nb_edges] = node_end->p;
 
+#if 1
 	while(1)
 	{
 		float cost = 0;
@@ -736,7 +897,90 @@
 			memcpy(best_positions, positions, sizeof(int) * nb_joints);
 		}
 	}
+#else
+	{
+		RigEdge *previous;
+		float *cost_cube;
+		
+		/* [joint: index][position: -1, 0, +2] */
+		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;
+		
+			printf("-----------------\n");
+		
+			for (i = 0; i < nb_joints; i++)
+			{
+				printf("%i[%i]: %f\t\t(%f)\t\t%f\n", i, positions[i], cost_cube[i * 3], cost_cube[i * 3 + 1], cost_cube[i * 3 + 2]); 
+				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)
+				{
+					min_gradient = cost_cube[i * 3 + 2]; 
+					moving_joint = i;
+					move_direction = 1;
+				}
+			}
+			
+			if (moving_joint == -1)
+			{
+				break;
+			}
+			
+			positions[moving_joint] += move_direction;
+			
+			/* update vector cache */
+			bucket = peekBucket(&iter, positions[moving_joint]);
+			vec_cache[moving_joint + 1] = bucket->p;
+
+			/* update cost cube */			
+			for (previous = iarc->edges.first, edge = previous->next, i = 0;
+				 edge;
+				 previous = edge, edge = edge->next, i += 1)
+			{
+				if (i == moving_joint - 1 ||
+					i == moving_joint ||
+					i == moving_joint + 1)
+				{
+					calcGradient(previous, edge, &iter, i, nb_joints, cost_cube, positions, vec_cache);
+				}
+			}
+			
+			
+		}
+		
+		memcpy(best_positions, positions, sizeof(int) * nb_joints);
+		
+		MEM_freeN(cost_cube);
+	}
+#endif
+
 	vec0 = node_start->p;
 	initArcIterator(&iter, earc, node_start);
 	
@@ -767,7 +1011,8 @@
 			printf("===\n");
 			printvecf("vec0", vec0);
 			printvecf("vec1", vec1);
-			printf("position: %i\n", best_positions[i]);
+			if (i < nb_joints)
+				printf("position: %i\n", best_positions[i]);
 			printf("last_index: %i\n", last_index);
 		}
 		

Modified: branches/harmonic-skeleton/source/blender/src/reeb.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/reeb.c	2008-06-13 12:54:44 UTC (rev 15215)
+++ branches/harmonic-skeleton/source/blender/src/reeb.c	2008-06-13 21:07:46 UTC (rev 15216)
@@ -228,6 +228,7 @@
 	bucket = nextBucket(&iter);
 	
 	vec0 = arc->head->p;
+	vec1 = arc->head->p; /* in case there's no embedding */
 	
 	while (bucket != NULL)
 	{
@@ -2431,8 +2432,8 @@
 	iter->index += n * iter->stride;
 
 	/* check if passed end */
-	if ((iter->stride == 1 && iter->index < iter->end) ||
-		(iter->stride == -1 && iter->index > iter->end))
+	if ((iter->stride == 1 && iter->index <= iter->end) ||
+		(iter->stride == -1 && iter->index >= iter->end))
 	{
 		result = &(iter->arc->buckets[iter->index]);
 	}
@@ -2445,6 +2446,21 @@
 	return result;
 }
 
+EmbedBucket * peekBucket(ReebArcIterator *iter, int n)
+{
+	EmbedBucket *result = NULL;
+	int index = iter->index + n * iter->stride;
+
+	/* check if passed end */
+	if ((iter->stride == 1 && index <= iter->end && index >= iter->start) ||
+		(iter->stride == -1 && index >= iter->end && index <= iter->start))
+	{
+		result = &(iter->arc->buckets[index]);
+	}
+	
+	return result;
+}
+
 EmbedBucket * previousBucket(struct ReebArcIterator *iter)
 {
 	EmbedBucket *result = NULL;





More information about the Bf-blender-cvs mailing list