[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15558] branches/harmonic-skeleton/source/ blender/src/autoarmature.c: Get simulated annealing working correctly.

Martin Poirier theeth at yahoo.com
Sun Jul 13 20:24:37 CEST 2008


Revision: 15558
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15558
Author:   theeth
Date:     2008-07-13 20:24:27 +0200 (Sun, 13 Jul 2008)

Log Message:
-----------
Get simulated annealing working correctly. Meaning bone arc retargeting is much faster than before.

Still need to do stability tests and analysis (brute force is probably better in some situations).

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

Modified: branches/harmonic-skeleton/source/blender/src/autoarmature.c
===================================================================
--- branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-07-13 17:50:09 UTC (rev 15557)
+++ branches/harmonic-skeleton/source/blender/src/autoarmature.c	2008-07-13 18:24:27 UTC (rev 15558)
@@ -578,49 +578,68 @@
 	printf("\n");
 }
 
-static float calcMaximumDistance(ReebArcIterator *iter, float *vec0, float *vec1, int i0, int i1)
+static float costDistance(ReebArcIterator *iter, float *vec0, float *vec1, int i0, int i1)
 {
 	EmbedBucket *bucket = NULL;
 	float max_dist = 0;
 	float v1[3], v2[3], c[3];
 	float v1_inpf;
 
-	VecSubf(v1, vec0, vec1);
-	
-	v1_inpf = Inpf(v1, v1);
-	
-	if (v1_inpf > 0)
+	if (G.scene->toolsettings->skgen_retarget_distance_weight > 0)
 	{
-		int j;
-		for (j = i0 + 1; j < i1 - 1; j++)
+		VecSubf(v1, vec0, vec1);
+		
+		v1_inpf = Inpf(v1, v1);
+		
+		if (v1_inpf > 0)
 		{
-			float dist;
-			
-			bucket = peekBucket(iter, j);
-
-			VecSubf(v2, bucket->p, vec1);
+			int j;
+			for (j = i0 + 1; j < i1 - 1; j++)
+			{
+				float dist;
+				
+				bucket = peekBucket(iter, j);
 	
-			Crossf(c, v1, v2);
+				VecSubf(v2, bucket->p, vec1);
+		
+				Crossf(c, v1, v2);
+				
+				dist = Inpf(c, c) / v1_inpf;
+				
+				max_dist = dist > max_dist ? dist : max_dist;
+			}
 			
-			dist = Inpf(c, c) / v1_inpf;
-			
-			max_dist = dist > max_dist ? dist : max_dist;
+			return max_dist;
 		}
+		else
+		{
+			return FLT_MAX;
+		}
 		
-		return max_dist;
+		return G.scene->toolsettings->skgen_retarget_distance_weight * max_dist;
 	}
 	else
 	{
-		return FLT_MAX;
+		return 0;
 	}
 }
 
+static float costAngle(float original_angle, float current_angle)
+{
+	return 0;
+}
+
+static float costLength(float original_length, float current_length)
+{
+	float length_ratio = fabs((current_length - original_length) / original_length);
+	return G.scene->toolsettings->skgen_retarget_length_weight * length_ratio * length_ratio;
+}
+
 static float calcCost(ReebArcIterator *iter, RigEdge *e1, RigEdge *e2, float *vec0, float *vec1, float *vec2, int i0, int i1, int i2)
 {
 	float vec_second[3], vec_first[3];
 	float angle = e1->angle;
 	float test_angle, length1, length2;
-	float max_dist;
 	float new_cost = 0;
 
 	VecSubf(vec_second, vec2, vec1);
@@ -647,16 +666,13 @@
 		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);
+	/* Length cost */
+	new_cost += costLength(e1->length, length1);
+	new_cost += costLength(e2->length, length2);
 
-	/* calculate maximum distance */
-	max_dist = calcMaximumDistance(iter, vec0, vec1, i0, i1);
-	new_cost += G.scene->toolsettings->skgen_retarget_distance_weight * max_dist;
-	
-	max_dist = calcMaximumDistance(iter, vec1, vec2, i1, i2);
-	new_cost += G.scene->toolsettings->skgen_retarget_distance_weight * max_dist;
+	/* Distance cost */
+	new_cost += costDistance(iter, vec0, vec1, i0, i1);
+	new_cost += costDistance(iter, vec1, vec2, i1, i2);
 
 	return new_cost;
 }
@@ -781,7 +797,7 @@
 		return 0;
 	}
 	
-	chosen = (int)BLI_drand() * total;
+	chosen = (int)(BLI_drand() * total);
 	
 	for (i = 0; i < nb_joints; i++)
 	{
@@ -868,7 +884,7 @@
 	vec_cache[0] = node_start->p;
 	vec_cache[nb_edges] = node_end->p;
 
-#if 1 /* BRUTE FORCE */
+#if 0 /* BRUTE FORCE */
 	while(1)
 	{
 		float cost = 0;
@@ -927,8 +943,6 @@
 			{ 
 				float vec_first[3], vec_second[3];
 				float length1, length2;
-				float max_dist;
-				float length_ratio;
 				float new_cost = 0;
 				int i1, i2;
 				
@@ -990,19 +1004,11 @@
 					}
 				}
 	
-				/* LENGTH COST HERE */
-				if (G.scene->toolsettings->skgen_retarget_length_weight > 0)
-				{
-					length_ratio = fabs((length2 - edge->length) / edge->length);
-					new_cost += G.scene->toolsettings->skgen_retarget_length_weight * length_ratio * length_ratio;
-				}
+				/* Length Cost */
+				new_cost += costLength(edge->length, length2);
 				
-				/* DISTANCE COST HERE */
-				if (G.scene->toolsettings->skgen_retarget_distance_weight > 0)
-				{
-					max_dist = calcMaximumDistance(&iter, vec1, vec2, i1, i2);
-					new_cost += G.scene->toolsettings->skgen_retarget_distance_weight * max_dist;
-				}
+				/* Distance Cost */
+				new_cost += calcMaximumDistance(&iter, vec1, vec2, i1, i2);
 				
 				cost_cache[i] = new_cost;
 			}
@@ -1034,8 +1040,10 @@
 		float *cost_cube;
 		int k, kmax;
 		
-		kmax = 100;
+		kmax = 10000;
 		
+		BLI_srand(nb_joints);
+		
 		/* [joint: index][position: -1, 0, +1] */
 		cost_cube = MEM_callocN(sizeof(float) * 3 * nb_joints, "Cost Cube");
 		
@@ -1047,6 +1055,8 @@
 			bucket = peekBucket(&iter, positions[i]);
 			vec_cache[i + 1] = bucket->p;
 		}
+		
+		min_cost = 0;
 
 		/* init cost cube */
 		for (previous = iarc->edges.first, edge = previous->next, i = 0;
@@ -1054,6 +1064,8 @@
 			 previous = edge, edge = edge->next, i += 1)
 		{
 			calcGradient(previous, edge, &iter, i, nb_joints, cost_cube, positions, vec_cache);
+			
+			min_cost += cost_cube[3 * i + 1];
 		}
 		
 		for (k = 0; k < kmax; k++)
@@ -1063,8 +1075,6 @@
 			int move_direction = -1;
 			float delta_cost;
 			
-			printf("\r%i", k);
-			
 			status = neighbour(nb_joints, cost_cube, &moving_joint, &move_direction);
 			
 			if (status == 0)
@@ -1082,6 +1092,10 @@
 				/* update vector cache */
 				bucket = peekBucket(&iter, positions[moving_joint]);
 				vec_cache[moving_joint + 1] = bucket->p;
+				
+				min_cost += delta_cost;
+
+				printf("%i: %0.3f\n", k, delta_cost);
 	
 				/* update cost cube */			
 				for (previous = iarc->edges.first, edge = previous->next, i = 0;
@@ -1098,8 +1112,6 @@
 			}
 		}
 		
-		printf("\n");
-		
 		memcpy(best_positions, positions, sizeof(int) * nb_joints);
 		
 		MEM_freeN(cost_cube);





More information about the Bf-blender-cvs mailing list