Compare commits
No commits in common. "b19cda86be004eae320a8dc1e387eb007b9e72fa" and "1904b58458123ae073093a254f46e58a3dae3544" have entirely different histories.
b19cda86be
...
1904b58458
1 changed files with 15 additions and 192 deletions
207
math/vec.jai
207
math/vec.jai
|
|
@ -123,182 +123,6 @@ operator / :: inline (l: Vec, r: Vec(l.N, l.T)) -> Vec(l.N, l.T) #no_abc {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator + :: inline (l: Vec, r: $R) -> Vec(l.N, l.T) #no_abc #symmetric
|
|
||||||
#modify { return is_type_scalar(R), "type is not integer or float"; } {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
for l res[it_index] = it + r;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator - :: inline (l: Vec, r: $R) -> Vec(l.N, l.T) #no_abc
|
|
||||||
#modify { return is_type_scalar(R), "type is not integer or float"; } {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
for l res[it_index] = it - r;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
operator - :: inline (l: $R, r: Vec) -> Vec(l.N, l.T) #no_abc
|
|
||||||
#modify { return is_type_scalar(R), "type is not integer or float"; } {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
for l res[it_index] = r - it;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator * :: inline (l: Vec, r: $R) -> Vec(l.N, l.T) #no_abc #symmetric
|
|
||||||
#modify { return is_type_scalar(R), "type is not integer or float"; } {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
for l res[it_index] = it*r;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator / :: inline (l: Vec, r: $R) -> Vec(l.N, l.T) #no_abc
|
|
||||||
#modify { return is_type_scalar(R), "type is not integer or float"; } {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
for l res[it_index] = it/r;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator == :: inline (l: Vec, r: Vec(l.N, l.T)) -> bool #no_abc {
|
|
||||||
for l if it != r[it_index] return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
min :: (l: Vec, r: Vec(l.N, l.T)) -> Vec(l.N, l.T) #no_abc {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
n := l.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if l[n] < r[n]
|
|
||||||
res[n] = l[n];
|
|
||||||
else
|
|
||||||
res[n] = r[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
max :: (l: Vec, r: Vec(l.N, l.T)) -> Vec(l.N, l.T) #no_abc {
|
|
||||||
res: Vec(l.N, l.T) = ---;
|
|
||||||
n := l.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if l[n] > r[n]
|
|
||||||
res[n] = l[n];
|
|
||||||
else
|
|
||||||
res[n] = r[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
ceil :: (l: Vec, x: l.T) -> Vec(l.N, l.T) #no_abc {
|
|
||||||
r: Vec(l.N, l.T) = ---;
|
|
||||||
n := l.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if x < l[n]
|
|
||||||
r[n] = x;
|
|
||||||
else
|
|
||||||
r[n] = l[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
floor :: (l: Vec, x: l.T) -> Vec(l.N, l.T) #no_abc {
|
|
||||||
r: Vec(l.N, l.T) = ---;
|
|
||||||
n := l.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if x > l[n]
|
|
||||||
r[n] = x;
|
|
||||||
else
|
|
||||||
r[n] = l[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
clamp :: (v: Vec, low: v.T, high: v.T) -> Vec(v.N, v.T) #no_abc {
|
|
||||||
r: Vec(v.N, v.T) = ---;
|
|
||||||
n := v.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if v[n] < low
|
|
||||||
r[n] = low;
|
|
||||||
else if v[n] > high
|
|
||||||
r[n] = high;
|
|
||||||
else
|
|
||||||
r[n] = v[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
dot :: (a: Vec, b: Vec(a.N, a.T)) -> a.T #no_abc {
|
|
||||||
sum: a.T;
|
|
||||||
n := a.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
sum += a[n]*b[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
length_squared :: (v: Vec) -> float #no_abc {
|
|
||||||
return dot(v, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
length :: (v: Vec) -> float #no_abc {
|
|
||||||
return math.sqrt(dot(v, v));
|
|
||||||
}
|
|
||||||
|
|
||||||
abs :: (v: Vec) -> Vec(v.N, v.T) #no_abc {
|
|
||||||
r: Vec(v.N, v.T) = ---;
|
|
||||||
n := v.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if v[n] < 0
|
|
||||||
r[n] = -v[n];
|
|
||||||
else
|
|
||||||
r[n] = v[n];
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
norm :: normalize;
|
|
||||||
normalize :: (v: Vec) -> Vec(v.N, v.T) #no_abc {
|
|
||||||
return v/length(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
lerp :: (a: Vec, b: Vec(a.N, a.T), t: float) -> Vec(a.N, a.T) #no_abc {
|
|
||||||
r: Vec(a.N, a.T) = ---;
|
|
||||||
n := a.N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
r[n] = a[n] + t*(b[n] - a[n]);
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note(Jesse): I don't think this is needed for bigger vectors
|
|
||||||
reflect :: (v: Vec3, p: Vec3) -> Vec3 #no_abc {
|
|
||||||
projection := p*dot(v, p)/length_squared(p);
|
|
||||||
return 2*projection - v;
|
|
||||||
}
|
|
||||||
reflect :: (v: Vec2, p: Vec2) -> Vec2 #no_abc {
|
|
||||||
projection := p*dot(v, p)/length_squared(p);
|
|
||||||
return 2*projection - v;
|
|
||||||
}
|
|
||||||
|
|
||||||
round :: (v: Vec($N, $T)) -> Vec(N, T) #no_abc
|
|
||||||
#modify { return is_type_float(T), "Used non-float vector on round"; } {
|
|
||||||
r: Vec(N, T) = ---;
|
|
||||||
n := N - 1;
|
|
||||||
while n >= 0 {
|
|
||||||
if v[n] < 0
|
|
||||||
r[n] = (v[n] - 0.5).(int).(float);
|
|
||||||
else
|
|
||||||
r[n] = (v[n] + 0.5).(int).(float);
|
|
||||||
n -= 1;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Concrete vector types (the usual cases)
|
// Concrete vector types (the usual cases)
|
||||||
|
|
||||||
Vec2 :: Vec(2, float);
|
Vec2 :: Vec(2, float);
|
||||||
|
|
@ -307,37 +131,37 @@ Vec4 :: Vec(4, float);
|
||||||
Quat :: Vec4;
|
Quat :: Vec4;
|
||||||
|
|
||||||
v2f :: (x: $T = 0, y: T = 0) -> Vec2
|
v2f :: (x: $T = 0, y: T = 0) -> Vec2
|
||||||
#modify { return is_type_float(T), "use v2i for integer arguments"; }
|
#modify { return T.(*Type_Info).type == .FLOAT, "use v2i for integer arguments"; }
|
||||||
#expand {
|
#expand {
|
||||||
return .{ x = x, y = y };
|
return .{ x = x, y = y };
|
||||||
}
|
}
|
||||||
|
|
||||||
v2i :: (x: $T = 0, y: T = 0) -> Vec(2, T)
|
v2i :: (x: $T = 0, y: T = 0) -> Vec(2, T)
|
||||||
#modify { return is_type_integer(T), "use v2f for float arguments"; }
|
#modify { return T.(*Type_Info).type == .INTEGER, "use v2f for float arguments"; }
|
||||||
#expand {
|
#expand {
|
||||||
return .{ x = x, y = y };
|
return .{ x = x, y = y };
|
||||||
}
|
}
|
||||||
|
|
||||||
v3f :: (x: $T = 0, y: T = 0, z: T = 0) -> Vec3
|
v3f :: (x: $T = 0, y: T = 0, z: T = 0) -> Vec3
|
||||||
#modify { return is_type_float(T), "use v3i for integer arguments"; }
|
#modify { return T.(*Type_Info).type == .FLOAT, "use v3i for integer arguments"; }
|
||||||
#expand {
|
#expand {
|
||||||
return .{ x = x, y = y, z = z };
|
return .{ x = x, y = y, z = z };
|
||||||
}
|
}
|
||||||
|
|
||||||
v3i :: (x: $T = 0, y: T = 0, z: T = 0) -> Vec(3, T)
|
v3i :: (x: $T = 0, y: T = 0, z: T = 0) -> Vec(3, T)
|
||||||
#modify { return is_type_integer(T), "use v3f for float arguments"; }
|
#modify { return T.(*Type_Info).type == .INTEGER, "use v3f for float arguments"; }
|
||||||
#expand {
|
#expand {
|
||||||
return .{ x = x, y = y, z = z };
|
return .{ x = x, y = y, z = z };
|
||||||
}
|
}
|
||||||
|
|
||||||
v4f :: (x: $T = 0, y: T = 0, z: T = 0, w: T = 0) -> Vec4
|
v4f :: (x: $T = 0, y: T = 0, z: T = 0, w: T = 0) -> Vec4
|
||||||
#modify { return is_type_float(T), "use v4i for integer arguments"; }
|
#modify { return T.(*Type_Info).type == .FLOAT, "use v4i for integer arguments"; }
|
||||||
#expand {
|
#expand {
|
||||||
return .{ x = x, y = y, z = z, w = w };
|
return .{ x = x, y = y, z = z, w = w };
|
||||||
}
|
}
|
||||||
|
|
||||||
v4i :: (x: $T = 0, y: T = 0, z: T = 0, w: T = 0) -> Vec(4, T)
|
v4i :: (x: $T = 0, y: T = 0, z: T = 0, w: T = 0) -> Vec(4, T)
|
||||||
#modify { return is_type_integer(T), "use v4f for float arguments"; }
|
#modify { return T.(*Type_Info).type == .INTEGER, "use v4f for float arguments"; }
|
||||||
#expand {
|
#expand {
|
||||||
return .{ x = x, y = y, z = z, w = w };
|
return .{ x = x, y = y, z = z, w = w };
|
||||||
}
|
}
|
||||||
|
|
@ -346,18 +170,17 @@ quat :: (x: float = 0, y: float = 0, z: float = 0, w: float = 0) -> Quat #expand
|
||||||
return .{ x = x, y = y, z = z, w = w };
|
return .{ x = x, y = y, z = z, w = w };
|
||||||
}
|
}
|
||||||
|
|
||||||
#scope_file
|
|
||||||
|
|
||||||
math :: #import "Math";
|
#if RUN_TESTS #run,stallable {
|
||||||
|
test.run("vec2:ops", t => {
|
||||||
|
a := v2f(10.0, 1);
|
||||||
|
b := v2f(20.0, 2);
|
||||||
|
c := a + b;
|
||||||
|
|
||||||
is_type_integer :: (t: Type) -> bool {
|
test.expect(t, c.x == 30 && c.y == 3);
|
||||||
return t.(*Type_Info).type == .INTEGER;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
is_type_float :: (t: Type) -> bool {
|
#scope_file;
|
||||||
return t.(*Type_Info).type == .FLOAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
is_type_scalar :: (t: Type) -> bool {
|
jx :: #import,file "../module.jai";
|
||||||
return is_type_integer(t) || is_type_float(t);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue