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;
u16 prev_x;
u16 prev_y;
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.MouseMotion:
{
f32 x = cast(f32)(g.window.inputs[i].x) - cast(f32)(g.prev_x);
f32 y = cast(f32)(g.window.inputs[i].y) - cast(f32)(g.prev_y);
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;
// (0, 0) top left
cam.yaw -= cast(f32)(g.window.inputs[i].rel_x) / 200.0;
cam.pitch += cast(f32)(g.window.inputs[i].rel_y) / 200.0;
} break;
default: break;
}
@ -123,12 +115,11 @@ void
Update(Game* g, Camera* 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);
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);
g.globals.projection_matrix[1, 1] *= -1.0;
@ -144,7 +135,7 @@ RotationMatrix(Camera* cam)
Quat pitch_rotation, yaw_rotation;
QuatFromAxis(&pitch_rotation, cam.pitch, Vec3(1.0, 0.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
@ -153,7 +144,7 @@ ViewMatrix(Camera* cam)
Mat4 translation;
Translate(&translation, cam.pos);
Mat4 rotation = RotationMatrix(cam);
return translation * rotation;
return Inverse(translation * rotation);
}
void

View File

@ -16,6 +16,19 @@ void main()
{
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);
scope(exit) Destroy(&g);

View File

@ -2,6 +2,10 @@ import aliases;
import includes;
import std.stdio;
import core.memory;
import core.thread.osthread;
import core.time;
const WINDOW_EDGE_BUFFER = 50;
enum Input
{
@ -48,6 +52,8 @@ struct InputEvent
};
struct
{
i32 rel_x;
i32 rel_y;
u16 x;
u16 y;
};
@ -63,6 +69,8 @@ struct PlatformWindow
xcb_atom_t minimize_event;
u16 w;
u16 h;
i32 mouse_prev_x;
i32 mouse_prev_y;
bool close;
InputEvent[10] inputs;
u32 input_count;
@ -189,20 +197,45 @@ PlatformWindow CreateWindow(string name, u16 width, u16 height)
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);
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;
};
void
FlushEvents(PlatformWindow* window)
{
xcb_generic_event_t* e;
do
{
e = xcb_poll_for_event(window.conn);
} while (e);
}
void
HandleEvents(PlatformWindow* window)
{
window.input_count = 0;
xcb_generic_event_t* e;
bool ignore_mouse_events = false;
do
{
@ -272,15 +305,52 @@ HandleEvents(PlatformWindow* window)
} break;
case XCB_MOTION_NOTIFY:
{
if (ignore_mouse_events) continue;
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].x = move_event.event_x;
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.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;
default:
break;

View File

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