#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_KEY_LINES 16 /* 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 MAX_KEYS 128 /* maximum number of keys per keyboard */
+#define MAX_KEY_LINES 32 /* maximum number of lines on each key */
+#define TILT_KEYS 45 /* rotate keyboard by given degrees */
/*
* The keys are defined by coordinates that are described by the following
*/
static const char *keyboard_layout[] = {
- "1 2 3 4 5 6 7 8 9 0 G",
- " fh e ",
- " 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;
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
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;
/* up to 4 letters/digits are displayed on key */
- for (d = 0; d < 4; d++) {
+ for (d = 0; d < 6; d++) {
if (!key_def->fkey) {
/* render regular key */
if (d == 0)
font_offset = -0.25;
if (key_def->key == 'h')
key = 'H';
+ else if (key_def->key == 'r')
+ key = 'R';
+ else if (key_def->key == 'e')
+ key = 'E';
else
key = 'F';
}
font_offset += 2.5;
if (key_def->key == 'h')
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
font_offset += 2.5;
if (key_def->key == 'h')
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
font_offset += 2.5;
if (key_def->key == 'h')
key = 'P';
+ else if (key_def->key == 'r')
+ key = 'U';
+ else
+ break;
+ }
+ else if (d == 4) {
+ font_offset += 2.5;
+ if (key_def->key == 'r')
+ key = 'R';
+ else
+ break;
+ }
+ else if (d == 5) {
+ font_offset += 2.5;
+ if (key_def->key == 'r')
+ key = 'N';
else
break;
}
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++) {
}
}
-#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);
-int init_vr_keyboard(double keyboard_height, double keyboard_distance)
+ *y = out_y;
+ *z = out_z;
+}
+
+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
- 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;
}
static int highlight_k;
static double from_x, from_y, from_z;
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;
to_y = from_y + sin(pointer_pitch) * 20;
to_z = from_z - cos(pointer_yaw) * cos(pointer_pitch) * 20;
- /* 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) {
- 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) {
- 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];
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;
}
}
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();
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();
}
}
glDisable(GL_CULL_FACE);
- /* render pointer */
+ if (!pointer_valid)
+ return;
+#if 0
+ /* render pointer as a line from pose to keyboard */
glColor4f(1.0, 0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex3f(from_x, from_y, from_z);
glVertex3f(to_x, to_y, to_z);
glEnd();
+#endif
+
+#if 0
+ /* render dot where pose points to */
+ double delta = 0.20;
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBegin(GL_POLYGON);
+ glColor4f(1.0, 0.0, 0.0, 0.7);
+ glVertex3f(to_x - delta / 2, to_y + delta, to_z);
+ glVertex3f(to_x + delta / 2, to_y + delta, to_z);
+ glVertex3f(to_x + delta, to_y + delta / 2, to_z);
+ glVertex3f(to_x + delta, to_y - delta / 2, to_z);
+ glVertex3f(to_x + delta / 2, to_y - delta, to_z);
+ glVertex3f(to_x - delta / 2, to_y - delta, to_z);
+ glVertex3f(to_x - delta, to_y - delta / 2, to_z);
+ glVertex3f(to_x - delta, to_y + delta / 2, to_z);
+ glEnd();
+ glDisable(GL_BLEND);
+#endif
+
+#if 1
+ /* render a 'shot' */
+ double delta = 0.50;
+ glBegin(GL_LINES);
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+ 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
}