Created
February 10, 2020 22:17
-
-
Save MatthewBlanchard/bd5ca418ece13a62cc41576e800bcaf8 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(result, a) | |
ffi.copy(result, a, ffi.sizeof(mlml_vec3)) | |
end | |
function vec3.clone(a) | |
return vec3._clone(vec3.new(), a) | |
end | |
function vec3.unpack(a) | |
return a.x, a.y, a.z | |
end | |
function vec3.totable(a) | |
return {a.x, a.y, a.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_s(a, s, result) | |
result = result or vec3.new() | |
result.x = a.x + s | |
result.x = a.x + s | |
result.x = a.x + 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_s(a, s, result) | |
result = result or vec3.new() | |
result.x = a.x - s | |
result.x = a.x - s | |
result.x = a.x - s | |
return result | |
end | |
-- expects a scalar as the 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_v(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 | |
-- b expects a scalar | |
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_v(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) | |
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_s(b, a) | |
elseif type(b) == "number" then | |
return vec3.add_s(a, b) | |
else | |
return vec3.add(a, b) | |
end | |
end | |
function vec3_mt.__sub(a, b) | |
if type(a) == "number" then | |
return vec3.sub_s(b, a) | |
elseif type(b) == "number" then | |
return vec3.sub_s(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_v(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_v(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