Keyboard input, translation, time
This commit is contained in:
@@ -69,15 +69,33 @@ pub fn init(controller: *Controller, graphics: *Graphics) !void {
|
|||||||
|
|
||||||
pub fn deinit() void {}
|
pub fn deinit() void {}
|
||||||
|
|
||||||
pub fn update(cube: *Cube, mouse: *Game.Mouse, graphics: *Graphics) void {
|
pub fn update(
|
||||||
|
mouse: *Game.Mouse,
|
||||||
|
keyboard: *Game.Keyboard,
|
||||||
|
graphics: *Graphics,
|
||||||
|
time: *Game.Time,
|
||||||
|
) void {
|
||||||
|
if (keyboard.is_pressed(sdl.SCANCODE_W)) {
|
||||||
|
graphics.camera.transform.translateLocal(.{ 0.0, 0.0, 5.0 * time.delta });
|
||||||
|
}
|
||||||
|
if (keyboard.is_pressed(sdl.SCANCODE_S)) {
|
||||||
|
graphics.camera.transform.translateLocal(.{ 0.0, 0.0, -5.0 * time.delta });
|
||||||
|
}
|
||||||
|
if (keyboard.is_pressed(sdl.SCANCODE_D)) {
|
||||||
|
graphics.camera.transform.translateLocal(.{ 5.0 * time.delta, 0.0, 0.0 });
|
||||||
|
}
|
||||||
|
if (keyboard.is_pressed(sdl.SCANCODE_A)) {
|
||||||
|
graphics.camera.transform.translateLocal(.{ -5.0 * time.delta, 0.0, 0.0 });
|
||||||
|
}
|
||||||
|
|
||||||
if (@abs(mouse.dx) < 0.01 and @abs(mouse.dy) < 0.01) return;
|
if (@abs(mouse.dx) < 0.01 and @abs(mouse.dy) < 0.01) return;
|
||||||
|
|
||||||
const delta, const length = Graphics.Transform.extractNormal(.{ -mouse.dy, -mouse.dx, 0.0 });
|
const delta, const length = Graphics.Transform.extractNormal(.{ mouse.dy, mouse.dx, 0.0 });
|
||||||
const rot = Graphics.Transform.rotationByAxis(
|
const rot = Graphics.Transform.rotationByAxis(
|
||||||
delta,
|
delta,
|
||||||
length * std.math.pi / @as(f32, @floatFromInt(graphics.window_size[1])) * 2.0,
|
length * std.math.pi / @as(f32, @floatFromInt(graphics.window_size[1])) * 2.0,
|
||||||
);
|
);
|
||||||
cube.transform.rotate(rot);
|
graphics.camera.transform.rotateLocal(rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw(cube: *Cube, graphics: *Graphics) !void {
|
pub fn draw(cube: *Cube, graphics: *Graphics) !void {
|
||||||
|
34
src/game.zig
34
src/game.zig
@@ -9,8 +9,10 @@ const Graphics = @import("graphics.zig");
|
|||||||
// TODO:
|
// TODO:
|
||||||
// - Do something about deallocating `Resource`s when `Graph` fails
|
// - Do something about deallocating `Resource`s when `Graph` fails
|
||||||
|
|
||||||
const RunInfo = struct { running: bool };
|
pub const RunInfo = struct { running: bool };
|
||||||
pub const Mouse = struct { x: f32, y: f32, dx: f32, dy: f32 };
|
pub const Mouse = @import("mouse.zig");
|
||||||
|
pub const Keyboard = @import("keyboard.zig");
|
||||||
|
pub const Time = @import("time.zig");
|
||||||
|
|
||||||
alloc: std.mem.Allocator,
|
alloc: std.mem.Allocator,
|
||||||
graph: Graph,
|
graph: Graph,
|
||||||
@@ -30,6 +32,11 @@ pub fn init(alloc: std.mem.Allocator) GameError!Self {
|
|||||||
.dx = 0.0,
|
.dx = 0.0,
|
||||||
.dy = 0.0,
|
.dy = 0.0,
|
||||||
});
|
});
|
||||||
|
controller.addResource(Keyboard{});
|
||||||
|
controller.addResource(Time{
|
||||||
|
.delta = 0.0,
|
||||||
|
.now = 0,
|
||||||
|
});
|
||||||
controller.queue(debug_scene.init);
|
controller.queue(debug_scene.init);
|
||||||
try graph.freeController(controller);
|
try graph.freeController(controller);
|
||||||
|
|
||||||
@@ -54,6 +61,13 @@ pub fn run(self: *Self) GameError!void {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var current_time: sdl.Time = undefined;
|
||||||
|
if (sdl.GetCurrentTime(¤t_time)) {
|
||||||
|
const time = self.graph.getResource(Time).?;
|
||||||
|
time.delta = @as(f32, @floatFromInt(current_time - time.now)) * 0.000000001;
|
||||||
|
time.now = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
var controller = try self.graph.getController();
|
var controller = try self.graph.getController();
|
||||||
controller.queue(.{
|
controller.queue(.{
|
||||||
.events = processEvents,
|
.events = processEvents,
|
||||||
@@ -84,9 +98,15 @@ fn clean(graphics: *Graphics) !void {
|
|||||||
// TODO: Also remove the resource
|
// TODO: Also remove the resource
|
||||||
}
|
}
|
||||||
|
|
||||||
fn processEvents(graphics: *Graphics, run_info: *RunInfo, mouse: *Mouse) GameError!void {
|
fn processEvents(
|
||||||
|
graphics: *Graphics,
|
||||||
|
run_info: *RunInfo,
|
||||||
|
mouse: *Mouse,
|
||||||
|
keyboard: *Keyboard,
|
||||||
|
) GameError!void {
|
||||||
mouse.dx = 0.0;
|
mouse.dx = 0.0;
|
||||||
mouse.dy = 0.0;
|
mouse.dy = 0.0;
|
||||||
|
keyboard.reset();
|
||||||
|
|
||||||
sdl.PumpEvents();
|
sdl.PumpEvents();
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -109,6 +129,14 @@ fn processEvents(graphics: *Graphics, run_info: *RunInfo, mouse: *Mouse) GameErr
|
|||||||
mouse.dx += event.motion.xrel;
|
mouse.dx += event.motion.xrel;
|
||||||
mouse.dy += event.motion.yrel;
|
mouse.dy += event.motion.yrel;
|
||||||
},
|
},
|
||||||
|
sdl.EVENT_KEY_DOWN => {
|
||||||
|
if (event.key.windowID != sdl.GetWindowID(graphics.window)) continue;
|
||||||
|
keyboard.press(event.key.scancode);
|
||||||
|
},
|
||||||
|
sdl.EVENT_KEY_UP => {
|
||||||
|
if (event.key.windowID != sdl.GetWindowID(graphics.window)) continue;
|
||||||
|
keyboard.release(event.key.scancode);
|
||||||
|
},
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -13,6 +13,7 @@ scale: Scale = @splat(1.0),
|
|||||||
|
|
||||||
pub fn matrix(transform: Transform) TMatrix {
|
pub fn matrix(transform: Transform) TMatrix {
|
||||||
@setFloatMode(.optimized);
|
@setFloatMode(.optimized);
|
||||||
|
|
||||||
const r = rotationMatrix(transform.rotation);
|
const r = rotationMatrix(transform.rotation);
|
||||||
const sx, const sy, const sz = transform.scale;
|
const sx, const sy, const sz = transform.scale;
|
||||||
return .{
|
return .{
|
||||||
@@ -25,6 +26,7 @@ pub fn matrix(transform: Transform) TMatrix {
|
|||||||
|
|
||||||
pub fn inverseMatrix(transform: Transform) TMatrix {
|
pub fn inverseMatrix(transform: Transform) TMatrix {
|
||||||
@setFloatMode(.optimized);
|
@setFloatMode(.optimized);
|
||||||
|
|
||||||
const r = rotationMatrix(flipRotation(transform.rotation));
|
const r = rotationMatrix(flipRotation(transform.rotation));
|
||||||
const tx, const ty, const tz = transform.position;
|
const tx, const ty, const tz = transform.position;
|
||||||
const sx = 1.0 / transform.scale[0];
|
const sx = 1.0 / transform.scale[0];
|
||||||
@@ -47,11 +49,49 @@ pub fn inverseMatrix(transform: Transform) TMatrix {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn translate(transform: *Transform, translation: Position) void {
|
||||||
|
@setFloatMode(.optimized);
|
||||||
|
|
||||||
|
transform.position += translation;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn translateLocal(transform: *Transform, translation: Position) void {
|
||||||
|
@setFloatMode(.optimized);
|
||||||
|
|
||||||
|
const a = transform.rotation[0];
|
||||||
|
const b = transform.rotation[1];
|
||||||
|
const c = transform.rotation[2];
|
||||||
|
const d = transform.rotation[3];
|
||||||
|
|
||||||
|
const s = 2.0 / (a * a + b * b + c * c + d * d);
|
||||||
|
const bs = b * s;
|
||||||
|
const cs = c * s;
|
||||||
|
const ds = d * s;
|
||||||
|
|
||||||
|
const ab = a * bs;
|
||||||
|
const ac = a * cs;
|
||||||
|
const ad = a * ds;
|
||||||
|
const bb = b * bs;
|
||||||
|
const bc = b * cs;
|
||||||
|
const bd = b * ds;
|
||||||
|
const cc = c * cs;
|
||||||
|
const cd = c * ds;
|
||||||
|
const dd = d * ds;
|
||||||
|
|
||||||
|
transform.position[0] += translation[0] * (1 - cc - dd) + translation[1] * (bc - ad) + translation[2] * (bd + ac);
|
||||||
|
transform.position[1] += translation[0] * (bc + ad) + translation[1] * (1 - bb - dd) + translation[2] * (cd - ab);
|
||||||
|
transform.position[2] += translation[0] * (bd - ac) + translation[1] * (cd + ab) + translation[2] * (1 - bb - cc);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn rotate(transform: *Transform, rotation: Rotation) void {
|
pub fn rotate(transform: *Transform, rotation: Rotation) void {
|
||||||
|
@setFloatMode(.optimized);
|
||||||
|
|
||||||
transform.rotation = normalizeRotation(combineRotations(transform.rotation, rotation));
|
transform.rotation = normalizeRotation(combineRotations(transform.rotation, rotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotateLocal(transform: *Transform, rotation: Rotation) void {
|
pub fn rotateLocal(transform: *Transform, rotation: Rotation) void {
|
||||||
|
@setFloatMode(.optimized);
|
||||||
|
|
||||||
transform.rotation = normalizeRotation(combineRotations(rotation, transform.rotation));
|
transform.rotation = normalizeRotation(combineRotations(rotation, transform.rotation));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
69
src/keyboard.zig
Normal file
69
src/keyboard.zig
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
const sdl = @import("sdl");
|
||||||
|
|
||||||
|
const BUFFER_SIZE = 16;
|
||||||
|
const ZERO = sdl.SCANCODE_UNKNOWN;
|
||||||
|
|
||||||
|
just_pressed: [BUFFER_SIZE]sdl.Scancode = .{ZERO} ** BUFFER_SIZE,
|
||||||
|
pressed: [BUFFER_SIZE]sdl.Scancode = .{ZERO} ** BUFFER_SIZE,
|
||||||
|
just_released: [BUFFER_SIZE]sdl.Scancode = .{ZERO} ** BUFFER_SIZE,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
pub fn reset(self: *Self) void {
|
||||||
|
self.just_pressed = .{ZERO} ** BUFFER_SIZE;
|
||||||
|
self.just_released = .{ZERO} ** BUFFER_SIZE;
|
||||||
|
}
|
||||||
|
pub fn press(self: *Self, code: sdl.Scancode) void {
|
||||||
|
for (self.pressed) |pressed| {
|
||||||
|
if (pressed == code) return;
|
||||||
|
}
|
||||||
|
for (&self.pressed) |*pressed| {
|
||||||
|
if (pressed.* == ZERO) {
|
||||||
|
pressed.* = code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (self.just_pressed) |just_pressed| {
|
||||||
|
if (just_pressed == code) return;
|
||||||
|
}
|
||||||
|
for (&self.just_pressed) |*just_pressed| {
|
||||||
|
if (just_pressed.* == ZERO) {
|
||||||
|
just_pressed.* = code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn release(self: *Self, code: sdl.Scancode) void {
|
||||||
|
for (&self.pressed) |*pressed| {
|
||||||
|
if (pressed.* == code) {
|
||||||
|
pressed.* = ZERO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (self.just_released) |just_released| {
|
||||||
|
if (just_released == code) return;
|
||||||
|
}
|
||||||
|
for (&self.just_released) |*just_released| {
|
||||||
|
if (just_released.* == ZERO) {
|
||||||
|
just_released.* = code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn is_just_pressed(self: *Self, code: sdl.Scancode) bool {
|
||||||
|
for (self.just_pressed) |just_pressed| {
|
||||||
|
if (just_pressed == code) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pub fn is_pressed(self: *Self, code: sdl.Scancode) bool {
|
||||||
|
for (self.pressed) |pressed| {
|
||||||
|
if (pressed == code) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pub fn is_just_released(self: *Self, code: sdl.Scancode) bool {
|
||||||
|
for (self.just_released) |just_released| {
|
||||||
|
if (just_released == code) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
4
src/mouse.zig
Normal file
4
src/mouse.zig
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
dx: f32,
|
||||||
|
dy: f32,
|
4
src/time.zig
Normal file
4
src/time.zig
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
const sdl = @import("sdl");
|
||||||
|
|
||||||
|
delta: f32,
|
||||||
|
now: sdl.Time,
|
Reference in New Issue
Block a user