Files
manigraph/src/input.c

245 lines
4.8 KiB
C

#include "main.h"
#include <glad.h>
#include <GLFW/glfw3.h>
#include <cglm/quat.h>
#include <stdio.h>
#define ANGLE ((float)0x01 / 0xff * 2 * GLM_PI)
unsigned char selected_axis = 0;
int window_width;
int window_height;
static versor q = GLM_QUAT_IDENTITY_INIT;
unsigned char animate_index = 0;
vec3 axis[3] = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
};
extern struct projection projection;
static inline
void __input_update_q(versor p)
{
glm_quat_mul(p, q, q);
glm_quat_rotatev(p, axis[0], axis[0]);
glm_quat_rotatev(p, axis[1], axis[1]);
glm_quat_rotatev(p, axis[2], axis[2]);
glm_quat_normalize(q);
}
void __error_callback_input(int x, const char * msg )
{
mlog("[GLFW] ");
mlog(msg);
mlog("\n");
}
void __key_callback_input(
GLFWwindow *window, int key, int scancode, int action, int mods)
{
if (action != GLFW_PRESS)
return;
if (GLFW_KEY_0 < key && key <= GLFW_KEY_9)
{
unsigned char selected_coord;
selected_coord = key - GLFW_KEY_0 - 1;
if (selected_coord >= projection.m)
return;
if (selected_coord == projection.x)
return;
if (selected_coord == projection.y)
return;
if (selected_coord == projection.z)
return;
projection.w = selected_coord;
}
if (projection.w >= projection.m)
return;
switch (key)
{
unsigned char tmp;
case GLFW_KEY_Z:
tmp = projection.w;
projection.w = projection.x;
projection.x = tmp;
animate_index = 1;
break;
case GLFW_KEY_X:
tmp = projection.w;
projection.w = projection.y;
projection.y = tmp;
animate_index = 2;
break;
case GLFW_KEY_C:
tmp = projection.w;
projection.w = projection.z;
projection.z = tmp;
animate_index = 3;
break;
default:
return;
}
printf("[AXIS] (X,Y,Z,W) = (%d,%d,%d,%d)\n", projection.x, projection.y, projection.z, projection.w);
return;
}
void __window_callback_input(GLFWwindow *window, int w, int h)
{
int m;
m = (w < h) ? w : h;
window_width = w;
window_height = h;
glViewport((w - m) / 2, (h - m) / 2, m, m);
}
static double xpos_s, ypos_s;
static char lbutton_down = 0;
void __mouse_callback_input(GLFWwindow* window, int button, int action, int mods)
{
if( button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
lbutton_down = 1;
if( button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE)
{
glfwGetCursorPos(window, &xpos_s, &ypos_s);
lbutton_down = 0;
}
}
void __cursor_callback_input(
GLFWwindow *window, double xpos, double ypos)
{
if( lbutton_down )
{
versor p = GLM_QUAT_IDENTITY_INIT;
glm_quatv(p, ANGLE, (vec3){-1*(ypos-ypos_s),(xpos-xpos_s),0});
__input_update_q(p);
}
}
void __scroll_callback_input(GLFWwindow *window, double xoffset, double yoffset)
{
versor p = GLM_QUAT_IDENTITY_INIT;
versor r = GLM_QUAT_IDENTITY_INIT;
// glm_quatv(p, yoffset * ANGLE, axis[selected_axis]);
glm_quatv(p, yoffset * ANGLE * 2, (vec3){-1, 0, 0});
glm_quatv(r, xoffset * ANGLE * 2, (vec3){0, 1, 0});
glm_quat_mul(p, q, q);
glm_quat_mul(r, q, q);
glm_quat_rotatev(p, axis[0], axis[0]);
glm_quat_rotatev(p, axis[1], axis[1]);
glm_quat_rotatev(p, axis[2], axis[2]);
glm_quat_rotatev(r, axis[0], axis[0]);
glm_quat_rotatev(r, axis[1], axis[1]);
glm_quat_rotatev(r, axis[2], axis[2]);
}
void __drop_callback_input(GLFWwindow *window, int count, char **path)
{
struct surface surface;
if (create_surface_klein(*path, &surface))
return;
if (!(projection.mesh = create_mesh(surface)))
return;
projection.m = surface.dim;
set_projection_mesh(projection);
free(surface.norm);
free(surface.data);
}
quat_t poll_input(window_t window)
{
versor p = GLM_QUAT_IDENTITY_INIT;
if (glfwGetKey((GLFWwindow *)window, 'W') == GLFW_PRESS)
{
glm_quatv(p, ANGLE, axis[0]);
goto end;
}
if (glfwGetKey((GLFWwindow *)window, 'S') == GLFW_PRESS)
{
glm_quatv(p, -ANGLE, axis[0]);
goto end;
}
if (glfwGetKey((GLFWwindow *)window, 'A') == GLFW_PRESS)
{
glm_quatv(p, -ANGLE, axis[1]);
goto end;
}
if (glfwGetKey((GLFWwindow *)window, 'D') == GLFW_PRESS)
{
glm_quatv(p, ANGLE, axis[1]);
goto end;
}
if (glfwGetKey((GLFWwindow *)window, 'Q') == GLFW_PRESS)
{
glm_quatv(p, ANGLE, axis[2]);
goto end;
}
if (glfwGetKey((GLFWwindow *)window, 'E') == GLFW_PRESS)
{
glm_quatv(p, -ANGLE, axis[2]);
goto end;
}
if (glfwGetKey((GLFWwindow *)window, GLFW_KEY_UP) == GLFW_PRESS)
{
glm_quatv(p, ANGLE, (vec3){1,0,0});
goto end;
}
if (glfwGetKey((GLFWwindow *)window, GLFW_KEY_DOWN) == GLFW_PRESS)
{
glm_quatv(p, -ANGLE, (vec3){1,0,0});
goto end;
}
if (glfwGetKey((GLFWwindow *)window, GLFW_KEY_RIGHT) == GLFW_PRESS)
{
glm_quatv(p, ANGLE, (vec3){0,1,0});
goto end;
}
if (glfwGetKey((GLFWwindow *)window, GLFW_KEY_LEFT) == GLFW_PRESS)
{
glm_quatv(p, -ANGLE, (vec3){0,1,0});
goto end;
}
end:
/*
// LOG INFO
if (0)
{
printf("QUAT: %2.5f %2.5f %2.5f %2.5f\n", q[0], q[1], q[2], q[3]);
printf("\n");
}
*/
__input_update_q(p);
return q;
}