Inexor
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
geom.hpp
Go to the documentation of this file.
1 
16 
17 #pragma once
18 
19 #include <boost/algorithm/clamp.hpp> // for clamp
20 #include <stdlib.h> // for abs
21 #include <algorithm> // for max, min, swap
22 #include <cmath> // for cosf, sinf, sqrtf, fabs, ceil
23 #include <iostream> // for operator<<, basic_ostream::o...
24 
25 #include "inexor/shared/cube_loops.hpp" // for i, loopi
26 #include "inexor/shared/cube_types.hpp" // for uchar, uint, ushort, RAD
27 
28 struct ivec2;
29 struct ivec4;
30 struct ivec;
31 struct svec;
32 struct usvec;
33 struct vec4;
35 struct vec;
36 
38 struct vec2
39 {
40  union
41  {
42  struct { float x, y; };
43  float v[2];
44  };
45 
46  vec2() {}
47  vec2(float x, float y) : x(x), y(y) {}
48  explicit vec2(const vec &v);
49  explicit vec2(const vec4 &v);
50 
51  float &operator[](int i) { return v[i]; }
52  float operator[](int i) const { return v[i]; }
53 
54  bool operator==(const vec2 &o) const { return x == o.x && y == o.y; }
55  bool operator!=(const vec2 &o) const { return x != o.x || y != o.y; }
56 
59  friend std::ostream &operator<<(std::ostream &os, const vec2 &v)
60  {
61  os << '(' << v.x << " ," << v.y << ')';
62  return os;
63  }
64 
65  bool iszero() const { return x==0 && y==0; }
66  float dot(const vec2 &o) const { return x*o.x + y*o.y; }
67  float squaredlen() const { return dot(*this); }
68  float magnitude() const { return sqrtf(squaredlen()); }
69  vec2 &normalize() { mul(1/magnitude()); return *this; }
70  float cross(const vec2 &o) const { return x*o.y - y*o.x; }
71 
72  vec2 &mul(float f) { x *= f; y *= f; return *this; }
73  vec2 &mul(const vec2 &o) { x *= o.x; y *= o.y; return *this; }
74  vec2 &div(float f) { x /= f; y /= f; return *this; }
75  vec2 &div(const vec2 &o) { x /= o.x; y /= o.y; return *this; }
76  vec2 &add(float f) { x += f; y += f; return *this; }
77  vec2 &add(const vec2 &o) { x += o.x; y += o.y; return *this; }
78  vec2 &sub(float f) { x -= f; y -= f; return *this; }
79  vec2 &sub(const vec2 &o) { x -= o.x; y -= o.y; return *this; }
80  vec2 &neg() { x = -x; y = -y; return *this; }
81  vec2 &min(const vec2 &o) { x = std::min(x, o.x); y = std::min(y, o.y); return *this; }
82  vec2 &max(const vec2 &o) { x = std::max(x, o.x); y = std::max(y, o.y); return *this; }
83  vec2 &min(float f) { x = std::min(x, f); y = std::min(y, f); return *this; }
84  vec2 &max(float f) { x = std::max(x, f); y = std::max(y, f); return *this; }
85  vec2 &abs() { x = fabs(x); y = fabs(y); return *this; }
86  vec2 &clamp(float l, float h) { x = boost::algorithm::clamp(x, l, h); y = boost::algorithm::clamp(y, l, h); return *this; }
87  vec2 &reflect(const vec2 &n) { float k = 2*dot(n); x -= k*n.x; y -= k*n.y; return *this; }
88  vec2 &lerp(const vec2 &b, float t) { x += (b.x-x)*t; y += (b.y-y)*t; return *this; }
89  vec2 &lerp(const vec2 &a, const vec2 &b, float t) { x = a.x + (b.x-a.x)*t; y = a.y + (b.y-a.y)*t; return *this; }
90  template<class B> vec2 &madd(const vec2 &a, const B &b) { return add(vec2(a).mul(b)); }
91  template<class B> vec2 &msub(const vec2 &a, const B &b) { return sub(vec2(a).mul(b)); }
92 };
93 
95 static inline bool htcmp(const vec2 &x, const vec2 &y)
96 {
97  return x == y;
98 }
99 
101 static inline uint hthash(const vec2 &k)
102 {
103  union { uint i; float f; } x, y;
104  x.f = k.x; y.f = k.y;
105  uint v = x.i^y.i;
106  return v + (v>>12);
107 }
108 
110 struct vec
111 {
114  union
115  {
116  struct { float x, y, z; };
117  struct { float r, g, b; };
118  float v[3];
119  };
120 
122  vec() {}
123  explicit vec(int a) : x(a), y(a), z(a) {}
124  explicit vec(float a) : x(a), y(a), z(a) {}
125  vec(float a, float b, float c) : x(a), y(b), z(c) {}
126  explicit vec(int v[3]) : x(v[0]), y(v[1]), z(v[2]) {}
127  explicit vec(const float *v) : x(v[0]), y(v[1]), z(v[2]) {}
128  explicit vec(const vec2 &v, float z = 0) : x(v.x), y(v.y), z(z) {}
129  explicit vec(const vec4 &v);
130  explicit vec(const ivec &v);
131 
133  vec(float yaw, float pitch) : x(-sinf(yaw)*cosf(pitch)), y(cosf(yaw)*cosf(pitch)), z(sinf(pitch)) {}
134 
136  float &operator[](int i) { return v[i]; }
137  float operator[](int i) const { return v[i]; }
138 
139  vec &set(int i, float f) { v[i] = f; return *this; }
140 
143  friend std::ostream &operator<<(std::ostream &os, const vec &v)
144  {
145  os << '(' << v.x << " ," << v.y << " ," << v.z << ')';
146  return os;
147  }
148 
150  bool operator==(const vec &o) const { return x == o.x && y == o.y && z == o.z; }
151  bool operator!=(const vec &o) const { return x != o.x || y != o.y || z != o.z; }
152 
154  vec &abs() { x = fabs(x); y = fabs(y); z = fabs(z); return *this; }
155 
157  bool iszero() const { return x==0 && y==0 && z==0; }
159  float squaredlen() const { return x*x + y*y + z*z; }
161  template<class T> float dot2(const T &o) const { return x*o.x + y*o.y; }
163  float dot(const vec &o) const { return x*o.x + y*o.y + z*o.z; }
165  float absdot(const vec &o) const { return fabs(x*o.x) + fabs(y*o.y) + fabs(z*o.z); }
166 
168  vec &mul(const vec &o) { x *= o.x; y *= o.y; z *= o.z; return *this; }
169  vec &mul(float f) { x *= f; y *= f; z *= f; return *this; }
171  vec &div(const vec &o) { x /= o.x; y /= o.y; z /= o.z; return *this; }
172  vec &div(float f) { x /= f; y /= f; z /= f; return *this; }
174  vec &add(const vec &o) { x += o.x; y += o.y; z += o.z; return *this; }
175  vec &add(float f) { x += f; y += f; z += f; return *this; }
177  vec &sub(const vec &o) { x -= o.x; y -= o.y; z -= o.z; return *this; }
178  vec &sub(float f) { x -= f; y -= f; z -= f; return *this; }
179 
181  vec &neg2() { x = -x; y = -y; return *this; }
183  vec &neg() { x = -x; y = -y; z = -z; return *this; }
184 
186  vec &min(const vec &o) { x = std::min(x, o.x); y = std::min(y, o.y); z = std::min(z, o.z); return *this; }
187  vec &max(const vec &o) { x = std::max(x, o.x); y = std::max(y, o.y); z = std::max(z, o.z); return *this; }
188  vec &min(float f) { x = std::min(x, f); y = std::min(y, f); z = std::min(z, f); return *this; }
189  vec &max(float f) { x = std::max(x, f); y = std::max(y, f); z = std::max(z, f); return *this; }
190  vec &clamp(float f, float h) { x = boost::algorithm::clamp(x, f, h); y = boost::algorithm::clamp(y, f, h); z = boost::algorithm::clamp(z, f, h); return *this; }
191 
193  float magnitude2() const { return sqrtf(dot2(*this)); }
195  float magnitude() const { return sqrtf(squaredlen()); }
196 
198  vec &normalize() { div(magnitude()); return *this; }
200  bool isnormalized() const { float m = squaredlen(); return (m>0.99f && m<1.01f); }
201 
203  float squaredist(const vec &e) const { return vec(*this).sub(e).squaredlen(); }
204  float dist(const vec &e) const { vec t; return dist(e, t); }
205  float dist(const vec &e, vec &t) const { t = *this; t.sub(e); return t.magnitude(); }
206  float dist2(const vec &o) const { float dx = x-o.x, dy = y-o.y; return sqrtf(dx*dx + dy*dy); }
207  bool reject(const vec &o, float r) { return x>o.x+r || x<o.x-r || y>o.y+r || y<o.y-r; }
208 
210  template<class A, class B>
211  vec &cross(const A &a, const B &b) { x = a.y*b.z-a.z*b.y; y = a.z*b.x-a.x*b.z; z = a.x*b.y-a.y*b.x; return *this; }
212  vec &cross(const vec &o, const vec &a, const vec &b) { return cross(vec(a).sub(o), vec(b).sub(o)); }
213 
216  float scalartriple(const vec &a, const vec &b) const { return x*(a.y*b.z-a.z*b.y) + y*(a.z*b.x-a.x*b.z) + z*(a.x*b.y-a.y*b.x); }
217 
219  vec &reflectz(float rz) { z = 2*rz - z; return *this; }
220  vec &reflect(const vec &n) { float k = 2*dot(n); x -= k*n.x; y -= k*n.y; z -= k*n.z; return *this; }
221 
223  vec &project(const vec &n) { float k = dot(n); x -= k*n.x; y -= k*n.y; z -= k*n.z; return *this; }
224  vec &projectxydir(const vec &n) { if(n.z) z = -(x*n.x/n.z + y*n.y/n.z); return *this; }
225  vec &projectxy(const vec &n)
226  {
227  float m = squaredlen(), k = dot(n);
228  projectxydir(n);
229  rescale(sqrtf(std::max(m - k*k, 0.0f)));
230  return *this;
231  }
232  vec &projectxy(const vec &n, float threshold)
233  {
234  float m = squaredlen(), k = std::min(dot(n), threshold);
235  projectxydir(n);
236  rescale(sqrtf(std::max(m - k*k, 0.0f)));
237  return *this;
238  }
239 
241  vec &lerp(const vec &b, float t) { x += (b.x-x)*t; y += (b.y-y)*t; z += (b.z-z)*t; return *this; }
242  vec &lerp(const vec &a, const vec &b, float t) { x = a.x + (b.x-a.x)*t; y = a.y + (b.y-a.y)*t; z = a.z + (b.z-a.z)*t; return *this; }
243  template<class B> vec &madd(const vec &a, const B &b) { return add(vec(a).mul(b)); }
244  template<class B> vec &msub(const vec &a, const B &b) { return sub(vec(a).mul(b)); }
245 
247  vec &rescale(float k)
248  {
249  float mag = magnitude();
250  if(mag > 1e-6f) mul(k / mag);
251  return *this;
252  }
253 
255  vec &rotate_around_z(float c, float s) { float rx = x, ry = y; x = c*rx-s*ry; y = c*ry+s*rx; return *this; }
256  vec &rotate_around_x(float c, float s) { float ry = y, rz = z; y = c*ry-s*rz; z = c*rz+s*ry; return *this; }
257  vec &rotate_around_y(float c, float s) { float rx = x, rz = z; x = c*rx+s*rz; z = c*rz-s*rx; return *this; }
258 
259  vec &rotate_around_z(float angle) { return rotate_around_z(cosf(angle), sinf(angle)); }
260  vec &rotate_around_x(float angle) { return rotate_around_x(cosf(angle), sinf(angle)); }
261  vec &rotate_around_y(float angle) { return rotate_around_y(cosf(angle), sinf(angle)); }
262 
263  vec &rotate_around_z(const vec2 &sc) { return rotate_around_z(sc.x, sc.y); }
264  vec &rotate_around_x(const vec2 &sc) { return rotate_around_x(sc.x, sc.y); }
265  vec &rotate_around_y(const vec2 &sc) { return rotate_around_y(sc.x, sc.y); }
266 
267  vec &rotate(float c, float s, const vec &d)
268  {
269  *this = vec(x*(d.x*d.x*(1-c)+c) + y*(d.x*d.y*(1-c)-d.z*s) + z*(d.x*d.z*(1-c)+d.y*s),
270  x*(d.y*d.x*(1-c)+d.z*s) + y*(d.y*d.y*(1-c)+c) + z*(d.y*d.z*(1-c)-d.x*s),
271  x*(d.x*d.z*(1-c)-d.y*s) + y*(d.y*d.z*(1-c)+d.x*s) + z*(d.z*d.z*(1-c)+c));
272  return *this;
273  }
274  vec &rotate(float angle, const vec &d) { return rotate(cosf(angle), sinf(angle), d); }
275  vec &rotate(const vec2 &sc, const vec &d) { return rotate(sc.x, sc.y, d); }
276 
278  void orthogonal(const vec &d)
279  {
280  *this = fabs(d.x) > fabs(d.z) ? vec(-d.y, d.x, 0) : vec(0, -d.z, d.y);
281  }
282  void orthonormalize(vec &s, vec &t) const
283  {
284  s.sub(vec(*this).mul(dot(s)));
285  t.sub(vec(*this).mul(dot(t)))
286  .sub(vec(s).mul(s.dot(t)));
287  }
288 
291  template<class T>
292  bool insidebb(const T &bbmin, const T &bbmax) const
293  {
294  return x >= bbmin.x && x <= bbmax.x && y >= bbmin.y && y <= bbmax.y && z >= bbmin.z && z <= bbmax.z;
295  }
296  template<class T, class U>
297  bool insidebb(const T &o, U size) const
298  {
299  return x >= o.x && x <= o.x + size && y >= o.y && y <= o.y + size && z >= o.z && z <= o.z + size;
300  }
301 
303  template<class T> float dist_to_bb(const T &min, const T &max) const
304  {
305  float sqrdist = 0;
306  loopi(3)
307  {
308  if (v[i] < min[i]) { float delta = v[i]-min[i]; sqrdist += delta*delta; }
309  else if(v[i] > max[i]) { float delta = max[i]-v[i]; sqrdist += delta*delta; }
310  }
311  return sqrtf(sqrdist);
312  }
313  template<class T, class S> float dist_to_bb(const T &o, S size) const
314  {
315  return dist_to_bb(o, T(o).add(size));
316  }
317 
318  static vec hexcolor(int color)
319  {
320  return vec(((color>>16)&0xFF)*(1.0f/255.0f), ((color>>8)&0xFF)*(1.0f/255.0f), (color&0xFF)*(1.0f/255.0f));
321  }
322 };
323 
324 inline vec2::vec2(const vec &v) : x(v.x), y(v.y) {}
325 
327 static inline bool htcmp(const vec &x, const vec &y)
328 {
329  return x == y;
330 }
331 
333 static inline uint hthash(const vec &k)
334 {
335  union { uint i; float f; } x, y, z;
336  x.f = k.x; y.f = k.y; z.f = k.z;
337  uint v = x.i^y.i^z.i;
338  return v + (v>>12);
339 }
340 
343 struct vec4
344 {
345  union
346  {
347  struct { float x, y, z, w; };
348  struct { float r, g, b, a; };
349  float v[4];
350  };
351 
353  vec4() {}
354  explicit vec4(const vec &p, float w = 0) : x(p.x), y(p.y), z(p.z), w(w) {}
355  vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
356  explicit vec4(const float *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
357 
359  float &operator[](int i) { return v[i]; }
360  float operator[](int i) const { return v[i]; }
361 
364  friend std::ostream &operator<<(std::ostream &os, const vec4 &v)
365  {
366  os << '(' << v.x << " ," << v.y << " ," << v.z << " ," << v.w << ')';
367  return os;
368  }
369 
371  template<class T> float dot3(const T &o) const { return x*o.x + y*o.y + z*o.z; }
372  float dot(const vec4 &o) const { return dot3(o) + w*o.w; }
373  float dot(const vec &o) const { return x*o.x + y*o.y + z*o.z + w; }
374 
375  float squaredlen() const { return dot(*this); }
376  float magnitude() const { return sqrtf(squaredlen()); }
377  float magnitude3() const { return sqrtf(dot3(*this)); }
378  vec4 &normalize() { mul(1/magnitude()); return *this; }
379 
380  vec4 &lerp(const vec4 &b, float t)
381  {
382  x += (b.x-x)*t;
383  y += (b.y-y)*t;
384  z += (b.z-z)*t;
385  w += (b.w-w)*t;
386  return *this;
387  }
388  vec4 &lerp(const vec4 &a, const vec4 &b, float t)
389  {
390  x = a.x+(b.x-a.x)*t;
391  y = a.y+(b.y-a.y)*t;
392  z = a.z+(b.z-a.z)*t;
393  w = a.w+(b.w-a.w)*t;
394  return *this;
395  }
396 
398  vec4 &mul3(float f) { x *= f; y *= f; z *= f; return *this; }
399  vec4 &mul(float f) { mul3(f); w *= f; return *this; }
400  vec4 &mul(const vec4 &o) { x *= o.x; y *= o.y; z *= o.z; w *= o.w; return *this; }
401  vec4 &div3(float f) { x /= f; y /= f; z /= f; return *this; }
402  vec4 &div(float f) { div3(f); w /= f; return *this; }
403  vec4 &div(const vec4 &o) { x /= o.x; y /= o.y; z /= o.z; w /= o.w; return *this; }
404  vec4 &add(const vec4 &o) { x += o.x; y += o.y; z += o.z; w += o.w; return *this; }
405  vec4 &addw(float f) { w += f; return *this; }
406  vec4 &sub(const vec4 &o) { x -= o.x; y -= o.y; z -= o.z; w -= o.w; return *this; }
407  vec4 &subw(float f) { w -= f; return *this; }
408  vec4 &neg3() { x = -x; y = -y; z = -z; return *this; }
409  vec4 &neg() { neg3(); w = -w; return *this; }
410  template<class B> vec4 &madd(const vec4 &a, const B &b) { return add(vec4(a).mul(b)); }
411  template<class B> vec4 &msub(const vec4 &a, const B &b) { return sub(vec4(a).mul(b)); }
412 
413  void setxyz(const vec &v) { x = v.x; y = v.y; z = v.z; }
414 
416  vec4 &rotate_around_z(float c, float s) { float rx = x, ry = y; x = c*rx-s*ry; y = c*ry+s*rx; return *this; }
417  vec4 &rotate_around_x(float c, float s) { float ry = y, rz = z; y = c*ry-s*rz; z = c*rz+s*ry; return *this; }
418  vec4 &rotate_around_y(float c, float s) { float rx = x, rz = z; x = c*rx+s*rz; z = c*rz-s*rx; return *this; }
419  vec4 &rotate_around_z(float angle) { return rotate_around_z(cosf(angle), sinf(angle)); }
420  vec4 &rotate_around_x(float angle) { return rotate_around_x(cosf(angle), sinf(angle)); }
421  vec4 &rotate_around_y(float angle) { return rotate_around_y(cosf(angle), sinf(angle)); }
422 };
423 
424 inline vec::vec(const vec4 &v) : x(v.x), y(v.y), z(v.z) {}
425 
426 struct matrix3;
427 struct matrix4;
428 struct matrix4x3;
429 
435 struct quat : vec4
436 {
437  quat() {}
438  quat(float x, float y, float z, float w) : vec4(x, y, z, w) {}
439  quat(const vec &axis, float angle)
440  {
441  w = cosf(angle/2);
442  float s = sinf(angle/2);
443  x = s*axis.x;
444  y = s*axis.y;
445  z = s*axis.z;
446  }
447  explicit quat(const vec &v)
448  {
449  x = v.x;
450  y = v.y;
451  z = v.z;
452  restorew();
453  }
454  explicit quat(const matrix3 &m) { convertmatrix(m); }
455  explicit quat(const matrix4x3 &m) { convertmatrix(m); }
456  explicit quat(const matrix4 &m) { convertmatrix(m); }
457 
458  void restorew() { w = 1.0f-x*x-y*y-z*z; w = w<0 ? 0 : -sqrtf(w); }
459 
460  quat &add(const vec4 &o) { vec4::add(o); return *this; }
461  quat &sub(const vec4 &o) { vec4::sub(o); return *this; }
462  quat &mul(float k) { vec4::mul(k); return *this; }
463 
464  quat &mul(const quat &p, const quat &o)
465  {
466  x = p.w*o.x + p.x*o.w + p.y*o.z - p.z*o.y;
467  y = p.w*o.y - p.x*o.z + p.y*o.w + p.z*o.x;
468  z = p.w*o.z + p.x*o.y - p.y*o.x + p.z*o.w;
469  w = p.w*o.w - p.x*o.x - p.y*o.y - p.z*o.z;
470  return *this;
471  }
472  quat &mul(const quat &o) { return mul(quat(*this), o); }
473 
474  quat &invert() { neg3(); return *this; }
475 
476  void calcangleaxis(float &angle, vec &axis)
477  {
478  float rr = dot3(*this);
479  if(rr>0)
480  {
481  angle = 2*acosf(w);
482  axis = vec(x, y, z).mul(1/rr);
483  }
484  else { angle = 0; axis = vec(0, 0, 1); }
485  }
486 
487  vec rotate(const vec &v) const
488  {
489  return vec().cross(*this, vec().cross(*this, v).add(vec(v).mul(w))).mul(2).add(v);
490  }
491 
492  vec invertedrotate(const vec &v) const
493  {
494  return vec().cross(*this, vec().cross(*this, v).sub(vec(v).mul(w))).mul(2).add(v);
495  }
496 
497  template<class M>
498  void convertmatrix(const M &m)
499  {
500  float trace = m.a.x + m.b.y + m.c.z;
501  if(trace>0)
502  {
503  float r = sqrtf(1 + trace), inv = 0.5f/r;
504  w = 0.5f*r;
505  x = (m.b.z - m.c.y)*inv;
506  y = (m.c.x - m.a.z)*inv;
507  z = (m.a.y - m.b.x)*inv;
508  }
509  else if(m.a.x > m.b.y && m.a.x > m.c.z)
510  {
511  float r = sqrtf(1 + m.a.x - m.b.y - m.c.z), inv = 0.5f/r;
512  x = 0.5f*r;
513  y = (m.a.y + m.b.x)*inv;
514  z = (m.c.x + m.a.z)*inv;
515  w = (m.b.z - m.c.y)*inv;
516  }
517  else if(m.b.y > m.c.z)
518  {
519  float r = sqrtf(1 + m.b.y - m.a.x - m.c.z), inv = 0.5f/r;
520  x = (m.a.y + m.b.x)*inv;
521  y = 0.5f*r;
522  z = (m.b.z + m.c.y)*inv;
523  w = (m.c.x - m.a.z)*inv;
524  }
525  else
526  {
527  float r = sqrtf(1 + m.c.z - m.a.x - m.b.y), inv = 0.5f/r;
528  x = (m.c.x + m.a.z)*inv;
529  y = (m.b.z + m.c.y)*inv;
530  z = 0.5f*r;
531  w = (m.a.y - m.b.x)*inv;
532  }
533  }
534 };
535 
536 struct dualquat
537 {
539 
540  dualquat() {}
541  dualquat(const quat &q, const vec &p)
542  : real(q),
543  dual(0.5f*( p.x*q.w + p.y*q.z - p.z*q.y),
544  0.5f*(-p.x*q.z + p.y*q.w + p.z*q.x),
545  0.5f*( p.x*q.y - p.y*q.x + p.z*q.w),
546  -0.5f*( p.x*q.x + p.y*q.y + p.z*q.z))
547  {
548  }
549  explicit dualquat(const quat &q) : real(q), dual(0, 0, 0, 0) {}
550  explicit dualquat(const matrix4x3 &m);
551 
552  dualquat &mul(float k) { real.mul(k); dual.mul(k); return *this; }
553  dualquat &add(const dualquat &d) { real.add(d.real); dual.add(d.dual); return *this; }
554 
555  dualquat &lerp(const dualquat &to, float t)
556  {
557  float k = real.dot(to.real) < 0 ? -t : t;
558  real.mul(1-t).add(vec4(to.real).mul(k));
559  dual.mul(1-t).add(vec4(to.dual).mul(k));
560  return *this;
561  }
562  dualquat &lerp(const dualquat &from, const dualquat &to, float t)
563  {
564  float k = from.real.dot(to.real) < 0 ? -t : t;
565  (real = from.real).mul(1-t).add(vec4(to.real).mul(k));
566  (dual = from.dual).mul(1-t).add(vec4(to.dual).mul(k));
567  return *this;
568  }
569 
571  {
572  real.invert();
573  dual.invert();
574  dual.sub(quat(real).mul(2*real.dot(dual)));
575  return *this;
576  }
577 
578  void mul(const dualquat &p, const dualquat &o)
579  {
580  real.mul(p.real, o.real);
581  dual.mul(p.real, o.dual).add(quat().mul(p.dual, o.real));
582  }
583  void mul(const dualquat &o) { mul(dualquat(*this), o); }
584 
585  void mulorient(const quat &q)
586  {
587  real.mul(q, quat(real));
588  dual.mul(quat(q).invert(), quat(dual));
589  }
590 
591  void mulorient(const quat &q, const dualquat &base)
592  {
593  quat trans;
594  trans.mul(base.dual, quat(base.real).invert());
595  dual.mul(quat(q).invert(), quat(real).mul(trans).add(dual));
596 
597  real.mul(q, quat(real));
598  dual.add(quat().mul(real, trans.invert())).sub(quat(real).mul(2*base.real.dot(base.dual)));
599  }
600 
601  void normalize()
602  {
603  float invlen = 1/real.magnitude();
604  real.mul(invlen);
605  dual.mul(invlen);
606  }
607 
608  void translate(const vec &p)
609  {
610  dual.x += 0.5f*( p.x*real.w + p.y*real.z - p.z*real.y);
611  dual.y += 0.5f*(-p.x*real.z + p.y*real.w + p.z*real.x);
612  dual.z += 0.5f*( p.x*real.y - p.y*real.x + p.z*real.w);
613  dual.w += -0.5f*( p.x*real.x + p.y*real.y + p.z*real.z);
614  }
615 
616  void scale(float k)
617  {
618  dual.mul(k);
619  }
620 
621  void fixantipodal(const dualquat &d)
622  {
623  if(real.dot(d.real) < 0)
624  {
625  real.neg();
626  dual.neg();
627  }
628  }
629 
630  void accumulate(const dualquat &d, float k)
631  {
632  if(real.dot(d.real) < 0) k = -k;
633  real.add(vec4(d.real).mul(k));
634  dual.add(vec4(d.dual).mul(k));
635  }
636 
637  vec transform(const vec &v) const
638  {
639  return vec().cross(real, vec().cross(real, v).add(vec(v).mul(real.w)).add(vec(dual))).add(vec(dual).mul(real.w)).sub(vec(real).mul(dual.w)).mul(2).add(v);
640  }
641 
642  quat transform(const quat &q) const
643  {
644  return quat().mul(real, q);
645  }
646 
647  vec transposedtransform(const vec &v) const
648  {
649  return dualquat(*this).invert().transform(v);
650  }
651 
652  vec transformnormal(const vec &v) const
653  {
654  return real.rotate(v);
655  }
656 
658  {
659  return real.invertedrotate(v);
660  }
661 
663  {
664  return vec().cross(real, dual).add(vec(dual).mul(real.w)).sub(vec(real).mul(dual.w)).mul(2);
665  }
666 };
667 
668 struct matrix3
669 {
670  vec a, b, c;
671 
672  matrix3() {}
673  matrix3(const vec &a, const vec &b, const vec &c) : a(a), b(b), c(c) {}
674  explicit matrix3(float angle, const vec &axis) { rotate(angle, axis); }
675  explicit matrix3(const quat &q)
676  {
677  float x = q.x, y = q.y, z = q.z, w = q.w,
678  tx = 2*x, ty = 2*y, tz = 2*z,
679  txx = tx*x, tyy = ty*y, tzz = tz*z,
680  txy = tx*y, txz = tx*z, tyz = ty*z,
681  twx = w*tx, twy = w*ty, twz = w*tz;
682  a = vec(1 - (tyy + tzz), txy + twz, txz - twy);
683  b = vec(txy - twz, 1 - (txx + tzz), tyz + twx);
684  c = vec(txz + twy, tyz - twx, 1 - (txx + tyy));
685  }
686  explicit matrix3(const matrix4x3 &m);
687  explicit matrix3(const matrix4 &m);
688 
689  void mul(const matrix3 &m, const matrix3 &n)
690  {
691  a = vec(m.a).mul(n.a.x).madd(m.b, n.a.y).madd(m.c, n.a.z);
692  b = vec(m.a).mul(n.b.x).madd(m.b, n.b.y).madd(m.c, n.b.z);
693  c = vec(m.a).mul(n.c.x).madd(m.b, n.c.y).madd(m.c, n.c.z);
694  }
695  void mul(const matrix3 &n) { mul(matrix3(*this), n); }
696 
697  void multranspose(const matrix3 &m, const matrix3 &n)
698  {
699  a = vec(m.a).mul(n.a.x).madd(m.b, n.b.x).madd(m.c, n.c.x);
700  b = vec(m.a).mul(n.a.y).madd(m.b, m.b.y).madd(m.c, n.c.y);
701  c = vec(m.a).mul(n.a.z).madd(m.b, n.b.z).madd(m.c, n.c.z);
702  }
703  void multranspose(const matrix3 &n) { multranspose(matrix3(*this), n); }
704 
705  void transposemul(const matrix3 &m, const matrix3 &n)
706  {
707  a = vec(m.a.dot(n.a), m.b.dot(n.a), m.c.dot(n.a));
708  b = vec(m.a.dot(n.b), m.b.dot(n.b), m.c.dot(n.b));
709  c = vec(m.a.dot(n.c), m.b.dot(n.c), m.c.dot(n.c));
710  }
711  void transposemul(const matrix3 &n) { transposemul(matrix3(*this), n); }
712 
713  void transpose()
714  {
715  std::swap(a.y, b.x); std::swap(a.z, c.x);
716  std::swap(b.z, c.y);
717  }
718 
719  template<class M>
720  void transpose(const M &m)
721  {
722  a = vec(m.a.x, m.b.x, m.c.x);
723  b = vec(m.a.y, m.b.y, m.c.y);
724  c = vec(m.a.z, m.b.z, m.c.z);
725  }
726 
727  void invert(const matrix3 &o)
728  {
729  vec unscale(1/o.a.squaredlen(), 1/o.b.squaredlen(), 1/o.c.squaredlen());
730  transpose(o);
731  a.mul(unscale);
732  b.mul(unscale);
733  c.mul(unscale);
734  }
735  void invert() { invert(matrix3(*this)); }
736 
737  void normalize()
738  {
739  a.normalize();
740  b.normalize();
741  c.normalize();
742  }
743 
744  void scale(float k)
745  {
746  a.mul(k);
747  b.mul(k);
748  c.mul(k);
749  }
750 
751  void rotate(float angle, const vec &axis)
752  {
753  rotate(cosf(angle), sinf(angle), axis);
754  }
755 
756  void rotate(float ck, float sk, const vec &axis)
757  {
758  a = vec(axis.x*axis.x*(1-ck)+ck, axis.x*axis.y*(1-ck)+axis.z*sk, axis.x*axis.z*(1-ck)-axis.y*sk);
759  b = vec(axis.x*axis.y*(1-ck)-axis.z*sk, axis.y*axis.y*(1-ck)+ck, axis.y*axis.z*(1-ck)+axis.x*sk);
760  c = vec(axis.x*axis.z*(1-ck)+axis.y*sk, axis.y*axis.z*(1-ck)-axis.x*sk, axis.z*axis.z*(1-ck)+ck);
761  }
762 
766  void rotationalign(const vec &d, const vec &z)
767  {
768  vec v;
769  v.cross(z, d);
770  const float s = z.dot(d);
771  const float k = 1.0f / (1.0f + s);
772 
773  a = vec(v.x*v.x*k + s, v.y*v.x*k - v.z, v.z*v.x*k + v.y);
774  b = vec(v.x*v.y*k + v.z, v.y*v.y*k + s, v.z*v.y*k - v.x);
775  c = vec(v.x*v.z*k - v.y, v.y*v.z*k + v.x, v.z*v.z*k + s);
776  }
777 
778  void setyaw(float ck, float sk)
779  {
780  a = vec(ck, sk, 0);
781  b = vec(-sk, ck, 0);
782  c = vec(0, 0, 1);
783  }
784 
785  void setyaw(float angle)
786  {
787  setyaw(cosf(angle), sinf(angle));
788  }
789 
790  float trace() const { return a.x + b.y + c.z; }
791 
792  bool calcangleaxis(float tr, float &angle, vec &axis, float threshold = 1e-16f) const
793  {
794  if(tr <= -1)
795  {
796  if(a.x >= b.y && a.x >= c.z)
797  {
798  float r = 1 + a.x - b.y - c.z;
799  if(r <= threshold) return false;
800  r = sqrtf(r);
801  axis.x = 0.5f*r;
802  axis.y = b.x/r;
803  axis.z = c.x/r;
804  }
805  else if(b.y >= c.z)
806  {
807  float r = 1 + b.y - a.x - c.z;
808  if(r <= threshold) return false;
809  r = sqrtf(r);
810  axis.y = 0.5f*r;
811  axis.x = b.x/r;
812  axis.z = c.y/r;
813  }
814  else
815  {
816  float r = 1 + b.y - a.x - c.z;
817  if(r <= threshold) return false;
818  r = sqrtf(r);
819  axis.z = 0.5f*r;
820  axis.x = c.x/r;
821  axis.y = c.y/r;
822  }
823  angle = M_PI;
824  }
825  else if(tr >= 3)
826  {
827  axis = vec(0, 0, 1);
828  angle = 0;
829  }
830  else
831  {
832  axis = vec(b.z - c.y, c.x - a.z, a.y - b.x);
833  float r = axis.squaredlen();
834  if(r <= threshold) return false;
835  axis.mul(1/sqrtf(r));
836  angle = acosf(0.5f*(tr - 1));
837  }
838  return true;
839  }
840 
841  bool calcangleaxis(float &angle, vec &axis, float threshold = 1e-16f) const { return calcangleaxis(trace(), angle, axis, threshold); }
842 
843  vec transform(const vec &o) const
844  {
845  return vec(a).mul(o.x).madd(b, o.y).madd(c, o.z);
846  }
847  vec transposedtransform(const vec &o) const { return vec(a.dot(o), b.dot(o), c.dot(o)); }
848  vec abstransform(const vec &o) const
849  {
850  return vec(a).mul(o.x).abs().add(vec(b).mul(o.y).abs()).add(vec(c).mul(o.z).abs());
851  }
853  {
854  return vec(a.absdot(o), b.absdot(o), c.absdot(o));
855  }
856 
857  void identity()
858  {
859  a = vec(1, 0, 0);
860  b = vec(0, 1, 0);
861  c = vec(0, 0, 1);
862  }
863 
864  void rotate_around_x(float ck, float sk)
865  {
866  vec rb = vec(b).mul(ck).madd(c, sk),
867  rc = vec(c).mul(ck).msub(b, sk);
868  b = rb;
869  c = rc;
870  }
871  void rotate_around_x(float angle) { rotate_around_x(cosf(angle), sinf(angle)); }
872  void rotate_around_x(const vec2 &sc) { rotate_around_x(sc.x, sc.y); }
873 
874  void rotate_around_y(float ck, float sk)
875  {
876  vec rc = vec(c).mul(ck).madd(a, sk),
877  ra = vec(a).mul(ck).msub(c, sk);
878  c = rc;
879  a = ra;
880  }
881  void rotate_around_y(float angle) { rotate_around_y(cosf(angle), sinf(angle)); }
882  void rotate_around_y(const vec2 &sc) { rotate_around_y(sc.x, sc.y); }
883 
884  void rotate_around_z(float ck, float sk)
885  {
886  vec ra = vec(a).mul(ck).madd(b, sk),
887  rb = vec(b).mul(ck).msub(a, sk);
888  a = ra;
889  b = rb;
890  }
891  void rotate_around_z(float angle) { rotate_around_z(cosf(angle), sinf(angle)); }
892  void rotate_around_z(const vec2 &sc) { rotate_around_z(sc.x, sc.y); }
893 
894  vec transform(const vec2 &o) { return vec(a).mul(o.x).madd(b, o.y); }
895  vec transposedtransform(const vec2 &o) const { return vec(a.dot2(o), b.dot2(o), c.dot2(o)); }
896 
897  vec rowx() const { return vec(a.x, b.x, c.x); }
898  vec rowy() const { return vec(a.y, b.y, c.y); }
899  vec rowz() const { return vec(a.z, b.z, c.z); }
900 };
901 
902 struct matrix4x3
903 {
904  vec a, b, c, d;
905 
907  matrix4x3(const vec &a, const vec &b, const vec &c, const vec &d) : a(a), b(b), c(c), d(d) {}
908  matrix4x3(const matrix3 &rot, const vec &trans) : a(rot.a), b(rot.b), c(rot.c), d(trans) {}
909  matrix4x3(const dualquat &dq)
910  {
911  vec4 r = vec4(dq.real).mul(1/dq.real.squaredlen()), rr = vec4(r).mul(dq.real);
912  r.mul(2);
913  float xy = r.x*dq.real.y, xz = r.x*dq.real.z, yz = r.y*dq.real.z,
914  wx = r.w*dq.real.x, wy = r.w*dq.real.y, wz = r.w*dq.real.z;
915  a = vec(rr.w + rr.x - rr.y - rr.z, xy + wz, xz - wy);
916  b = vec(xy - wz, rr.w + rr.y - rr.x - rr.z, yz + wx);
917  c = vec(xz + wy, yz - wx, rr.w + rr.z - rr.x - rr.y);
918  d = vec(-(dq.dual.w*r.x - dq.dual.x*r.w + dq.dual.y*r.z - dq.dual.z*r.y),
919  -(dq.dual.w*r.y - dq.dual.x*r.z - dq.dual.y*r.w + dq.dual.z*r.x),
920  -(dq.dual.w*r.z + dq.dual.x*r.y - dq.dual.y*r.x - dq.dual.z*r.w));
921 
922  }
923  explicit matrix4x3(const matrix4 &m);
924 
925  void mul(float k)
926  {
927  a.mul(k);
928  b.mul(k);
929  c.mul(k);
930  d.mul(k);
931  }
932 
933  void setscale(float x, float y, float z) { a.x = x; b.y = y; c.z = z; }
934  void setscale(const vec &v) { setscale(v.x, v.y, v.z); }
935  void setscale(float n) { setscale(n, n, n); }
936 
937  void scale(float x, float y, float z)
938  {
939  a.mul(x);
940  b.mul(y);
941  c.mul(z);
942  }
943  void scale(const vec &v) { scale(v.x, v.y, v.z); }
944  void scale(float n) { scale(n, n, n); }
945 
946  void settranslation(const vec &p) { d = p; }
947  void settranslation(float x, float y, float z) { d = vec(x, y, z); }
948 
949  void translate(const vec &p) { d.madd(a, p.x).madd(b, p.y).madd(c, p.z); }
950  void translate(float x, float y, float z) { translate(vec(x, y, z)); }
951  void translate(const vec &p, float scale) { translate(vec(p).mul(scale)); }
952 
953  void accumulate(const matrix4x3 &m, float k)
954  {
955  a.madd(m.a, k);
956  b.madd(m.b, k);
957  c.madd(m.c, k);
958  d.madd(m.d, k);
959  }
960 
961  void normalize()
962  {
963  a.normalize();
964  b.normalize();
965  c.normalize();
966  }
967 
968  void lerp(const matrix4x3 &to, float t)
969  {
970  a.lerp(to.a, t);
971  b.lerp(to.b, t);
972  c.lerp(to.c, t);
973  d.lerp(to.d, t);
974  }
975  void lerp(const matrix4x3 &from, const matrix4x3 &to, float t)
976  {
977  a.lerp(from.a, to.a, t);
978  b.lerp(from.b, to.b, t);
979  c.lerp(from.c, to.c, t);
980  d.lerp(from.d, to.d, t);
981  }
982 
983  void identity()
984  {
985  a = vec(1, 0, 0);
986  b = vec(0, 1, 0);
987  c = vec(0, 0, 1);
988  d = vec(0, 0, 0);
989  }
990 
991  void mul(const matrix4x3 &m, const matrix4x3 &n)
992  {
993  a = vec(m.a).mul(n.a.x).madd(m.b, n.a.y).madd(m.c, n.a.z);
994  b = vec(m.a).mul(n.b.x).madd(m.b, n.b.y).madd(m.c, n.b.z);
995  c = vec(m.a).mul(n.c.x).madd(m.b, n.c.y).madd(m.c, n.c.z);
996  d = vec(m.d).madd(m.a, n.d.x).madd(m.b, n.d.y).madd(m.c, n.d.z);
997  }
998  void mul(const matrix4x3 &n) { mul(matrix4x3(*this), n); }
999 
1000  void mul(const matrix3 &m, const matrix4x3 &n)
1001  {
1002  a = vec(m.a).mul(n.a.x).madd(m.b, n.a.y).madd(m.c, n.a.z);
1003  b = vec(m.a).mul(n.b.x).madd(m.b, n.b.y).madd(m.c, n.b.z);
1004  c = vec(m.a).mul(n.c.x).madd(m.b, n.c.y).madd(m.c, n.c.z);
1005  d = vec(m.a).mul(n.d.x).madd(m.b, n.d.y).madd(m.c, n.d.z);
1006  }
1007 
1008  void mul(const matrix3 &rot, const vec &trans, const matrix4x3 &n)
1009  {
1010  mul(rot, n);
1011  d.add(trans);
1012  }
1013 
1014  void transpose()
1015  {
1016  d = vec(a.dot(d), b.dot(d), c.dot(d)).neg();
1017  std::swap(a.y, b.x); std::swap(a.z, c.x);
1018  std::swap(b.z, c.y);
1019  }
1020 
1021  void transpose(const matrix4x3 &o)
1022  {
1023  a = vec(o.a.x, o.b.x, o.c.x);
1024  b = vec(o.a.y, o.b.y, o.c.y);
1025  c = vec(o.a.z, o.b.z, o.c.z);
1026  d = vec(o.a.dot(o.d), o.b.dot(o.d), o.c.dot(o.d)).neg();
1027  }
1028 
1029  void transposemul(const matrix4x3 &m, const matrix4x3 &n)
1030  {
1031  vec t(m.a.dot(m.d), m.b.dot(m.d), m.c.dot(m.d));
1032  a = vec(m.a.dot(n.a), m.b.dot(n.a), m.c.dot(n.a));
1033  b = vec(m.a.dot(n.b), m.b.dot(n.b), m.c.dot(n.b));
1034  c = vec(m.a.dot(n.c), m.b.dot(n.c), m.c.dot(n.c));
1035  d = vec(m.a.dot(n.d), m.b.dot(n.d), m.c.dot(n.d)).sub(t);
1036  }
1037 
1038  void multranspose(const matrix4x3 &m, const matrix4x3 &n)
1039  {
1040  vec t(n.a.dot(n.d), n.b.dot(n.d), n.c.dot(n.d));
1041  a = vec(m.a).mul(n.a.x).madd(m.b, n.b.x).madd(m.c, n.c.x);
1042  b = vec(m.a).mul(n.a.y).madd(m.b, m.b.y).madd(m.c, n.c.y);
1043  c = vec(m.a).mul(n.a.z).madd(m.b, n.b.z).madd(m.c, n.c.z);
1044  d = vec(m.d).msub(m.a, t.x).msub(m.b, t.y).msub(m.c, t.z);
1045  }
1046 
1047  void invert(const matrix4x3 &o)
1048  {
1049  vec unscale(1/o.a.squaredlen(), 1/o.b.squaredlen(), 1/o.c.squaredlen());
1050  transpose(o);
1051  a.mul(unscale);
1052  b.mul(unscale);
1053  c.mul(unscale);
1054  d.mul(unscale);
1055  }
1056  void invert() { invert(matrix4x3(*this)); }
1057 
1058  void rotate(float angle, const vec &d)
1059  {
1060  rotate(cosf(angle), sinf(angle), d);
1061  }
1062 
1063  void rotate(float ck, float sk, const vec &axis)
1064  {
1065  matrix3 m;
1066  m.rotate(ck, sk, axis);
1067  *this = matrix4x3(m, vec(0, 0, 0));
1068  }
1069 
1070  void rotate_around_x(float ck, float sk)
1071  {
1072  vec rb = vec(b).mul(ck).madd(c, sk),
1073  rc = vec(c).mul(ck).msub(b, sk);
1074  b = rb;
1075  c = rc;
1076  }
1077  void rotate_around_x(float angle) { rotate_around_x(cosf(angle), sinf(angle)); }
1078  void rotate_around_x(const vec2 &sc) { rotate_around_x(sc.x, sc.y); }
1079 
1080  void rotate_around_y(float ck, float sk)
1081  {
1082  vec rc = vec(c).mul(ck).madd(a, sk),
1083  ra = vec(a).mul(ck).msub(c, sk);
1084  c = rc;
1085  a = ra;
1086  }
1087  void rotate_around_y(float angle) { rotate_around_y(cosf(angle), sinf(angle)); }
1088  void rotate_around_y(const vec2 &sc) { rotate_around_y(sc.x, sc.y); }
1089 
1090  void rotate_around_z(float ck, float sk)
1091  {
1092  vec ra = vec(a).mul(ck).madd(b, sk),
1093  rb = vec(b).mul(ck).msub(a, sk);
1094  a = ra;
1095  b = rb;
1096  }
1097  void rotate_around_z(float angle) { rotate_around_z(cosf(angle), sinf(angle)); }
1098  void rotate_around_z(const vec2 &sc) { rotate_around_z(sc.x, sc.y); }
1099 
1100  vec transform(const vec &o) const { return vec(d).madd(a, o.x).madd(b, o.y).madd(c, o.z); }
1101  vec transposedtransform(const vec &o) const { vec p = vec(o).sub(d); return vec(a.dot(p), b.dot(p), c.dot(p)); }
1102  vec transformnormal(const vec &o) const { return vec(a).mul(o.x).madd(b, o.y).madd(c, o.z); }
1103  vec transposedtransformnormal(const vec &o) const { return vec(a.dot(o), b.dot(o), c.dot(o)); }
1104  vec transform(const vec2 &o) const { return vec(d).madd(a, o.x).madd(b, o.y); }
1105 
1106  vec4 rowx() const { return vec4(a.x, b.x, c.x, d.x); }
1107  vec4 rowy() const { return vec4(a.y, b.y, c.y, d.y); }
1108  vec4 rowz() const { return vec4(a.z, b.z, c.z, d.z); }
1109 };
1110 
1111 inline dualquat::dualquat(const matrix4x3 &m) : real(m)
1112 {
1113  dual.x = 0.5f*( m.d.x*real.w + m.d.y*real.z - m.d.z*real.y);
1114  dual.y = 0.5f*(-m.d.x*real.z + m.d.y*real.w + m.d.z*real.x);
1115  dual.z = 0.5f*( m.d.x*real.y - m.d.y*real.x + m.d.z*real.w);
1116  dual.w = -0.5f*( m.d.x*real.x + m.d.y*real.y + m.d.z*real.z);
1117 }
1118 
1119 inline matrix3::matrix3(const matrix4x3 &m) : a(m.a), b(m.b), c(m.c) {}
1120 
1121 struct plane : vec
1122 {
1123  float offset;
1124 
1125  float dist(const vec &p) const { return dot(p)+offset; }
1126  float dist(const vec4 &p) const { return p.dot3(*this) + p.w*offset; }
1127  bool operator==(const plane &p) const { return x==p.x && y==p.y && z==p.z && offset==p.offset; }
1128  bool operator!=(const plane &p) const { return x!=p.x || y!=p.y || z!=p.z || offset!=p.offset; }
1129 
1130  plane() {}
1131  plane(const vec &c, float off) : vec(c), offset(off) {}
1132  plane(const vec4 &p) : vec(p), offset(p.w) {}
1133  plane(int d, float off)
1134  {
1135  x = y = z = 0.0f;
1136  v[d] = 1.0f;
1137  offset = -off;
1138  }
1139  plane(float a, float b, float c, float d) : vec(a, b, c), offset(d) {}
1140 
1141  void toplane(const vec &n, const vec &p)
1142  {
1143  x = n.x; y = n.y; z = n.z;
1144  offset = -dot(p);
1145  }
1146 
1147  bool toplane(const vec &a, const vec &b, const vec &c)
1148  {
1149  cross(vec(b).sub(a), vec(c).sub(a));
1150  float mag = magnitude();
1151  if(!mag) return false;
1152  div(mag);
1153  offset = -dot(a);
1154  return true;
1155  }
1156 
1157  bool rayintersect(const vec &o, const vec &ray, float &dist)
1158  {
1159  float cosalpha = dot(ray);
1160  if(cosalpha==0) return false;
1161  float deltac = offset+dot(o);
1162  dist -= deltac/cosalpha;
1163  return true;
1164  }
1165 
1166  plane &reflectz(float rz)
1167  {
1168  offset += 2*rz*z;
1169  z = -z;
1170  return *this;
1171  }
1172 
1174  {
1175  neg();
1176  offset = -offset;
1177  return *this;
1178  }
1179 
1180  plane &scale(float k)
1181  {
1182  mul(k);
1183  return *this;
1184  }
1185 
1186  plane &translate(const vec &p)
1187  {
1188  offset += dot(p);
1189  return *this;
1190  }
1191 
1193  {
1194  float mag = magnitude();
1195  div(mag);
1196  offset /= mag;
1197  return *this;
1198  }
1199 
1200  float zintersect(const vec &p) const { return -(x*p.x+y*p.y+offset)/z; }
1201  float zdelta(const vec &p) const { return -(x*p.x+y*p.y)/z; }
1202  float zdist(const vec &p) const { return p.z-zintersect(p); }
1203 };
1204 
1207 struct triangle
1208 {
1209  vec a, b, c;
1210 
1211  triangle(const vec &a, const vec &b, const vec &c) : a(a), b(b), c(c) {}
1213 
1214  triangle &add(const vec &o) { a.add(o); b.add(o); c.add(o); return *this; }
1215  triangle &sub(const vec &o) { a.sub(o); b.sub(o); c.sub(o); return *this; }
1216 
1217  bool operator==(const triangle &t) const { return a == t.a && b == t.b && c == t.c; }
1218 };
1219 
1220 // DIM: X=0 Y=1 Z=2.
1221 const int R[3] = {1, 2, 0}; // row
1222 const int C[3] = {2, 0, 1}; // col
1223 const int D[3] = {0, 1, 2}; // depth
1224 
1226 struct ivec
1227 {
1228  union
1229  {
1230  struct { int x, y, z; };
1231  struct { int r, g, b; };
1232  int v[3];
1233  };
1234 
1235  ivec() {}
1236  explicit ivec(const vec &v) : x(int(v.x)), y(int(v.y)), z(int(v.z)) {}
1237  ivec(int a, int b, int c) : x(a), y(b), z(c) {}
1238  ivec(int d, int row, int col, int depth)
1239  {
1240  v[R[d]] = row;
1241  v[C[d]] = col;
1242  v[D[d]] = depth;
1243  }
1244  ivec(int i, const ivec &co, int size) : x(co.x+((i&1)>>0)*size), y(co.y+((i&2)>>1)*size), z(co.z +((i&4)>>2)*size) {}
1245  explicit ivec(const ivec4 &v);
1246  explicit ivec(const ivec2 &v, int z = 0);
1247  explicit ivec(const usvec &v);
1248  explicit ivec(const svec &v);
1249 
1250  int &operator[](int i) { return v[i]; }
1251  int operator[](int i) const { return v[i]; }
1252 
1253  //int idx(int i) { return v[i]; }
1254  bool operator==(const ivec &v) const { return x==v.x && y==v.y && z==v.z; }
1255  bool operator!=(const ivec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
1256 
1258  friend std::ostream &operator<<(std::ostream &os, const ivec &v)
1259  {
1260  os << '(' << v.x << " ," << v.y << " ," << v.z << ')';
1261  return os;
1262  }
1263 
1264  bool iszero() const { return x==0 && y==0 && z==0; }
1265  ivec &shl(int n) { x<<= n; y<<= n; z<<= n; return *this; }
1266  ivec &shr(int n) { x>>= n; y>>= n; z>>= n; return *this; }
1267  ivec &mul(int n) { x *= n; y *= n; z *= n; return *this; }
1268  ivec &div(int n) { x /= n; y /= n; z /= n; return *this; }
1269  ivec &add(int n) { x += n; y += n; z += n; return *this; }
1270  ivec &sub(int n) { x -= n; y -= n; z -= n; return *this; }
1271  ivec &mul(const ivec &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
1272  ivec &div(const ivec &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
1273  ivec &add(const ivec &v) { x += v.x; y += v.y; z += v.z; return *this; }
1274  ivec &sub(const ivec &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
1275  ivec &mask(int n) { x &= n; y &= n; z &= n; return *this; }
1276  ivec &neg() { return mul(-1); }
1277  ivec &min(const ivec &o) { x = std::min(x, o.x); y = std::min(y, o.y); z = std::min(z, o.z); return *this; }
1278  ivec &max(const ivec &o) { x = std::max(x, o.x); y = std::max(y, o.y); z = std::max(z, o.z); return *this; }
1279  ivec &min(int n) { x = std::min(x, n); y = std::min(y, n); z = std::min(z, n); return *this; }
1280  ivec &max(int n) { x = std::max(x, n); y = std::max(y, n); z = std::max(z, n); return *this; }
1281  ivec &abs() { x = ::abs(x); y = ::abs(y); z = ::abs(z); return *this; }
1282  ivec &clamp(int l, int h) { x = boost::algorithm::clamp(x, l, h); y = boost::algorithm::clamp(y, l, h); z = boost::algorithm::clamp(z, l, h); return *this; }
1283  ivec &cross(const ivec &a, const ivec &b) { x = a.y*b.z-a.z*b.y; y = a.z*b.x-a.x*b.z; z = a.x*b.y-a.y*b.x; return *this; }
1284  int dot(const ivec &o) const { return x*o.x + y*o.y + z*o.z; }
1285  float dist(const plane &p) const { return x*p.x + y*p.y + z*p.z + p.offset; }
1286 
1287  static inline ivec floor(const vec &o) { return ivec(int(::floor(o.x)), int(::floor(o.y)), int(::floor(o.z))); }
1288  static inline ivec ceil(const vec &o) { return ivec(int(::ceil(o.x)), int(::ceil(o.y)), int(::ceil(o.z))); }
1289 };
1290 
1291 inline vec::vec(const ivec &v) : x(v.x), y(v.y), z(v.z) {}
1292 
1293 static inline bool htcmp(const ivec &x, const ivec &y)
1294 {
1295  return x == y;
1296 }
1297 
1298 static inline uint hthash(const ivec &k)
1299 {
1300  return k.x^k.y^k.z;
1301 }
1302 
1304 struct ivec2
1305 {
1306  union
1307  {
1308  struct { int x, y; };
1309  int v[2];
1310  };
1311 
1312  ivec2() {}
1313  ivec2(int x, int y) : x(x), y(y) {}
1314  explicit ivec2(const vec2 &v) : x(int(v.x)), y(int(v.y)) {}
1315  explicit ivec2(const ivec &v) : x(v.x), y(v.y) {}
1316 
1317  int &operator[](int i) { return v[i]; }
1318  int operator[](int i) const { return v[i]; }
1319 
1320  bool operator==(const ivec2 &o) const { return x == o.x && y == o.y; }
1321  bool operator!=(const ivec2 &o) const { return x != o.x || y != o.y; }
1322 
1324  friend std::ostream &operator<<(std::ostream &os, const ivec2 &v)
1325  {
1326  os << '(' << v.x << " ," << v.y << ')';
1327  return os;
1328  }
1329 
1330  bool iszero() const { return x==0 && y==0; }
1331  ivec2 &shl(int n) { x<<= n; y<<= n; return *this; }
1332  ivec2 &shr(int n) { x>>= n; y>>= n; return *this; }
1333  ivec2 &mul(int n) { x *= n; y *= n; return *this; }
1334  ivec2 &div(int n) { x /= n; y /= n; return *this; }
1335  ivec2 &add(int n) { x += n; y += n; return *this; }
1336  ivec2 &sub(int n) { x -= n; y -= n; return *this; }
1337  ivec2 &mul(const ivec2 &v) { x *= v.x; y *= v.y; return *this; }
1338  ivec2 &div(const ivec2 &v) { x /= v.x; y /= v.y; return *this; }
1339  ivec2 &add(const ivec2 &v) { x += v.x; y += v.y; return *this; }
1340  ivec2 &sub(const ivec2 &v) { x -= v.x; y -= v.y; return *this; }
1341  ivec2 &mask(int n) { x &= n; y &= n; return *this; }
1342  ivec2 &neg() { x = -x; y = -y; return *this; }
1343  ivec2 &min(const ivec2 &o) { x = std::min(x, o.x); y = std::min(y, o.y); return *this; }
1344  ivec2 &max(const ivec2 &o) { x = std::max(x, o.x); y = std::max(y, o.y); return *this; }
1345  ivec2 &min(int n) { x = std::min(x, n); y = std::min(y, n); return *this; }
1346  ivec2 &max(int n) { x = std::max(x, n); y = std::max(y, n); return *this; }
1347  ivec2 &abs() { x = ::abs(x); y = ::abs(y); return *this; }
1348  int dot(const ivec2 &o) const { return x*o.x + y*o.y; }
1349  int cross(const ivec2 &o) const { return x*o.y - y*o.x; }
1350 };
1351 
1352 inline ivec::ivec(const ivec2 &v, int z) : x(v.x), y(v.y), z(z) {}
1353 
1354 static inline bool htcmp(const ivec2 &x, const ivec2 &y)
1355 {
1356  return x == y;
1357 }
1358 
1359 static inline uint hthash(const ivec2 &k)
1360 {
1361  return k.x^k.y;
1362 }
1363 
1365 struct ivec4
1366 {
1367  union
1368  {
1369  struct { int x, y, z, w; };
1370  struct { int r, g, b, a; };
1371  int v[4];
1372  };
1373 
1374  ivec4() {}
1375  explicit ivec4(const ivec &p, int w = 0) : x(p.x), y(p.y), z(p.z), w(w) {}
1376  ivec4(int x, int y, int z, int w) : x(x), y(y), z(z), w(w) {}
1377  explicit ivec4(const vec4 &v) : x(int(v.x)), y(int(v.y)), z(int(v.z)), w(int(v.w)) {}
1378 
1379  bool operator==(const ivec4 &o) const { return x == o.x && y == o.y && z == o.z && w == o.w; }
1380  bool operator!=(const ivec4 &o) const { return x != o.x || y != o.y || z != o.z || w != o.w; }
1381 };
1382 
1383 inline ivec::ivec(const ivec4 &v) : x(v.x), y(v.y), z(v.z) {}
1384 
1385 static inline bool htcmp(const ivec4 &x, const ivec4 &y)
1386 {
1387  return x == y;
1388 }
1389 
1390 static inline uint hthash(const ivec4 &k)
1391 {
1392  return k.x^k.y^k.z^k.w;
1393 }
1394 
1395 struct bvec4;
1396 
1398 struct bvec
1399 {
1400  union
1401  {
1402  struct { uchar x, y, z; };
1403  struct { uchar r, g, b; };
1404  uchar v[3];
1405  };
1406 
1407  bvec() {}
1408  bvec(uchar x, uchar y, uchar z) : x(x), y(y), z(z) {}
1409  explicit bvec(const vec &v) : x(uchar((v.x+1)*(255.0f/2.0f))), y(uchar((v.y+1)*(255.0f/2.0f))), z(uchar((v.z+1)*(255.0f/2.0f))) {}
1410  explicit bvec(const bvec4 &v);
1411 
1412  uchar &operator[](int i) { return v[i]; }
1413  uchar operator[](int i) const { return v[i]; }
1414 
1415  bool operator==(const bvec &v) const { return x==v.x && y==v.y && z==v.z; }
1416  bool operator!=(const bvec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
1417 
1418  bool iszero() const { return x==0 && y==0 && z==0; }
1419 
1420  vec tonormal() const { return vec(x*(2.0f/255.0f)-1.0f, y*(2.0f/255.0f)-1.0f, z*(2.0f/255.0f)-1.0f); }
1421 
1423  {
1424  vec n(x-127.5f, y-127.5f, z-127.5f);
1425  float mag = 127.5f/n.magnitude();
1426  x = uchar(n.x*mag+127.5f);
1427  y = uchar(n.y*mag+127.5f);
1428  z = uchar(n.z*mag+127.5f);
1429  return *this;
1430  }
1431 
1432  void lerp(const bvec &a, const bvec &b, float t) { x = uchar(a.x + (b.x-a.x)*t); y = uchar(a.y + (b.y-a.y)*t); z = uchar(a.z + (b.z-a.z)*t); }
1433 
1434  void lerp(const bvec &a, const bvec &b, int ka, int kb, int d)
1435  {
1436  x = uchar((a.x*ka + b.x*kb)/d);
1437  y = uchar((a.y*ka + b.y*kb)/d);
1438  z = uchar((a.z*ka + b.z*kb)/d);
1439  }
1440 
1441  void flip() { x ^= 0x80; y ^= 0x80; z ^= 0x80; }
1442 
1443  void scale(int k, int d) { x = uchar((x*k)/d); y = uchar((y*k)/d); z = uchar((z*k)/d); }
1444 
1445  bvec &shl(int n) { x<<= n; y<<= n; z<<= n; return *this; }
1446  bvec &shr(int n) { x>>= n; y>>= n; z>>= n; return *this; }
1447 
1448  static bvec fromcolor(const vec &v) { return bvec(uchar(v.x*255.0f), uchar(v.y*255.0f), uchar(v.z*255.0f)); }
1449  vec tocolor() const { return vec(x*(1.0f/255.0f), y*(1.0f/255.0f), z*(1.0f/255.0f)); }
1450 
1451  static bvec from565(ushort c) { return bvec((((c>>11)&0x1F)*527 + 15) >> 6, (((c>>5)&0x3F)*259 + 35) >> 6, ((c&0x1F)*527 + 15) >> 6); }
1452 };
1453 
1455 struct bvec4
1456 {
1457  union
1458  {
1459  struct { uchar x, y, z, w; };
1460  struct { uchar r, g, b, a; };
1461  uchar v[4];
1462  uint mask;
1463  };
1464 
1465  bvec4() {}
1466  bvec4(uchar x, uchar y, uchar z, uchar w = 0) : x(x), y(y), z(z), w(w) {}
1467  bvec4(const bvec &v, uchar w = 0) : x(v.x), y(v.y), z(v.z), w(w) {}
1468 
1469  uchar &operator[](int i) { return v[i]; }
1470  uchar operator[](int i) const { return v[i]; }
1471 
1472  bool operator==(const bvec4 &v) const { return mask==v.mask; }
1473  bool operator!=(const bvec4 &v) const { return mask!=v.mask; }
1474 
1475  bool iszero() const { return mask==0; }
1476 
1477  vec tonormal() const { return vec(x*(2.0f/255.0f)-1.0f, y*(2.0f/255.0f)-1.0f, z*(2.0f/255.0f)-1.0f); }
1478 
1479  void lerp(const bvec4 &a, const bvec4 &b, float t)
1480  {
1481  x = uchar(a.x + (b.x-a.x)*t);
1482  y = uchar(a.y + (b.y-a.y)*t);
1483  z = uchar(a.z + (b.z-a.z)*t);
1484  w = a.w;
1485  }
1486 
1487  void lerp(const bvec4 &a, const bvec4 &b, int ka, int kb, int d)
1488  {
1489  x = uchar((a.x*ka + b.x*kb)/d);
1490  y = uchar((a.y*ka + b.y*kb)/d);
1491  z = uchar((a.z*ka + b.z*kb)/d);
1492  w = a.w;
1493  }
1494 
1495  void flip() { mask ^= 0x80808080; }
1496 };
1497 
1498 inline bvec::bvec(const bvec4 &v) : x(v.x), y(v.y), z(v.z) {}
1499 
1501 struct usvec
1502 {
1503  union
1504  {
1505  struct { ushort x, y, z; };
1506  ushort v[3];
1507  };
1508 
1509  ushort &operator[](int i) { return v[i]; }
1510  ushort operator[](int i) const { return v[i]; }
1511 };
1512 
1513 inline ivec::ivec(const usvec &v) : x(v.x), y(v.y), z(v.z) {}
1514 
1516 struct svec
1517 {
1518  union
1519  {
1520  struct { short x, y, z; };
1521  short v[3];
1522  };
1523 
1524  svec() {}
1525  svec(short x, short y, short z) : x(x), y(y), z(z) {}
1526  explicit svec(const ivec &v) : x(v.x), y(v.y), z(v.z) {}
1527 
1528  short &operator[](int i) { return v[i]; }
1529  short operator[](int i) const { return v[i]; }
1530 };
1531 
1532 inline ivec::ivec(const svec &v) : x(v.x), y(v.y), z(v.z) {}
1533 
1535 struct svec2
1536 {
1537  union
1538  {
1539  struct { short x, y; };
1540  short v[2];
1541  };
1542 
1543  svec2() {}
1544  svec2(short x, short y) : x(x), y(y) {}
1545 
1546  short &operator[](int i) { return v[i]; }
1547  short operator[](int i) const { return v[i]; }
1548 
1549  bool operator==(const svec2 &o) const { return x == o.x && y == o.y; }
1550  bool operator!=(const svec2 &o) const { return x != o.x || y != o.y; }
1551 
1552  bool iszero() const { return x==0 && y==0; }
1553 };
1554 
1555 struct dvec4
1556 {
1557  double x, y, z, w;
1558 
1559  dvec4() {}
1560  dvec4(double x, double y, double z, double w) : x(x), y(y), z(z), w(w) {}
1561  dvec4(const vec4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) {}
1562 
1563  template<class B> dvec4 &madd(const dvec4 &a, const B &b) { return add(dvec4(a).mul(b)); }
1564  dvec4 &mul(double f) { x *= f; y *= f; z *= f; w *= f; return *this; }
1565  dvec4 &mul(const dvec4 &o) { x *= o.x; y *= o.y; z *= o.z; w *= o.w; return *this; }
1566  dvec4 &add(double f) { x += f; y += f; z += f; w += f; return *this; }
1567  dvec4 &add(const dvec4 &o) { x += o.x; y += o.y; z += o.z; w += o.w; return *this; }
1568 
1569  operator vec4() const { return vec4(x, y, z, w); }
1570 };
1571 
1572 struct matrix4
1573 {
1574  vec4 a, b, c, d;
1575 
1576  matrix4() {}
1577  matrix4(const float *m) : a(m), b(m+4), c(m+8), d(m+12) {}
1578  matrix4(const vec &a, const vec &b, const vec &c = vec(0, 0, 1))
1579  : a(a.x, b.x, c.x, 0), b(a.y, b.y, c.y, 0), c(a.z, b.z, c.z, 0), d(0, 0, 0, 1)
1580  {}
1581  matrix4(const vec4 &a, const vec4 &b, const vec4 &c, const vec4 &d = vec4(0, 0, 0, 1))
1582  : a(a), b(b), c(c), d(d)
1583  {}
1584  matrix4(const matrix4x3 &m)
1585  : a(m.a, 0), b(m.b, 0), c(m.c, 0), d(m.d, 1)
1586  {}
1587  matrix4(const matrix3 &rot, const vec &trans)
1588  : a(rot.a, 0), b(rot.b, 0), c(rot.c, 0), d(trans, 1)
1589  {}
1590 
1591  void mul(const matrix4 &x, const matrix3 &y)
1592  {
1593  a = vec4(x.a).mul(y.a.x).madd(x.b, y.a.y).madd(x.c, y.a.z);
1594  b = vec4(x.a).mul(y.b.x).madd(x.b, y.b.y).madd(x.c, y.b.z);
1595  c = vec4(x.a).mul(y.c.x).madd(x.b, y.c.y).madd(x.c, y.c.z);
1596  d = x.d;
1597  }
1598  void mul(const matrix3 &y) { mul(matrix4(*this), y); }
1599 
1600  template<class T> void mult(const matrix4 &x, const matrix4 &y)
1601  {
1602  a = T(x.a).mul(y.a.x).madd(x.b, y.a.y).madd(x.c, y.a.z).madd(x.d, y.a.w);
1603  b = T(x.a).mul(y.b.x).madd(x.b, y.b.y).madd(x.c, y.b.z).madd(x.d, y.b.w);
1604  c = T(x.a).mul(y.c.x).madd(x.b, y.c.y).madd(x.c, y.c.z).madd(x.d, y.c.w);
1605  d = T(x.a).mul(y.d.x).madd(x.b, y.d.y).madd(x.c, y.d.z).madd(x.d, y.d.w);
1606  }
1607 
1608  void mul(const matrix4 &x, const matrix4 &y) { mult<vec4>(x, y); }
1609  void mul(const matrix4 &y) { mult<vec4>(matrix4(*this), y); }
1610 
1611  void muld(const matrix4 &x, const matrix4 &y) { mult<dvec4>(x, y); }
1612  void muld(const matrix4 &y) { mult<dvec4>(matrix4(*this), y); }
1613 
1614  void rotate_around_x(float ck, float sk)
1615  {
1616  vec4 rb = vec4(b).mul(ck).madd(c, sk),
1617  rc = vec4(c).mul(ck).msub(b, sk);
1618  b = rb;
1619  c = rc;
1620  }
1621  void rotate_around_x(float angle) { rotate_around_x(cosf(angle), sinf(angle)); }
1622  void rotate_around_x(const vec2 &sc) { rotate_around_x(sc.x, sc.y); }
1623 
1624  void rotate_around_y(float ck, float sk)
1625  {
1626  vec4 rc = vec4(c).mul(ck).madd(a, sk),
1627  ra = vec4(a).mul(ck).msub(c, sk);
1628  c = rc;
1629  a = ra;
1630  }
1631  void rotate_around_y(float angle) { rotate_around_y(cosf(angle), sinf(angle)); }
1632  void rotate_around_y(const vec2 &sc) { rotate_around_y(sc.x, sc.y); }
1633 
1634  void rotate_around_z(float ck, float sk)
1635  {
1636  vec4 ra = vec4(a).mul(ck).madd(b, sk),
1637  rb = vec4(b).mul(ck).msub(a, sk);
1638  a = ra;
1639  b = rb;
1640  }
1641  void rotate_around_z(float angle) { rotate_around_z(cosf(angle), sinf(angle)); }
1642  void rotate_around_z(const vec2 &sc) { rotate_around_z(sc.x, sc.y); }
1643 
1644  void rotate(float ck, float sk, const vec &axis)
1645  {
1646  matrix3 m;
1647  m.rotate(ck, sk, axis);
1648  mul(m);
1649  }
1650  void rotate(float angle, const vec &dir) { rotate(cosf(angle), sinf(angle), dir); }
1651  void rotate(const vec2 &sc, const vec &dir) { rotate(sc.x, sc.y, dir); }
1652 
1653  void identity()
1654  {
1655  a = vec4(1, 0, 0, 0);
1656  b = vec4(0, 1, 0, 0);
1657  c = vec4(0, 0, 1, 0);
1658  d = vec4(0, 0, 0, 1);
1659  }
1660 
1661  void settranslation(const vec &v) { d.setxyz(v); }
1662  void settranslation(float x, float y, float z) { d.x = x; d.y = y; d.z = z; }
1663 
1664  void translate(const vec &p) { d.madd(a, p.x).madd(b, p.y).madd(c, p.z); }
1665  void translate(float x, float y, float z) { translate(vec(x, y, z)); }
1666  void translate(const vec &p, float scale) { translate(vec(p).mul(scale)); }
1667 
1668  void setscale(float x, float y, float z) { a.x = x; b.y = y; c.z = z; }
1669  void setscale(const vec &v) { setscale(v.x, v.y, v.z); }
1670  void setscale(float n) { setscale(n, n, n); }
1671 
1672  void scale(float x, float y, float z)
1673  {
1674  a.mul(x);
1675  b.mul(y);
1676  c.mul(z);
1677  }
1678  void scale(const vec &v) { scale(v.x, v.y, v.z); }
1679  void scale(float n) { scale(n, n, n); }
1680 
1681  void scalexy(float x, float y)
1682  {
1683  a.x *= x; a.y *= y;
1684  b.x *= x; b.y *= y;
1685  c.x *= x; c.y *= y;
1686  d.x *= x; d.y *= y;
1687  }
1688 
1689  void scalez(float k)
1690  {
1691  a.z *= k;
1692  b.z *= k;
1693  c.z *= k;
1694  d.z *= k;
1695  }
1696 
1697  void reflectz(float z)
1698  {
1699  d.add(vec4(c).mul(2*z));
1700  c.neg();
1701  }
1702 
1703  void projective(float zscale = 0.5f, float zoffset = 0.5f)
1704  {
1705  a.x = 0.5f*(a.x + a.w);
1706  a.y = 0.5f*(a.y + a.w);
1707  b.x = 0.5f*(b.x + b.w);
1708  b.y = 0.5f*(b.y + b.w);
1709  c.x = 0.5f*(c.x + c.w);
1710  c.y = 0.5f*(c.y + c.w);
1711  d.x = 0.5f*(d.x + d.w);
1712  d.y = 0.5f*(d.y + d.w);
1713  a.z = zscale*a.z + zoffset*a.w;
1714  b.z = zscale*b.z + zoffset*b.w;
1715  c.z = zscale*c.z + zoffset*c.w;
1716  d.z = zscale*d.z + zoffset*d.w;
1717  }
1718 
1719  void jitter(float x, float y)
1720  {
1721  a.x += x * a.w;
1722  a.y += y * a.w;
1723  b.x += x * b.w;
1724  b.y += y * b.w;
1725  c.x += x * c.w;
1726  c.y += y * c.w;
1727  d.x += x * d.w;
1728  d.y += y * d.w;
1729  }
1730 
1731  void transpose()
1732  {
1733  std::swap(a.y, b.x); std::swap(a.z, c.x); std::swap(a.w, d.x);
1734  std::swap(b.z, c.y); std::swap(b.w, d.y);
1735  std::swap(c.w, d.z);
1736  }
1737 
1738  void transpose(const matrix4 &m)
1739  {
1740  a = vec4(m.a.x, m.b.x, m.c.x, m.d.x);
1741  b = vec4(m.a.y, m.b.y, m.c.y, m.d.y);
1742  c = vec4(m.a.z, m.b.z, m.c.z, m.d.z);
1743  d = vec4(m.a.w, m.b.w, m.c.w, m.d.w);
1744  }
1745 
1746  void frustum(float left, float right, float bottom, float top, float znear, float zfar)
1747  {
1748  float width = right - left, height = top - bottom, zrange = znear - zfar;
1749  a = vec4(2*znear/width, 0, 0, 0);
1750  b = vec4(0, 2*znear/height, 0, 0);
1751  c = vec4((right + left)/width, (top + bottom)/height, (zfar + znear)/zrange, -1);
1752  d = vec4(0, 0, 2*znear*zfar/zrange, 0);
1753  }
1754 
1755  void perspective(float fovy, float aspect, float znear, float zfar)
1756  {
1757  float ydist = znear * tan(fovy/2*RAD), xdist = ydist * aspect;
1758  frustum(-xdist, xdist, -ydist, ydist, znear, zfar);
1759  }
1760 
1761  void ortho(float left, float right, float bottom, float top, float znear, float zfar)
1762  {
1763  float width = right - left, height = top - bottom, zrange = znear - zfar;
1764  a = vec4(2/width, 0, 0, 0);
1765  b = vec4(0, 2/height, 0, 0);
1766  c = vec4(0, 0, 2/zrange, 0);
1767  d = vec4(-(right+left)/width, -(top+bottom)/height, (zfar+znear)/zrange, 1);
1768  }
1769 
1770  void clip(const plane &p, const matrix4 &m)
1771  {
1772  float x = ((p.x<0 ? -1 : (p.x>0 ? 1 : 0)) + m.c.x) / m.a.x,
1773  y = ((p.y<0 ? -1 : (p.y>0 ? 1 : 0)) + m.c.y) / m.b.y,
1774  w = (1 + m.c.z) / m.d.z,
1775  scale = 2 / (x*p.x + y*p.y - p.z + w*p.offset);
1776  a = vec4(m.a.x, m.a.y, p.x*scale, m.a.w);
1777  b = vec4(m.b.x, m.b.y, p.y*scale, m.b.w);
1778  c = vec4(m.c.x, m.c.y, p.z*scale + 1.0f, m.c.w);
1779  d = vec4(m.d.x, m.d.y, p.offset*scale, m.d.w);
1780  }
1781 
1782  void transform(const vec &in, vec &out) const
1783  {
1784  out = vec(a).mul(in.x).add(vec(b).mul(in.y)).add(vec(c).mul(in.z)).add(vec(d));
1785  }
1786 
1787  void transform(const vec4 &in, vec &out) const
1788  {
1789  out = vec(a).mul(in.x).add(vec(b).mul(in.y)).add(vec(c).mul(in.z)).add(vec(d).mul(in.w));
1790  }
1791 
1792  void transform(const vec &in, vec4 &out) const
1793  {
1794  out = vec4(a).mul(in.x).madd(b, in.y).madd(c, in.z).add(d);
1795  }
1796 
1797  void transform(const vec4 &in, vec4 &out) const
1798  {
1799  out = vec4(a).mul(in.x).madd(b, in.y).madd(c, in.z).madd(d, in.w);
1800  }
1801 
1802  template<class T, class U> T transform(const U &in) const
1803  {
1804  T v;
1805  transform(in, v);
1806  return v;
1807  }
1808 
1809  template<class T> vec perspectivetransform(const T &in) const
1810  {
1811  vec4 v;
1812  transform(in, v);
1813  return vec(v).div(v.w);
1814  }
1815 
1816  void transformnormal(const vec &in, vec &out) const
1817  {
1818  out = vec(a).mul(in.x).add(vec(b).mul(in.y)).add(vec(c).mul(in.z));
1819  }
1820 
1821  void transformnormal(const vec &in, vec4 &out) const
1822  {
1823  out = vec4(a).mul(in.x).madd(b, in.y).madd(c, in.z);
1824  }
1825 
1826  template<class T, class U> T transformnormal(const U &in) const
1827  {
1828  T v;
1829  transformnormal(in, v);
1830  return v;
1831  }
1832 
1833  void transposedtransform(const vec &in, vec &out) const
1834  {
1835  vec p = vec(in).sub(vec(d));
1836  out.x = a.dot3(p);
1837  out.y = b.dot3(p);
1838  out.z = c.dot3(p);
1839  }
1840 
1841  void transposedtransformnormal(const vec &in, vec &out) const
1842  {
1843  out.x = a.dot3(in);
1844  out.y = b.dot3(in);
1845  out.z = c.dot3(in);
1846  }
1847 
1848  void transposedtransform(const plane &in, plane &out) const
1849  {
1850  out.x = in.dist(a);
1851  out.y = in.dist(b);
1852  out.z = in.dist(c);
1853  out.offset = in.dist(d);
1854  }
1855 
1856  float getscale() const
1857  {
1858  return sqrtf(a.x*a.y + b.x*b.x + c.x*c.x);
1859  }
1860 
1862  {
1863  return vec(d);
1864  }
1865 
1866  vec4 rowx() const { return vec4(a.x, b.x, c.x, d.x); }
1867  vec4 rowy() const { return vec4(a.y, b.y, c.y, d.y); }
1868  vec4 rowz() const { return vec4(a.z, b.z, c.z, d.z); }
1869  vec4 roww() const { return vec4(a.w, b.w, c.w, d.w); }
1870 
1871  bool invert(const matrix4 &m, double mindet = 1.0e-12);
1872 
1874  {
1875  return vec2(d.w, -d.z).div(c.z*d.w - d.z*c.w);
1876  }
1877 };
1878 
1879 inline matrix3::matrix3(const matrix4 &m)
1880  : a(m.a), b(m.b), c(m.c)
1881 {}
1882 
1884  : a(m.a), b(m.b), c(m.c), d(m.d)
1885 {}
1886 
1887 struct matrix2
1888 {
1890 
1891  matrix2() {}
1892  matrix2(const vec2 &a, const vec2 &b) : a(a), b(b) {}
1893  explicit matrix2(const matrix4 &m) : a(m.a), b(m.b) {}
1894  explicit matrix2(const matrix3 &m) : a(m.a), b(m.b) {}
1895 };
1896 
1897 struct squat
1898 {
1899  short x, y, z, w;
1900 
1901  squat() {}
1902  squat(const vec4 &q) { convert(q); }
1903 
1904  void convert(const vec4 &q)
1905  {
1906  x = short(q.x*32767.5f-0.5f);
1907  y = short(q.y*32767.5f-0.5f);
1908  z = short(q.z*32767.5f-0.5f);
1909  w = short(q.w*32767.5f-0.5f);
1910  }
1911 
1912  void lerp(const vec4 &a, const vec4 &b, float t)
1913  {
1914  vec4 q;
1915  q.lerp(a, b, t);
1916  convert(q);
1917  }
1918 };
1919 
1921 extern bool raysphereintersect(const vec &center, float radius, const vec &o, const vec &ray, float &dist);
1922 extern bool rayboxintersect(const vec &b, const vec &s, const vec &o, const vec &ray, float &dist, int &orient);
1923 extern bool linecylinderintersect(const vec &from, const vec &to, const vec &start, const vec &end, float radius, float &dist);
1924 
1927 extern const vec2 sincos360[];
1928 static inline int mod360(int angle)
1929 {
1930  if(angle < 0) angle = 360 + (angle <= -360 ? angle%360 : angle);
1931  else if(angle >= 360) angle %= 360;
1932  return angle;
1933 }
1934 static inline const vec2 &sincosmod360(int angle) { return sincos360[mod360(angle)]; }
1935 static inline float cos360(int angle) { return sincos360[angle].x; }
1936 static inline float sin360(int angle) { return sincos360[angle].y; }
1937 static inline float tan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.y/sc.x; }
1938 static inline float cotan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.x/sc.y; }
1939 
void invert()
Definition: geom.hpp:735
matrix4(const matrix4x3 &m)
Definition: geom.hpp:1584
bvec4(const bvec &v, uchar w=0)
Definition: geom.hpp:1467
ushort & operator[](int i)
Definition: geom.hpp:1509
vec(const vec2 &v, float z=0)
Definition: geom.hpp:128
float dot2(const T &o) const
dot product (line by line) of 2 dimensions
Definition: geom.hpp:161
void lerp(const matrix4x3 &from, const matrix4x3 &to, float t)
Definition: geom.hpp:975
void scale(float k)
Definition: geom.hpp:744
vec & rotate_around_x(const vec2 &sc)
Definition: geom.hpp:264
short w
Definition: geom.hpp:1899
bvec4()
Definition: geom.hpp:1465
dualquat & lerp(const dualquat &from, const dualquat &to, float t)
Definition: geom.hpp:562
vec c
Definition: geom.hpp:904
dualquat(const quat &q, const vec &p)
Definition: geom.hpp:541
quat(const matrix4x3 &m)
Definition: geom.hpp:455
vec a
Definition: geom.hpp:1209
Definition: geom.hpp:902
void muld(const matrix4 &x, const matrix4 &y)
Definition: geom.hpp:1611
bool iszero() const
Definition: geom.hpp:65
uchar & operator[](int i)
Definition: geom.hpp:1469
matrix2(const matrix3 &m)
Definition: geom.hpp:1894
#define RAD
Definition: cube_types.hpp:32
quat & mul(float k)
Definition: geom.hpp:462
int operator[](int i) const
Definition: geom.hpp:1318
vec2 & min(const vec2 &o)
Definition: geom.hpp:81
float magnitude() const
Definition: geom.hpp:376
vec2 & max(float f)
Definition: geom.hpp:84
ivec2 & shr(int n)
Definition: geom.hpp:1332
void transform(const vec4 &in, vec &out) const
Definition: geom.hpp:1787
vec transposedtransform(const vec &v) const
Definition: geom.hpp:647
void rotationalign(const vec &d, const vec &z)
Cheap (and mathematically advanced) rotation method.
Definition: geom.hpp:766
vec & rotate_around_y(float c, float s)
Definition: geom.hpp:257
vec transform(const vec2 &o)
Definition: geom.hpp:894
void lerp(const bvec4 &a, const bvec4 &b, float t)
Definition: geom.hpp:1479
bool operator!=(const plane &p) const
Definition: geom.hpp:1128
triangle & add(const vec &o)
Definition: geom.hpp:1214
ivec2()
Definition: geom.hpp:1312
const T & max(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:224
void rotate_around_x(float angle)
Definition: geom.hpp:871
vec4 & div3(float f)
Definition: geom.hpp:401
T transform(const U &in) const
Definition: geom.hpp:1802
int dot(const ivec &o) const
Definition: geom.hpp:1284
vec2()
Definition: geom.hpp:46
plane(const vec &c, float off)
Definition: geom.hpp:1131
bvec(const vec &v)
Definition: geom.hpp:1409
void transposedtransformnormal(const vec &in, vec &out) const
Definition: geom.hpp:1841
vec b
Definition: geom.hpp:670
bool operator!=(const bvec &v) const
Definition: geom.hpp:1416
bool operator==(const ivec4 &o) const
Definition: geom.hpp:1379
vec4 & normalize()
Definition: geom.hpp:378
triangle interface does not inherit from vec because 3 members (the 3 vertices) are required to descr...
Definition: geom.hpp:1207
dvec4()
Definition: geom.hpp:1559
short x
Definition: geom.hpp:1899
GLenum GLsizei GLsizei height
Definition: glexts.hpp:291
float scalartriple(const vec &a, const vec &b) const
scalar triple product can be used to calculate the volume of a 3 dimensional parallelogram ...
Definition: geom.hpp:216
matrix4x3(const dualquat &dq)
Definition: geom.hpp:909
vec4 & addw(float f)
Definition: geom.hpp:405
vec2 a
Definition: geom.hpp:1889
matrix2()
Definition: geom.hpp:1891
plane(const vec4 &p)
Definition: geom.hpp:1132
vec & projectxy(const vec &n)
Definition: geom.hpp:225
unsigned int uint
Definition: cube_types.hpp:9
vec4 & msub(const vec4 &a, const B &b)
Definition: geom.hpp:411
ivec2(const ivec &v)
Definition: geom.hpp:1315
float fovy
Definition: rendergl.cpp:802
vec4 & lerp(const vec4 &b, float t)
Definition: geom.hpp:380
ivec(const vec &v)
Definition: geom.hpp:1236
Definition: geom.hpp:1897
ivec4()
Definition: geom.hpp:1374
vec & min(const vec &o)
vector min/max-comparison and clamp methods
Definition: geom.hpp:186
vec2 & abs()
Definition: geom.hpp:85
float operator[](int i) const
Definition: geom.hpp:360
vec4 & mul(float f)
Definition: geom.hpp:399
void lerp(const vec4 &a, const vec4 &b, float t)
Definition: geom.hpp:1912
vec & reflect(const vec &n)
Definition: geom.hpp:220
void toplane(const vec &n, const vec &p)
Definition: geom.hpp:1141
void transposedtransform(const vec &in, vec &out) const
Definition: geom.hpp:1833
int & operator[](int i)
Definition: geom.hpp:1250
void setscale(float n)
Definition: geom.hpp:935
vec & rotate_around_x(float angle)
Definition: geom.hpp:260
bvec()
Definition: geom.hpp:1407
dvec4(double x, double y, double z, double w)
Definition: geom.hpp:1560
float operator[](int i) const
Definition: geom.hpp:52
float trace() const
Definition: geom.hpp:790
ivec2(const vec2 &v)
Definition: geom.hpp:1314
void transpose(const matrix4 &m)
Definition: geom.hpp:1738
void rotate_around_z(float ck, float sk)
Definition: geom.hpp:884
vec & project(const vec &n)
vector projection
Definition: geom.hpp:223
ivec()
Definition: geom.hpp:1235
bvec & shr(int n)
Definition: geom.hpp:1446
void settranslation(const vec &v)
Definition: geom.hpp:1661
void scale(const vec &v)
Definition: geom.hpp:943
void lerp(const bvec &a, const bvec &b, int ka, int kb, int d)
Definition: geom.hpp:1434
ivec & add(int n)
Definition: geom.hpp:1269
quat & add(const vec4 &o)
Definition: geom.hpp:460
float squaredlen() const
calculate the squared length of this vector (pythagoras)
Definition: geom.hpp:159
const int R[3]
Definition: geom.hpp:1221
bool operator!=(const bvec4 &v) const
Definition: geom.hpp:1473
dvec4 & add(double f)
Definition: geom.hpp:1566
quat(const matrix4 &m)
Definition: geom.hpp:456
vec & mul(const vec &o)
scalar multiplication
Definition: geom.hpp:168
void frustum(float left, float right, float bottom, float top, float znear, float zfar)
Definition: geom.hpp:1746
float offset
Definition: geom.hpp:1123
vec4 d
Definition: geom.hpp:1574
ivec & shr(int n)
Definition: geom.hpp:1266
void translate(float x, float y, float z)
Definition: geom.hpp:1665
bool isnormalized() const
"is this vector normalized?"
Definition: geom.hpp:200
vec & rotate_around_z(const vec2 &sc)
Definition: geom.hpp:263
vec transposedtransform(const vec &o) const
Definition: geom.hpp:1101
vec4 & div(float f)
Definition: geom.hpp:402
bool operator!=(const vec &o) const
Definition: geom.hpp:151
vec invertedrotate(const vec &v) const
Definition: geom.hpp:492
float dist(const vec4 &p) const
Definition: geom.hpp:1126
vec & cross(const vec &o, const vec &a, const vec &b)
Definition: geom.hpp:212
vec transposedtransformnormal(const vec &o) const
Definition: geom.hpp:1103
bool toplane(const vec &a, const vec &b, const vec &c)
Definition: geom.hpp:1147
void lerp(const matrix4x3 &to, float t)
Definition: geom.hpp:968
bool operator!=(const vec2 &o) const
Definition: geom.hpp:55
void multranspose(const matrix3 &m, const matrix3 &n)
Definition: geom.hpp:697
vec transform(const vec &o) const
Definition: geom.hpp:843
void projective(float zscale=0.5f, float zoffset=0.5f)
Definition: geom.hpp:1703
vec2 & msub(const vec2 &a, const B &b)
Definition: geom.hpp:91
2-dimensional float vectors
Definition: geom.hpp:38
ivec2 & div(const ivec2 &v)
Definition: geom.hpp:1338
vec4 rowx() const
Definition: geom.hpp:1106
void transpose(const M &m)
Definition: geom.hpp:720
static float cotan360(int angle)
Definition: geom.hpp:1938
float dot(const vec2 &o) const
Definition: geom.hpp:66
vec4 & add(const vec4 &o)
Definition: geom.hpp:404
float squaredist(const vec &e) const
distance calculation methods
Definition: geom.hpp:203
void transposemul(const matrix4x3 &m, const matrix4x3 &n)
Definition: geom.hpp:1029
vec2(float x, float y)
Definition: geom.hpp:47
GLenum GLsizei width
Definition: glexts.hpp:291
void rotate_around_y(float ck, float sk)
Definition: geom.hpp:1624
friend std::ostream & operator<<(std::ostream &os, const ivec &v)
Output operator, used for simple << ivec << functionality: output of form "(x, y, z)"...
Definition: geom.hpp:1258
void transposedtransform(const plane &in, plane &out) const
Definition: geom.hpp:1848
void rotate_around_z(const vec2 &sc)
Definition: geom.hpp:1642
float dist(const vec &e, vec &t) const
Definition: geom.hpp:205
vec2 & reflect(const vec2 &n)
Definition: geom.hpp:87
vec()
a variety of constructor calls is supported
Definition: geom.hpp:122
vec4 & rotate_around_z(float angle)
Definition: geom.hpp:419
void rotate_around_y(float angle)
Definition: geom.hpp:1631
bool operator==(const bvec &v) const
Definition: geom.hpp:1415
vec transform(const vec &v) const
Definition: geom.hpp:637
void rotate_around_x(float ck, float sk)
Definition: geom.hpp:1614
ivec2 & min(int n)
Definition: geom.hpp:1345
void mul(const matrix3 &y)
Definition: geom.hpp:1598
quat transform(const quat &q) const
Definition: geom.hpp:642
float aspect
Definition: rendergl.cpp:802
float magnitude() const
Definition: geom.hpp:68
void setscale(float x, float y, float z)
Definition: geom.hpp:933
static vec hexcolor(int color)
Definition: geom.hpp:318
ivec & min(int n)
Definition: geom.hpp:1279
vec2 b
Definition: geom.hpp:1889
void mulorient(const quat &q, const dualquat &base)
Definition: geom.hpp:591
vec abstransform(const vec &o) const
Definition: geom.hpp:848
static const vec2 & sincosmod360(int angle)
Definition: geom.hpp:1934
bool operator==(const bvec4 &v) const
Definition: geom.hpp:1472
vec4 & sub(const vec4 &o)
Definition: geom.hpp:406
ivec & abs()
Definition: geom.hpp:1281
void lerp(const bvec4 &a, const bvec4 &b, int ka, int kb, int d)
Definition: geom.hpp:1487
void rotate(float angle, const vec &d)
Definition: geom.hpp:1058
3 dimensional vector containing unsigned shorts.
Definition: geom.hpp:1501
matrix3()
Definition: geom.hpp:672
float dist(const vec &e) const
Definition: geom.hpp:204
void rotate_around_y(const vec2 &sc)
Definition: geom.hpp:882
ivec2 & max(const ivec2 &o)
Definition: geom.hpp:1344
void setxyz(const vec &v)
Definition: geom.hpp:413
GLint GLint GLint GLint GLint GLint GLint GLbitfield mask
Definition: glexts.hpp:299
ivec & mul(const ivec &v)
Definition: geom.hpp:1271
void rotate_around_z(float ck, float sk)
Definition: geom.hpp:1634
ivec & min(const ivec &o)
Definition: geom.hpp:1277
static float cos360(int angle)
Definition: geom.hpp:1935
bool operator==(const ivec2 &o) const
Definition: geom.hpp:1320
float dist_to_bb(const T &min, const T &max) const
calculate vector's distance to a bounding box
Definition: geom.hpp:303
quat(const vec &v)
Definition: geom.hpp:447
ivec4(const vec4 &v)
Definition: geom.hpp:1377
void flip()
Definition: geom.hpp:1495
vec transposedtransformnormal(const vec &v) const
Definition: geom.hpp:657
int cross(const ivec2 &o) const
Definition: geom.hpp:1349
Definition: geom.hpp:668
uchar operator[](int i) const
Definition: geom.hpp:1413
void mul(const matrix4 &y)
Definition: geom.hpp:1609
vec & rotate(const vec2 &sc, const vec &d)
Definition: geom.hpp:275
void transposemul(const matrix3 &n)
Definition: geom.hpp:711
short & operator[](int i)
Definition: geom.hpp:1528
vec & set(int i, float f)
Definition: geom.hpp:139
vec(float a, float b, float c)
Definition: geom.hpp:125
vec & rotate_around_y(const vec2 &sc)
Definition: geom.hpp:265
void jitter(float x, float y)
Definition: geom.hpp:1719
vec & rotate(float angle, const vec &d)
Definition: geom.hpp:274
vec4 & mul3(float f)
basic algebraic methods
Definition: geom.hpp:398
void rotate_around_z(const vec2 &sc)
Definition: geom.hpp:1098
void multranspose(const matrix4x3 &m, const matrix4x3 &n)
Definition: geom.hpp:1038
vec c
Definition: geom.hpp:670
void rotate_around_z(float angle)
Definition: geom.hpp:1097
vec4 & rotate_around_z(float c, float s)
rotation members
Definition: geom.hpp:416
float zintersect(const vec &p) const
Definition: geom.hpp:1200
void transposemul(const matrix3 &m, const matrix3 &n)
Definition: geom.hpp:705
void scale(float x, float y, float z)
Definition: geom.hpp:937
void rotate_around_y(float angle)
Definition: geom.hpp:1087
plane(int d, float off)
Definition: geom.hpp:1133
vec & mul(float f)
Definition: geom.hpp:169
void setyaw(float angle)
Definition: geom.hpp:785
dvec4 & add(const dvec4 &o)
Definition: geom.hpp:1567
plane & translate(const vec &p)
Definition: geom.hpp:1186
float cross(const vec2 &o) const
Definition: geom.hpp:70
void multranspose(const matrix3 &n)
Definition: geom.hpp:703
vec transform(const vec &o) const
Definition: geom.hpp:1100
vec b
Definition: geom.hpp:904
Definition: geom.hpp:536
vec & add(float f)
Definition: geom.hpp:175
ivec & mul(int n)
Definition: geom.hpp:1267
ICOMMAND * f(float *a, float *b), floatret(*a **b)
quat & mul(const quat &p, const quat &o)
Definition: geom.hpp:464
vec & lerp(const vec &a, const vec &b, float t)
Definition: geom.hpp:242
4-dimensional float vector all methods stay basicly the same but with an extra dimension ...
Definition: geom.hpp:343
void mul(const matrix3 &m, const matrix3 &n)
Definition: geom.hpp:689
friend std::ostream & operator<<(std::ostream &os, const vec2 &v)
Output operator, used for simple << vec2 << functionality: "(x, y)" You may want to set the precision...
Definition: geom.hpp:59
short y
Definition: geom.hpp:1899
ivec & clamp(int l, int h)
Definition: geom.hpp:1282
svec()
Definition: geom.hpp:1524
vec4 a
Definition: geom.hpp:1574
svec2(short x, short y)
Definition: geom.hpp:1544
quat(const vec &axis, float angle)
Definition: geom.hpp:439
dualquat & invert()
Definition: geom.hpp:570
bvec & normalize()
Definition: geom.hpp:1422
float magnitude() const
vector's magnitude in all 3 (XYZ) dimensions
Definition: geom.hpp:195
unsigned short ushort
Definition: cube_types.hpp:8
vec & neg()
turn all 3 (XYZ) coordinates into its negative values
Definition: geom.hpp:183
void rotate_around_y(const vec2 &sc)
Definition: geom.hpp:1632
vec & clamp(float f, float h)
Definition: geom.hpp:190
const int D[3]
Definition: geom.hpp:1223
float squaredlen() const
Definition: geom.hpp:375
float dist(const vec &p) const
Definition: geom.hpp:1125
static float sin360(int angle)
Definition: geom.hpp:1936
void mul(const matrix4x3 &n)
Definition: geom.hpp:998
void scale(float n)
Definition: geom.hpp:944
vec2 & div(const vec2 &o)
Definition: geom.hpp:75
void convertmatrix(const M &m)
Definition: geom.hpp:498
ivec2 & max(int n)
Definition: geom.hpp:1346
ivec2 & mul(int n)
Definition: geom.hpp:1333
vec4(float x, float y, float z, float w)
Definition: geom.hpp:355
vec2 & lerp(const vec2 &a, const vec2 &b, float t)
Definition: geom.hpp:89
else loopi(numargs)
Definition: command.cpp:3019
void settranslation(float x, float y, float z)
Definition: geom.hpp:947
void transformnormal(const vec &in, vec &out) const
Definition: geom.hpp:1816
vec4 & subw(float f)
Definition: geom.hpp:407
vec & msub(const vec &a, const B &b)
Definition: geom.hpp:244
ivec & sub(int n)
Definition: geom.hpp:1270
double x
Definition: geom.hpp:1557
static uint hthash(const vec2 &k)
hashtable hashing function to create unique key
Definition: geom.hpp:101
vec2 & lerp(const vec2 &b, float t)
Definition: geom.hpp:88
void transformnormal(const vec &in, vec4 &out) const
Definition: geom.hpp:1821
bool reject(const vec &o, float r)
Definition: geom.hpp:207
static bool htcmp(const vec2 &x, const vec2 &y)
hashtable comparison function
Definition: geom.hpp:95
int & operator[](int i)
Definition: geom.hpp:1317
bool operator!=(const ivec4 &o) const
Definition: geom.hpp:1380
void rotate(float angle, const vec &dir)
Definition: geom.hpp:1650
bool iszero() const
"do all cartesian coordinates (XYZ) of this vector have the value zero?"
Definition: geom.hpp:157
void mul(float k)
Definition: geom.hpp:925
void settranslation(const vec &p)
Definition: geom.hpp:946
vec & rotate_around_y(float angle)
Definition: geom.hpp:261
vec4 & rotate_around_y(float c, float s)
Definition: geom.hpp:418
svec(const ivec &v)
Definition: geom.hpp:1526
float dot(const vec &o) const
dot product (line by line) of all 3 dimensions
Definition: geom.hpp:163
ivec & div(int n)
Definition: geom.hpp:1268
vec rowx() const
Definition: geom.hpp:897
triangle & sub(const vec &o)
Definition: geom.hpp:1215
matrix4x3()
Definition: geom.hpp:906
void clip(const plane &p, const matrix4 &m)
Definition: geom.hpp:1770
ivec & add(const ivec &v)
Definition: geom.hpp:1273
vec & max(const vec &o)
Definition: geom.hpp:187
vec & lerp(const vec &b, float t)
interpolation between two vectors
Definition: geom.hpp:241
ivec4(int x, int y, int z, int w)
Definition: geom.hpp:1376
dvec4 & mul(double f)
Definition: geom.hpp:1564
static int mod360(int angle)
Definition: geom.hpp:1928
vec d
Definition: geom.hpp:904
vec2 & min(float f)
Definition: geom.hpp:83
bool calcangleaxis(float tr, float &angle, vec &axis, float threshold=1e-16f) const
Definition: geom.hpp:792
vec2 & sub(const vec2 &o)
Definition: geom.hpp:79
bool operator==(const triangle &t) const
Definition: geom.hpp:1217
matrix4x3(const matrix3 &rot, const vec &trans)
Definition: geom.hpp:908
ivec2 & mul(const ivec2 &v)
Definition: geom.hpp:1337
void translate(const vec &p)
Definition: geom.hpp:949
vec & max(float f)
Definition: geom.hpp:189
void start(const char *filename, int videofps, int videow, int videoh, bool sound)
Definition: movie.cpp:975
vec(const float *v)
Definition: geom.hpp:127
vec rowy() const
Definition: geom.hpp:898
plane & invert()
Definition: geom.hpp:1173
void normalize()
Definition: geom.hpp:961
static ivec ceil(const vec &o)
Definition: geom.hpp:1288
void rotate(float ck, float sk, const vec &axis)
Definition: geom.hpp:1063
vec & rotate_around_x(float c, float s)
Definition: geom.hpp:256
void setyaw(float ck, float sk)
Definition: geom.hpp:778
vector with 3 floats and some useful methods.
Definition: geom.hpp:110
dualquat & lerp(const dualquat &to, float t)
Definition: geom.hpp:555
void rotate_around_x(const vec2 &sc)
Definition: geom.hpp:872
void rotate_around_z(float ck, float sk)
Definition: geom.hpp:1090
bool iszero() const
Definition: geom.hpp:1330
short & operator[](int i)
Definition: geom.hpp:1546
ivec2 & sub(const ivec2 &v)
Definition: geom.hpp:1340
float dot(const vec4 &o) const
Definition: geom.hpp:372
void scalexy(float x, float y)
Definition: geom.hpp:1681
matrix3(const vec &a, const vec &b, const vec &c)
Definition: geom.hpp:673
double w
Definition: geom.hpp:1557
bool rayintersect(const vec &o, const vec &ray, float &dist)
Definition: geom.hpp:1157
ivec2 & abs()
Definition: geom.hpp:1347
vec2 & mul(const vec2 &o)
Definition: geom.hpp:73
bool operator==(const svec2 &o) const
Definition: geom.hpp:1549
ivec4(const ivec &p, int w=0)
Definition: geom.hpp:1375
vec2 & add(float f)
Definition: geom.hpp:76
vec4 & mul(const vec4 &o)
Definition: geom.hpp:400
ivec & div(const ivec &v)
Definition: geom.hpp:1272
Definition: geom.hpp:1887
vec & sub(const vec &o)
scalar subtraction
Definition: geom.hpp:177
void mul(const matrix3 &m, const matrix4x3 &n)
Definition: geom.hpp:1000
void rotate_around_z(float angle)
Definition: geom.hpp:891
const T & min(const inexor::rpc::SharedVar< T > &a, const T &b)
Definition: SharedVar.hpp:210
void reflectz(float z)
Definition: geom.hpp:1697
short operator[](int i) const
Definition: geom.hpp:1547
float & operator[](int i)
Definition: geom.hpp:51
float getscale() const
Definition: geom.hpp:1856
dvec4(const vec4 &v)
Definition: geom.hpp:1561
void settranslation(float x, float y, float z)
Definition: geom.hpp:1662
bool iszero() const
Definition: geom.hpp:1475
friend std::ostream & operator<<(std::ostream &os, const vec &v)
Output operator, used for simple << vec << functionality: output of form"(x, y, z)" You may want to s...
Definition: geom.hpp:143
void lerp(const bvec &a, const bvec &b, float t)
Definition: geom.hpp:1432
const int C[3]
Definition: geom.hpp:1222
Definition: geom.hpp:1572
matrix4(const matrix3 &rot, const vec &trans)
Definition: geom.hpp:1587
vec4 & rotate_around_x(float c, float s)
Definition: geom.hpp:417
2 dimensional vector containing shorts.
Definition: geom.hpp:1535
void rotate_around_x(float ck, float sk)
Definition: geom.hpp:1070
ivec & max(const ivec &o)
Definition: geom.hpp:1278
bool iszero() const
Definition: geom.hpp:1418
void accumulate(const matrix4x3 &m, float k)
Definition: geom.hpp:953
vec4 rowz() const
Definition: geom.hpp:1868
3-dimensional UNSIGNED CHAR vector.
Definition: geom.hpp:1398
2 dimensional integer vector.
Definition: geom.hpp:1304
void translate(float x, float y, float z)
Definition: geom.hpp:950
quat(float x, float y, float z, float w)
Definition: geom.hpp:438
bvec(uchar x, uchar y, uchar z)
Definition: geom.hpp:1408
vec transposedtransform(const vec &o) const
Definition: geom.hpp:847
void ortho(float left, float right, float bottom, float top, float znear, float zfar)
Definition: geom.hpp:1761
vec transposedtransform(const vec2 &o) const
Definition: geom.hpp:895
void mul(const matrix3 &rot, const vec &trans, const matrix4x3 &n)
Definition: geom.hpp:1008
float & operator[](int i)
operators for accessing XYZ vector coordinates
Definition: geom.hpp:136
bool operator!=(const ivec2 &o) const
Definition: geom.hpp:1321
vec4 & neg()
Definition: geom.hpp:409
vec a
Definition: geom.hpp:670
quat()
Definition: geom.hpp:437
squat(const vec4 &q)
Definition: geom.hpp:1902
void scale(const vec &v)
Definition: geom.hpp:1678
matrix4x3(const vec &a, const vec &b, const vec &c, const vec &d)
Definition: geom.hpp:907
ivec2 & min(const ivec2 &o)
Definition: geom.hpp:1343
vec & abs()
Receive the absolute values of this vec.
Definition: geom.hpp:154
static ivec floor(const vec &o)
Definition: geom.hpp:1287
void setscale(float x, float y, float z)
Definition: geom.hpp:1668
bool raysphereintersect(const vec &center, float radius, const vec &o, const vec &ray, float &dist)
physics engine: collision (intersection) check functions
Definition: geom.cpp:54
matrix4(const vec &a, const vec &b, const vec &c=vec(0, 0, 1))
Definition: geom.hpp:1578
void orthogonal(const vec &d)
orthogonal projection
Definition: geom.hpp:278
ivec & cross(const ivec &a, const ivec &b)
Definition: geom.hpp:1283
void mul(const matrix4 &x, const matrix3 &y)
Definition: geom.hpp:1591
quaternions are number systems that extend complex numbers complex numbers extend the number system o...
Definition: geom.hpp:435
friend std::ostream & operator<<(std::ostream &os, const vec4 &v)
Output operator, used for simple << vec4 << functionality: output of form "(x, y, z...
Definition: geom.hpp:364
ivec & max(int n)
Definition: geom.hpp:1280
vec2 & normalize()
Definition: geom.hpp:69
vec b
Definition: geom.hpp:1209
vec & projectxy(const vec &n, float threshold)
Definition: geom.hpp:232
vec(int v[3])
Definition: geom.hpp:126
plane()
Definition: geom.hpp:1130
void rotate_around_y(const vec2 &sc)
Definition: geom.hpp:1088
int orient
Definition: octaedit.cpp:164
matrix3(float angle, const vec &axis)
Definition: geom.hpp:674
float absdot(const vec &o) const
dot product with absolute values.
Definition: geom.hpp:165
triangle(const vec &a, const vec &b, const vec &c)
Definition: geom.hpp:1211
float dist_to_bb(const T &o, S size) const
Definition: geom.hpp:313
void invert()
Definition: geom.hpp:1056
int operator[](int i) const
Definition: geom.hpp:1251
void rotate_around_x(float angle)
Definition: geom.hpp:1621
float dist2(const vec &o) const
Definition: geom.hpp:206
int d
Definition: octaedit.cpp:1749
vec & neg2()
turn XY coordinates into its negative values
Definition: geom.hpp:181
void rotate_around_y(float ck, float sk)
Definition: geom.hpp:1080
void translate(const vec &p)
Definition: geom.hpp:608
void t(T x, const char *cmp)
Definition: utilTest.cpp:52
vec tonormal() const
Definition: geom.hpp:1420
vec transform(const vec2 &o) const
Definition: geom.hpp:1104
void scale(float k)
Definition: geom.hpp:616
squat()
Definition: geom.hpp:1901
matrix4()
Definition: geom.hpp:1576
triangle()
Definition: geom.hpp:1212
bool invert(const matrix4 &m, double mindet=1.0e-12)
Definition: geom.cpp:15
void transpose()
Definition: geom.hpp:713
#define dir(name, v, d, s, os)
Definition: physics.cpp:2014
vec2 & div(float f)
Definition: geom.hpp:74
unsigned char uchar
Basic type definitions.
Definition: cube_types.hpp:7
vec(float yaw, float pitch)
vector constructor which converts yaw and pitch angles to XYZ coordinates
Definition: geom.hpp:133
ivec & sub(const ivec &v)
Definition: geom.hpp:1274
ivec(int d, int row, int col, int depth)
Definition: geom.hpp:1238
T transformnormal(const U &in) const
Definition: geom.hpp:1826
void translate(const vec &p)
Definition: geom.hpp:1664
static bvec fromcolor(const vec &v)
Definition: geom.hpp:1448
void scale(float n)
Definition: geom.hpp:1679
quat dual
Definition: geom.hpp:538
vec gettranslation() const
Definition: geom.hpp:1861
float operator[](int i) const
Definition: geom.hpp:137
bool operator==(const plane &p) const
Definition: geom.hpp:1127
void normalize()
Definition: geom.hpp:601
vec gettranslation() const
Definition: geom.hpp:662
dualquat & add(const dualquat &d)
Definition: geom.hpp:553
vec & reflectz(float rz)
vector reflection (around angle or other vectors)
Definition: geom.hpp:219
int end()
Definition: glemu.cpp:256
bool operator==(const vec2 &o) const
Definition: geom.hpp:54
GLuint GLuint GLintptr GLsizeiptr size
Definition: glexts.hpp:412
vec & rescale(float k)
scale a vector to a certain length
Definition: geom.hpp:247
void rotate_around_x(const vec2 &sc)
Definition: geom.hpp:1078
GLintptr offset
Definition: glexts.hpp:354
vec & rotate_around_z(float c, float s)
vector rotation methods
Definition: geom.hpp:255
vec a
Definition: geom.hpp:904
4 dimensional integer vector.
Definition: geom.hpp:1365
vec2 & clamp(float l, float h)
Definition: geom.hpp:86
void transform(const vec &in, vec &out) const
Definition: geom.hpp:1782
void setscale(const vec &v)
Definition: geom.hpp:1669
void mul(const matrix4x3 &m, const matrix4x3 &n)
Definition: geom.hpp:991
void setscale(float n)
Definition: geom.hpp:1670
matrix4(const vec4 &a, const vec4 &b, const vec4 &c, const vec4 &d=vec4(0, 0, 0, 1))
Definition: geom.hpp:1581
svec(short x, short y, short z)
Definition: geom.hpp:1525
void scalez(float k)
Definition: geom.hpp:1689
vec4 & lerp(const vec4 &a, const vec4 &b, float t)
Definition: geom.hpp:388
dualquat()
Definition: geom.hpp:540
ivec(int a, int b, int c)
Definition: geom.hpp:1237
matrix2(const vec2 &a, const vec2 &b)
Definition: geom.hpp:1892
void mulorient(const quat &q)
Definition: geom.hpp:585
vec & add(const vec &o)
scalar sum
Definition: geom.hpp:174
vec2 & neg()
Definition: geom.hpp:80
Definition: geom.hpp:1555
vec4 rowz() const
Definition: geom.hpp:1108
float squaredlen() const
Definition: geom.hpp:67
matrix4(const float *m)
Definition: geom.hpp:1577
bool iszero() const
Definition: geom.hpp:1552
bool rayboxintersect(const vec &b, const vec &s, const vec &o, const vec &ray, float &dist, int &orient)
Definition: geom.cpp:67
float magnitude2() const
vector's magnitude in XY dimension
Definition: geom.hpp:193
void restorew()
Definition: geom.hpp:458
dualquat(const quat &q)
Definition: geom.hpp:549
matrix3(const quat &q)
Definition: geom.hpp:675
vec(float a)
Definition: geom.hpp:124
static float tan360(int angle)
Definition: geom.hpp:1937
vec & sub(float f)
Definition: geom.hpp:178
plane & reflectz(float rz)
Definition: geom.hpp:1166
dvec4 & mul(const dvec4 &o)
Definition: geom.hpp:1565
quat & mul(const quat &o)
Definition: geom.hpp:472
void translate(const vec &p, float scale)
Definition: geom.hpp:1666
bool insidebb(const T &o, U size) const
Definition: geom.hpp:297
void rotate_around_y(float ck, float sk)
Definition: geom.hpp:874
void normalize()
Definition: geom.hpp:737
ivec2 & div(int n)
Definition: geom.hpp:1334
void convert(const vec4 &q)
Definition: geom.hpp:1904
void rotate_around_x(float ck, float sk)
Definition: geom.hpp:864
vec4 c
Definition: geom.hpp:1574
quat(const matrix3 &m)
Definition: geom.hpp:454
vec4 rowy() const
Definition: geom.hpp:1867
int dot(const ivec2 &o) const
Definition: geom.hpp:1348
float dist(const plane &p) const
Definition: geom.hpp:1285
ivec2 & mask(int n)
Definition: geom.hpp:1341
const vec2 sincos360[]
sine and cosine values are stored in approximated valuey because calculating them in realtime would b...
bool operator!=(const svec2 &o) const
Definition: geom.hpp:1550
float dot3(const T &o) const
dot products
Definition: geom.hpp:371
vec tocolor() const
Definition: geom.hpp:1449
vec transformnormal(const vec &v) const
Definition: geom.hpp:652
double z
Definition: geom.hpp:1557
void accumulate(const dualquat &d, float k)
Definition: geom.hpp:630
void mul(const dualquat &p, const dualquat &o)
Definition: geom.hpp:578
void rotate(const vec2 &sc, const vec &dir)
Definition: geom.hpp:1651
void rotate(float ck, float sk, const vec &axis)
Definition: geom.hpp:756
vec4(const float *v)
Definition: geom.hpp:356
vec4 & rotate_around_y(float angle)
Definition: geom.hpp:421
vec & min(float f)
Definition: geom.hpp:188
svec2()
Definition: geom.hpp:1543
vec2 & max(const vec2 &o)
Definition: geom.hpp:82
short operator[](int i) const
Definition: geom.hpp:1529
void setscale(const vec &v)
Definition: geom.hpp:934
matrix2(const matrix4 &m)
Definition: geom.hpp:1893
void calcangleaxis(float &angle, vec &axis)
Definition: geom.hpp:476
static bvec from565(ushort c)
Definition: geom.hpp:1451
void invert(const matrix3 &o)
Definition: geom.hpp:727
bool operator==(const ivec &v) const
Definition: geom.hpp:1254
ivec2 & shl(int n)
Definition: geom.hpp:1331
void rotate(float angle, const vec &axis)
Definition: geom.hpp:751
vec rowz() const
Definition: geom.hpp:899
vec & div(float f)
Definition: geom.hpp:172
vec(int a)
Definition: geom.hpp:123
float dot(const vec &o) const
Definition: geom.hpp:373
void rotate_around_z(const vec2 &sc)
Definition: geom.hpp:892
vec2 & sub(float f)
Definition: geom.hpp:78
vec & div(const vec &o)
scalar division
Definition: geom.hpp:171
ivec & neg()
Definition: geom.hpp:1276
void scale(float x, float y, float z)
Definition: geom.hpp:1672
float & operator[](int i)
operators for XYZ coordinate access
Definition: geom.hpp:359
quat real
Definition: geom.hpp:538
plane & normalize()
Definition: geom.hpp:1192
void orthonormalize(vec &s, vec &t) const
Definition: geom.hpp:282
ivec & shl(int n)
Definition: geom.hpp:1265
ivec2 & add(const ivec2 &v)
Definition: geom.hpp:1339
quat & sub(const vec4 &o)
Definition: geom.hpp:461
vec & madd(const vec &a, const B &b)
Definition: geom.hpp:243
vec & projectxydir(const vec &n)
Definition: geom.hpp:224
static void color(const bvec &v, uchar alpha=255)
Definition: glemu.hpp:71
ivec2(int x, int y)
Definition: geom.hpp:1313
vec4 & neg3()
Definition: geom.hpp:408
void rotate_around_z(float angle)
Definition: geom.hpp:1641
dualquat & mul(float k)
Definition: geom.hpp:552
Definition: geom.hpp:1121
vec4 & rotate_around_x(float angle)
Definition: geom.hpp:420
void rotate_around_x(const vec2 &sc)
Definition: geom.hpp:1622
ivec2 & sub(int n)
Definition: geom.hpp:1336
vec transformnormal(const vec &o) const
Definition: geom.hpp:1102
vec2 lineardepthscale() const
Definition: geom.hpp:1873
bool operator!=(const ivec &v) const
Definition: geom.hpp:1255
bool operator==(const vec &o) const
operators for vector comparisn
Definition: geom.hpp:150
void identity()
Definition: geom.hpp:857
ivec2 & neg()
Definition: geom.hpp:1342
ushort operator[](int i) const
Definition: geom.hpp:1510
ivec2 & add(int n)
Definition: geom.hpp:1335
void mul(const matrix4 &x, const matrix4 &y)
Definition: geom.hpp:1608
void identity()
Definition: geom.hpp:983
vec & cross(const A &a, const B &b)
template based vector cross product
Definition: geom.hpp:211
plane(float a, float b, float c, float d)
Definition: geom.hpp:1139
void fixantipodal(const dualquat &d)
Definition: geom.hpp:621
3-dimensional INTEGER vectors
Definition: geom.hpp:1226
void mul(const dualquat &o)
Definition: geom.hpp:583
vec2 & add(const vec2 &o)
Definition: geom.hpp:77
ivec(int i, const ivec &co, int size)
Definition: geom.hpp:1244
vec4(const vec &p, float w=0)
Definition: geom.hpp:354
void transform(const vec4 &in, vec4 &out) const
Definition: geom.hpp:1797
void rotate_around_x(float angle)
Definition: geom.hpp:1077
quat & invert()
Definition: geom.hpp:474
double y
Definition: geom.hpp:1557
friend std::ostream & operator<<(std::ostream &os, const ivec2 &v)
Output operator, used for simple << ivec2 << functionality: output of form "(x, y)".
Definition: geom.hpp:1324
void translate(const vec &p, float scale)
Definition: geom.hpp:951
vec abstransposedtransform(const vec &o) const
Definition: geom.hpp:852
void transform(const vec &in, vec4 &out) const
Definition: geom.hpp:1792
void muld(const matrix4 &y)
Definition: geom.hpp:1612
void mul(const matrix3 &n)
Definition: geom.hpp:695
Definition: geom.hpp:1455
vec & rotate_around_z(float angle)
Definition: geom.hpp:259
bool calcangleaxis(float &angle, vec &axis, float threshold=1e-16f) const
Definition: geom.hpp:841
vec c
Definition: geom.hpp:1209
vec4 rowx() const
Definition: geom.hpp:1866
bool insidebb(const T &bbmin, const T &bbmax) const
is vector inside bounding box bounding boxes have a minimal vector and a maximal vector ...
Definition: geom.hpp:292
vec & rotate(float c, float s, const vec &d)
Definition: geom.hpp:267
void identity()
Definition: geom.hpp:1653
void invert(const matrix4x3 &o)
Definition: geom.hpp:1047
vec & normalize()
normalize vector: divide it by its length (magnitude)
Definition: geom.hpp:198
bool linecylinderintersect(const vec &from, const vec &to, const vec &start, const vec &end, float radius, float &dist)
Definition: geom.cpp:86
vec tonormal() const
Definition: geom.hpp:1477
void scale(int k, int d)
Definition: geom.hpp:1443
void transpose()
Definition: geom.hpp:1014
bool iszero() const
Definition: geom.hpp:1264
plane & scale(float k)
Definition: geom.hpp:1180
short z
Definition: geom.hpp:1899
void rotate_around_y(float angle)
Definition: geom.hpp:881
vec4 & madd(const vec4 &a, const B &b)
Definition: geom.hpp:410
vec4 roww() const
Definition: geom.hpp:1869
bvec & shl(int n)
Definition: geom.hpp:1445
vec rotate(const vec &v) const
Definition: geom.hpp:487
uchar & operator[](int i)
Definition: geom.hpp:1412
dvec4 & madd(const dvec4 &a, const B &b)
Definition: geom.hpp:1563
void perspective(float fovy, float aspect, float znear, float zfar)
Definition: geom.hpp:1755
vec perspectivetransform(const T &in) const
Definition: geom.hpp:1809
vec4 & div(const vec4 &o)
Definition: geom.hpp:403
vec2 & mul(float f)
Definition: geom.hpp:72
ivec & mask(int n)
Definition: geom.hpp:1275
float zdist(const vec &p) const
Definition: geom.hpp:1202
bvec4(uchar x, uchar y, uchar z, uchar w=0)
Definition: geom.hpp:1466
vec2 & madd(const vec2 &a, const B &b)
Definition: geom.hpp:90
void transpose(const matrix4x3 &o)
Definition: geom.hpp:1021
void transpose()
Definition: geom.hpp:1731
void flip()
Definition: geom.hpp:1441
void mult(const matrix4 &x, const matrix4 &y)
Definition: geom.hpp:1600
float magnitude3() const
Definition: geom.hpp:377
vec4 b
Definition: geom.hpp:1574
3 dimensional vector containing shorts.
Definition: geom.hpp:1516
vec4()
constructors
Definition: geom.hpp:353
float zdelta(const vec &p) const
Definition: geom.hpp:1201
void rotate(float ck, float sk, const vec &axis)
Definition: geom.hpp:1644
uchar operator[](int i) const
Definition: geom.hpp:1470
vec4 rowy() const
Definition: geom.hpp:1107