const std = @import("std"); const vm = @import("vecmath"); pub const Iterator2 = @import("math/Iterator2.zig").Iterator2; pub const Iterator3 = @import("math/Iterator3.zig").Iterator3; pub const noise2 = @import("math/noise.zig").noise2; pub const noise2x8 = @import("math/noise.zig").noise2x8; pub inline fn asFloatFrac(frac: i32) f32 { const numerator: f64 = @floatFromInt(frac); const denominator: f64 = std.math.maxInt(i32); return @floatCast(numerator / denominator); } pub inline fn asFloatFrac2(frac: vm.Vector2Int) vm.Vector2 { return .init( asFloatFrac(frac.x), asFloatFrac(frac.y), ); } pub inline fn asFloatFrac3(frac: vm.Vector3Int) vm.Vector3 { return .init( asFloatFrac(frac.x), asFloatFrac(frac.y), asFloatFrac(frac.z), ); } pub inline fn asFloatFrac4(frac: vm.Vector4Int) vm.Vector4 { return .init( asFloatFrac(frac.x), asFloatFrac(frac.y), asFloatFrac(frac.z), asFloatFrac(frac.w), ); } pub inline fn asIntFrac(frac: f32) i32 { const fraction: f64 = @floatCast(frac); const scale: f64 = std.math.maxInt(i32); return @intFromFloat(@round(fraction * scale)); } pub inline fn asIntFrac2(frac: vm.Vector2) vm.Vector2Int { return .init( asIntFrac(frac.x), asIntFrac(frac.y), ); } pub inline fn asIntFrac3(frac: vm.Vector3) vm.Vector3Int { return .init( asIntFrac(frac.x), asIntFrac(frac.y), asIntFrac(frac.z), ); } pub inline fn asIntFrac4(frac: vm.Vector4) vm.Vector4Int { return .init( asIntFrac(frac.x), asIntFrac(frac.y), asIntFrac(frac.z), asIntFrac(frac.w), ); } pub inline fn mulIntFloat(int: i32, float: f32) i32 { const int_float: f64 = @floatFromInt(int); const float_wide: f64 = @floatCast(float); return @intFromFloat(@round(int_float * float_wide)); } pub inline fn mulIntFloat2(int: vm.Vector2Int, float: f32) vm.Vector2Int { return .init( mulIntFloat(int.x, float), mulIntFloat(int.y, float), ); } pub inline fn mulIntFloat3(int: vm.Vector3Int, float: f32) vm.Vector3Int { return .init( mulIntFloat(int.x, float), mulIntFloat(int.y, float), mulIntFloat(int.z, float), ); } pub inline fn mulIntFloat4(int: vm.Vector4Int, float: f32) vm.Vector4Int { return .init( mulIntFloat(int.x, float), mulIntFloat(int.y, float), mulIntFloat(int.z, float), mulIntFloat(int.w, float), ); } pub inline fn mulFrac(a: i32, b: i32) i32 { const denominator: i64 = std.math.maxInt(i32); const rounding_bias: i64 = denominator >> 1; const a_wide: i64 = a; const b_wide: i64 = b; return @intCast(@divFloor(a_wide * b_wide + rounding_bias, denominator)); } pub inline fn mulFrac2(a: vm.Vector2Int, b: i32) vm.Vector2Int { return .init( mulFrac(a.x, b), mulFrac(a.y, b), ); } pub inline fn mulFrac3(a: vm.Vector3Int, b: i32) vm.Vector3Int { return .init( mulFrac(a.x, b), mulFrac(a.y, b), mulFrac(a.z, b), ); } pub inline fn mulFrac4(a: vm.Vector4Int, b: i32) vm.Vector4Int { return .init( mulFrac(a.x, b), mulFrac(a.y, b), mulFrac(a.z, b), mulFrac(a.w, b), ); } pub inline fn mulFracFrac(a: i32, b: i32) i32 { const denominator: i64 = std.math.maxInt(i32) * std.math.maxInt(i32); const rounding_bias: i64 = denominator >> 1; const a_wide: i64 = a; const b_wide: i64 = b; return .{ .vector = @intCast(@divFloor(a_wide * b_wide + rounding_bias, denominator)) }; } pub inline fn mulFracFrac2(a: vm.Vector2Int, b: i32) vm.Vector2Int { return .init( mulFracFrac(a.x, b), mulFracFrac(a.y, b), ); } pub inline fn mulFracFrac3(a: vm.Vector3Int, b: i32) vm.Vector3Int { return .init( mulFracFrac(a.x, b), mulFracFrac(a.y, b), mulFracFrac(a.z, b), ); } pub inline fn mulFracFrac4(a: vm.Vector4Int, b: i32) vm.Vector4Int { return .init( mulFracFrac(a.x, b), mulFracFrac(a.y, b), mulFracFrac(a.z, b), mulFracFrac(a.w, b), ); } pub inline fn wideMulDivFloor(a: i32, mul: i32, div: i32) i32 { return @intCast(@divFloor(@as(i64, a) * @as(i64, mul), div)); } pub inline fn wideMulDivCeil(a: i32, mul: i32, div: i32) i32 { return @intCast(@divFloor(@as(i64, a) * @as(i64, mul) + @as(i64, div) - std.math.sign(div), div)); }