From 88c2ec822210f0efa7ee2b6c99bc4747bf3fd71d Mon Sep 17 00:00:00 2001 From: Andrzej Date: Sun, 3 Mar 2013 09:45:03 +0100 Subject: [PATCH] Implement eye position calculations in 3D coords (bug #9036). Current behavior is better but it still feels unnatural. This is mostly because the eye balls are in the same x-y plane as the mouse pointer. The attached patch calculates 3D angles of the eye sight as if the eye ball was slightly behind the screen (at the moment the distance is hardcoded to 3x eyeball radius). Smaller z distance makes the eyeballs more independent, larger - increases the (x-y) tracking distance (the eyes remain in their center position longer). --- panel-plugin/eyes.c | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/panel-plugin/eyes.c b/panel-plugin/eyes.c index d1a28fb..aa3cf48 100644 --- a/panel-plugin/eyes.c +++ b/panel-plugin/eyes.c @@ -68,11 +68,10 @@ calculate_pupil_xy (EyesPlugin *eyes_applet, gint *pupil_y, GtkWidget *widget) { - double sina; - double cosa; - double h; - double temp; double nx, ny; + double distance; + double angle, angle_z; + double radius_x, radius_y; gfloat xalign, yalign; gint width, height; @@ -81,32 +80,34 @@ calculate_pupil_xy (EyesPlugin *eyes_applet, height = GTK_WIDGET(widget)->allocation.height; gtk_misc_get_alignment(GTK_MISC(widget), &xalign, &yalign); + /* calculate x,y pointer offsets wrt to eye center */ nx = x - MAX(width - eyes_applet->eye_width, 0) * xalign - eyes_applet->eye_width / 2 - GTK_WIDGET(widget)->allocation.x; ny = y - MAX(height - eyes_applet->eye_height, 0) * yalign - eyes_applet->eye_height / 2 - GTK_WIDGET(widget)->allocation.y; - h = hypot (nx, ny); - if (h < 0.5 || - abs (h) < (abs (hypot (eyes_applet->eye_height / 2, - eyes_applet->eye_width / 2)) - - eyes_applet->wall_thickness - - eyes_applet->pupil_height)) - { - *pupil_x = nx + eyes_applet->eye_width / 2; - *pupil_y = ny + eyes_applet->eye_height / 2; - return; - } + /* calculate eye sizes */ + radius_x = (eyes_applet->eye_width - + eyes_applet->wall_thickness - + eyes_applet->pupil_width) / 2.0; + radius_y = (eyes_applet->eye_height - + eyes_applet->wall_thickness - + eyes_applet->pupil_height) / 2.0; - sina = nx / h; - cosa = ny / h; + /* by default assume the z-axis distance of 3 radius_x */ + distance = 3 * radius_x; - temp = hypot ((eyes_applet->eye_width / 2) * sina, (eyes_applet->eye_height / 2) * cosa); - temp -= hypot ((eyes_applet->pupil_width / 2) * sina, (eyes_applet->pupil_height / 2) * cosa); - temp -= hypot ((eyes_applet->wall_thickness / 2) * sina, (eyes_applet->wall_thickness / 2) * cosa); + /* correction factor for aspect ratio of the eye */ + if (radius_y != 0) + ny *= radius_x / radius_y; - *pupil_x = temp * sina + (eyes_applet->eye_width / 2); - *pupil_y = temp * cosa + (eyes_applet->eye_height / 2); + /* calculate 3D rotation angles */ + angle_z = atan2 (ny, nx); + angle = atan2 (hypot (nx, ny), distance); + + /* perform 3D rotation of a vector [0,0,1] (z=1) */ + *pupil_x = radius_x * sin (angle) * cos (angle_z) + eyes_applet->eye_width / 2; + *pupil_y = radius_y * sin (angle) * sin (angle_z) + eyes_applet->eye_height / 2; }