Created
October 25, 2019 17:46
-
-
Save DoctorGester/a3f100dd6dfd979a6ee42b027bbf2c69 to your computer and use it in GitHub Desktop.
This file contains 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" | |
ffi.cdef [[ | |
void* malloc(size_t size); | |
typedef struct { | |
float x; | |
float y; | |
} vector; | |
]] | |
local storage_size = 1024 * 1024 | |
local storage = ffi.new("vector[?]", storage_size) | |
local storage_pointer = 0 | |
function vector(x, y) | |
if storage_pointer >= storage_size then | |
storage_pointer = storage_pointer + 1 | |
return ffi.new("vector", x or 0, y or 0) | |
end | |
local v = storage[storage_pointer] | |
storage_pointer = storage_pointer + 1 | |
v.x = x or 0 | |
v.y = y or 0 | |
return v | |
end | |
function get_storage_watermark() | |
return storage_pointer | |
end | |
function reset_vector_storage() | |
if storage_pointer >= storage_size then | |
print("WARNING: Storage size of", storage_size, "issued", storage_pointer - storage_size + 1, "extra elements") | |
end | |
storage_pointer = 0 | |
end | |
local vector_meta = { | |
__add = function(v1, v2) | |
return vector(v1.x + v2.x, v1.y + v2.y) | |
end, | |
__sub = function(v1, v2) | |
return vector(v1.x - v2.x, v1.y - v2.y) | |
end, | |
__mul = function(v1, v2) | |
if type(v1) == "number" then -- v2 is a vector | |
return vector(v1 * v2.x, v1 * v2.y) | |
elseif type(v2) == "number" then -- v1 is a vector | |
return vector(v1.x * v2, v1.y * v2) | |
end | |
return vector(v1.x * v2.x, v1.y * v2.y) | |
end, | |
__div = function(v1, v2) | |
if type(v1) == "number" then -- v2 is a vector | |
return vector(v1 / v2.x, v1 / v2.y) | |
elseif type(v2) == "number" then -- v1 is a vector | |
return vector(v1.x / v2, v1.y / v2) | |
end | |
return vector(v1.x / v2.x, v1.y / v2.y) | |
end, | |
__eq = function(v1, v2) | |
if v2 == nil then return false end | |
return v1.x == v2.x and v1.y == v2.y | |
end, | |
__unm = function(v) | |
return vector(-v.x, -v.y) | |
end, | |
__tostring = function(v) | |
return string.format("(%.2f, %.2f)", v.x, v.y) | |
end, | |
__index = { | |
persist = function(v) | |
return ffi.new("vector", v.x, v.y) | |
end, | |
set = function(target, source, second_value) | |
if second_value ~= nil then | |
target.x = source | |
target.y = second_value | |
else | |
target.x = source.x | |
target.y = source.y | |
end | |
end, | |
length = function(v) | |
return math.sqrt(v.x * v.x + v.y * v.y) | |
end, | |
normalize = function(v) | |
return v / v:length() | |
end, | |
dot = function(a, b) | |
return a.x * b.x + a.y * b.y | |
end, | |
unpack = function(v) | |
return v.x, v.y | |
end | |
} | |
} | |
ffi.metatype("vector", vector_meta) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment