fix camera and x11 inputs

This commit is contained in:
matthew 2025-07-29 08:34:21 +10:00
parent d9e0325794
commit b24ff3cb8e
4 changed files with 93 additions and 20 deletions

View File

@ -32,9 +32,6 @@ struct Game
Camera camera; Camera camera;
u16 prev_x;
u16 prev_y;
Model model; Model model;
} }
@ -105,14 +102,9 @@ ProcessInputs(Game* g, Camera* cam)
case Input.D: cam.velocity.x = pressed ? +1.0 : 0.0; break; case Input.D: cam.velocity.x = pressed ? +1.0 : 0.0; break;
case Input.MouseMotion: case Input.MouseMotion:
{ {
f32 x = cast(f32)(g.window.inputs[i].x) - cast(f32)(g.prev_x); // (0, 0) top left
f32 y = cast(f32)(g.window.inputs[i].y) - cast(f32)(g.prev_y); cam.yaw -= cast(f32)(g.window.inputs[i].rel_x) / 200.0;
cam.pitch += cast(f32)(g.window.inputs[i].rel_y) / 200.0;
cam.yaw += x / 200.0;
cam.pitch -= y / 200.0;
g.prev_x = g.window.inputs[i].x;
g.prev_y = g.window.inputs[i].y;
} break; } break;
default: break; default: break;
} }
@ -123,12 +115,11 @@ void
Update(Game* g, Camera* cam) Update(Game* g, Camera* cam)
{ {
Mat4 rotation = RotationMatrix(cam); Mat4 rotation = RotationMatrix(cam);
cam.pos += (rotation * Vec4(cam.velocity * 0.5, 0.0)).xyz * g.delta; cam.pos += (rotation * Vec4(cam.velocity, 0.0)).xyz * g.delta;
Extent ext = GetExtent(&g.rd); Extent ext = GetExtent(&g.rd);
g.globals.view_matrix = ViewMatrix(cam); g.globals.view_matrix = ViewMatrix(cam);
Mat4Identity(&g.globals.projection_matrix);
Perspective(&g.globals.projection_matrix, Radians(70.0), cast(f32)(ext.x), cast(f32)(ext.y), 10000.0, 0.1); Perspective(&g.globals.projection_matrix, Radians(70.0), cast(f32)(ext.x), cast(f32)(ext.y), 10000.0, 0.1);
g.globals.projection_matrix[1, 1] *= -1.0; g.globals.projection_matrix[1, 1] *= -1.0;
@ -144,7 +135,7 @@ RotationMatrix(Camera* cam)
Quat pitch_rotation, yaw_rotation; Quat pitch_rotation, yaw_rotation;
QuatFromAxis(&pitch_rotation, cam.pitch, Vec3(1.0, 0.0, 0.0)); QuatFromAxis(&pitch_rotation, cam.pitch, Vec3(1.0, 0.0, 0.0));
QuatFromAxis(&yaw_rotation, cam.yaw, Vec3(0.0, -1.0, 0.0)); QuatFromAxis(&yaw_rotation, cam.yaw, Vec3(0.0, -1.0, 0.0));
return Inverse(cast(Mat4)(yaw_rotation) * cast(Mat4)(pitch_rotation)); return cast(Mat4)(yaw_rotation) * cast(Mat4)(pitch_rotation);
} }
pragma(inline): Mat4 pragma(inline): Mat4
@ -153,7 +144,7 @@ ViewMatrix(Camera* cam)
Mat4 translation; Mat4 translation;
Translate(&translation, cam.pos); Translate(&translation, cam.pos);
Mat4 rotation = RotationMatrix(cam); Mat4 rotation = RotationMatrix(cam);
return translation * rotation; return Inverse(translation * rotation);
} }
void void

View File

@ -16,6 +16,19 @@ void main()
{ {
PlatformWindow window = CreateWindow("Video Game", 1920, 1080); PlatformWindow window = CreateWindow("Video Game", 1920, 1080);
Vec4 vec = Vec4(Vec3(22.0, 53.0, 3.0), 12.0);
Mat4 mat = Mat4(
1.0, 55.0, 23.0, 0.0,
0.0, 1.0, 0.0, 0.0,
123.0, 0.0, 13.0, 0.0,
0.0, 77.0, 0.0, 17.0
);
Vec4 res = mat * vec;
Logf("%s", res.v);
Game g = InitGame(&window); Game g = InitGame(&window);
scope(exit) Destroy(&g); scope(exit) Destroy(&g);

View File

@ -2,6 +2,10 @@ import aliases;
import includes; import includes;
import std.stdio; import std.stdio;
import core.memory; import core.memory;
import core.thread.osthread;
import core.time;
const WINDOW_EDGE_BUFFER = 50;
enum Input enum Input
{ {
@ -48,6 +52,8 @@ struct InputEvent
}; };
struct struct
{ {
i32 rel_x;
i32 rel_y;
u16 x; u16 x;
u16 y; u16 y;
}; };
@ -63,6 +69,8 @@ struct PlatformWindow
xcb_atom_t minimize_event; xcb_atom_t minimize_event;
u16 w; u16 w;
u16 h; u16 h;
i32 mouse_prev_x;
i32 mouse_prev_y;
bool close; bool close;
InputEvent[10] inputs; InputEvent[10] inputs;
u32 input_count; u32 input_count;
@ -189,20 +197,45 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
xcb_map_window(window.conn, window.window); xcb_map_window(window.conn, window.window);
xcb_grab_pointer(window.conn, 1, window.window, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, window.window, XCB_NONE, XCB_CURRENT_TIME);
i32 stream_result = xcb_flush(window.conn); i32 stream_result = xcb_flush(window.conn);
assert(stream_result > 0, "xcb_flush failure"); assert(stream_result > 0, "xcb_flush failure");
u32 counter = 0;
for(;;)
{
xcb_grab_pointer_cookie_t grab_cookie = xcb_grab_pointer(window.conn, true, window.window, 0, XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, window.window, XCB_NONE, XCB_CURRENT_TIME);
xcb_grab_pointer_reply_t* grab_reply = xcb_grab_pointer_reply(window.conn, grab_cookie, &error);
if (grab_reply.status == XCB_GRAB_STATUS_SUCCESS)
{
break;
}
assert(counter < 5, "Unable to grab cursor");
counter += 1;
Thread.sleep(dur!("msecs")(50));
}
return window; return window;
}; };
void
FlushEvents(PlatformWindow* window)
{
xcb_generic_event_t* e;
do
{
e = xcb_poll_for_event(window.conn);
} while (e);
}
void void
HandleEvents(PlatformWindow* window) HandleEvents(PlatformWindow* window)
{ {
window.input_count = 0; window.input_count = 0;
xcb_generic_event_t* e; xcb_generic_event_t* e;
bool ignore_mouse_events = false;
do do
{ {
@ -272,15 +305,52 @@ HandleEvents(PlatformWindow* window)
} break; } break;
case XCB_MOTION_NOTIFY: case XCB_MOTION_NOTIFY:
{ {
if (ignore_mouse_events) continue;
xcb_motion_notify_event_t* move_event = cast(xcb_motion_notify_event_t*)e; xcb_motion_notify_event_t* move_event = cast(xcb_motion_notify_event_t*)e;
if (move_event.event_x > 0 || move_event.event_y > 0) i16 x = move_event.event_x;
i16 y = move_event.event_y;
static bool first = true;
if (first)
{
window.mouse_prev_x = x;
window.mouse_prev_y = y;
first = false;
}
if (x > 0 || y > 0)
{ {
window.inputs[window.input_count].key = Input.MouseMotion; window.inputs[window.input_count].key = Input.MouseMotion;
window.inputs[window.input_count].x = move_event.event_x; window.inputs[window.input_count].x = move_event.event_x;
window.inputs[window.input_count].y = move_event.event_y; window.inputs[window.input_count].y = move_event.event_y;
window.inputs[window.input_count].rel_x = window.mouse_prev_x - x;
window.inputs[window.input_count].rel_y = window.mouse_prev_y - y;
window.input_count += 1; window.input_count += 1;
} }
window.mouse_prev_x = x;
window.mouse_prev_y = y;
if (x < WINDOW_EDGE_BUFFER || y < WINDOW_EDGE_BUFFER || x > window.w - WINDOW_EDGE_BUFFER || y > window.h - WINDOW_EDGE_BUFFER)
{
i16 new_x = cast(i16)(window.w / 2);
i16 new_y = cast(i16)(window.h / 2);
xcb_warp_pointer(window.conn, window.window, window.window, 0, 0, cast(i16)window.w, cast(i16)window.h, new_x, new_y);
window.mouse_prev_x = new_x;
window.mouse_prev_y = new_y;
ignore_mouse_events = true;
}
} break;
case XCB_CONFIGURE_NOTIFY:
{
xcb_configure_notify_event_t* config_event = cast(xcb_configure_notify_event_t*)e;
if (window.w != config_event.width || window.h != config_event.height)
{
window.w = config_event.width;
window.h = config_event.height;
}
} break; } break;
default: default:
break; break;

View File

@ -198,8 +198,7 @@ DrawModel(Renderer* rd, Model* model)
BindBuffers(&rd.vk, &model.index_buffer, &model.vertex_buffer); BindBuffers(&rd.vk, &model.index_buffer, &model.vertex_buffer);
rd.push_const.model_matrix = Mat4Identity(); rd.push_const.model_matrix = Mat4Identity();
//rd.push_const.model_matrix.translate(Vec3(1.0, 0.0, 0.0)); Translate(&rd.push_const.model_matrix, Vec3(0.0, 0.0, 0.0));
//rd.push_const.model_matrix = rd.push_const.model_matrix.transposed();
foreach(i, part; model.parts) foreach(i, part; model.parts)
{ {