1 --[[ builtin/vector.lua ]]--
3 local function wrap(op, body_wrapper, ...)
4 return loadstring("return function(a, b) " .. body_wrapper(op, ...) .. "end")()
7 local function arith_mt(...)
9 __add = wrap("+", ...),
10 __sub = wrap("-", ...),
11 __mul = wrap("*", ...),
12 __div = wrap("/", ...),
13 __mod = wrap("%", ...),
19 local mt_vec2 = arith_mt(function(op)
21 if type(b) == "number" then
22 return vec2(a.x ]] .. op.. [[ b, a.y ]] .. op .. [[ b)
24 return vec2(a.x ]] .. op.. [[ b.x, a.y ]] .. op.. [[ b.y)
29 function mt_vec2:__neg()
30 return vec2(-self.x, -self.y)
33 function mt_vec2:__len()
34 return math.sqrt(self.x ^ 2 + self.y ^ 2)
37 function mt_vec2:__tostring()
38 return "(" .. self.x .. ", " .. self.y .. ")"
42 validate = function(self)
43 assert(type(self.x) == "number")
44 assert(type(self.y) == "number")
47 round = function(self)
48 return vec2(math.round(self.x), math.round(self.y))
55 if type(a) == "number" then
63 setmetatable(o, mt_vec2)
69 local mt_vec3 = arith_mt(function(op)
71 if type(b) == "number" then
72 return vec3(a.x ]] .. op.. [[ b, a.y ]] .. op .. [[ b, a.z ]] .. op .. [[ b)
74 return vec3(a.x ]] .. op.. [[ b.x, a.y ]] .. op.. [[ b.y, a.z ]] .. op.. [[ b.z)
79 function mt_vec3:__neg()
80 return vec3(-self.x, -self.y, -self.z)
83 function mt_vec3:__len()
84 return math.sqrt(self.x ^ 2 + self.y ^ 2 + self.z ^ 2)
87 function mt_vec3:__tostring()
88 return "(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")"
92 validate = function(self)
93 assert(type(self.x) == "number")
94 assert(type(self.y) == "number")
95 assert(type(self.z) == "number")
98 round = function(self)
99 return vec3(math.floor(self.x), math.floor(self.y), math.floor(self.z))
103 function vec3(a, b, c)
106 if type(a) == "number" then
116 setmetatable(o, mt_vec3)
122 local mt_box = arith_mt(function(op)
123 return "return box(a.min " .. op .. " b, a.max " .. op .. " b)"
126 function mt_box:__neg()
127 return box(-self.min, -self.max)
130 function mt_box:__tostring()
131 return "[" .. self.min .. "; " .. self.max .. "]"
135 contains = function(a, b)
136 if type(b) == "number" or b.x then
137 return a.min <= b and a.max >= b
139 return a.min <= b.min and a.max >= b.max
142 validate = function(self)
143 if type(self.min) == "number" then
144 assert(type(self.max) == "number")
146 assert(not self.min.z == not self.max.z)
156 if type(a) == "number" or a.x then
164 setmetatable(o, mt_box)