]> git.lizzy.rs Git - hydra-dragonfire.git/blob - builtin/vector.lua
Implement sending of packets
[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 mt_vec2.__index = {
38         validate = function(self)
39                 assert(type(self.x) == "number")
40                 assert(type(self.y) == "number")
41                 return self
42         end
43 }
44
45 function vec2(a, b)
46         local o = {}
47
48         if type(a) == "number" then
49                 o.x = a
50                 o.y = b or a
51         else
52                 o.x = a.x
53                 o.y = a.y
54         end
55
56         setmetatable(o, mt_vec2)
57         return o:validate()
58 end
59
60 -- vec3
61
62 local mt_vec3 = arith_mt(function(op)
63         return [[
64                 if type(b) == "number" then
65                         return vec3(a.x ]] .. op.. [[ b, a.y ]] .. op .. [[ b, a.z ]] .. op .. [[ b)
66                 else
67                         return vec3(a.x ]] .. op.. [[ b.x, a.y ]] .. op.. [[ b.y, a.z ]] .. op.. [[ b.z)
68                 end
69         ]]
70 end)
71
72 function mt_vec3:__neg()
73         return vec3(-self.x, -self.y, -self.z)
74 end
75
76 function mt_vec3:__tostring()
77         return "(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")"
78 end
79
80 mt_vec3.__index = {
81         validate = function(self)
82                 assert(type(self.x) == "number")
83                 assert(type(self.y) == "number")
84                 assert(type(self.z) == "number")
85                 return self
86         end
87 }
88
89 function vec3(a, b, c)
90         local o = {}
91
92         if type(a) == "number" then
93                 o.x = a
94                 o.y = b or a
95                 o.z = c or a
96         else
97                 o.x = a.x
98                 o.y = a.y
99                 o.z = a.z
100         end
101
102         setmetatable(o, mt_vec3)
103         return o:validate()
104 end
105
106 -- box
107
108 local mt_box = arith_mt(function(op)
109         return "return box(a.min " .. op .. " b, a.max " .. op .. " b)"
110 end)
111
112 function mt_box:__neg()
113         return box(-self.min, -self.max)
114 end
115
116 function mt_box:__tostring()
117         return "[" .. self.min .. "; " .. self.max .. "]"
118 end
119
120 mt_box.__index = {
121         contains = function(a, b)
122                 if type(b) == "number" or b.x then
123                         return a.min <= b and a.max >= b
124                 else
125                         return a.min <= b.min and a.max >= b.max
126                 end
127         end,
128         validate = function(self)
129                 if type(self.min) == "number" then
130                         assert(type(self.max) == "number")
131                 else
132                         assert(not self.min.z == not self.max.z)
133                         self.min:validate()
134                         self.max:validate()
135                 end
136         end,
137 }
138
139 function box(a, b)
140         local o = {}
141
142         if type(a) == "number" or a.x then
143                 o.min = a
144                 o.max = b
145         else
146                 o.min = a.min
147                 o.max = a.max
148         end
149
150         setmetatable(o, mt_box)
151         return o:validate()
152 end