| 1 | const std = @import("std"); |
| 2 | |
| 3 | pub fn mixin( |
| 4 | comptime T: type, |
| 5 | comptime I: type, |
| 6 | comptime f1: std.meta.FieldEnum(T), |
| 7 | comptime f2: std.meta.FieldEnum(T), |
| 8 | comptime f3: std.meta.FieldEnum(T), |
| 9 | ) type { |
| 10 | return struct { |
| 11 | pub fn to_vec(x: T) @Vector(4, f32) { |
| 12 | if (I == f32) { |
| 13 | return x.to_array(); |
| 14 | } |
| 15 | return .{ |
| 16 | @floatFromInt(@field(x, @tagName(f1))), |
| 17 | @floatFromInt(@field(x, @tagName(f2))), |
| 18 | @floatFromInt(@field(x, @tagName(f3))), |
| 19 | @floatFromInt(x.a), |
| 20 | }; |
| 21 | } |
| 22 | |
| 23 | pub fn from_vec(in: @Vector(4, f32)) T { |
| 24 | if (I == f32) { |
| 25 | var x: T = undefined; |
| 26 | @field(x, @tagName(f1)) = in[0]; |
| 27 | @field(x, @tagName(f2)) = in[1]; |
| 28 | @field(x, @tagName(f3)) = in[2]; |
| 29 | x.a = in[3]; |
| 30 | return x; |
| 31 | } |
| 32 | var x: T = undefined; |
| 33 | @field(x, @tagName(f1)) = @intFromFloat(in[0]); |
| 34 | @field(x, @tagName(f2)) = @intFromFloat(in[1]); |
| 35 | @field(x, @tagName(f3)) = @intFromFloat(in[2]); |
| 36 | x.a = @intFromFloat(in[3]); |
| 37 | return x; |
| 38 | } |
| 39 | |
| 40 | pub fn to_array(x: T) [4]I { |
| 41 | return .{ |
| 42 | @field(x, @tagName(f1)), |
| 43 | @field(x, @tagName(f2)), |
| 44 | @field(x, @tagName(f3)), |
| 45 | x.a, |
| 46 | }; |
| 47 | } |
| 48 | }; |
| 49 | } |