OVR: Rework on virtual VR keyboard
authorAndreas Eversberg <jolly@eversberg.eu>
Mon, 30 Apr 2018 06:47:29 +0000 (08:47 +0200)
committerAndreas Eversberg <jolly@eversberg.eu>
Mon, 30 Apr 2018 09:50:07 +0000 (11:50 +0200)
src/libovr/keyboard.c
src/libovr/keyboard.h
src/mercenary/main.c

index 82831ee..a844257 100644 (file)
 #define GL3_PROTOTYPES 1
 #include <GL/glew.h>
 
-#define MAX_KEYBOARDS  2       /* maximum number of keyboards to we have */
-#define MAX_KEYS       64      /* maximum number of keys per keyboard */
+#define MAX_KEYS       128     /* maximum number of keys per keyboard */
 #define MAX_KEY_LINES  32      /* maximum number of lines on each key */
-#define TILT_KEYBOARD          /* keyboard is tilted up from horzontal x-z-plane to vertical x-y-plane */
+#define TILT_KEYS      45      /* rotate keyboard by given degrees */
 
 /*
  * The keys are defined by coordinates that are described by the following
@@ -114,54 +113,41 @@ static struct key_font {
  */
 
 static const char *keyboard_layout[] = {
-       "1   2   3   4   5   6   7   8   9   0   G",
-       "    fh      fr                           ",
-       "    f1    f2    f0     7   8   9   *     ",
-       "                       4   5   6   -     ",
-       "           u           1   2   3   +     ",
-       "       l   d   r       02      e2        ",
-       NULL, /* end of keyboard */
-       "1   2   3   4   5   6   7   8   9   0   b",
-       "  Q   W   E   R   T   Y   U   I   O   P  ",
-       "   A   S   D   F   G   H   J   K   L   e ",
-       "     Z   X   C   V   B   N   M   ,   .   ",
+       "fe     f1   f2   f3   f4   f5    f6   f7   f8   f9   f0",
+       "1   2   3   4   5   6   7   8   9   0   b2         fh          7   8   9   *",
+       "  Q   W   E   R   T   Y   U   I   O   P                        4   5   6   -",
+       "   A   S   D   F   G   H   J   K   L   fr            u         1   2   3   +",
+       "     Z   X   C   V   B   N   M   ,   .           l   d   r     02      e2   ",
        "          s6                             ",
        NULL, /* end of keyboard */
-       NULL, /* end of all keyboards */
-};
-
-static enum keycode keyboard_codes_1[] = {
-       KEYCODE_1, KEYCODE_2, KEYCODE_3, KEYCODE_4, KEYCODE_5, KEYCODE_6, KEYCODE_7, KEYCODE_8, KEYCODE_9, KEYCODE_0, KEYCODE_g,
-       KEYCODE_HELP, KEYCODE_RETURN,
-       KEYCODE_F1, KEYCODE_F2, KEYCODE_F10, KEYCODE_KP_7, KEYCODE_KP_8, KEYCODE_KP_9, KEYCODE_KP_MULTIPLY,
-       KEYCODE_KP_4, KEYCODE_KP_5, KEYCODE_KP_6, KEYCODE_KP_MINUS,
-       KEYCODE_UP, KEYCODE_KP_1, KEYCODE_KP_2, KEYCODE_KP_3, KEYCODE_KP_PLUS,
-       KEYCODE_LEFT, KEYCODE_DOWN, KEYCODE_RIGHT, KEYCODE_KP_0, KEYCODE_KP_ENTER,
 };
 
-static enum keycode keyboard_codes_2[] = {
+static enum keycode keyboard_codes[] = {
+       KEYCODE_ESCAPE, KEYCODE_F1, KEYCODE_F2, KEYCODE_F3, KEYCODE_F4, KEYCODE_F5, KEYCODE_F6, KEYCODE_F7, KEYCODE_F8, KEYCODE_F9, KEYCODE_F10,
        KEYCODE_1, KEYCODE_2, KEYCODE_3, KEYCODE_4, KEYCODE_5, KEYCODE_6, KEYCODE_7, KEYCODE_8, KEYCODE_9, KEYCODE_0, KEYCODE_BACKSPACE,
+       KEYCODE_HELP, KEYCODE_KP_7, KEYCODE_KP_8, KEYCODE_KP_9, KEYCODE_KP_MULTIPLY,
        KEYCODE_q, KEYCODE_w, KEYCODE_e, KEYCODE_r, KEYCODE_t, KEYCODE_y, KEYCODE_u, KEYCODE_i, KEYCODE_o, KEYCODE_p,
+       KEYCODE_KP_4, KEYCODE_KP_5, KEYCODE_KP_6, KEYCODE_KP_MINUS,
        KEYCODE_a, KEYCODE_s, KEYCODE_d, KEYCODE_f, KEYCODE_g, KEYCODE_h, KEYCODE_j, KEYCODE_k, KEYCODE_l, KEYCODE_RETURN,
+       KEYCODE_UP, KEYCODE_KP_1, KEYCODE_KP_2, KEYCODE_KP_3, KEYCODE_KP_PLUS,
        KEYCODE_z, KEYCODE_x, KEYCODE_c, KEYCODE_v, KEYCODE_b, KEYCODE_n, KEYCODE_m, KEYCODE_COMMA, KEYCODE_PERIOD,
+       KEYCODE_LEFT, KEYCODE_DOWN, KEYCODE_RIGHT, KEYCODE_KP_0, KEYCODE_KP_ENTER,
        KEYCODE_SPACE,
 };
 
-static enum keycode *keyboard_codes[] = {
-       keyboard_codes_1, keyboard_codes_2,
-};
-
 /* definition of keys with coordinates for rendering */
-
 struct key_def {
        char key;
        int fkey;
-       double left_top_x, right_top_x;
-       double top_y;
-       double front_top_z, back_top_z;
-       double left_bottom_x, right_bottom_x;
-       double bottom_y;
-       double front_bottom_z, back_bottom_z;
+       double margin_left, margin_right, margin_front, margin_back;
+       double left_top_front_x, left_top_front_y, left_top_front_z;
+       double right_top_front_x, right_top_front_y, right_top_front_z;
+       double left_top_back_x, left_top_back_y, left_top_back_z;
+       double right_top_back_x, right_top_back_y, right_top_back_z;
+       double left_bottom_front_x, left_bottom_front_y, left_bottom_front_z;
+       double right_bottom_front_x, right_bottom_front_y, right_bottom_front_z;
+       double left_bottom_back_x, left_bottom_back_y, left_bottom_back_z;
+       double right_bottom_back_x, right_bottom_back_y, right_bottom_back_z;
        double x1[MAX_KEY_LINES], y1[MAX_KEY_LINES], z1[MAX_KEY_LINES];
        double x2[MAX_KEY_LINES], y2[MAX_KEY_LINES], z2[MAX_KEY_LINES];
        int lines;
@@ -171,9 +157,7 @@ struct key_def {
 static struct keyboard_def {
        struct key_def key[MAX_KEYS];
        int keys;
-} keyboard_def[MAX_KEYBOARDS];
-
-static int keyboards = 0;
+} keyboard_def;
 
 /*
  * add key to keyboard_def[].key structure
@@ -202,16 +186,37 @@ static int add_key(char key, int fkey, double width, struct key_def *key_def)
        key_def->fkey = fkey;
 
        /* key case (see layout in the description above) */
-       key_def->left_top_x = -3.0;
-       key_def->right_top_x = 3.0 + (width - 1.0) * 9.0;
-       key_def->top_y = 0;
-       key_def->front_top_z = 3.0;
-       key_def->back_top_z = -3.0;
-       key_def->left_bottom_x = -4.0;
-       key_def->right_bottom_x = 4.0 + (width - 1.0) * 9.0;
-       key_def->bottom_y = -4.0;
-       key_def->front_bottom_z = 4.0;
-       key_def->back_bottom_z = -4.0;
+       key_def->left_top_front_x = -3.0;
+       key_def->left_top_front_y = 0;
+       key_def->left_top_front_z = 3.0;
+
+       key_def->right_top_front_x = 3.0 + (width - 1.0) * 9.0;
+       key_def->right_top_front_y = 0;
+       key_def->right_top_front_z = 3.0;
+
+       key_def->left_top_back_x = -3.0;
+       key_def->left_top_back_y = 0;
+       key_def->left_top_back_z = -3.0;
+
+       key_def->right_top_back_x = 3.0 + (width - 1.0) * 9.0;
+       key_def->right_top_back_y = 0;
+       key_def->right_top_back_z = -3.0;
+
+       key_def->left_bottom_front_x = -4.0;
+       key_def->left_bottom_front_y = -2.0;
+       key_def->left_bottom_front_z = 4.0;
+
+       key_def->right_bottom_front_x = 4.0 + (width - 1.0) * 9.0;
+       key_def->right_bottom_front_y = -2.0;
+       key_def->right_bottom_front_z = 4.0;
+
+       key_def->left_bottom_back_x = -4.0;
+       key_def->left_bottom_back_y = -2.0;
+       key_def->left_bottom_back_z = -4.0;
+
+       key_def->right_bottom_back_x = 4.0 + (width - 1.0) * 9.0;
+       key_def->right_bottom_back_y = -2.0;
+       key_def->right_bottom_back_z = -4.0;
 
        /* lines to be drawn ontop of the key (see layout in the description above) */
        l = 0;
@@ -232,6 +237,8 @@ static int add_key(char key, int fkey, double width, struct key_def *key_def)
                                        key = 'H';
                                else if (key_def->key == 'r')
                                        key = 'R';
+                               else if (key_def->key == 'e')
+                                       key = 'E';
                                else
                                        key = 'F';
                        }
@@ -241,6 +248,8 @@ static int add_key(char key, int fkey, double width, struct key_def *key_def)
                                        key = 'E';
                                else if (key_def->key == 'r')
                                        key = 'E';
+                               else if (key_def->key == 'e')
+                                       key = 'S';
                                else if (key_def->key != '0')
                                        key = key_def->key;
                                else
@@ -252,6 +261,8 @@ static int add_key(char key, int fkey, double width, struct key_def *key_def)
                                        key = 'L';
                                else if (key_def->key == 'r')
                                        key = 'T';
+                               else if (key_def->key == 'e')
+                                       key = 'C';
                                else if (key_def->key != '0')
                                        break;
                                else
@@ -328,16 +339,30 @@ static void scale_key(double px, double py, double pz, double scale, struct key_
        int l;
 
        /* scale and translate key case */
-       key_def->left_top_x = key_def->left_top_x * scale + px;
-       key_def->right_top_x = key_def->right_top_x * scale + px;
-       key_def->top_y = key_def->top_y * scale + py;
-       key_def->front_top_z = key_def->front_top_z * scale + pz;
-       key_def->back_top_z = key_def->back_top_z * scale + pz;
-       key_def->left_bottom_x = key_def->left_bottom_x * scale + px;
-       key_def->right_bottom_x = key_def->right_bottom_x * scale + px;
-       key_def->bottom_y = key_def->bottom_y * scale + py;
-       key_def->front_bottom_z = key_def->front_bottom_z * scale + pz;
-       key_def->back_bottom_z = key_def->back_bottom_z * scale + pz;
+       key_def->left_top_front_x = key_def->left_top_front_x * scale + px;
+       key_def->right_top_front_x = key_def->right_top_front_x * scale + px;
+       key_def->left_top_back_x = key_def->left_top_back_x * scale + px;
+       key_def->right_top_back_x = key_def->right_top_back_x * scale + px;
+       key_def->left_bottom_front_x = key_def->left_bottom_front_x * scale + px;
+       key_def->right_bottom_front_x = key_def->right_bottom_front_x * scale + px;
+       key_def->left_bottom_back_x = key_def->left_bottom_back_x * scale + px;
+       key_def->right_bottom_back_x = key_def->right_bottom_back_x * scale + px;
+       key_def->left_top_front_y = key_def->left_top_front_y * scale + py;
+       key_def->right_top_front_y = key_def->right_top_front_y * scale + py;
+       key_def->left_top_back_y = key_def->left_top_back_y * scale + py;
+       key_def->right_top_back_y = key_def->right_top_back_y * scale + py;
+       key_def->left_bottom_front_y = key_def->left_bottom_front_y * scale + py;
+       key_def->right_bottom_front_y = key_def->right_bottom_front_y * scale + py;
+       key_def->left_bottom_back_y = key_def->left_bottom_back_y * scale + py;
+       key_def->right_bottom_back_y = key_def->right_bottom_back_y * scale + py;
+       key_def->left_top_front_z = key_def->left_top_front_z * scale + pz;
+       key_def->right_top_front_z = key_def->right_top_front_z * scale + pz;
+       key_def->left_top_back_z = key_def->left_top_back_z * scale + pz;
+       key_def->right_top_back_z = key_def->right_top_back_z * scale + pz;
+       key_def->left_bottom_front_z = key_def->left_bottom_front_z * scale + pz;
+       key_def->right_bottom_front_z = key_def->right_bottom_front_z * scale + pz;
+       key_def->left_bottom_back_z = key_def->left_bottom_back_z * scale + pz;
+       key_def->right_bottom_back_z = key_def->right_bottom_back_z * scale + pz;
 
        /* scale and translate line ontop of keys */
        for (l = 0; l < key_def->lines; l++) {
@@ -350,62 +375,109 @@ static void scale_key(double px, double py, double pz, double scale, struct key_
        }
 }
 
-#define KEY_SIZE_INCH  3.0
+static void rotate_yz(double *y, double *z, double angle)
+{
+       double out_y, out_z;
+
+       out_y = (*y) * cos(angle) - (*z) * sin(angle);
+       out_z = (*y) * sin(angle) + (*z) * cos(angle);
+
+       *y = out_y;
+       *z = out_z;
+}
 
-int init_vr_keyboard(double keyboard_height, double keyboard_distance)
+static void rotate_key(double angle, struct key_def *key_def)
+{
+       int l;
+
+       /* rotate key case */
+       rotate_yz(&key_def->left_top_front_y, &key_def->left_top_front_z, angle);
+       rotate_yz(&key_def->right_top_front_y, &key_def->right_top_front_z, angle);
+       rotate_yz(&key_def->left_top_back_y, &key_def->left_top_back_z, angle);
+       rotate_yz(&key_def->right_top_back_y, &key_def->right_top_back_z, angle);
+       rotate_yz(&key_def->left_bottom_front_y, &key_def->left_bottom_front_z, angle);
+       rotate_yz(&key_def->right_bottom_front_y, &key_def->right_bottom_front_z, angle);
+       rotate_yz(&key_def->left_bottom_back_y, &key_def->left_bottom_back_z, angle);
+       rotate_yz(&key_def->right_bottom_back_y, &key_def->right_bottom_back_z, angle);
+
+       /* rotate line ontop of keys */
+       for (l = 0; l < key_def->lines; l++) {
+               rotate_yz(&key_def->y1[l], &key_def->z1[l], angle);
+               rotate_yz(&key_def->y2[l], &key_def->z2[l], angle);
+       }
+}
+
+#define KEY_OFFSET     9.5     /* adjust x-posion of keyboard */
+#define KEY_SIZE_INCH  2.0     /* size of keys */
+static double keyboard_height, keyboard_distance;
+
+int init_vr_keyboard(double _keyboard_height, double _keyboard_distance)
 {
        double width;
        int l, k, y, x;
        int rc;
        int key, fkey;
 
-       l = 0;
-       /* count all keyboards */
-       while (keyboard_layout[l]) {
-               k = 0;
-               /* for each row in keyboard */
-               for (y = 0; keyboard_layout[l]; y++, l++) {
-                       /* for each key in row */
-                       for (x = 0; keyboard_layout[l][x]; x++) {
-                               /* skip spaces, because this is no key */
-                               if (keyboard_layout[l][x] == ' ')
-                                       continue;
-                               width = 1;
-                               key = keyboard_layout[l][x];
-                               fkey = 0;
-                               /* if we have an F-key, this means size * 1.5 */
-                               if (keyboard_layout[l][x] == 'f') {
-                                       if (keyboard_layout[l][x + 1] == 'h')
-                                               width = 2.0; /* help key */
-                                       else
-                                       if (keyboard_layout[l][x + 1] == 'r')
-                                               width = 2.5; /* return key */
-                                       else
-                                               width = 1.5; /* f-key */
-                                       key = keyboard_layout[l][x + 1];
-                                       fkey = 1;
-                               } else
-                               /* if we have a digit after the key, this means different size */
-                               if (keyboard_layout[l][x + 1] > '0')
-                                       width = (double)(keyboard_layout[l][x + 1] - '0');
-                               rc = add_key(key, fkey, width, &keyboard_def[keyboards].key[k]);
-                               if (rc < 0)
-                                       return -EINVAL;
-#ifdef TILT_KEYBOARD
-                               scale_key(((double)x / 4.0 - 5.0) * KEY_SIZE_INCH, -keyboard_distance, (double)y * KEY_SIZE_INCH - keyboard_height, KEY_SIZE_INCH / 9, &keyboard_def[keyboards].key[k]);
-#else
-                               scale_key(((double)x / 4.0 - 5.0) * KEY_SIZE_INCH, keyboard_height, (double)y * KEY_SIZE_INCH - keyboard_distance, KEY_SIZE_INCH / 9, &keyboard_def[keyboards].key[k]);
-#endif
-                               k++;
-                               /* skip size information, if any */
-                               if (keyboard_layout[l][x + 1] > ' ')
-                                       x++;
+       keyboard_height = _keyboard_height;
+       keyboard_distance = _keyboard_distance;
+
+       k = 0;
+       /* for each row in keyboard */
+       for (l = 0, y = 0; keyboard_layout[l]; y++, l++) {
+               /* for each key in row */
+               for (x = 0; keyboard_layout[l][x]; x++) {
+                       /* skip spaces, because this is no key */
+                       if (keyboard_layout[l][x] == ' ')
+                               continue;
+                       width = 1;
+                       key = keyboard_layout[l][x];
+                       fkey = 0;
+                       /* if we have an F-key, this means size * 1.5 */
+                       if (keyboard_layout[l][x] == 'f') {
+                               if (keyboard_layout[l][x + 1] == 'h')
+                                       width = 2.0; /* help key */
+                               else
+                               if (keyboard_layout[l][x + 1] == 'r')
+                                       width = 2.375; /* return key */
+                               else
+                               if (keyboard_layout[l][x + 1] == 'e')
+                                       width = 1.5; /* escape key */
+                               else
+                               if (keyboard_layout[l][x + 1] == '0')
+                                       width = 1.5; /* F10-key */
+                               else
+                                       width = 1.25; /* F-key */
+                               key = keyboard_layout[l][x + 1];
+                               fkey = 1;
+                       } else
+                       /* if we have a digit after the key, this means different size */
+                       if (keyboard_layout[l][x + 1] > '0')
+                               width = (double)(keyboard_layout[l][x + 1] - '0');
+                       if (k == MAX_KEYS) {
+                               print_error("Failed to add key, maximum number keys exeeded, please fix\n");
+                               return -EINVAL;
                        }
+                       rc = add_key(key, fkey, width, &keyboard_def.key[k]);
+                       if (rc < 0)
+                               return -EINVAL;
+                       /* order keys and scale, but keep it at origin */
+                       scale_key(((double)x / 4.0 - KEY_OFFSET) * KEY_SIZE_INCH, 0.0, (double)y * KEY_SIZE_INCH, KEY_SIZE_INCH / 9, &keyboard_def.key[k]);
+                       /* margin for locating keys */
+                       keyboard_def.key[k].margin_left = keyboard_def.key[k].left_bottom_front_x;
+                       keyboard_def.key[k].margin_right = keyboard_def.key[k].right_bottom_front_x;
+                       keyboard_def.key[k].margin_front = keyboard_def.key[k].left_bottom_front_z;
+                       keyboard_def.key[k].margin_back = keyboard_def.key[k].left_bottom_back_z;
+                       /* rotate whole keyboard */
+                       rotate_key(TILT_KEYS / 180.0 * M_PI, &keyboard_def.key[k]);
+                       /* shift keyboard from origin to it's location */
+                       scale_key(0.0, keyboard_height, -keyboard_distance, 1.0, &keyboard_def.key[k]);
+                       k++;
+                       /* skip size information, if any */
+                       if (keyboard_layout[l][x + 1] > ' ')
+                               x++;
                }
-               keyboard_def[keyboards].keys = k;
-               keyboards++;
-               l++;
        }
+       keyboard_def.keys = k;
 
        return 0;
 }
@@ -416,15 +488,13 @@ static double to_x, to_y, to_z;
 static int pointer_valid;
 
 /* calculate pointer and to what key it points to */
-void handle_vr_keyboard(int keyboard, double pointer_x, double pointer_y, double pointer_z, double pointer_yaw, double pointer_pitch, enum keycode *key)
+int handle_vr_keyboard(double pointer_x, double pointer_y, double pointer_z, double pointer_yaw, double pointer_pitch, enum keycode *key)
 {
        int k;
        struct key_def *key_def;
-#ifdef TILT_KEYBOARD
-       double keyboard_dist = keyboard_def[keyboard].key[0].y1[0]; /* just get the dist from first line of first key */
-#else
-       double keyboard_height = keyboard_def[keyboard].key[0].y1[0]; /* just get the height from first line of first key */
-#endif
+
+       pointer_valid = 0;
+       highlight_k = -1;
 
        /* generate poiting vector */
        from_x = pointer_x;
@@ -433,67 +503,63 @@ void handle_vr_keyboard(int keyboard, double pointer_x, double pointer_y, double
        to_x = from_x - sin(pointer_yaw) * cos(pointer_pitch) * 20;
        to_y = from_y + sin(pointer_pitch) * 20;
        to_z = from_z - cos(pointer_yaw) * cos(pointer_pitch) * 20;
-       pointer_valid = 0;
 
-       /* if pointer points down, intersect with keyboard */
-       highlight_k = -1;
-#ifdef TILT_KEYBOARD
-       if (from_z - 1.0 > keyboard_dist && to_z < from_z - 1.0) {
-               pointer_valid = 1;
-               to_x = (to_x - from_x) / (from_z - to_z) * (from_z - keyboard_dist) + from_x;
-               to_y = (to_y - from_y) / (from_z - to_z) * (from_z - keyboard_dist) + from_y;
-               to_z = keyboard_dist;
-
-               /* find key that we intersect with */
-               for (k = 0; k < keyboard_def[keyboard].keys; k++) {
-                       key_def = &keyboard_def[keyboard].key[k];
-                       if (to_x < key_def->left_top_x)
-                               continue;
-                       if (to_x > key_def->right_top_x)
-                               continue;
-                       if (-to_y < key_def->back_top_z)
-                               continue;
-                       if (-to_y > key_def->front_top_z)
-                               continue;
-                       highlight_k = k;
-                       *key = keyboard_codes[keyboard][k];
-                       break;
-               }
-       }
-#else
-       if (from_y - 1.0 > keyboard_height && to_y < from_y - 1.0) {
-               pointer_valid = 1;
-               to_x = (to_x - from_x) / (from_y - to_y) * (from_y - keyboard_height) + from_x;
-               to_z = (to_z - from_z) / (from_y - to_y) * (from_y - keyboard_height) + from_z;
-               to_y = keyboard_height;
-
-               /* find key that we intersect with */
-               for (k = 0; k < keyboard_def[keyboard].keys; k++) {
-                       key_def = &keyboard_def[keyboard].key[k];
-                       if (to_x < key_def->left_top_x)
-                               continue;
-                       if (to_x > key_def->right_top_x)
-                               continue;
-                       if (to_z < key_def->back_top_z)
-                               continue;
-                       if (to_z > key_def->front_top_z)
-                               continue;
-                       highlight_k = k;
-                       *key = keyboard_codes[keyboard][k];
-                       break;
-               }
+       /* translate pointer back to keyboard's origin */
+       from_y -= keyboard_height;
+       from_z -= -keyboard_distance;
+       to_y -= keyboard_height;
+       to_z -= -keyboard_distance;
+
+       /* rotate pointer back to horizontal */
+       rotate_yz(&from_y, &from_z, -TILT_KEYS / 180.0 * M_PI);
+       rotate_yz(&to_y, &to_z, -TILT_KEYS / 180.0 * M_PI);
+
+       /* check if pointer points towards keypad plane */
+       if (from_y - 1.0 < 0.0 || to_y > from_y - 1.0)
+               return 0;
+
+       /* intesct */
+       to_x = (to_x - from_x) / (from_y - to_y) * from_y + from_x;
+       to_z = (to_z - from_z) / (from_y - to_y) * from_y + from_z;
+       to_y = 0.0;
+
+       /* check for margin */
+       if (to_x > 22 || to_x < -22 || to_z > 13 || to_z < -2)
+               return 0;
+
+       /* find key that we intersect with */
+       for (k = 0; k < keyboard_def.keys; k++) {
+               key_def = &keyboard_def.key[k];
+               if (to_x < key_def->margin_left)
+                       continue;
+               if (to_x > key_def->margin_right)
+                       continue;
+               if (to_z < key_def->margin_back)
+                       continue;
+               if (to_z > key_def->margin_front)
+                       continue;
+               highlight_k = k;
+               *key = keyboard_codes[k];
+               break;
        }
-#endif
-}
 
-#ifdef TILT_KEYBOARD
-#define FLIP_YZ(y, z) -z, y
-#else
-#define FLIP_YZ(y, z) y, z
-#endif
+       /* rotate pointer to keyboard's tilt */
+       rotate_yz(&from_y, &from_z, TILT_KEYS / 180.0 * M_PI);
+       rotate_yz(&to_y, &to_z, TILT_KEYS / 180.0 * M_PI);
+
+       /* translate pointer to keyboard's position */
+       from_y += keyboard_height;
+       from_z += -keyboard_distance;
+       to_y += keyboard_height;
+       to_z += -keyboard_distance;
+
+       pointer_valid = 1;
+
+       return 1;
+}
 
 /* render keyboard per eye */
-void render_vr_keyboard(int keyboard, double camera_x, double camera_y)
+void render_vr_keyboard(double camera_x, double camera_y)
 {
        int k, l, distant_k;
        int rendered[MAX_KEYS];
@@ -507,28 +573,24 @@ void render_vr_keyboard(int keyboard, double camera_x, double camera_y)
        memset(rendered, 0, sizeof(rendered));
 
        /* calculate distances to keys */
-       for (k = 0; k < keyboard_def[keyboard].keys; k++) {
-               key_def = &keyboard_def[keyboard].key[k];
-#ifdef TILT_KEYBOARD
-               dist_x = (key_def->left_top_x + key_def->right_top_x) / 2.0 - camera_x;
-               dist_y = (key_def->front_top_z + key_def->back_top_z) / 2.0 + camera_y;
-#else
-               dist_x = (key_def->left_top_x + key_def->right_top_x) / 2.0 - camera_x;
-               dist_y = (key_def->front_top_z + key_def->back_top_z) / 2.0;
-#endif
+       for (k = 0; k < keyboard_def.keys; k++) {
+               key_def = &keyboard_def.key[k];
+               // FIXME: this works, but we sould only use margin with camera_x
+               dist_x = (key_def->left_top_front_x + key_def->right_top_front_x) / 2.0 - camera_x;
+               dist_y = (key_def->left_top_front_z + key_def->left_top_back_z) / 2.0;
                dists[k] = sqrt(dist_x * dist_x + dist_y * dist_y);
        }
 
        while (1) {
                key_def = NULL;
                /* search for most distant key */
-               for (k = 0; k < keyboard_def[keyboard].keys; k++) {
+               for (k = 0; k < keyboard_def.keys; k++) {
                        /* skip keys that have been already rendered */
                        if (rendered[k])
                                continue;
                        if (!key_def || dists[k] > dist) {
                                dist = dists[k];
-                               key_def = &keyboard_def[keyboard].key[k];
+                               key_def = &keyboard_def.key[k];
                                distant_k = k;
                        }
                }
@@ -541,36 +603,45 @@ void render_vr_keyboard(int keyboard, double camera_x, double camera_y)
                glBegin(GL_QUADS);
                /* top plane */
                if (distant_k == highlight_k)
-                       glColor4f(0.0, 0.7, 0.7, 1.0);
+                       glColor4f(0.3, 0.7, 0.7, 1.0);
                else
                        glColor4f(0.5, 0.5, 0.5, 1.0);
-               glVertex3f(key_def->left_top_x, FLIP_YZ(key_def->top_y, key_def->back_top_z));
-               glVertex3f(key_def->right_top_x, FLIP_YZ(key_def->top_y, key_def->back_top_z));
-               glVertex3f(key_def->right_top_x, FLIP_YZ(key_def->top_y, key_def->front_top_z));
-               glVertex3f(key_def->left_top_x, FLIP_YZ(key_def->top_y, key_def->front_top_z));
+               glVertex3f(key_def->left_top_back_x, key_def->left_top_back_y, key_def->left_top_back_z);
+               glVertex3f(key_def->right_top_back_x, key_def->right_top_back_y, key_def->right_top_back_z);
+               glVertex3f(key_def->right_top_front_x, key_def->right_top_front_y, key_def->right_top_front_z);
+               glVertex3f(key_def->left_top_front_x, key_def->left_top_front_y, key_def->left_top_front_z);
                /* front plane (in front of player) */
-               glColor4f(0.1, 0.1, 0.1, 1.0);
-               glVertex3f(key_def->left_top_x, FLIP_YZ(key_def->top_y, key_def->front_top_z));
-               glVertex3f(key_def->right_top_x, FLIP_YZ(key_def->top_y, key_def->front_top_z));
-               glVertex3f(key_def->right_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->front_bottom_z));
-               glVertex3f(key_def->left_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->front_bottom_z));
+               if (distant_k == highlight_k)
+                       glColor4f(0.15, 0.2, 0.2, 1.0);
+               else
+                       glColor4f(0.1, 0.1, 0.1, 1.0);
+               glVertex3f(key_def->left_top_front_x, key_def->left_top_front_y, key_def->left_top_front_z);
+               glVertex3f(key_def->right_top_front_x, key_def->right_top_front_y, key_def->right_top_front_z);
+               glVertex3f(key_def->right_bottom_front_x, key_def->right_bottom_front_y, key_def->right_bottom_front_z);
+               glVertex3f(key_def->left_bottom_front_x, key_def->left_bottom_front_y, key_def->left_bottom_front_z);
                /* back plane (away from player) */
-               glColor4f(0.3, 0.3, 0.3, 1.0);
-               glVertex3f(key_def->right_top_x, FLIP_YZ(key_def->top_y, key_def->back_top_z));
-               glVertex3f(key_def->left_top_x, FLIP_YZ(key_def->top_y, key_def->back_top_z));
-               glVertex3f(key_def->left_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->back_bottom_z));
-               glVertex3f(key_def->right_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->back_bottom_z));
+               if (distant_k == highlight_k)
+                       glColor4f(0.45, 0.6, 0.6, 1.0);
+               else
+                       glColor4f(0.3, 0.3, 0.3, 1.0);
+               glVertex3f(key_def->right_top_back_x, key_def->right_top_back_y, key_def->right_top_back_z);
+               glVertex3f(key_def->left_top_back_x, key_def->left_top_back_y, key_def->left_top_back_z);
+               glVertex3f(key_def->left_bottom_back_x, key_def->left_bottom_back_y, key_def->left_bottom_back_z);
+               glVertex3f(key_def->right_bottom_back_x, key_def->right_bottom_back_y, key_def->right_bottom_back_z);
                /* left plane */
-               glColor4f(0.2, 0.2, 0.2, 1.0);
-               glVertex3f(key_def->left_top_x, FLIP_YZ(key_def->top_y, key_def->back_top_z));
-               glVertex3f(key_def->left_top_x, FLIP_YZ(key_def->top_y, key_def->front_top_z));
-               glVertex3f(key_def->left_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->front_bottom_z));
-               glVertex3f(key_def->left_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->back_bottom_z));
+               if (distant_k == highlight_k)
+                       glColor4f(0.3, 0.4, 0.4, 1.0);
+               else
+                       glColor4f(0.2, 0.2, 0.2, 1.0);
+               glVertex3f(key_def->left_top_back_x, key_def->left_top_back_y, key_def->left_top_back_z);
+               glVertex3f(key_def->left_top_front_x, key_def->left_top_front_y, key_def->left_top_front_z);
+               glVertex3f(key_def->left_bottom_front_x, key_def->left_bottom_front_y, key_def->left_bottom_front_z);
+               glVertex3f(key_def->left_bottom_back_x, key_def->left_bottom_back_y, key_def->left_bottom_back_z);
                /* right plane */
-               glVertex3f(key_def->right_top_x, FLIP_YZ(key_def->top_y, key_def->front_top_z));
-               glVertex3f(key_def->right_top_x, FLIP_YZ(key_def->top_y, key_def->back_top_z));
-               glVertex3f(key_def->right_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->back_bottom_z));
-               glVertex3f(key_def->right_bottom_x, FLIP_YZ(key_def->bottom_y, key_def->front_bottom_z));
+               glVertex3f(key_def->right_top_front_x, key_def->right_top_front_y, key_def->right_top_front_z);
+               glVertex3f(key_def->right_top_back_x, key_def->right_top_back_y, key_def->right_top_back_z);
+               glVertex3f(key_def->right_bottom_back_x, key_def->right_bottom_back_y, key_def->right_bottom_back_z);
+               glVertex3f(key_def->right_bottom_front_x, key_def->right_bottom_front_y, key_def->right_bottom_front_z);
                /* no bottom plane, because it is unlikely visible */
                glEnd();
 
@@ -580,12 +651,12 @@ void render_vr_keyboard(int keyboard, double camera_x, double camera_y)
                        if (key_def->x1[l] == key_def->x2[l] && key_def->z1[l] == key_def->z2[l]) {
                                /* just a point */
                                glBegin(GL_POINTS);
-                               glVertex3f(key_def->x1[l], FLIP_YZ(key_def->y1[l], key_def->z1[l]));
+                               glVertex3f(key_def->x1[l], key_def->y1[l], key_def->z1[l]);
                                glEnd();
                        } else {
                                glBegin(GL_LINES);
-                               glVertex3f(key_def->x1[l], FLIP_YZ(key_def->y1[l], key_def->z1[l]));
-                               glVertex3f(key_def->x2[l], FLIP_YZ(key_def->y2[l], key_def->z2[l]));
+                               glVertex3f(key_def->x1[l], key_def->y1[l], key_def->z1[l]);
+                               glVertex3f(key_def->x2[l], key_def->y2[l], key_def->z2[l]);
                                glEnd();
                        }
                }
@@ -595,8 +666,6 @@ void render_vr_keyboard(int keyboard, double camera_x, double camera_y)
 
        if (!pointer_valid)
                return;
-       if (to_x > 25 || to_x < -25 || to_y > 20 || to_y < -20)
-               return;
 #if 0
        /* render pointer as a line from pose to keyboard */
        glColor4f(1.0, 0.0, 0.0, 1.0);
@@ -630,32 +699,32 @@ void render_vr_keyboard(int keyboard, double camera_x, double camera_y)
        double delta = 0.50;
        glBegin(GL_LINES);
        glColor4f(1.0, 1.0, 1.0, 1.0);
-       glVertex3f(to_x - delta / 2, to_y + delta, to_z - delta / 2 + delta);
-       glVertex3f(to_x + delta / 2, to_y - delta, to_z + delta / 2 + delta);
-       glVertex3f(to_x + delta / 2, to_y + delta, to_z - delta / 2 + delta);
-       glVertex3f(to_x - delta / 2, to_y - delta, to_z + delta / 2 + delta);
-       glVertex3f(to_x - delta / 2, to_y + delta, to_z + delta / 2 + delta);
-       glVertex3f(to_x + delta / 2, to_y - delta, to_z - delta / 2 + delta);
-       glVertex3f(to_x + delta / 2, to_y + delta, to_z + delta / 2 + delta);
-       glVertex3f(to_x - delta / 2, to_y - delta, to_z - delta / 2 + delta);
-
-       glVertex3f(to_x - delta, to_y + delta / 2, to_z - delta / 2 + delta);
-       glVertex3f(to_x + delta, to_y - delta / 2, to_z + delta / 2 + delta);
-       glVertex3f(to_x - delta, to_y - delta / 2, to_z - delta / 2 + delta);
-       glVertex3f(to_x + delta, to_y + delta / 2, to_z + delta / 2 + delta);
-       glVertex3f(to_x - delta, to_y + delta / 2, to_z + delta / 2 + delta);
-       glVertex3f(to_x + delta, to_y - delta / 2, to_z - delta / 2 + delta);
-       glVertex3f(to_x - delta, to_y - delta / 2, to_z + delta / 2 + delta);
-       glVertex3f(to_x + delta, to_y + delta / 2, to_z - delta / 2 + delta);
-
-       glVertex3f(to_x - delta / 2, to_y + delta / 2, to_z + delta + delta);
-       glVertex3f(to_x + delta / 2, to_y - delta / 2, to_z - delta + delta);
-       glVertex3f(to_x + delta / 2, to_y + delta / 2, to_z + delta + delta);
-       glVertex3f(to_x - delta / 2, to_y - delta / 2, to_z - delta + delta);
-       glVertex3f(to_x - delta / 2, to_y - delta / 2, to_z + delta + delta);
-       glVertex3f(to_x + delta / 2, to_y + delta / 2, to_z - delta + delta);
-       glVertex3f(to_x + delta / 2, to_y - delta / 2, to_z + delta + delta);
-       glVertex3f(to_x - delta / 2, to_y + delta / 2, to_z - delta + delta);
+       glVertex3f(to_x - delta / 2, to_y + delta + delta, to_z - delta / 2 + delta);
+       glVertex3f(to_x + delta / 2, to_y - delta + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x + delta / 2, to_y + delta + delta, to_z - delta / 2 + delta);
+       glVertex3f(to_x - delta / 2, to_y - delta + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x - delta / 2, to_y + delta + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x + delta / 2, to_y - delta + delta, to_z - delta / 2 + delta);
+       glVertex3f(to_x + delta / 2, to_y + delta + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x - delta / 2, to_y - delta + delta, to_z - delta / 2 + delta);
+
+       glVertex3f(to_x - delta, to_y + delta / 2 + delta, to_z - delta / 2 + delta);
+       glVertex3f(to_x + delta, to_y - delta / 2 + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x - delta, to_y - delta / 2 + delta, to_z - delta / 2 + delta);
+       glVertex3f(to_x + delta, to_y + delta / 2 + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x - delta, to_y + delta / 2 + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x + delta, to_y - delta / 2 + delta, to_z - delta / 2 + delta);
+       glVertex3f(to_x - delta, to_y - delta / 2 + delta, to_z + delta / 2 + delta);
+       glVertex3f(to_x + delta, to_y + delta / 2 + delta, to_z - delta / 2 + delta);
+
+       glVertex3f(to_x - delta / 2, to_y + delta / 2 + delta, to_z + delta + delta);
+       glVertex3f(to_x + delta / 2, to_y - delta / 2 + delta, to_z - delta + delta);
+       glVertex3f(to_x + delta / 2, to_y + delta / 2 + delta, to_z + delta + delta);
+       glVertex3f(to_x - delta / 2, to_y - delta / 2 + delta, to_z - delta + delta);
+       glVertex3f(to_x - delta / 2, to_y - delta / 2 + delta, to_z + delta + delta);
+       glVertex3f(to_x + delta / 2, to_y + delta / 2 + delta, to_z - delta + delta);
+       glVertex3f(to_x + delta / 2, to_y - delta / 2 + delta, to_z + delta + delta);
+       glVertex3f(to_x - delta / 2, to_y + delta / 2 + delta, to_z - delta + delta);
        glEnd();
 #endif
 }
index 106f7c8..ff42f58 100644 (file)
@@ -1,5 +1,5 @@
 
 int init_vr_keyboard(double keyboard_height, double keyboard_distance);
-void handle_vr_keyboard(int keyboard, double pointer_x, double pointer_y, double pointer_z, double pointer_yaw, double pointer_pitch, enum keycode *key);
-void render_vr_keyboard(int keyboard, double camera_x, double camera_y);
+int handle_vr_keyboard(double pointer_x, double pointer_y, double pointer_z, double pointer_yaw, double pointer_pitch, enum keycode *key);
+void render_vr_keyboard(double camera_x, double camera_y);
 
index b6b59be..24ea8a0 100644 (file)
@@ -73,8 +73,8 @@ static double config_fov = FOV_NOVAGEN;
 #endif
 static double config_monitor_distance = 31.5; /* inch */
 #ifdef HAVE_OVR
-static double config_keyboard_distance = 28.5; /* inch */
-static double config_keyboard_height = 4.0; /* inch */
+static double config_keyboard_distance = 30.5; /* inch */
+static double config_keyboard_height = -22.0; /* inch */
 #endif
 static int config_debug_transparent = 0;
 static int config_debug_opengl = 0;
@@ -400,20 +400,6 @@ static void handle_vr_poses(void)
                osd_info("", "reset observer");
        }
        if (!help_view) {
-               if (button_a && !button_a_last) {
-                       /* keyboard A toggle */
-                       if (keyboard_on == 1)
-                               keyboard_on = 0;
-                       else
-                               keyboard_on = 1;
-               }
-               if (button_b && !button_b_last) {
-                       /* keyboard B toggle */
-                       if (keyboard_on == 2)
-                               keyboard_on = 0;
-                       else
-                               keyboard_on = 2;
-               }
                if (button_x && !button_x_last) {
                        /* 'board' pressed */
                        set_amiga_key(KEYCODE_b, 1);
@@ -614,8 +600,7 @@ static void handle_vr_poses(void)
        /* we must handle keyboard after toggeling keyboard_on,
         * so that keyboard_on will not change until keyboard is rendered */
        vr_key = 0;
-       if (keyboard_on)
-               handle_vr_keyboard(keyboard_on - 1, hand_right_x, hand_right_y, hand_right_z, hand_right_yaw, hand_right_pitch, &vr_key);
+       keyboard_on = handle_vr_keyboard(hand_right_x, hand_right_y, hand_right_z, hand_right_yaw, hand_right_pitch, &vr_key);
 }
 #endif
 
@@ -815,7 +800,7 @@ static void main_loop(void)
 #ifdef HAVE_OVR
                        /* render keyboard */
                        if (keyboard_on)
-                               render_vr_keyboard(keyboard_on - 1, camera_x, camera_y);
+                               render_vr_keyboard(camera_x, camera_y);
 
                        /* end of rendering eye */
                        end_render_ovr_eye(eye);
@@ -1384,10 +1369,8 @@ int main(int argc, char *argv[])
        text_render(help_osd[1], IMAGE_WIDTH * 2, IMAGE_HEIGHT * 2,
                "Emulation using Controller:\n"
                "        Press `Enter' button to toggle this help screen on or off.\n"
-               "        Press `A' button to emulate keyboard to control game.\n"
-               "        Press `B' button to emulate keyboard to enter alphanumeric keys.\n"
-               "        Press `A' or `B' button again to dismiss keyboard.\n"
-               "        Point right controller to a key on keyboard. The key will highlight.\n"
+               "        To have a virtual keyboard, point below benson (control pannel).\n"
+               "        Point to a key on keyboard. The key will highlight.\n"
                "        Pull `Trigger' on right controller enter the highlighted key.\n"
                "        Pull `Trigger' on both controllers to reset observer position.\n"
                "\n"