2021-02-15 14:40:28 +01:00
|
|
|
/**********************************************************************
|
|
|
|
*
|
|
|
|
* Simply vector/matrix utility
|
|
|
|
*
|
|
|
|
* Copyright (c) 2021 Dario Deledda. All rights reserved.
|
|
|
|
* Use of this source code is governed by an MIT license
|
|
|
|
* that can be found in the LICENSE file.
|
|
|
|
*
|
|
|
|
* TODO:
|
|
|
|
**********************************************************************/
|
|
|
|
module m4
|
|
|
|
|
|
|
|
import math
|
|
|
|
|
|
|
|
pub struct Vec4 {
|
|
|
|
pub mut:
|
|
|
|
e [4]f32
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Utility
|
|
|
|
*
|
|
|
|
*********************************************************************/
|
|
|
|
pub fn (x Vec4) str() string {
|
|
|
|
return '|${x.e[0]:-6.3},${x.e[1]:-6.3},${x.e[2]:-6.3},${x.e[3]:-6.3}|\n'
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove all the raw zeros
|
|
|
|
[direct_array_access]
|
|
|
|
pub fn (a Vec4) clean() Vec4 {
|
2021-03-03 09:20:13 +01:00
|
|
|
mut x := Vec4{}
|
|
|
|
for c, value in a.e {
|
|
|
|
if abs(value) < precision {
|
|
|
|
x.e[c] = 0
|
|
|
|
} else {
|
|
|
|
x.e[c] = value
|
2021-02-15 14:40:28 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-03 09:20:13 +01:00
|
|
|
return x
|
2021-02-15 14:40:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Set all elements to value
|
|
|
|
pub fn (mut x Vec4) copy(value f32) {
|
|
|
|
x.e = [ value, value, value, value, ]!
|
|
|
|
}
|
|
|
|
|
|
|
|
// Scale the vector using a scalar
|
|
|
|
pub fn (x Vec4) mul_scalar(value f32) Vec4 {
|
|
|
|
return Vec4{ e: [ x.e[0] * value, x.e[1] * value, x.e[2] * value, x.e[3] * value, ]! }
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reciprocal of the vector
|
|
|
|
pub fn (x Vec4) inv() Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
if x.e[0] != 0 { 1.0 / x.e[0] } else { f32(0) },
|
|
|
|
if x.e[1] != 0 { 1.0 / x.e[1] } else { f32(0) },
|
|
|
|
if x.e[2] != 0 { 1.0 / x.e[2] } else { f32(0) },
|
|
|
|
if x.e[3] != 0 { 1.0 / x.e[3] } else { f32(0) },
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Normalize the vector
|
|
|
|
pub fn (x Vec4) normalize() Vec4 {
|
|
|
|
m := x.mod()
|
|
|
|
if m == 0 {
|
|
|
|
return zero_v4()
|
|
|
|
}
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
x.e[0] * (1 / m),
|
|
|
|
x.e[1] * (1 / m),
|
|
|
|
x.e[2] * (1 / m),
|
|
|
|
x.e[3] * (1 / m),
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Normalize only xyz, w set to 0
|
|
|
|
pub fn (x Vec4) normalize3() Vec4 {
|
|
|
|
m := x.mod3()
|
|
|
|
if m == 0 {
|
|
|
|
return zero_v4()
|
|
|
|
}
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
x.e[0] * (1 / m),
|
|
|
|
x.e[1] * (1 / m),
|
|
|
|
x.e[2] * (1 / m),
|
|
|
|
0,
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Module of the vector xyzw
|
|
|
|
pub fn (x Vec4) mod() f32 {
|
|
|
|
return f32(math.sqrt(x.e[0] * x.e[0] + x.e[1] * x.e[1] + x.e[2] * x.e[2] + x.e[3] * x.e[3]))
|
|
|
|
}
|
|
|
|
|
|
|
|
// Module for 3d vector xyz, w ignored
|
|
|
|
pub fn (x Vec4) mod3() f32 {
|
|
|
|
return f32(math.sqrt(x.e[0] * x.e[0] + x.e[1] * x.e[1] + x.e[2] * x.e[2]))
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Math
|
|
|
|
*
|
|
|
|
*********************************************************************/
|
|
|
|
// Return a zero vector
|
|
|
|
pub fn zero_v4() Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
f32(0),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return all one vector
|
|
|
|
pub fn one_v4() Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
f32(1),
|
|
|
|
1,
|
|
|
|
1,
|
|
|
|
1,
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return a blank vector
|
|
|
|
pub fn blank_v4() Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
f32(0),
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
1,
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Set all elements to value
|
|
|
|
pub fn set_v4(value f32) Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
value,
|
|
|
|
value,
|
|
|
|
value,
|
|
|
|
value,
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sum of all the elements
|
|
|
|
pub fn (x Vec4) sum() f32 {
|
|
|
|
return x.e[0] + x.e[1] + x.e[2] + x.e[3]
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************************************************************
|
|
|
|
*
|
|
|
|
* Operators
|
|
|
|
*
|
|
|
|
*********************************************************************/
|
|
|
|
// Addition
|
|
|
|
pub fn (a Vec4) + (b Vec4) Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
a.e[0] + b.e[0],
|
|
|
|
a.e[1] + b.e[1],
|
|
|
|
a.e[2] + b.e[2],
|
|
|
|
a.e[3] + b.e[3],
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subtraction
|
|
|
|
pub fn (a Vec4) - (b Vec4) Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
a.e[0] - b.e[0],
|
|
|
|
a.e[1] - b.e[1],
|
|
|
|
a.e[2] - b.e[2],
|
|
|
|
a.e[3] - b.e[3],
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Dot product
|
|
|
|
pub fn (a Vec4) * (b Vec4) f32 {
|
|
|
|
return a.e[0] * b.e[0] + a.e[1] * b.e[1] + a.e[2] * b.e[2] + a.e[3] * b.e[3]
|
|
|
|
}
|
|
|
|
|
|
|
|
// Cross product
|
|
|
|
pub fn (a Vec4) % (b Vec4) Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
(a.e[1] * b.e[2]) - (a.e[2] * b.e[1]),
|
|
|
|
(a.e[2] * b.e[0]) - (a.e[0] * b.e[2]),
|
|
|
|
(a.e[0] * b.e[1]) - (a.e[1] * b.e[0]),
|
|
|
|
0,
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Components multiplication
|
|
|
|
pub fn (x Vec4) mul_vec4(y Vec4) Vec4 {
|
|
|
|
return Vec4{
|
|
|
|
e: [
|
|
|
|
x.e[0] * y.e[0],
|
|
|
|
x.e[1] * y.e[1],
|
|
|
|
x.e[2] * y.e[2],
|
|
|
|
x.e[3] * y.e[3],
|
|
|
|
]!
|
|
|
|
}
|
|
|
|
}
|