mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 23:28:48 +00:00
Add deprecated and require_results attributes to math_functions.odin
This commit is contained in:
Vendored
+74
-12
@@ -28,155 +28,184 @@ Mat22_zero :: Mat22{0, 0, 0, 0}
|
|||||||
|
|
||||||
|
|
||||||
// @return the minimum of two floats
|
// @return the minimum of two floats
|
||||||
|
@(deprecated="Prefer the built-in 'min(a, b)'", require_results)
|
||||||
MinFloat :: proc "c" (a, b: f32) -> f32 {
|
MinFloat :: proc "c" (a, b: f32) -> f32 {
|
||||||
return min(a, b)
|
return min(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return the maximum of two floats
|
// @return the maximum of two floats
|
||||||
|
@(deprecated="Prefer the built-in 'max(a, b)'", require_results)
|
||||||
MaxFloat :: proc "c" (a, b: f32) -> f32 {
|
MaxFloat :: proc "c" (a, b: f32) -> f32 {
|
||||||
return max(a, b)
|
return max(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return the absolute value of a float
|
// @return the absolute value of a float
|
||||||
|
@(deprecated="Prefer the built-in 'abs(a)'", require_results)
|
||||||
AbsFloat :: proc "c" (a: f32) -> f32 {
|
AbsFloat :: proc "c" (a: f32) -> f32 {
|
||||||
return abs(a)
|
return abs(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return a f32 clamped between a lower and upper bound
|
// @return a f32 clamped between a lower and upper bound
|
||||||
|
@(deprecated="Prefer the built-in 'clamp(a, lower, upper)'", require_results)
|
||||||
ClampFloat :: proc "c" (a, lower, upper: f32) -> f32 {
|
ClampFloat :: proc "c" (a, lower, upper: f32) -> f32 {
|
||||||
return clamp(a, lower, upper)
|
return clamp(a, lower, upper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return the minimum of two integers
|
// @return the minimum of two integers
|
||||||
|
@(deprecated="Prefer the built-in 'min(a, b)'", require_results)
|
||||||
MinInt :: proc "c" (a, b: c.int) -> c.int {
|
MinInt :: proc "c" (a, b: c.int) -> c.int {
|
||||||
return min(a, b)
|
return min(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return the maximum of two integers
|
// @return the maximum of two integers
|
||||||
|
@(deprecated="Prefer the built-in 'max(a, b)'", require_results)
|
||||||
MaxInt :: proc "c" (a, b: c.int) -> c.int {
|
MaxInt :: proc "c" (a, b: c.int) -> c.int {
|
||||||
return max(a, b)
|
return max(a, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return the absolute value of an integer
|
// @return the absolute value of an integer
|
||||||
|
@(deprecated="Prefer the built-in 'abs(a)'", require_results)
|
||||||
AbsInt :: proc "c" (a: c.int) -> c.int {
|
AbsInt :: proc "c" (a: c.int) -> c.int {
|
||||||
return abs(a)
|
return abs(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @return an integer clamped between a lower and upper bound
|
// @return an integer clamped between a lower and upper bound
|
||||||
|
@(deprecated="Prefer the built-in 'clamp(a, lower, upper)'", require_results)
|
||||||
ClampInt :: proc "c" (a, lower, upper: c.int) -> c.int {
|
ClampInt :: proc "c" (a, lower, upper: c.int) -> c.int {
|
||||||
return clamp(a, lower, upper)
|
return clamp(a, lower, upper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector dot product
|
// Vector dot product
|
||||||
|
@(require_results)
|
||||||
Dot :: proc "c" (a, b: Vec2) -> f32 {
|
Dot :: proc "c" (a, b: Vec2) -> f32 {
|
||||||
return a.x * b.x + a.y * b.y
|
return a.x * b.x + a.y * b.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector cross product. In 2D this yields a scalar.
|
// Vector cross product. In 2D this yields a scalar.
|
||||||
|
@(require_results)
|
||||||
Cross :: proc "c" (a, b: Vec2) -> f32 {
|
Cross :: proc "c" (a, b: Vec2) -> f32 {
|
||||||
return a.x * b.y - a.y * b.x
|
return a.x * b.y - a.y * b.x
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the cross product on a vector and a scalar. In 2D this produces a vector.
|
// Perform the cross product on a vector and a scalar. In 2D this produces a vector.
|
||||||
|
@(require_results)
|
||||||
CrossVS :: proc "c" (v: Vec2, s: f32) -> Vec2 {
|
CrossVS :: proc "c" (v: Vec2, s: f32) -> Vec2 {
|
||||||
return {s * v.y, -s * v.x}
|
return {s * v.y, -s * v.x}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the cross product on a scalar and a vector. In 2D this produces a vector.
|
// Perform the cross product on a scalar and a vector. In 2D this produces a vector.
|
||||||
|
@(require_results)
|
||||||
CrossSV :: proc "c" (s: f32, v: Vec2) -> Vec2 {
|
CrossSV :: proc "c" (s: f32, v: Vec2) -> Vec2 {
|
||||||
return {-s * v.y, s * v.x}
|
return {-s * v.y, s * v.x}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a left pointing perpendicular vector. Equivalent to b2CrossSV(1, v)
|
// Get a left pointing perpendicular vector. Equivalent to b2CrossSV(1, v)
|
||||||
|
@(require_results)
|
||||||
LeftPerp :: proc "c" (v: Vec2) -> Vec2 {
|
LeftPerp :: proc "c" (v: Vec2) -> Vec2 {
|
||||||
return {-v.y, v.x}
|
return {-v.y, v.x}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a right pointing perpendicular vector. Equivalent to b2CrossVS(v, 1)
|
// Get a right pointing perpendicular vector. Equivalent to b2CrossVS(v, 1)
|
||||||
|
@(require_results)
|
||||||
RightPerp :: proc "c" (v: Vec2) -> Vec2 {
|
RightPerp :: proc "c" (v: Vec2) -> Vec2 {
|
||||||
return {v.y, -v.x}
|
return {v.y, -v.x}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector addition
|
// Vector addition
|
||||||
|
@(deprecated="Prefer 'a + b'", require_results)
|
||||||
Add :: proc "c" (a, b: Vec2) -> Vec2 {
|
Add :: proc "c" (a, b: Vec2) -> Vec2 {
|
||||||
return a + b
|
return a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector subtraction
|
// Vector subtraction
|
||||||
|
@(deprecated="Prefer 'a - b'", require_results)
|
||||||
Sub :: proc "c" (a, b: Vec2) -> Vec2 {
|
Sub :: proc "c" (a, b: Vec2) -> Vec2 {
|
||||||
return a - b
|
return a - b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector negation
|
// Vector negation
|
||||||
|
@(deprecated="Prefer '-a'", require_results)
|
||||||
Neg :: proc "c" (a: Vec2) -> Vec2 {
|
Neg :: proc "c" (a: Vec2) -> Vec2 {
|
||||||
return -a
|
return -a
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vector linear interpolation
|
// Vector linear interpolation
|
||||||
// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
||||||
|
@(require_results)
|
||||||
Lerp :: proc "c" (a, b: Vec2, t: f32) -> Vec2 {
|
Lerp :: proc "c" (a, b: Vec2, t: f32) -> Vec2 {
|
||||||
return {(1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y}
|
return {(1 - t) * a.x + t * b.x, (1 - t) * a.y + t * b.y}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component-wise multiplication
|
// Component-wise multiplication
|
||||||
|
@(deprecated="Prefer 'a * b'", require_results)
|
||||||
Mul :: proc "c" (a, b: Vec2) -> Vec2 {
|
Mul :: proc "c" (a, b: Vec2) -> Vec2 {
|
||||||
return a * b
|
return a * b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply a scalar and vector
|
// Multiply a scalar and vector
|
||||||
|
@(deprecated="Prefer 's * v'", require_results)
|
||||||
MulSV :: proc "c" (s: f32, v: Vec2) -> Vec2 {
|
MulSV :: proc "c" (s: f32, v: Vec2) -> Vec2 {
|
||||||
return s * v
|
return s * v
|
||||||
}
|
}
|
||||||
|
|
||||||
// a + s * b
|
// a + s * b
|
||||||
|
@(deprecated="Prefer 'a + s * b'", require_results)
|
||||||
MulAdd :: proc "c" (a: Vec2, s: f32, b: Vec2) -> Vec2 {
|
MulAdd :: proc "c" (a: Vec2, s: f32, b: Vec2) -> Vec2 {
|
||||||
return a + s * b
|
return a + s * b
|
||||||
}
|
}
|
||||||
|
|
||||||
// a - s * b
|
// a - s * b
|
||||||
|
@(deprecated="Prefer 'a - s * b'", require_results)
|
||||||
MulSub :: proc "c" (a: Vec2, s: f32, b: Vec2) -> Vec2 {
|
MulSub :: proc "c" (a: Vec2, s: f32, b: Vec2) -> Vec2 {
|
||||||
return a - s * b
|
return a - s * b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component-wise absolute vector
|
// Component-wise absolute vector
|
||||||
|
@(require_results)
|
||||||
Abs :: proc "c" (a: Vec2) -> (b: Vec2) {
|
Abs :: proc "c" (a: Vec2) -> (b: Vec2) {
|
||||||
b.x = AbsFloat(a.x)
|
b.x = abs(a.x)
|
||||||
b.y = AbsFloat(a.y)
|
b.y = abs(a.y)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component-wise minimum vector
|
// Component-wise minimum vector
|
||||||
|
@(require_results)
|
||||||
Min :: proc "c" (a, b: Vec2) -> (c: Vec2) {
|
Min :: proc "c" (a, b: Vec2) -> (c: Vec2) {
|
||||||
c.x = MinFloat(a.x, b.x)
|
c.x = min(a.x, b.x)
|
||||||
c.y = MinFloat(a.y, b.y)
|
c.y = min(a.y, b.y)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component-wise maximum vector
|
// Component-wise maximum vector
|
||||||
|
@(require_results)
|
||||||
Max :: proc "c" (a, b: Vec2) -> (c: Vec2) {
|
Max :: proc "c" (a, b: Vec2) -> (c: Vec2) {
|
||||||
c.x = MaxFloat(a.x, b.x)
|
c.x = max(a.x, b.x)
|
||||||
c.y = MaxFloat(a.y, b.y)
|
c.y = max(a.y, b.y)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Component-wise clamp vector v into the range [a, b]
|
// Component-wise clamp vector v into the range [a, b]
|
||||||
|
@(require_results)
|
||||||
Clamp :: proc "c" (v: Vec2, a, b: Vec2) -> (c: Vec2) {
|
Clamp :: proc "c" (v: Vec2, a, b: Vec2) -> (c: Vec2) {
|
||||||
c.x = ClampFloat(v.x, a.x, b.x)
|
c.x = clamp(v.x, a.x, b.x)
|
||||||
c.y = ClampFloat(v.y, a.y, b.y)
|
c.y = clamp(v.y, a.y, b.y)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the length of this vector (the norm)
|
// Get the length of this vector (the norm)
|
||||||
|
@(require_results)
|
||||||
Length :: proc "c" (v: Vec2) -> f32 {
|
Length :: proc "c" (v: Vec2) -> f32 {
|
||||||
return math.sqrt(v.x * v.x + v.y * v.y)
|
return math.sqrt(v.x * v.x + v.y * v.y)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the length squared of this vector
|
// Get the length squared of this vector
|
||||||
|
@(require_results)
|
||||||
LengthSquared :: proc "c" (v: Vec2) -> f32 {
|
LengthSquared :: proc "c" (v: Vec2) -> f32 {
|
||||||
return v.x * v.x + v.y * v.y
|
return v.x * v.x + v.y * v.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the distance between two points
|
// Get the distance between two points
|
||||||
|
@(require_results)
|
||||||
Distance :: proc "c" (a, b: Vec2) -> f32 {
|
Distance :: proc "c" (a, b: Vec2) -> f32 {
|
||||||
dx := b.x - a.x
|
dx := b.x - a.x
|
||||||
dy := b.y - a.y
|
dy := b.y - a.y
|
||||||
@@ -184,18 +213,21 @@ Distance :: proc "c" (a, b: Vec2) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the distance squared between points
|
// Get the distance squared between points
|
||||||
|
@(require_results)
|
||||||
DistanceSquared :: proc "c" (a, b: Vec2) -> f32 {
|
DistanceSquared :: proc "c" (a, b: Vec2) -> f32 {
|
||||||
c := Vec2{b.x - a.x, b.y - a.y}
|
c := Vec2{b.x - a.x, b.y - a.y}
|
||||||
return c.x * c.x + c.y * c.y
|
return c.x * c.x + c.y * c.y
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a rotation using an angle in radians
|
// Make a rotation using an angle in radians
|
||||||
|
@(require_results)
|
||||||
MakeRot :: proc "c" (angle: f32) -> Rot {
|
MakeRot :: proc "c" (angle: f32) -> Rot {
|
||||||
// todo determinism
|
// todo determinism
|
||||||
return {math.cos(angle), math.sin(angle)}
|
return {math.cos(angle), math.sin(angle)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize rotation
|
// Normalize rotation
|
||||||
|
@(require_results)
|
||||||
NormalizeRot :: proc "c" (q: Rot) -> Rot {
|
NormalizeRot :: proc "c" (q: Rot) -> Rot {
|
||||||
mag := math.sqrt(q.s * q.s + q.c * q.c)
|
mag := math.sqrt(q.s * q.s + q.c * q.c)
|
||||||
invMag := f32(mag > 0.0 ? 1.0 / mag : 0.0)
|
invMag := f32(mag > 0.0 ? 1.0 / mag : 0.0)
|
||||||
@@ -203,6 +235,7 @@ NormalizeRot :: proc "c" (q: Rot) -> Rot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Is this rotation normalized?
|
// Is this rotation normalized?
|
||||||
|
@(require_results)
|
||||||
IsNormalized :: proc "c" (q: Rot) -> bool {
|
IsNormalized :: proc "c" (q: Rot) -> bool {
|
||||||
// larger tolerance due to failure on mingw 32-bit
|
// larger tolerance due to failure on mingw 32-bit
|
||||||
qq := q.s * q.s + q.c * q.c
|
qq := q.s * q.s + q.c * q.c
|
||||||
@@ -211,6 +244,7 @@ IsNormalized :: proc "c" (q: Rot) -> bool {
|
|||||||
|
|
||||||
// Normalized linear interpolation
|
// Normalized linear interpolation
|
||||||
// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
// https://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
||||||
|
@(require_results)
|
||||||
NLerp :: proc "c" (q1: Rot, q2: Rot, t: f32) -> Rot {
|
NLerp :: proc "c" (q1: Rot, q2: Rot, t: f32) -> Rot {
|
||||||
omt := 1 - t
|
omt := 1 - t
|
||||||
return NormalizeRot({
|
return NormalizeRot({
|
||||||
@@ -222,6 +256,7 @@ NLerp :: proc "c" (q1: Rot, q2: Rot, t: f32) -> Rot {
|
|||||||
// Integration rotation from angular velocity
|
// Integration rotation from angular velocity
|
||||||
// @param q1 initial rotation
|
// @param q1 initial rotation
|
||||||
// @param deltaAngle the angular displacement in radians
|
// @param deltaAngle the angular displacement in radians
|
||||||
|
@(require_results)
|
||||||
IntegrateRotation :: proc "c" (q1: Rot, deltaAngle: f32) -> Rot {
|
IntegrateRotation :: proc "c" (q1: Rot, deltaAngle: f32) -> Rot {
|
||||||
// dc/dt = -omega * sin(t)
|
// dc/dt = -omega * sin(t)
|
||||||
// ds/dt = omega * cos(t)
|
// ds/dt = omega * cos(t)
|
||||||
@@ -237,6 +272,7 @@ IntegrateRotation :: proc "c" (q1: Rot, deltaAngle: f32) -> Rot {
|
|||||||
// @param q1 initial rotation
|
// @param q1 initial rotation
|
||||||
// @param q2 final rotation
|
// @param q2 final rotation
|
||||||
// @param inv_h inverse time step
|
// @param inv_h inverse time step
|
||||||
|
@(require_results)
|
||||||
ComputeAngularVelocity :: proc "c" (q1: Rot, q2: Rot, inv_h: f32) -> f32 {
|
ComputeAngularVelocity :: proc "c" (q1: Rot, q2: Rot, inv_h: f32) -> f32 {
|
||||||
// ds/dt = omega * cos(t)
|
// ds/dt = omega * cos(t)
|
||||||
// dc/dt = -omega * sin(t)
|
// dc/dt = -omega * sin(t)
|
||||||
@@ -253,22 +289,26 @@ ComputeAngularVelocity :: proc "c" (q1: Rot, q2: Rot, inv_h: f32) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the angle in radians in the range [-pi, pi]
|
// Get the angle in radians in the range [-pi, pi]
|
||||||
|
@(require_results)
|
||||||
Rot_GetAngle :: proc "c" (q: Rot) -> f32 {
|
Rot_GetAngle :: proc "c" (q: Rot) -> f32 {
|
||||||
// todo determinism
|
// todo determinism
|
||||||
return math.atan2(q.s, q.c)
|
return math.atan2(q.s, q.c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the x-axis
|
// Get the x-axis
|
||||||
|
@(require_results)
|
||||||
Rot_GetXAxis :: proc "c" (q: Rot) -> Vec2 {
|
Rot_GetXAxis :: proc "c" (q: Rot) -> Vec2 {
|
||||||
return {q.c, q.s}
|
return {q.c, q.s}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the y-axis
|
// Get the y-axis
|
||||||
|
@(require_results)
|
||||||
Rot_GetYAxis :: proc "c" (q: Rot) -> Vec2 {
|
Rot_GetYAxis :: proc "c" (q: Rot) -> Vec2 {
|
||||||
return {-q.s, q.c}
|
return {-q.s, q.c}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Multiply two rotations: q * r
|
// Multiply two rotations: q * r
|
||||||
|
@(require_results)
|
||||||
MulRot :: proc "c" (q, r: Rot) -> (qr: Rot) {
|
MulRot :: proc "c" (q, r: Rot) -> (qr: Rot) {
|
||||||
// [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
|
// [qc -qs] * [rc -rs] = [qc*rc-qs*rs -qc*rs-qs*rc]
|
||||||
// [qs qc] [rs rc] [qs*rc+qc*rs -qs*rs+qc*rc]
|
// [qs qc] [rs rc] [qs*rc+qc*rs -qs*rs+qc*rc]
|
||||||
@@ -280,6 +320,7 @@ MulRot :: proc "c" (q, r: Rot) -> (qr: Rot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Transpose multiply two rotations: qT * r
|
// Transpose multiply two rotations: qT * r
|
||||||
|
@(require_results)
|
||||||
InvMulRot :: proc "c" (q, r: Rot) -> (qr: Rot) {
|
InvMulRot :: proc "c" (q, r: Rot) -> (qr: Rot) {
|
||||||
// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
|
// [ qc qs] * [rc -rs] = [qc*rc+qs*rs -qc*rs+qs*rc]
|
||||||
// [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc]
|
// [-qs qc] [rs rc] [-qs*rc+qc*rs qs*rs+qc*rc]
|
||||||
@@ -291,6 +332,7 @@ InvMulRot :: proc "c" (q, r: Rot) -> (qr: Rot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// relative angle between b and a (rot_b * inv(rot_a))
|
// relative angle between b and a (rot_b * inv(rot_a))
|
||||||
|
@(require_results)
|
||||||
RelativeAngle :: proc "c" (b, a: Rot) -> f32 {
|
RelativeAngle :: proc "c" (b, a: Rot) -> f32 {
|
||||||
// sin(b - a) = bs * ac - bc * as
|
// sin(b - a) = bs * ac - bc * as
|
||||||
// cos(b - a) = bc * ac + bs * as
|
// cos(b - a) = bc * ac + bs * as
|
||||||
@@ -300,6 +342,7 @@ RelativeAngle :: proc "c" (b, a: Rot) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert an angle in the range [-2*pi, 2*pi] into the range [-pi, pi]
|
// Convert an angle in the range [-2*pi, 2*pi] into the range [-pi, pi]
|
||||||
|
@(require_results)
|
||||||
UnwindAngle :: proc "c" (angle: f32) -> f32 {
|
UnwindAngle :: proc "c" (angle: f32) -> f32 {
|
||||||
if angle < -pi {
|
if angle < -pi {
|
||||||
return angle + 2.0 * pi
|
return angle + 2.0 * pi
|
||||||
@@ -310,16 +353,19 @@ UnwindAngle :: proc "c" (angle: f32) -> f32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Rotate a vector
|
// Rotate a vector
|
||||||
|
@(require_results)
|
||||||
RotateVector :: proc "c" (q: Rot, v: Vec2) -> Vec2 {
|
RotateVector :: proc "c" (q: Rot, v: Vec2) -> Vec2 {
|
||||||
return {q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y}
|
return {q.c * v.x - q.s * v.y, q.s * v.x + q.c * v.y}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inverse rotate a vector
|
// Inverse rotate a vector
|
||||||
|
@(require_results)
|
||||||
InvRotateVector :: proc "c" (q: Rot, v: Vec2) -> Vec2 {
|
InvRotateVector :: proc "c" (q: Rot, v: Vec2) -> Vec2 {
|
||||||
return {q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y}
|
return {q.c * v.x + q.s * v.y, -q.s * v.x + q.c * v.y}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform a point (e.g. local space to world space)
|
// Transform a point (e.g. local space to world space)
|
||||||
|
@(require_results)
|
||||||
TransformPoint :: proc "c" (t: Transform, p: Vec2) -> Vec2 {
|
TransformPoint :: proc "c" (t: Transform, p: Vec2) -> Vec2 {
|
||||||
x := (t.q.c * p.x - t.q.s * p.y) + t.p.x
|
x := (t.q.c * p.x - t.q.s * p.y) + t.p.x
|
||||||
y := (t.q.s * p.x + t.q.c * p.y) + t.p.y
|
y := (t.q.s * p.x + t.q.c * p.y) + t.p.y
|
||||||
@@ -327,6 +373,7 @@ TransformPoint :: proc "c" (t: Transform, p: Vec2) -> Vec2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Inverse transform a point (e.g. world space to local space)
|
// Inverse transform a point (e.g. world space to local space)
|
||||||
|
@(require_results)
|
||||||
InvTransformPoint :: proc "c" (t: Transform, p: Vec2) -> Vec2 {
|
InvTransformPoint :: proc "c" (t: Transform, p: Vec2) -> Vec2 {
|
||||||
vx := p.x - t.p.x
|
vx := p.x - t.p.x
|
||||||
vy := p.y - t.p.y
|
vy := p.y - t.p.y
|
||||||
@@ -335,6 +382,7 @@ InvTransformPoint :: proc "c" (t: Transform, p: Vec2) -> Vec2 {
|
|||||||
|
|
||||||
// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p
|
// v2 = A.q.Rot(B.q.Rot(v1) + B.p) + A.p
|
||||||
// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p
|
// = (A.q * B.q).Rot(v1) + A.q.Rot(B.p) + A.p
|
||||||
|
@(require_results)
|
||||||
MulTransforms :: proc "c" (A, B: Transform) -> (C: Transform) {
|
MulTransforms :: proc "c" (A, B: Transform) -> (C: Transform) {
|
||||||
C.q = MulRot(A.q, B.q)
|
C.q = MulRot(A.q, B.q)
|
||||||
C.p = RotateVector(A.q, B.p) + A.p
|
C.p = RotateVector(A.q, B.p) + A.p
|
||||||
@@ -343,6 +391,7 @@ MulTransforms :: proc "c" (A, B: Transform) -> (C: Transform) {
|
|||||||
|
|
||||||
// v2 = A.q' * (B.q * v1 + B.p - A.p)
|
// v2 = A.q' * (B.q * v1 + B.p - A.p)
|
||||||
// = A.q' * B.q * v1 + A.q' * (B.p - A.p)
|
// = A.q' * B.q * v1 + A.q' * (B.p - A.p)
|
||||||
|
@(require_results)
|
||||||
InvMulTransforms :: proc "c" (A, B: Transform) -> (C: Transform) {
|
InvMulTransforms :: proc "c" (A, B: Transform) -> (C: Transform) {
|
||||||
C.q = InvMulRot(A.q, B.q)
|
C.q = InvMulRot(A.q, B.q)
|
||||||
C.p = InvRotateVector(A.q, B.p-A.p)
|
C.p = InvRotateVector(A.q, B.p-A.p)
|
||||||
@@ -350,11 +399,13 @@ InvMulTransforms :: proc "c" (A, B: Transform) -> (C: Transform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Multiply a 2-by-2 matrix times a 2D vector
|
// Multiply a 2-by-2 matrix times a 2D vector
|
||||||
|
@(deprecated="Prefer 'A * v'", require_results)
|
||||||
MulMV :: proc "c" (A: Mat22, v: Vec2) -> Vec2 {
|
MulMV :: proc "c" (A: Mat22, v: Vec2) -> Vec2 {
|
||||||
return A * v
|
return A * v
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the inverse of a 2-by-2 matrix
|
// Get the inverse of a 2-by-2 matrix
|
||||||
|
@(require_results)
|
||||||
GetInverse22 :: proc "c" (A: Mat22) -> Mat22 {
|
GetInverse22 :: proc "c" (A: Mat22) -> Mat22 {
|
||||||
a := A[0, 0]
|
a := A[0, 0]
|
||||||
b := A[0, 1]
|
b := A[0, 1]
|
||||||
@@ -373,6 +424,7 @@ GetInverse22 :: proc "c" (A: Mat22) -> Mat22 {
|
|||||||
|
|
||||||
// Solve A * x = b, where b is a column vector. This is more efficient
|
// Solve A * x = b, where b is a column vector. This is more efficient
|
||||||
// than computing the inverse in one-shot cases.
|
// than computing the inverse in one-shot cases.
|
||||||
|
@(require_results)
|
||||||
Solve22 :: proc "c" (A: Mat22, b: Vec2) -> Vec2 {
|
Solve22 :: proc "c" (A: Mat22, b: Vec2) -> Vec2 {
|
||||||
a11 := A[0, 0]
|
a11 := A[0, 0]
|
||||||
a12 := A[0, 1]
|
a12 := A[0, 1]
|
||||||
@@ -386,6 +438,7 @@ Solve22 :: proc "c" (A: Mat22, b: Vec2) -> Vec2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Does a fully contain b
|
// Does a fully contain b
|
||||||
|
@(require_results)
|
||||||
AABB_Contains :: proc "c" (a, b: AABB) -> bool {
|
AABB_Contains :: proc "c" (a, b: AABB) -> bool {
|
||||||
(a.lowerBound.x <= b.lowerBound.x) or_return
|
(a.lowerBound.x <= b.lowerBound.x) or_return
|
||||||
(a.lowerBound.y <= b.lowerBound.y) or_return
|
(a.lowerBound.y <= b.lowerBound.y) or_return
|
||||||
@@ -395,42 +448,49 @@ AABB_Contains :: proc "c" (a, b: AABB) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the center of the AABB.
|
// Get the center of the AABB.
|
||||||
|
@(require_results)
|
||||||
AABB_Center :: proc "c" (a: AABB) -> Vec2 {
|
AABB_Center :: proc "c" (a: AABB) -> Vec2 {
|
||||||
return {0.5 * (a.lowerBound.x + a.upperBound.x), 0.5 * (a.lowerBound.y + a.upperBound.y)}
|
return {0.5 * (a.lowerBound.x + a.upperBound.x), 0.5 * (a.lowerBound.y + a.upperBound.y)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the extents of the AABB (half-widths).
|
// Get the extents of the AABB (half-widths).
|
||||||
|
@(require_results)
|
||||||
AABB_Extents :: proc "c" (a: AABB) -> Vec2 {
|
AABB_Extents :: proc "c" (a: AABB) -> Vec2 {
|
||||||
return {0.5 * (a.upperBound.x - a.lowerBound.x), 0.5 * (a.upperBound.y - a.lowerBound.y)}
|
return {0.5 * (a.upperBound.x - a.lowerBound.x), 0.5 * (a.upperBound.y - a.lowerBound.y)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Union of two AABBs
|
// Union of two AABBs
|
||||||
|
@(require_results)
|
||||||
AABB_Union :: proc "c" (a, b: AABB) -> (c: AABB) {
|
AABB_Union :: proc "c" (a, b: AABB) -> (c: AABB) {
|
||||||
c.lowerBound.x = MinFloat(a.lowerBound.x, b.lowerBound.x)
|
c.lowerBound.x = min(a.lowerBound.x, b.lowerBound.x)
|
||||||
c.lowerBound.y = MinFloat(a.lowerBound.y, b.lowerBound.y)
|
c.lowerBound.y = min(a.lowerBound.y, b.lowerBound.y)
|
||||||
c.upperBound.x = MaxFloat(a.upperBound.x, b.upperBound.x)
|
c.upperBound.x = max(a.upperBound.x, b.upperBound.x)
|
||||||
c.upperBound.y = MaxFloat(a.upperBound.y, b.upperBound.y)
|
c.upperBound.y = max(a.upperBound.y, b.upperBound.y)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
Float_IsValid :: proc "c" (a: f32) -> bool {
|
Float_IsValid :: proc "c" (a: f32) -> bool {
|
||||||
math.is_nan(a) or_return
|
math.is_nan(a) or_return
|
||||||
math.is_inf(a) or_return
|
math.is_inf(a) or_return
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
Vec2_IsValid :: proc "c" (v: Vec2) -> bool {
|
Vec2_IsValid :: proc "c" (v: Vec2) -> bool {
|
||||||
(math.is_nan(v.x) || math.is_nan(v.y)) or_return
|
(math.is_nan(v.x) || math.is_nan(v.y)) or_return
|
||||||
(math.is_inf(v.x) || math.is_inf(v.y)) or_return
|
(math.is_inf(v.x) || math.is_inf(v.y)) or_return
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
Rot_IsValid :: proc "c" (q: Rot) -> bool {
|
Rot_IsValid :: proc "c" (q: Rot) -> bool {
|
||||||
(math.is_nan(q.s) || math.is_nan(q.c)) or_return
|
(math.is_nan(q.s) || math.is_nan(q.c)) or_return
|
||||||
(math.is_inf(q.s) || math.is_inf(q.c)) or_return
|
(math.is_inf(q.s) || math.is_inf(q.c)) or_return
|
||||||
return IsNormalized(q)
|
return IsNormalized(q)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
Normalize :: proc "c" (v: Vec2) -> Vec2 {
|
Normalize :: proc "c" (v: Vec2) -> Vec2 {
|
||||||
length := Length(v)
|
length := Length(v)
|
||||||
if length < 1e-23 {
|
if length < 1e-23 {
|
||||||
@@ -440,6 +500,7 @@ Normalize :: proc "c" (v: Vec2) -> Vec2 {
|
|||||||
return invLength * v
|
return invLength * v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
NormalizeChecked :: proc "odin" (v: Vec2) -> Vec2 {
|
NormalizeChecked :: proc "odin" (v: Vec2) -> Vec2 {
|
||||||
length := Length(v)
|
length := Length(v)
|
||||||
if length < 1e-23 {
|
if length < 1e-23 {
|
||||||
@@ -449,6 +510,7 @@ NormalizeChecked :: proc "odin" (v: Vec2) -> Vec2 {
|
|||||||
return invLength * v
|
return invLength * v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
GetLengthAndNormalize :: proc "c" (v: Vec2) -> (length: f32, vn: Vec2) {
|
GetLengthAndNormalize :: proc "c" (v: Vec2) -> (length: f32, vn: Vec2) {
|
||||||
length = Length(v)
|
length = Length(v)
|
||||||
if length < 1e-23 {
|
if length < 1e-23 {
|
||||||
|
|||||||
Reference in New Issue
Block a user