Basic scene graph with inherited transforms
This commit is contained in:
parent
756f4fa6f9
commit
59ccd86a5d
13
src/game.zig
13
src/game.zig
@ -142,7 +142,7 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
|
||||
gl.viewport(0, 0, globals.g_init.width, globals.g_init.height);
|
||||
|
||||
_ = globals.g_mem.world.addEntity(.{
|
||||
const light1 = globals.g_mem.world.addEntity(.{
|
||||
.transform = .{ .pos = Vec3.new(1.8, 1, 0) },
|
||||
.flags = .{ .point_light = true, .rotate = true },
|
||||
.point_light = .{ .color_intensity = Vec4.new(1.0, 0.3, 0.1, 100.0), .radius = 0.1 },
|
||||
@ -150,7 +150,8 @@ export fn game_init(global_allocator: *std.mem.Allocator) void {
|
||||
});
|
||||
|
||||
_ = globals.g_mem.world.addEntity(.{
|
||||
.transform = .{ .pos = Vec3.new(-2, 1, 0) },
|
||||
.transform = .{ .pos = Vec3.new(-2, 0, 0) },
|
||||
.parent = light1,
|
||||
.flags = .{ .point_light = true, .rotate = true },
|
||||
.point_light = .{
|
||||
.color_intensity = Vec4.new(0.2, 0.5, 1.0, 100.0),
|
||||
@ -371,11 +372,11 @@ export fn game_update() bool {
|
||||
ent.rotate.rate * gmem.delta_time,
|
||||
ent.rotate.axis,
|
||||
).mulByVec4(Vec4.new(old_pos.x(), old_pos.y(), old_pos.z(), 1));
|
||||
ent.transform.pos = Vec3.new(new_pos.x(), new_pos.y(), new_pos.z());
|
||||
ent.transform.setPos(Vec3.new(new_pos.x(), new_pos.y(), new_pos.z()));
|
||||
}
|
||||
|
||||
if (ent.flags.point_light) {
|
||||
const pos = ent.transform.pos;
|
||||
const pos = ent.globalMatrix(&gmem.world).extractTranslation();
|
||||
var pos4 = Vec4.new(pos.x(), pos.y(), pos.z(), 1.0);
|
||||
pos4 = gmem.render.camera.view_mat.mulByVec4(pos4);
|
||||
|
||||
@ -400,13 +401,13 @@ export fn game_update() bool {
|
||||
gmem.render.draw(.{
|
||||
.mesh = ent.mesh.handle,
|
||||
.material = ent.mesh.material,
|
||||
.transform = ent.transform.matrix(),
|
||||
.transform = ent.globalMatrix(&gmem.world).*,
|
||||
});
|
||||
} else if (ent.flags.point_light) {
|
||||
gmem.render.draw(.{
|
||||
.mesh = a.Meshes.sphere,
|
||||
.material = .{ .albedo = ent.point_light.color() },
|
||||
.transform = ent.transform.matrix(),
|
||||
.transform = ent.globalMatrix(&gmem.world).*,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,25 @@ pub const Entity = struct {
|
||||
rot: Quat = Quat.identity(),
|
||||
scale: Vec3 = Vec3.one(),
|
||||
|
||||
pub fn matrix(self: *Transform) Mat4 {
|
||||
// TODO: cache
|
||||
return Mat4.recompose(self.pos, self.rot, self.scale);
|
||||
_local_dirty: bool = true,
|
||||
_local: Mat4 = Mat4.identity(),
|
||||
|
||||
_global_dirty: bool = true,
|
||||
_global: Mat4 = Mat4.identity(),
|
||||
|
||||
pub fn dirty(self: *Transform) void {
|
||||
self._local_dirty = true;
|
||||
self._global_dirty = true;
|
||||
}
|
||||
|
||||
pub fn setPos(self: *Transform, new_pos: Vec3) void {
|
||||
self.pos = new_pos;
|
||||
self.dirty();
|
||||
}
|
||||
|
||||
pub fn translate(self: *Transform, by: Vec3) void {
|
||||
self.pos = self.pos.add(by);
|
||||
self.dirty();
|
||||
}
|
||||
};
|
||||
|
||||
@ -75,10 +91,35 @@ pub const Entity = struct {
|
||||
next: ?*Entity = null,
|
||||
|
||||
flags: Flags = .{},
|
||||
parent: ?EntityHandle = null,
|
||||
transform: Transform = .{},
|
||||
mesh: Mesh = .{},
|
||||
point_light: PointLight = .{},
|
||||
rotate: Rotate = .{},
|
||||
|
||||
pub fn localMatrix(self: *Entity) *const Mat4 {
|
||||
if (self.transform._local_dirty) {
|
||||
self.transform._local = Mat4.recompose(self.transform.pos, self.transform.rot, self.transform.scale);
|
||||
self.transform._local_dirty = false;
|
||||
}
|
||||
return &self.transform._local;
|
||||
}
|
||||
|
||||
pub fn globalMatrix(self: *Entity, world: *World) *const Mat4 {
|
||||
// TODO: think how to reduce pointer chasing
|
||||
if (self.parent) |parent_ent| {
|
||||
if (world.getEntity(parent_ent)) |parent| {
|
||||
if (parent.transform._global_dirty or self.transform._global_dirty) {
|
||||
self.transform._global = parent.globalMatrix(world).mul(self.localMatrix().*);
|
||||
self.transform._global_dirty = false;
|
||||
}
|
||||
|
||||
return &self.transform._global;
|
||||
}
|
||||
}
|
||||
|
||||
return self.localMatrix();
|
||||
}
|
||||
};
|
||||
|
||||
pub const EntityHandle = packed struct {
|
||||
|
@ -69,6 +69,7 @@ pub fn main() !void {
|
||||
.Shader => try std.fs.Dir.copyFile(std.fs.cwd(), abs_input, output_dir, std.fs.path.basename(rel_input), .{}),
|
||||
.ShaderProgram => try processShaderProgram(allocator, abs_input, output_dir),
|
||||
.Texture => try processTexture(allocator, abs_input, output_dir, false),
|
||||
.Scene => return error.NotImplemented,
|
||||
}
|
||||
|
||||
const out_writer = std.io.getStdOut().writer();
|
||||
|
@ -1,6 +1,7 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const AssetType = enum {
|
||||
Scene,
|
||||
Mesh,
|
||||
Shader,
|
||||
ShaderProgram,
|
||||
@ -8,6 +9,7 @@ pub const AssetType = enum {
|
||||
|
||||
pub fn pluralName(self: AssetType) []const u8 {
|
||||
return switch (self) {
|
||||
.Scene => "Scenes",
|
||||
.Mesh => "Meshes",
|
||||
.Shader => "Shaders",
|
||||
.ShaderProgram => "ShaderPrograms",
|
||||
@ -17,6 +19,7 @@ pub const AssetType = enum {
|
||||
|
||||
pub fn ext(self: AssetType) []const u8 {
|
||||
return switch (self) {
|
||||
.Scene => "scn",
|
||||
.Mesh => "mesh",
|
||||
.Shader => "glsl",
|
||||
.ShaderProgram => "prog",
|
||||
|
Loading…
x
Reference in New Issue
Block a user