[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