]> git.lizzy.rs Git - hydra-dragonfire.git/blob - builtin/vector.lua
95e1ebd3c8948bb17eada814426ea370a31043b6
[hydra-dragonfire.git] / builtin / vector.lua
1 --[[ builtin/vector.lua ]]--
2
3 local function wrap(op, body_wrapper, ...)
4         return loadstring("return function(a, b) " .. body_wrapper(op, ...) .. "end")()
5 end
6
7 local function arith_mt(...)
8         return {
9                 __add = wrap("+", ...),
10                 __sub = wrap("-", ...),
11                 __mul = wrap("*", ...),
12                 __div = wrap("/", ...),
13                 __mod = wrap("%", ...),
14         }
15 end
16
17 -- vec2
18
19 local mt_vec2 = arith_mt(function(op)
20         return [[
21                 if type(b) == "number" then
22                         return vec2(a.x ]] .. op.. [[ b, a.y ]] .. op .. [[ b)
23                 else
24                         return vec2(a.x ]] .. op.. [[ b.x, a.y ]] .. op.. [[ b.y)
25                 end
26         ]]
27 end)
28
29 function mt_vec2:__neg()
30         return vec2(-self.x, -self.y)
31 end
32
33 function mt_vec2:__tostring()
34         return "(" .. self.x .. ", " .. self.y .. ")"
35 end
36
37 function vec2(a, b)
38         local o = {}
39
40         if type(a) == "number" then
41                 o.x = a
42                 o.y = b or a
43         else
44                 o.x = a.x
45                 o.y = a.y
46         end
47
48         setmetatable(o, mt_vec2)
49         return o
50 end
51
52 -- vec3
53
54 local mt_vec3 = arith_mt(function(op)
55         return [[
56                 if type(b) == "number" then
57                         return vec3(a.x ]] .. op.. [[ b, a.y ]] .. op .. [[ b, a.z ]] .. op .. [[ b)
58                 else
59                         return vec3(a.x ]] .. op.. [[ b.x, a.y ]] .. op.. [[ b.y, a.z ]] .. op.. [[ b.z)
60                 end     
61         ]]
62 end)
63
64 function mt_vec3:__neg()
65         return vec3(-self.x, -self.y, -self.z)
66 end
67
68 function mt_vec3:__tostring()
69         return "(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")"
70 end
71
72 function vec3(a, b, c)
73         local o = {}
74
75         if type(a) == "number" then
76                 o.x = a
77                 o.y = b or a
78                 o.z = c or a
79         else
80                 o.x = a.x
81                 o.y = a.y
82                 o.z = a.z
83         end
84
85         setmetatable(o, mt_vec3)
86         return o
87 end
88
89 -- box
90
91 local mt_box = arith_mt(function(op)
92         return "return box(a.min " .. op .. " b, a.max " .. op .. " b)"
93 end)
94
95 function mt_box:__neg()
96         return box(-self.min, -self.max)
97 end
98
99 function mt_box:__tostring()
100         return "[" .. self.min .. "; " .. self.max .. "]"
101 end
102
103 mt_box.__index = {
104         contains = function(a, b)
105                 if type(b) == "number" or b.x then
106                         return a.min <= b and a.max >= b
107                 else
108                         return a.min <= b.min and a.max >= b.max
109                 end
110         end,
111 }
112
113 function box(a, b)
114         local o = {}
115
116         if type(a) == "number" or a.x then
117                 o.min = a
118                 o.max = b
119         else
120                 o.min = a.min
121                 o.max = a.max
122         end
123
124         setmetatable(o, mt_box)
125         return o
126 end