Created
February 14, 2020 02:53
-
-
Save MatthewBlanchard/af0c27d971279a3e495dc176731d79f8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local ffi = require "ffi" | |
local sqrt = math.sqrt | |
ffi.cdef [[ | |
typedef struct { | |
double x, y, z; | |
} mlml_vec3; | |
]] | |
local vec3 = {} | |
local mlml_vec3 = ffi.typeof("mlml_vec3") | |
vec3.new = mlml_vec3 | |
function vec3.clone(a, result) | |
result = result or vec3.new() | |
ffi.copy(result, a, ffi.sizeof(mlml_vec3)) | |
return result | |
end | |
function vec3.new_array(n) | |
return ffi.new("mlml_vec3[?]", n) | |
end | |
function vec3.unpack(a) | |
return a.x, a.y, a.z | |
end | |
function vec3.to_table(a) | |
return {x = a.x, y = a.y, z = a.z} | |
end | |
function vec3.to_flat_table(a) | |
return {a.x, a.y, a.z} | |
end | |
function vec3.from_table(t) | |
return vec3.new(t.x, t.y, t.z) | |
end | |
-- a, left operand | |
-- b, right operand | |
-- [result], output vector to store results in | |
-- returns the component-wise addition of two vectors | |
function vec3.add(a, b, result) | |
result = result or vec3.new() | |
result.x = a.x + b.x | |
result.y = a.y + b.y | |
result.z = a.z + b.z | |
return result | |
end | |
-- accepts a scalar as the right hand operand | |
function vec3.add_scalar(a, s, result) | |
result = result or vec3.new() | |
result.x = a.x + s | |
result.y = a.y + s | |
result.z = a.z + s | |
return result | |
end | |
function vec3.sub(a, b, result) | |
result = result or vec3.new() | |
result.x = a.x - b.x | |
result.y = a.y - b.y | |
result.z = a.z - b.z | |
return result | |
end | |
function vec3.sub_scalar(a, s, result) | |
result = result or vec3.new() | |
result.x = a.x - s | |
result.y = a.y - s | |
result.z = a.z - s | |
return result | |
end | |
-- scalar as right hand operand | |
function vec3.mul(a, s, result) | |
result = result or vec3.new() | |
result.x = a.x * s | |
result.y = a.y * s | |
result.z = a.z * s | |
return result | |
end | |
function vec3.mul_vec3(a, b, result) | |
result = result or vec3.new() | |
result.x = a.x * b.x | |
result.y = a.y * b.y | |
result.z = a.z * b.z | |
return result | |
end | |
-- scalar as right hand operand | |
function vec3.div(a, s, result) | |
result = result or vec3.new() | |
result.x = a.x / s | |
result.y = a.y / s | |
result.z = a.z / s | |
return result | |
end | |
function vec3.div_vec3(a, b, result) | |
result = result or vec3.new() | |
result.x = a.x / b.x | |
result.y = a.y / b.y | |
result.z = a.z / b.z | |
return result | |
end | |
function vec3.cross(a, b, result) | |
result = result or vec3.new() | |
result.x = a.y*b.z - a.z*b.y | |
result.y = a.z*b.x - a.x*b.z | |
result.z = a.x*b.y - a.y*b.x | |
return result | |
end | |
function vec3.normalize(a, result) | |
result = result or vec3.new() | |
local l = vec3.len(a) | |
if l == 0 then l = 1 end | |
result.x, result.y, result.z = a.x / l, a.y / l, a.z / l | |
return result | |
end | |
function vec3.equality(a, b) | |
return a.x == b.x and a.y == b.y and a.z == b.z | |
end | |
function vec3.dot(a, b) | |
return a.x * b.x + a.y * b.y + a.z * b.z | |
end | |
function vec3.len(a) | |
return sqrt(a.x * a.x + a.y * a.y + a.z * a.z) | |
end | |
function vec3.dist(a, b) | |
local dx = a.x - b.x | |
local dy = a.y - b.y | |
local dz = a.z - b.z | |
return sqrt(dx * dx + dy * dy + dz * dz) | |
end | |
function vec3.dist2(a, b) | |
local dx = a.x - b.x | |
local dy = a.y - b.y | |
local dz = a.z - b.z | |
return (dx * dx + dy * dy + dz * dz) | |
end | |
function vec3.lerp(a, b, s) | |
return a + s * (b - a) | |
end | |
function vec3.tostring(a) | |
return string.format("(%+0.3f,%+0.3f,%+0.3f)", a.x, a.y, a.z) | |
end | |
local vec3_mt = {} | |
vec3_mt.__index = vec3 | |
vec3_mt.__call = vec3.new | |
vec3_mt.__tostring = vec3.tostring | |
function vec3_mt.__unm(a) | |
return vec3.new(-a.x, -a.y, -a.z) | |
end | |
function vec3_mt.__eq(a,b) | |
return vec3.equality(a, b) | |
end | |
function vec3_mt.__add(a, b) | |
if type(a) == "number" then | |
return vec3.add_scalar(b, a) | |
elseif type(b) == "number" then | |
return vec3.add_scalar(a, b) | |
else | |
return vec3.add(a, b) | |
end | |
end | |
function vec3_mt.__sub(a, b) | |
if type(a) == "number" then | |
return vec3.sub_scalar(b, a) | |
elseif type(b) == "number" then | |
return vec3.sub_scalar(a, b) | |
else | |
return vec3.sub(a, b) | |
end | |
end | |
function vec3_mt.__mul(a, b) | |
if type(a) == "number" then | |
return vec3.mul(b, a) | |
elseif type(b) == "number" then | |
return vec3.mul(a, b) | |
else | |
return vec3.mul_vec3(a, b) | |
end | |
end | |
function vec3_mt.__div(a, b) | |
if type(a) == "number" then | |
return vec3.div(b, a) | |
elseif type(b) == "number" then | |
return vec3.div(a, b) | |
else | |
return vec3.div_vec3(a, b) | |
end | |
end | |
ffi.metatype(mlml_vec3, vec3_mt) | |
return setmetatable({}, vec3_mt) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment