Implemented rotations

This commit is contained in:
Lorenzo Torres 2025-08-06 16:35:29 +02:00
parent 7a634d53b5
commit defdf051ec
6 changed files with 29 additions and 13 deletions

View file

@ -15,6 +15,7 @@ layout (binding = 1) uniform ViewUniform {
layout (binding = 4) uniform TransformUniform {
mat4 translation;
mat4 scale;
mat4 rotation;
} transform;
layout(location = 2) out vec3 Normal;
@ -22,7 +23,7 @@ layout(location = 3) out vec3 FragPos;
layout(location = 4) out vec2 TexCoords;
void main() {
mat4 transformation = transform.translation * transform.scale;
mat4 transformation = transform.translation * transform.scale * transform.rotation;
vec4 out_vec = proj.proj * view.view * transformation * vec4(vertPos, 1.0);
FragPos = vec3(vec4(vertPos, 1.0));
Normal = normal;

View file

@ -26,7 +26,7 @@ pub const Human = struct {
// TODO(ernesto): Move pool to its own file
pub const Pool = struct {
humans: std.MultiArrayList(Human),
resources: Resources,
resources: *Resources,
allocator: Allocator,
system_groups: std.ArrayList(SystemGroup),
sync_groups: std.ArrayList(SyncGroup),
@ -34,7 +34,7 @@ pub const Pool = struct {
wait_group: std.Thread.WaitGroup,
mutex: std.Thread.Mutex,
pub fn init(allocator: Allocator, resources: Resources) !@This() {
pub fn init(allocator: Allocator, resources: *Resources) !@This() {
var pool = @This(){
.humans = .{},
.resources = resources,

View file

@ -11,18 +11,21 @@ pub const Axis = struct {
pub const z: [3]f32 = .{0.0, 0.0, 1.0};
};
pub const Transform = struct {
pub const Transform = extern struct {
translation: Matrix,
scale: Matrix,
rotation_matrix: Matrix,
rotation: Quaternion,
pub fn init(position: [3]f32, scale: [3]f32, rotation: [3]f32) Transform {
var translation = Matrix.identity();
translation.translate(position);
const quaternion = Quaternion.fromEulerAngles(rotation);
return .{
.translation = translation,
.rotation = Quaternion.fromEulerAngles(rotation),
.rotation = quaternion,
.rotation_matrix = quaternion.matrix(),
.scale = Matrix.scale(scale),
};
}
@ -35,10 +38,11 @@ pub const Transform = struct {
const delta = Quaternion.fromAxisAngle(axis, angle);
self.rotation = self.rotation.mul(delta);
self.rotation = self.rotation.normalize();
self.rotation_matrix = self.rotation.matrix();
}
};
pub const Matrix = struct {
pub const Matrix = extern struct {
rows: [4][4]f32,
pub fn lookAt(eye: [3]f32, target: [3]f32, arbitrary_up: [3]f32) Matrix {
@ -134,7 +138,7 @@ pub const Matrix = struct {
}
};
const Quaternion = struct {
pub const Quaternion = extern struct {
w: f32,
x: f32,
y: f32,
@ -150,7 +154,7 @@ const Quaternion = struct {
.w = cos(half_angle),
.x = axis[0] * s,
.y = axis[1] * s,
.z = axis[3] * s,
.z = axis[2] * s,
};
}

View file

@ -20,6 +20,7 @@ current_frame: u32,
vertex_buffer: vk.Buffer,
index_buffer: vk.Buffer,
transform: math.Transform,
previous_time: std.time.Instant,
pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_handle: vk.c.VkSurfaceKHR) !Renderer {
const instance: vk.Instance = .{ .handle = instance_handle };
@ -68,7 +69,8 @@ pub fn init(allocator: Allocator, instance_handle: vk.c.VkInstance, surface_hand
// TODO: Why are we storing the buffer and not the Mesh?
.vertex_buffer = triangle.vertex_buffer,
.index_buffer = triangle.index_buffer,
.transform = math.Transform.init(.{0.0, 0.0, 0.0}, .{1.0, 1.0, 1.0}, .{0.0, 0.0, 0.0}),
.transform = math.Transform.init(.{0.0, 0.0, 0.0}, .{1.0, 1.0, 1.0}, .{0.0, math.rad(45.0), 0.0}),
.previous_time = try std.time.Instant.now(),
};
}
@ -87,6 +89,10 @@ pub fn render(pool: *ecs.Pool) anyerror!void {
var renderer = pool.resources.renderer;
var camera = pool.resources.camera;
const now = try std.time.Instant.now();
const delta_time: f32 = @as(f32, @floatFromInt(now.since(renderer.previous_time))) / @as(f32, 1_000_000_000.0);
renderer.previous_time = now;
const view_memory = renderer.graphics_pipeline.view_memory;
@memcpy(view_memory[0..@sizeOf(math.Matrix)], std.mem.asBytes(&camera.getView()));
@ -96,8 +102,10 @@ pub fn render(pool: *ecs.Pool) anyerror!void {
view_pos[1] = camera.position[1];
view_pos[2] = camera.position[2];
renderer.transform.rotate(math.rad(10) * delta_time, .{0.0, 1.0, 0.0});
const transform_memory = renderer.graphics_pipeline.transform_memory;
@memcpy(transform_memory[0..@sizeOf(math.Transform)], std.mem.asBytes(&renderer.transform));
@memcpy(transform_memory[0..(@sizeOf(math.Transform)-@sizeOf(math.Quaternion))], std.mem.asBytes(&renderer.transform)[0..(@sizeOf(math.Transform)-@sizeOf(math.Quaternion))]);
try renderer.device.waitFence(renderer.current_frame);
const image = try renderer.swapchain.nextImage(renderer.device, renderer.current_frame);

View file

@ -548,7 +548,7 @@ pub fn GraphicsPipeline(comptime n: usize) type {
c.vkUpdateDescriptorSets(device.handle, 1, &write_view_descriptor_set, 0, null);
const transform_buffer = try device.createBuffer(BufferUsage{ .uniform_buffer = true, .transfer_dst = true }, BufferFlags{ .device_local = true }, @sizeOf(math.Transform));
const transform_buffer = try device.createBuffer(BufferUsage{ .uniform_buffer = true, .transfer_dst = true }, BufferFlags{ .device_local = true }, @sizeOf(math.Transform) - @sizeOf(math.Quaternion));
var transform_data: [*c]u8 = undefined;

View file

@ -12,6 +12,7 @@ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
const allocator = gpa.allocator();
var pool: ecs.Pool = undefined;
var renderer: Renderer = undefined;
var resources: ecs.Resources = undefined;
fn init_mods() void {
var global_runtime = mods.GlobalRuntime.init(allocator);
@ -43,14 +44,16 @@ fn init_mods() void {
}
export fn sideros_init(init: api.GameInit) callconv(.c) void {
pool = ecs.Pool.init(allocator, .{
resources = .{
.camera = .{
.position = .{ 5.0, 5.0, 5.0 },
.target = .{ 0.0, 0.0, 0.0 },
},
.renderer = undefined,
.input = .{ .key_pressed = .{false} ** @intFromEnum(ecs.Input.KeyCode.menu) },
}) catch @panic("TODO: Gracefully handle error");
};
pool = ecs.Pool.init(allocator, &resources) catch @panic("TODO: Gracefully handle error");
// TODO(ernesto): I think this @ptrCast are unavoidable but maybe not?
renderer = Renderer.init(allocator, @ptrCast(init.instance), @ptrCast(init.surface)) catch @panic("TODO: Gracefully handle error");
pool.addSystemGroup(&[_]ecs.System{Renderer.render}, true) catch @panic("TODO: Gracefuly handle error");