Mercurial > games > semicongine
comparison semiconginev2/core/vector.nim @ 1218:56781cc0fc7c compiletime-tests
did: renamge main package
author | sam <sam@basx.dev> |
---|---|
date | Wed, 17 Jul 2024 21:01:37 +0700 |
parents | semicongine/core/vector.nim@a3eb305bcac2 |
children | c4f98eb4bb05 |
comparison
equal
deleted
inserted
replaced
1217:f819a874058f | 1218:56781cc0fc7c |
---|---|
1 | |
2 type | |
3 TVec1*[T: SomeNumber] = array[1, T] | |
4 TVec2*[T: SomeNumber] = array[2, T] | |
5 TVec3*[T: SomeNumber] = array[3, T] | |
6 TVec4*[T: SomeNumber] = array[4, T] | |
7 TVec* = TVec1|TVec2|TVec3|TVec4 | |
8 Vec1f* = TVec1[float32] | |
9 Vec2f* = TVec2[float32] | |
10 Vec3f* = TVec3[float32] | |
11 Vec4f* = TVec4[float32] | |
12 Vec1i* = TVec1[int32] | |
13 Vec2i* = TVec2[int32] | |
14 Vec3i* = TVec3[int32] | |
15 Vec4i* = TVec4[int32] | |
16 Vec1u* = TVec1[uint32] | |
17 Vec2u* = TVec2[uint32] | |
18 Vec3u* = TVec3[uint32] | |
19 Vec4u* = TVec4[uint32] | |
20 | |
21 converter ToVec1*[T: SomeNumber](orig: TVec3[T]|TVec4[T]): TVec1[T] = | |
22 TVec1[T]([orig[0]]) | |
23 converter ToVec2*[T: SomeNumber](orig: TVec3[T]|TVec4[T]): TVec2[T] = | |
24 TVec2[T]([orig[0], orig[1]]) | |
25 converter ToVec3*[T: SomeNumber](orig: TVec4[T]): TVec3[T] = | |
26 TVec3[T]([orig[0], orig[1], orig[2]]) | |
27 | |
28 func ToVec4*[T: SomeNumber](orig: TVec3[T], value: T = default(T)): TVec4[T] = | |
29 TVec4[T]([orig[0], orig[1], orig[2], value]) | |
30 func ToVec3*[T: SomeNumber](orig: TVec2[T], value: T = default(T)): TVec3[T] = | |
31 TVec3[T]([orig[0], orig[1], value]) | |
32 func ToVec2*[T: SomeNumber](orig: TVec1[T], value: T = default(T)): TVec2[T] = | |
33 TVec2[T]([orig[0], value]) | |
34 | |
35 # define some often used constants | |
36 func ConstOne1[T: SomeNumber](): auto {.compiletime.} = TVec1[T]([T(1)]) | |
37 func ConstOne2[T: SomeNumber](): auto {.compiletime.} = TVec2[T]([T(1), T(1)]) | |
38 func ConstOne3[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(1), T(1), T(1)]) | |
39 func ConstOne4[T: SomeNumber](): auto {.compiletime.} = TVec4[T]([T(1), T(1), T(1), T(1)]) | |
40 func ConstX[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(1), T(0), T(0)]) | |
41 func ConstY[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(0), T(1), T(0)]) | |
42 func ConstZ[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(0), T(0), T(1)]) | |
43 func ConstR[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(1), T(0), T(0)]) | |
44 func ConstG[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(0), T(1), T(0)]) | |
45 func ConstB[T: SomeNumber](): auto {.compiletime.} = TVec3[T]([T(0), T(0), T(1)]) | |
46 | |
47 func NewVec2f*(x = 0'f32, y = 0'f32): auto = | |
48 Vec2f([x, y]) | |
49 func NewVec3f*(x = 0'f32, y = 0'f32, z = 0'f32): auto = | |
50 Vec3f([x, y, z]) | |
51 func NewVec4f*(x = 0'f32, y = 0'f32, z = 0'f32, a = 0'f32): auto = | |
52 Vec4f([x, y, z, a]) | |
53 func NewVec2i*(x = 0'i32, y = 0'i32): auto = | |
54 Vec2i([x, y]) | |
55 func NewVec3i*(x = 0'i32, y = 0'i32, z = 0'i32): auto = | |
56 Vec3i([x, y, z]) | |
57 func NewVec4i*(x = 0'i32, y = 0'i32, z = 0'i32, a = 0'i32): auto = | |
58 Vec4i([x, y, z, a]) | |
59 func NewVec2u*(x = 0'u32, y = 0'u32): auto = | |
60 Vec2u([x, y]) | |
61 func NewVec3u*(x = 0'u32, y = 0'u32, z = 0'u32): auto = | |
62 Vec3u([x, y, z]) | |
63 func NewVec4u*(x = 0'u32, y = 0'u32, z = 0'u32, a = 0'u32): auto = | |
64 Vec4u([x, y, z, a]) | |
65 | |
66 # generates constants: Xf, Xf32, Xf64, Xi, Xi8, Xi16, Xi32, Xi64 | |
67 # Also for Y, Z, R, G, B and One | |
68 # not sure if this is necessary or even a good idea... | |
69 macro generateAllVectorConsts() = | |
70 result = newStmtList() | |
71 for component in ["X", "Y", "Z", "R", "G", "B", "One2", "One3", "One4"]: | |
72 for theType in ["int", "int8", "int16", "int32", "int64", "float", "float32", "float64"]: | |
73 var typename = theType[0 .. 0] | |
74 if theType[^2].isDigit: | |
75 typename = typename & theType[^2] | |
76 if theType[^1].isDigit: | |
77 typename = typename & theType[^1] | |
78 result.add( | |
79 newConstStmt( | |
80 postfix(ident(component & typename), "*"), | |
81 newCall(nnkBracketExpr.newTree(ident("Const" & component), ident(theType))) | |
82 ) | |
83 ) | |
84 | |
85 generateAllVectorConsts() | |
86 | |
87 const X* = ConstX[float32]() | |
88 const Y* = ConstY[float32]() | |
89 const Z* = ConstZ[float32]() | |
90 const One1* = ConstOne1[float32]() | |
91 const One2* = ConstOne2[float32]() | |
92 const One3* = ConstOne3[float32]() | |
93 const One4* = ConstOne4[float32]() | |
94 | |
95 func NewVec1*[T](x: T): auto = TVec1([x]) | |
96 func NewVec2*[T](x, y: T): auto = TVec2([x, y]) | |
97 func NewVec3*[T](x, y, z: T): auto = TVec3([x, y, z]) | |
98 func NewVec4*[T](x, y, z, w: T): auto = TVec4([x, y, z, w]) | |
99 | |
100 func To*[T](v: TVec1): auto = TVec1([T(v[0])]) | |
101 func To*[T](v: TVec2): auto = TVec2([T(v[0]), T(v[1])]) | |
102 func To*[T](v: TVec3): auto = TVec3([T(v[0]), T(v[1]), T(v[2])]) | |
103 func To*[T](v: TVec4): auto = TVec4([T(v[0]), T(v[1]), T(v[2]), T(v[3])]) | |
104 | |
105 func toString[T: TVec](value: T): string = | |
106 var items: seq[string] | |
107 for item in value: | |
108 items.add(&"{item.float:.5f}") | |
109 & "(" & join(items, " ") & ")" | |
110 | |
111 func `$`*(v: TVec1[SomeNumber]): string = toString[TVec1[SomeNumber]](v) | |
112 func `$`*(v: TVec2[SomeNumber]): string = toString[TVec2[SomeNumber]](v) | |
113 func `$`*(v: TVec3[SomeNumber]): string = toString[TVec3[SomeNumber]](v) | |
114 func `$`*(v: TVec4[SomeNumber]): string = toString[TVec4[SomeNumber]](v) | |
115 | |
116 func Length*(vec: TVec1): auto = vec[0] | |
117 func Length*(vec: TVec2[SomeFloat]): auto = sqrt(vec[0] * vec[0] + vec[1] * vec[1]) | |
118 func Length*(vec: TVec2[SomeInteger]): auto = sqrt(float(vec[0] * vec[0] + vec[1] * vec[1])) | |
119 func Length*(vec: TVec3[SomeFloat]): auto = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]) | |
120 func Length*(vec: TVec3[SomeInteger]): auto = sqrt(float(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2])) | |
121 func Length*(vec: TVec4[SomeFloat]): auto = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] + vec[3] * vec[3]) | |
122 func Length*(vec: TVec4[SomeInteger]): auto = sqrt(float(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2] + vec[3] * vec[3])) | |
123 | |
124 func Normal*[T: SomeFloat](vec: TVec2[T]): auto = | |
125 TVec2[T]([vec[1], -vec[0]]) | |
126 | |
127 func Normalized*[T: SomeFloat](vec: TVec1[T]): auto = | |
128 return T(1) | |
129 func Normalized*[T: SomeFloat](vec: TVec2[T]): auto = | |
130 let l = vec.Length | |
131 if l == 0: vec | |
132 else: TVec2[T]([vec[0] / l, vec[1] / l]) | |
133 func Normalized*[T: SomeFloat](vec: TVec3[T]): auto = | |
134 let l = vec.Length | |
135 if l == 0: return vec | |
136 else: TVec3[T]([vec[0] / l, vec[1] / l, vec[2] / l]) | |
137 func Normalized*[T: SomeFloat](vec: TVec4[T]): auto = | |
138 let l = vec.Length | |
139 if l == 0: return vec | |
140 else: TVec4[T]([vec[0] / l, vec[1] / l, vec[2] / l, vec[3] / l]) | |
141 | |
142 # scalar operations | |
143 func `+`*(a: TVec1, b: SomeNumber): auto = TVec1([a[0] + b]) | |
144 func `+`*(a: TVec2, b: SomeNumber): auto = TVec2([a[0] + b, a[1] + b]) | |
145 func `+`*(a: TVec3, b: SomeNumber): auto = TVec3([a[0] + b, a[1] + b, a[2] + b]) | |
146 func `+`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] + b, a[1] + b, a[2] + b, a[3] + b]) | |
147 func `-`*(a: TVec1, b: SomeNumber): auto = TVec1([a[0] - b]) | |
148 func `-`*(a: TVec2, b: SomeNumber): auto = TVec2([a[0] - b, a[1] - b]) | |
149 func `-`*(a: TVec3, b: SomeNumber): auto = TVec3([a[0] - b, a[1] - b, a[2] - b]) | |
150 func `-`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] - b, a[1] - b, a[2] - b, | |
151 a[3] - b]) | |
152 func `*`*(a: TVec1, b: SomeNumber): auto = TVec1([a[0] * b]) | |
153 func `*`*(a: TVec2, b: SomeNumber): auto = TVec2([a[0] * b, a[1] * b]) | |
154 func `*`*(a: TVec3, b: SomeNumber): auto = TVec3([a[0] * b, a[1] * b, a[2] * b]) | |
155 func `*`*(a: TVec4, b: SomeNumber): auto = TVec4([a[0] * b, a[1] * b, a[2] * b, | |
156 a[3] * b]) | |
157 func `/`*[T: SomeInteger](a: TVec1[T], b: SomeInteger): auto = TVec1([a[0] div b]) | |
158 func `/`*[T: SomeFloat](a: TVec1[T], b: SomeFloat): auto = TVec1([a[0] / b]) | |
159 func `/`*[T: SomeInteger](a: TVec2[T], b: SomeInteger): auto = TVec2([a[0] div b, a[1] div b]) | |
160 func `/`*[T: SomeFloat](a: TVec2[T], b: SomeFloat): auto = TVec2([a[0] / b, a[1] / b]) | |
161 func `/`*[T: SomeInteger](a: TVec3[T], b: SomeInteger): auto = TVec3([a[0] div b, a[1] div b, a[2] div b]) | |
162 func `/`*[T: SomeFloat](a: TVec3[T], b: SomeFloat): auto = TVec3([a[0] / b, a[1] / b, a[2] / b]) | |
163 func `/`*[T: SomeInteger](a: TVec4[T], b: SomeInteger): auto = TVec4([a[0] div b, a[1] div b, a[2] div b, a[3] div b]) | |
164 func `/`*[T: SomeFloat](a: TVec4[T], b: SomeFloat): auto = TVec4([a[0] / b, a[1] / b, a[2] / b, a[3] / b]) | |
165 | |
166 func `+`*(a: SomeNumber, b: TVec1): auto = TVec1([a + b[0]]) | |
167 func `+`*(a: SomeNumber, b: TVec2): auto = TVec2([a + b[0], a + b[1]]) | |
168 func `+`*(a: SomeNumber, b: TVec3): auto = TVec3([a + b[0], a + b[1], a + b[2]]) | |
169 func `+`*(a: SomeNumber, b: TVec4): auto = TVec4([a + b[0], a + b[1], a + b[2], a + b[3]]) | |
170 func `-`*(a: SomeNumber, b: TVec1): auto = TVec1([a - b[0]]) | |
171 func `-`*(a: SomeNumber, b: TVec2): auto = TVec2([a - b[0], a - b[1]]) | |
172 func `-`*(a: SomeNumber, b: TVec3): auto = TVec3([a - b[0], a - b[1], a - b[2]]) | |
173 func `-`*(a: SomeNumber, b: TVec4): auto = TVec4([a - b[0], a - b[1], a - b[2], a - b[3]]) | |
174 func `*`*(a: SomeNumber, b: TVec1): auto = TVec1([a * b[0]]) | |
175 func `*`*(a: SomeNumber, b: TVec2): auto = TVec2([a * b[0], a * b[1]]) | |
176 func `*`*(a: SomeNumber, b: TVec3): auto = TVec3([a * b[0], a * b[1], a * b[2]]) | |
177 func `*`*(a: SomeNumber, b: TVec4): auto = TVec4([a * b[0], a * b[1], a * b[2], a * b[3]]) | |
178 func `/`*[T: SomeInteger](a: SomeInteger, b: TVec1[T]): auto = TVec1([a div b[0]]) | |
179 func `/`*[T: SomeFloat](a: SomeFloat, b: TVec1[T]): auto = TVec1([a / b[0]]) | |
180 func `/`*[T: SomeInteger](a: SomeInteger, b: TVec2[T]): auto = TVec2([a div b[0], a div b[1]]) | |
181 func `/`*[T: SomeFloat](a: SomeFloat, b: TVec2[T]): auto = TVec2([a / b[0], a / b[1]]) | |
182 func `/`*[T: SomeInteger](a: SomeInteger, b: TVec3[T]): auto = TVec3([a div b[0], a div b[1], a div b[2]]) | |
183 func `/`*[T: SomeFloat](a: SomeFloat, b: TVec3[T]): auto = TVec3([a / b[0], a / b[1], a / b[2]]) | |
184 func `/`*[T: SomeInteger](a: SomeInteger, b: TVec4[T]): auto = TVec4([a div b[ | |
185 0], a div b[1], a div b[2], a div b[3]]) | |
186 func `/`*[T: SomeFloat](a: SomeFloat, b: TVec4[T]): auto = TVec4([a / b[0], a / | |
187 b[1], a / b[2], a / b[3]]) | |
188 | |
189 # compontent-wise operations | |
190 func `+`*(a, b: TVec1): auto = TVec1([a[0] + b[0]]) | |
191 func `+`*(a, b: TVec2): auto = TVec2([a[0] + b[0], a[1] + b[1]]) | |
192 func `+`*(a, b: TVec3): auto = TVec3([a[0] + b[0], a[1] + b[1], a[2] + b[2]]) | |
193 func `+`*(a, b: TVec4): auto = TVec4([a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]]) | |
194 func `-`*(a: TVec1): auto = TVec1([-a[0]]) | |
195 func `-`*(a: TVec2): auto = TVec2([-a[0], -a[1]]) | |
196 func `-`*(a: TVec3): auto = TVec3([-a[0], -a[1], -a[2]]) | |
197 func `-`*(a: TVec4): auto = TVec4([-a[0], -a[1], -a[2], -a[3]]) | |
198 func `-`*(a, b: TVec1): auto = TVec1([a[0] - b[0]]) | |
199 func `-`*(a, b: TVec2): auto = TVec2([a[0] - b[0], a[1] - b[1]]) | |
200 func `-`*(a, b: TVec3): auto = TVec3([a[0] - b[0], a[1] - b[1], a[2] - b[2]]) | |
201 func `-`*(a, b: TVec4): auto = TVec4([a[0] - b[0], a[1] - b[1], a[2] - b[2], a[3] - b[3]]) | |
202 func `*`*(a, b: TVec1): auto = TVec1([a[0] * b[0]]) | |
203 func `*`*(a, b: TVec2): auto = TVec2([a[0] * b[0], a[1] * b[1]]) | |
204 func `*`*(a, b: TVec3): auto = TVec3([a[0] * b[0], a[1] * b[1], a[2] * b[2]]) | |
205 func `*`*(a, b: TVec4): auto = TVec4([a[0] * b[0], a[1] * b[1], a[2] * b[2], a[3] * b[3]]) | |
206 func `/`*[T: SomeInteger](a, b: TVec1[T]): auto = TVec1([a[0] div b[0]]) | |
207 func `/`*[T: SomeFloat](a, b: TVec1[T]): auto = TVec1([a[0] / b[0]]) | |
208 func `/`*[T: SomeInteger](a, b: TVec2[T]): auto = TVec2([a[0] div b[0], a[1] div b[1]]) | |
209 func `/`*[T: SomeFloat](a, b: TVec2[T]): auto = TVec2([a[0] / b[0], a[1] / b[1]]) | |
210 func `/`*[T: SomeInteger](a, b: TVec3[T]): auto = TVec3([a[0] div b[0], a[1] div b[1], a[2] div b[2]]) | |
211 func `/`*[T: SomeFloat](a, b: TVec3[T]): auto = TVec3([a[0] / b[0], a[1] / b[1], a[2] / b[2]]) | |
212 func `/`*[T: SomeInteger](a, b: TVec4[T]): auto = TVec4([a[0] div b[0], a[1] div b[1], a[2] div b[2], a[3] div b[3]]) | |
213 func `/`*[T: SomeFloat](a, b: TVec4[T]): auto = TVec4([a[0] / b[0], a[1] / b[1], a[2] / b[2], a[3] / b[3]]) | |
214 | |
215 # assignment operations, scalar | |
216 func `+=`*(a: var TVec1, b: SomeNumber) = a = a + b | |
217 func `+=`*(a: var TVec2, b: SomeNumber) = a = a + b | |
218 func `+=`*(a: var TVec3, b: SomeNumber) = a = a + b | |
219 func `+=`*(a: var TVec4, b: SomeNumber) = a = a + b | |
220 func `-=`*(a: var TVec1, b: SomeNumber) = a = a - b | |
221 func `-=`*(a: var TVec2, b: SomeNumber) = a = a - b | |
222 func `-=`*(a: var TVec3, b: SomeNumber) = a = a - b | |
223 func `-=`*(a: var TVec4, b: SomeNumber) = a = a - b | |
224 func `*=`*(a: var TVec1, b: SomeNumber) = a = a * b | |
225 func `*=`*(a: var TVec2, b: SomeNumber) = a = a * b | |
226 func `*=`*(a: var TVec3, b: SomeNumber) = a = a * b | |
227 func `*=`*(a: var TVec4, b: SomeNumber) = a = a * b | |
228 func `/=`*(a: var TVec1, b: SomeNumber) = a = a / b | |
229 func `/=`*(a: var TVec2, b: SomeNumber) = a = a / b | |
230 func `/=`*(a: var TVec3, b: SomeNumber) = a = a / b | |
231 func `/=`*(a: var TVec4, b: SomeNumber) = a = a / b | |
232 # assignment operations, vector | |
233 func `+=`*(a: var TVec1, b: TVec1) = a = a + b | |
234 func `+=`*(a: var TVec2, b: TVec2) = a = a + b | |
235 func `+=`*(a: var TVec3, b: TVec3) = a = a + b | |
236 func `+=`*(a: var TVec4, b: TVec4) = a = a + b | |
237 func `-=`*(a: var TVec1, b: TVec1) = a = a - b | |
238 func `-=`*(a: var TVec2, b: TVec2) = a = a - b | |
239 func `-=`*(a: var TVec3, b: TVec3) = a = a - b | |
240 func `-=`*(a: var TVec4, b: TVec4) = a = a - b | |
241 func `*=`*(a: var TVec1, b: TVec1) = a = a * b | |
242 func `*=`*(a: var TVec2, b: TVec2) = a = a * b | |
243 func `*=`*(a: var TVec3, b: TVec3) = a = a * b | |
244 func `*=`*(a: var TVec4, b: TVec4) = a = a * b | |
245 func `/=`*(a: var TVec1, b: TVec1) = a = a / b | |
246 func `/=`*(a: var TVec2, b: TVec2) = a = a / b | |
247 func `/=`*(a: var TVec3, b: TVec3) = a = a / b | |
248 func `/=`*(a: var TVec4, b: TVec4) = a = a / b | |
249 | |
250 | |
251 # special operations | |
252 func Pow*(a: TVec1, b: SomeNumber): auto = | |
253 TVec1([pow(a[0], b)]) | |
254 func Pow*(a: TVec2, b: SomeNumber): auto = | |
255 TVec2([pow(a[0], b), pow(a[1], b)]) | |
256 func Pow*(a: TVec3, b: SomeNumber): auto = | |
257 TVec3([pow(a[0], b), pow(a[1], b), pow(a[2], b)]) | |
258 func Pow*(a: TVec4, b: SomeNumber): auto = | |
259 TVec4([pow(a[0], b), pow(a[1], b), pow(a[2], b), pow(a[3], b)]) | |
260 func Dot*(a, b: TVec1): auto = a[0] * b[0] | |
261 func Dot*(a, b: TVec2): auto = a[0] * b[0] + a[1] * b[1] | |
262 func Dot*(a, b: TVec3): auto = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] | |
263 func Dot*(a, b: TVec4): auto = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3] | |
264 func Cross*(a, b: TVec3): auto = TVec3([ | |
265 a[1] * b[2] - a[2] * b[1], | |
266 a[2] * b[0] - a[0] * b[2], | |
267 a[0] * b[1] - a[1] * b[0], | |
268 ]) | |
269 | |
270 | |
271 # macro to allow creation of new vectors by specifying vector components as attributes | |
272 # e.g. myVec.xxy will return a new Vec3 that contains the components x, x an y of the original vector | |
273 # (instead of x, y, z for a simple copy) | |
274 proc vectorAttributeAccessor(accessor: string): seq[NimNode] = | |
275 const ACCESSOR_INDICES = { | |
276 'x': 0, | |
277 'y': 1, | |
278 'z': 2, | |
279 'w': 3, | |
280 'r': 0, | |
281 'g': 1, | |
282 'b': 2, | |
283 'a': 3, | |
284 }.toTable | |
285 var getterCode, setterCode: NimNode | |
286 let accessorvalue = accessor | |
287 | |
288 if accessorvalue.len == 0: | |
289 raise newException(Exception, "empty attribute") | |
290 elif accessorvalue.len == 1: | |
291 getterCode = nnkBracketExpr.newTree(ident("vec"), newLit(ACCESSOR_INDICES[accessorvalue[0]])) | |
292 setterCode = nnkStmtList.newTree( | |
293 nnkAsgn.newTree( | |
294 nnkBracketExpr.newTree(ident("vec"), newLit(ACCESSOR_INDICES[accessorvalue[0]])), ident("value")) | |
295 ) | |
296 if accessorvalue.len > 1: | |
297 var attrs = nnkBracket.newTree() | |
298 for attrname in accessorvalue: | |
299 attrs.add(nnkBracketExpr.newTree(ident("vec"), newLit(ACCESSOR_INDICES[attrname]))) | |
300 getterCode = nnkCall.newTree(ident("TVec" & $accessorvalue.len), attrs) | |
301 setterCode = nnkStmtList.newTree() | |
302 var i = 0 | |
303 for attrname in accessorvalue: | |
304 setterCode.add nnkAsgn.newTree( | |
305 nnkBracketExpr.newTree(ident("vec"), newLit(ACCESSOR_INDICES[attrname])), | |
306 nnkBracketExpr.newTree(ident("value"), newLit(i)), | |
307 ) | |
308 inc i | |
309 | |
310 result.add newProc( | |
311 name = nnkPostfix.newTree(ident("*"), ident(accessor)), | |
312 params = [ident("auto"), nnkIdentDefs.newTree(ident("vec"), ident("TVec"), newEmptyNode())], | |
313 body = newStmtList(getterCode), | |
314 procType = nnkFuncDef, | |
315 ) | |
316 | |
317 result.add nnkFuncDef.newTree( | |
318 nnkPostfix.newTree( | |
319 newIdentNode("*"), | |
320 nnkAccQuoted.newTree(newIdentNode(accessor), newIdentNode("=")) | |
321 ), | |
322 newEmptyNode(), | |
323 nnkGenericParams.newTree(nnkIdentDefs.newTree(newIdentNode("T"), newEmptyNode(), newEmptyNode())), | |
324 nnkFormalParams.newTree( | |
325 newEmptyNode(), | |
326 nnkIdentDefs.newTree(newIdentNode("vec"), nnkVarTy.newTree(newIdentNode("TVec")), newEmptyNode()), | |
327 nnkIdentDefs.newTree(newIdentNode("value"), newIdentNode("T"), newEmptyNode()) | |
328 ), | |
329 newEmptyNode(), | |
330 newEmptyNode(), | |
331 setterCode | |
332 ) | |
333 | |
334 macro createVectorAttribAccessorFuncs() = | |
335 const COORD_ATTRS = ["x", "y", "z", "w"] | |
336 const COLOR_ATTRS = ["r", "g", "b", "a"] | |
337 result = nnkStmtList.newTree() | |
338 for attlist in [COORD_ATTRS, COLOR_ATTRS]: | |
339 for i in attlist: | |
340 result.add(vectorAttributeAccessor(i)) | |
341 for j in attlist: | |
342 result.add(vectorAttributeAccessor(i & j)) | |
343 for k in attlist: | |
344 result.add(vectorAttributeAccessor(i & j & k)) | |
345 for l in attlist: | |
346 result.add(vectorAttributeAccessor(i & j & k & l)) | |
347 | |
348 createVectorAttribAccessorFuncs() | |
349 | |
350 # call e.g. Vec2[int]().randomized() to get a random matrix | |
351 template makeRandomVectorInit(mattype: typedesc) = | |
352 proc Randomized*[T: SomeInteger](m: mattype[T]): mattype[T] = | |
353 for i in 0 ..< result.len: | |
354 result[i] = rand(low(typeof(m[0])) .. high(typeof(m[0]))) | |
355 proc Randomized*[T: SomeFloat](m: mattype[T]): mattype[T] = | |
356 for i in 0 ..< result.len: | |
357 result[i] = rand(1.0) | |
358 | |
359 makeRandomVectorInit(TVec1) | |
360 makeRandomVectorInit(TVec2) | |
361 makeRandomVectorInit(TVec3) | |
362 makeRandomVectorInit(TVec4) | |
363 | |
364 converter Vec2VkExtent*(vec: TVec2[uint32]): VkExtent2D = VkExtent2D(width: vec[0], height: vec[1]) | |
365 converter Vec3VkExtent*(vec: TVec2[uint32]): VkExtent3D = VkExtent3D(width: vec[0], height: vec[1], depth: vec[2]) | |
366 | |
367 func AngleBetween*(a, b: Vec3f): float32 = | |
368 arccos(a.Dot(b) / (a.Length * b.Length)) |