Libprimis
Imprimis' 3D destroyable world engine
Loading...
Searching...
No Matches
geom.h
Go to the documentation of this file.
1
10#ifndef GEOM_H_
11#define GEOM_H_
12
13struct vec;
14
15template<typename T>
16struct vec4;
17
18struct plane;
19struct quat;
20struct dualquat;
21class matrix3;
22struct matrix4x3;
23struct matrix4;
24
25
33struct vec2
34{
35 union
36 {
37 struct
38 {
39 float x, y;
40 };
41 float v[2];
42 };
43
44 vec2() {}
45 vec2(float x, float y) : x(x), y(y) {}
46 explicit vec2(const vec &v);
47 explicit vec2(const vec4<float> &v);
48
49 float &operator[](int i) { return v[i]; }
50 float operator[](int i) const { return v[i]; }
51
52 bool operator==(const vec2 &o) const { return x == o.x && y == o.y; }
53 bool operator!=(const vec2 &o) const { return x != o.x || y != o.y; }
54
55 bool iszero() const { return x==0 && y==0; }
56 float dot(const vec2 &o) const { return x*o.x + y*o.y; }
57 float squaredlen() const { return dot(*this); }
58 float magnitude() const { return sqrtf(squaredlen()); }
59 vec2 &normalize() { mul(1/magnitude()); return *this; }
60 vec2 &safenormalize() { float m = magnitude(); if(m) mul(1/m); return *this; }
61 float cross(const vec2 &o) const { return x*o.y - y*o.x; }
62 float squaredist(const vec2 &e) const { return vec2(*this).sub(e).squaredlen(); }
63 float dist(const vec2 &e) const { return sqrtf(squaredist(e)); }
64
65 vec2 &mul(float f) { x *= f; y *= f; return *this; }
66 vec2 &mul(const vec2 &o) { x *= o.x; y *= o.y; return *this; }
67 vec2 &square() { mul(*this); return *this; }
68 vec2 &div(float f) { x /= f; y /= f; return *this; }
69 vec2 &div(const vec2 &o) { x /= o.x; y /= o.y; return *this; }
70 vec2 &recip() { x = 1/x; y = 1/y; return *this; }
71 vec2 &add(float f) { x += f; y += f; return *this; }
72 vec2 &add(const vec2 &o) { x += o.x; y += o.y; return *this; }
73 vec2 &sub(float f) { x -= f; y -= f; return *this; }
74 vec2 &sub(const vec2 &o) { x -= o.x; y -= o.y; return *this; }
75 vec2 &neg() { x = -x; y = -y; return *this; }
76 vec2 &min(const vec2 &o) { x = ::min(x, o.x); y = ::min(y, o.y); return *this; }
77 vec2 &max(const vec2 &o) { x = ::max(x, o.x); y = ::max(y, o.y); return *this; }
78 vec2 &min(float f) { x = ::min(x, f); y = ::min(y, f); return *this; }
79 vec2 &max(float f) { x = ::max(x, f); y = ::max(y, f); return *this; }
80 vec2 &abs() { x = fabs(x); y = fabs(y); return *this; }
81 vec2 &clamp(float l, float h) { x = ::std::clamp(x, l, h); y = ::std::clamp(y, l, h); return *this; }
82 vec2 &reflect(const vec2 &n) { float k = 2*dot(n); x -= k*n.x; y -= k*n.y; return *this; }
83
93 vec2 &lerp(const vec2 &b, float t)
94 {
95 x += (b.x-x)*t;
96 y += (b.y-y)*t;
97 return *this;
98 }
99
110 vec2 &lerp(const vec2 &a, const vec2 &b, float t)
111 {
112 x = a.x + (b.x-a.x)*t;
113 y = a.y + (b.y-a.y)*t;
114 return *this;
115 }
116
117 vec2 &avg(const vec2 &b) { add(b); mul(0.5f); return *this; }
118
119 vec2 operator+(const vec2 &v2) const
120 {
121 return vec2(x+v2.x, y+v2.y);
122 }
123
124 vec2 operator-(const vec2 &v2) const
125 {
126 return vec2(x-v2.x, y-v2.y);
127 }
128
129 vec2 operator-() const
130 {
131 return vec2(-x, -y);
132 }
133
134 template<typename T>
135 vec2 operator*(const T &n)
136 {
137 return vec2(n*x, n*y);
138 }
139
140 vec2 operator*(const vec2 &v2)
141 {
142 return vec2(x*v2.x, y*v2.y);
143 }
144
145 template<typename T>
146 vec2 operator/(const T &n)
147 {
148 return vec2(x/n, y/n);
149 }
150
151 vec2 operator/(const vec2 &v2)
152 {
153 return vec2(x/v2.x, y/v2.y);
154 }
155
156 template<class B>
157 vec2 &madd(const vec2 &a, const B &b) { return add(vec2(a).mul(b)); }
158
159 template<class B>
160 vec2 &msub(const vec2 &a, const B &b) { return sub(vec2(a).mul(b)); }
161
162 vec2 &rotate_around_z(float c, float s) { float rx = x, ry = y; x = c*rx-s*ry; y = c*ry+s*rx; return *this; }
163 vec2 &rotate_around_z(float angle) { return rotate_around_z(cosf(angle), std::sin(angle)); }
164 vec2 &rotate_around_z(const vec2 &sc) { return rotate_around_z(sc.x, sc.y); }
165};
166
167struct ivec;
168struct svec;
169
184struct vec
185{
186 union
187 {
188 struct
189 {
190 float x, y, z;
191 };
192 struct
193 {
194 float r, g, b;
195 };
196 float v[3];
197 };
198
199 vec() {}
200 explicit vec(int a) : x(a), y(a), z(a) {}
201 explicit vec(float a) : x(a), y(a), z(a) {}
202 vec(float a, float b, float c) : x(a), y(b), z(c) {}
203 explicit vec(int v[3]) : x(v[0]), y(v[1]), z(v[2]) {}
204 explicit vec(const float *v) : x(v[0]), y(v[1]), z(v[2]) {}
205 explicit vec(const vec2 &v, float z = 0) : x(v.x), y(v.y), z(z) {}
206 explicit vec(const vec4<float> &v);
207 explicit vec(const ivec &v);
208 explicit vec(const svec &v);
209
210 vec(float yaw, float pitch) : x(-std::sin(yaw)*cosf(pitch)), y(cosf(yaw)*cosf(pitch)), z(std::sin(pitch)) {}
211 vec &set(int i, float f) { v[i] = f; return *this; }
212
213 //operator overloads
214 float &operator[](int i) { return v[i]; }
215 float operator[](int i) const { return v[i]; }
216 bool operator==(const vec &o) const { return x == o.x && y == o.y && z == o.z; }
217 bool operator!=(const vec &o) const { return x != o.x || y != o.y || z != o.z; }
218
219 vec operator+(const vec &v2)
220 {
221 return vec(x+v2.x, y+v2.y, z+v2.z);
222 }
223
224 vec operator-(const vec &v2)
225 {
226 return vec(x-v2.x, y-v2.y, z-v2.z);
227 }
228
229 vec operator-()
230 {
231 return vec(-x, -y, -z);
232 }
233
234 template<typename T>
235 vec operator*(const T &n)
236 {
237 return vec(n*x, n*y, n*z);
238 }
239
240 vec operator*(const vec &v2)
241 {
242 return vec(x*v2.x, y*v2.y, z*v2.z);
243 }
244
245 template<typename T>
246 vec operator/(const T &n)
247 {
248 return vec(x/n, y/n, z/n);
249 }
250
251 vec operator/(const vec &v2)
252 {
253 return vec(x/v2.x, y/v2.y, z/v2.z);
254 }
255
256
257 //unary operators
267 bool iszero() const
268 {
269 return x==0 && y==0 && z==0;
270 }
278 float squaredlen() const { return x*x + y*y + z*z; }
279
287 vec &square() { mul(*this); return *this; }
288 vec &neg2() { x = -x; y = -y; return *this; } //unused
289 vec &neg() { x = -x; y = -y; z = -z; return *this; } //overloaded by operator-()
290 vec &abs() { x = fabs(x); y = fabs(y); z = fabs(z); return *this; }
291 vec &recip() { x = 1/x; y = 1/y; z = 1/z; return *this; } //used twice
292 float magnitude2() const { return sqrtf(dot2(*this)); }
293 float magnitude() const { return sqrtf(squaredlen()); }
294 vec &normalize() { div(magnitude()); return *this; }
295 vec &safenormalize() { float m = magnitude(); if(m) div(m); return *this; }
296 bool isnormalized() const { float m = squaredlen(); return (m>0.99f && m<1.01f); }
297
298 //elementwise float operators
299 vec &mul(float f) { x *= f; y *= f; z *= f; return *this; }
300 vec &mul2(float f) { x *= f; y *= f; return *this; } //unused
301 vec &div(float f) { x /= f; y /= f; z /= f; return *this; }
302 vec &div2(float f) { x /= f; y /= f; return *this; } //unused
303 vec &add(float f) { x += f; y += f; z += f; return *this; }
304 vec &add2(float f) { x += f; y += f; return *this; } //used once
305 vec &addz(float f) { z += f; return *this; } //unused
306 vec &sub(float f) { x -= f; y -= f; z -= f; return *this; }
307 vec &sub2(float f) { x -= f; y -= f; return *this; } //unused
308 vec &subz(float f) { z -= f; return *this; } //unused
309 vec &min(float f) { x = ::min(x, f); y = ::min(y, f); z = ::min(z, f); return *this; }
310 vec &max(float f) { x = ::max(x, f); y = ::max(y, f); z = ::max(z, f); return *this; }
311 vec &clamp(float l, float h) { x = ::std::clamp(x, l, h); y = ::std::clamp(y, l, h); z = ::std::clamp(z, l, h); return *this; }
312
313 //elementwise vector operators
314 vec &mul(const vec &o) { x *= o.x; y *= o.y; z *= o.z; return *this; }
315 vec &div(const vec &o) { x /= o.x; y /= o.y; z /= o.z; return *this; }
316 vec &add(const vec &o) { x += o.x; y += o.y; z += o.z; return *this; }
317 vec &sub(const vec &o) { x -= o.x; y -= o.y; z -= o.z; return *this; }
318 vec &min(const vec &o) { x = ::min(x, o.x); y = ::min(y, o.y); z = ::min(z, o.z); return *this; }
319 vec &max(const vec &o) { x = ::max(x, o.x); y = ::max(y, o.y); z = ::max(z, o.z); return *this; }
320
321 //dot products
322 float dot2(const vec2 &o) const { return x*o.x + y*o.y; }
323 float dot2(const vec &o) const { return x*o.x + y*o.y; }
324 float dot(const vec &o) const { return x*o.x + y*o.y + z*o.z; }
325 float squaredot(const vec &o) const { float k = dot(o); return k*k; } //unused
326 float absdot(const vec &o) const { return fabs(x*o.x) + fabs(y*o.y) + fabs(z*o.z); } //used once
327 float zdot(const vec &o) const { return z*o.z; } //unused
328
329 //distances
330 float squaredist(const vec &e) const { return vec(*this).sub(e).squaredlen(); }
331 float dist(const vec &e) const { return sqrtf(squaredist(e)); }
332 float dist(const vec &e, vec &t) const { t = *this; t.sub(e); return t.magnitude(); }
333 float dist2(const vec &o) const { float dx = x-o.x, dy = y-o.y; return sqrtf(dx*dx + dy*dy); }
334
335 //cross products
336
350 bool reject(const vec &o, float r) const
351 {
352 return x>o.x+r || x<o.x-r || y>o.y+r || y<o.y-r;
353 }
354
355 template<class A, class B>
356 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; }
357
358 vec &cross(const vec &o, const vec &a, const vec &b) { return cross(vec(a).sub(o), vec(b).sub(o)); }
359
363 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); }
364
368 float zscalartriple(const vec &a, const vec &b) const { return z*(a.x*b.y-a.y*b.x); } //unused
369
370 //transformations
371 vec &reflectz(float rz) { z = 2*rz - z; return *this; }
372 vec &reflect(const vec &n) { float k = 2*dot(n); x -= k*n.x; y -= k*n.y; z -= k*n.z; return *this; }
373 vec &project(const vec &n) { float k = dot(n); x -= k*n.x; y -= k*n.y; z -= k*n.z; return *this; }
374 vec &projectxydir(const vec &n) { if(n.z) z = -(x*n.x/n.z + y*n.y/n.z); return *this; } //used once
375 vec &projectxy(const vec &n)
376 {
377 float m = squaredlen(), k = dot(n);
378 projectxydir(n);
379 rescale(sqrtf(::max(m - k*k, 0.0f)));
380 return *this;
381 } //used once
382 vec &projectxy(const vec &n, float threshold)
383 {
384 float m = squaredlen(), k = ::min(dot(n), threshold);
385 projectxydir(n);
386 rescale(sqrtf(::max(m - k*k, 0.0f)));
387 return *this;
388 } //used once
389
399 vec &lerp(const vec &b, float t)
400 {
401 x += (b.x-x)*t;
402 y += (b.y-y)*t;
403 z += (b.z-z)*t;
404 return *this;
405 }
406
417 vec &lerp(const vec &a, const vec &b, float t)
418 {
419 x = a.x + (b.x-a.x)*t;
420 y = a.y + (b.y-a.y)*t;
421 z = a.z + (b.z-a.z)*t;
422 return *this;
423 }
424
432 vec &avg(const vec &b)
433 {
434 add(b);
435 mul(0.5f);
436 return *this;
437 }
438
439 template<class B>
440 vec &madd(const vec &a, const B &b) { return add(vec(a).mul(b)); }
441
442 template<class B>
443 vec &msub(const vec &a, const B &b) { return sub(vec(a).mul(b)); }
444
445 vec &rescale(float k)
446 {
447 float mag = magnitude();
448 if(mag > 1e-6f) mul(k / mag);
449 return *this;
450 }
451
452 //all rotate_around functions use RH coordinates (positive rotation in CCW direction)
453 vec &rotate_around_z(float c, float s)
454 {
455 float rx = x,
456 ry = y;
457 x = c*rx-s*ry;
458 y = c*ry+s*rx;
459 return *this;
460 }
461
462 vec &rotate_around_x(float c, float s)
463 {
464 float ry = y,
465 rz = z;
466 y = c*ry-s*rz;
467 z = c*rz+s*ry;
468 return *this;
469 }
470
471 vec &rotate_around_y(float c, float s)
472 {
473 float rx = x,
474 rz = z;
475 x = c*rx-s*rz;
476 z = c*rz+s*rx;
477 return *this;
478 }
479
480 vec &rotate_around_z(float angle)
481 {
482 return rotate_around_z(cosf(angle), std::sin(angle));
483 }
484
485 vec &rotate_around_x(float angle)
486 {
487 return rotate_around_x(cosf(angle), std::sin(angle));
488 }
489
490 vec &rotate_around_y(float angle)
491 {
492 return rotate_around_y(cosf(angle), std::sin(angle));
493 }
494
495 vec &rotate_around_z(const vec2 &sc)
496 {
497 return rotate_around_z(sc.x, sc.y);
498 }
499
500 vec &rotate_around_x(const vec2 &sc)
501 {
502 return rotate_around_x(sc.x, sc.y);
503 }
504
505 vec &rotate_around_y(const vec2 &sc)
506 {
507 return rotate_around_y(sc.x, sc.y);
508 }
509
510 vec &rotate(float c, float s, const vec &d)
511 {
512 *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),
513 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),
514 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));
515 return *this;
516 }
517 vec &rotate(float angle, const vec &d)
518 {
519 return rotate(cosf(angle), std::sin(angle), d);
520 }
521
522 vec &rotate(const vec2 &sc, const vec &d)
523 {
524 return rotate(sc.x, sc.y, d);
525 }
526
527 void orthogonal(const vec &d)
528 {
529 *this = fabs(d.x) > fabs(d.z) ? vec(-d.y, d.x, 0) : vec(0, -d.z, d.y);
530 }
531
532 void orthonormalize(vec &s, vec &t) const
533 {
534 s.project(*this);
535 t.project(*this).project(s);
536 } //unused
537
538 template<class T>
539 bool insidebb(const T &bbmin, const T &bbmax) const
540 {
541 return x >= bbmin.x && x <= bbmax.x && y >= bbmin.y && y <= bbmax.y && z >= bbmin.z && z <= bbmax.z;
542 }
543
544 template<class T, class U>
545 bool insidebb(const T &bbmin, const T &bbmax, U margin) const
546 {
547 return x >= bbmin.x-margin && x <= bbmax.x+margin && y >= bbmin.y-margin && y <= bbmax.y+margin && z >= bbmin.z-margin && z <= bbmax.z+margin;
548 }
549
562 bool insidebb(const ivec &o, int size) const;
563
578 bool insidebb(const ivec &o, int size, int margin) const;
579 float dist_to_bb(const ivec &min, const ivec &max) const;
580
594 float project_bb(const ivec &min, const ivec &max) const;
595
596 static vec hexcolor(int color)
597 {
598 return vec(((color>>16)&0xFF)*(1.0f/255.0f), ((color>>8)&0xFF)*(1.0f/255.0f), (color&0xFF)*(1.0f/255.0f));
599 }
600
601 int tohexcolor() const
602 {
603 return (static_cast<int>(::std::clamp(r, 0.0f, 1.0f)*255)<<16) |
604 (static_cast<int>(::std::clamp(g, 0.0f, 1.0f)*255)<<8) |
605 static_cast<int>(::std::clamp(b, 0.0f, 1.0f)*255);
606 }
607};
608
609inline vec2::vec2(const vec &v) : x(v.x), y(v.y) {}
610
611template<>
612struct std::hash<vec>
613{
614 size_t operator()(const vec& k) const
615 {
616 union { uint i; float f; } x, y, z;
617 x.f = k.x;
618 y.f = k.y;
619 z.f = k.z;
620 uint v = x.i^y.i^z.i;
621 return v + (v>>12);
622 }
623};
624
636struct bvec
637{
638 union
639 {
640 struct
641 {
642 uchar x, y, z;
643 };
644 struct
645 {
646 uchar r, g, b;
647 };
648 uchar v[3];
649 };
650
651 bvec() {}
652 bvec(uchar x, uchar y, uchar z) : x(x), y(y), z(z) {}
653 explicit bvec(const vec &v) : x(static_cast<uchar>((v.x+1)*(255.0f/2.0f))), y(static_cast<uchar>((v.y+1)*(255.0f/2.0f))), z(static_cast<uchar>((v.z+1)*(255.0f/2.0f))) {}
654 explicit bvec(const vec4<uchar> &v);
655
656 uchar &operator[](int i) { return v[i]; }
657 uchar operator[](int i) const { return v[i]; }
658
659 bool operator==(const bvec &v) const { return x==v.x && y==v.y && z==v.z; }
660 bool operator!=(const bvec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
661
662 bool iszero() const { return x==0 && y==0 && z==0; }
663
664 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); }
665
666 bvec &normalize()
667 {
668 vec n(x-127.5f, y-127.5f, z-127.5f);
669 float mag = 127.5f/n.magnitude();
670 x = static_cast<uchar>(n.x*mag+127.5f);
671 y = static_cast<uchar>(n.y*mag+127.5f);
672 z = static_cast<uchar>(n.z*mag+127.5f);
673 return *this;
674 }
675
676 void lerp(const bvec &a, const bvec &b, float t)
677 {
678 x = static_cast<uchar>(a.x + (b.x-a.x)*t);
679 y = static_cast<uchar>(a.y + (b.y-a.y)*t);
680 z = static_cast<uchar>(a.z + (b.z-a.z)*t);
681 }
682
683 void lerp(const bvec &a, const bvec &b, int ka, int kb, int d)
684 {
685 x = static_cast<uchar>((a.x*ka + b.x*kb)/d);
686 y = static_cast<uchar>((a.y*ka + b.y*kb)/d);
687 z = static_cast<uchar>((a.z*ka + b.z*kb)/d);
688 }
689
690 void flip()
691 {
692 x ^= 0x80;
693 y ^= 0x80;
694 z ^= 0x80;
695 }
696
697 void scale(int k, int d)
698 {
699 x = static_cast<uchar>((x*k)/d);
700 y = static_cast<uchar>((y*k)/d);
701 z = static_cast<uchar>((z*k)/d);
702 }
703
704 bvec &shl(int n)
705 {
706 x <<= n;
707 y <<= n;
708 z <<= n;
709 return *this;
710 }
711 bvec &shr(int n)
712 {
713 x >>= n;
714 y >>= n;
715 z >>= n;
716 return *this;
717 }
718
719 static bvec fromcolor(const vec &v)
720 {
721 return bvec(static_cast<uchar>(v.x*255.0f), static_cast<uchar>(v.y*255.0f), static_cast<uchar>(v.z*255.0f));
722 }
723
724 vec tocolor() const
725 {
726 return vec(x*(1.0f/255.0f), y*(1.0f/255.0f), z*(1.0f/255.0f));
727 }
728
729 static bvec from565(ushort c)
730 {
731 return bvec((((c>>11)&0x1F)*527 + 15) >> 6, (((c>>5)&0x3F)*259 + 35) >> 6, ((c&0x1F)*527 + 15) >> 6);
732 }
733
734 static bvec hexcolor(int color)
735 {
736 return bvec((color>>16)&0xFF, (color>>8)&0xFF, color&0xFF);
737 }
738
739 int tohexcolor() const
740 {
741 return (static_cast<int>(r)<<16)|(static_cast<int>(g)<<8)|static_cast<int>(b);
742 }
743};
744
753template<typename T>
754struct vec4
755{
756 union
757 {
758 struct { T x, y, z, w; };
759 struct { T r, g, b, a; };
760 T v[4];
761 uint mask;
762 };
763
764 vec4() {}
765 explicit vec4(const vec &p, T w = 0) : x(p.x), y(p.y), z(p.z), w(w) {}
766 explicit vec4(const vec2 &p, T z = 0, T w = 0) : x(p.x), y(p.y), z(z), w(w) {}
767 vec4(T x, T y = 0, T z = 0, T w = 0) : x(x), y(y), z(z), w(w) {}
768 vec4(bvec v, uchar c)
769 {
770 x = v.x;
771 y = v.y;
772 z = v.z;
773 w = c;
774 }
775 vec4(bvec v)
776 {
777 x = v.x;
778 y = v.y;
779 z = v.z;
780 w = 0;
781 }
782
783 explicit vec4(const T *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
784
785 template<class U>
786 vec4(const vec4<U> &p) : x(p.x), y(p.y), z(p.z), w(p.w) {}
787
788 template<class U>
789 operator vec4<U>()
790 {
791 return vec4<U>(static_cast<U>(this->x),
792 static_cast<U>(this->y),
793 static_cast<U>(this->z),
794 static_cast<U>(this->w));
795 }
796
797 T &operator[](int i) { return v[i]; }
798 T operator[](int i) const { return v[i]; }
799
800 bool operator==(const vec4 &o) const { return x == o.x && y == o.y && z == o.z && w == o.w; }
801 bool operator!=(const vec4 &o) const { return x != o.x || y != o.y || z != o.z || w != o.w; }
802
813 T dot3(const vec4 &o) const { return x*o.x + y*o.y + z*o.z; }
814
825 T dot3(const vec &o) const { return x*o.x + y*o.y + z*o.z; }
826
837 T dot(const vec4 &o) const { return dot3(o) + w*o.w; }
838
848 T dot(const vec &o) const { return x*o.x + y*o.y + z*o.z + w; }
849
858 T squaredlen() const { return dot(*this); }
859
868 T magnitude() const { return sqrtf(squaredlen()); }
869
878 T magnitude3() const { return sqrtf(dot3(*this)); }
879
887 vec4 &normalize() { mul(1/magnitude()); return *this; }
888
896 vec4 &safenormalize() { T m = magnitude(); if(m) mul(1/m); return *this; }
897
898 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, float t)
899 {
900 x = static_cast<uchar>(a.x + (b.x-a.x)*t);
901 y = static_cast<uchar>(a.y + (b.y-a.y)*t);
902 z = static_cast<uchar>(a.z + (b.z-a.z)*t);
903 w = a.w;
904 }
905
906 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, int ka, int kb, int d)
907 {
908 x = static_cast<uchar>((a.x*ka + b.x*kb)/d);
909 y = static_cast<uchar>((a.y*ka + b.y*kb)/d);
910 z = static_cast<uchar>((a.z*ka + b.z*kb)/d);
911 w = a.w;
912 }
913
914 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, const vec4<uchar> &c, float ta, float tb, float tc)
915 {
916 x = static_cast<uchar>(a.x*ta + b.x*tb + c.x*tc);
917 y = static_cast<uchar>(a.y*ta + b.y*tb + c.y*tc);
918 z = static_cast<uchar>(a.z*ta + b.z*tb + c.z*tc);
919 w = static_cast<uchar>(a.w*ta + b.w*tb + c.w*tc);
920 }
921
927 void flip() { mask ^= 0x80808080; }
928
929 vec4 &lerp(const vec4 &b, T t)
930 {
931 x += (b.x-x)*t;
932 y += (b.y-y)*t;
933 z += (b.z-z)*t;
934 w += (b.w-w)*t;
935 return *this;
936 }
937 vec4 &lerp(const vec4 &a, const vec4 &b, T t)
938 {
939 x = a.x+(b.x-a.x)*t;
940 y = a.y+(b.y-a.y)*t;
941 z = a.z+(b.z-a.z)*t;
942 w = a.w+(b.w-a.w)*t;
943 return *this;
944 }
945
957 vec4 &avg(const vec4 &b) { add(b); mul(0.5f); return *this; }
958
959 template<class B>
960 vec4 &madd(const vec4 &a, const B &b) { return add(vec4(a).mul(b)); }
961
962 template<class B>
963 vec4 &msub(const vec4 &a, const B &b) { return sub(vec4(a).mul(b)); }
964
975 vec4 &mul3(T f) { x *= f; y *= f; z *= f; return *this; }
976
987 vec4 &mul(T f) { mul3(f); w *= f; return *this; }
988
1000 vec4 &mul(const vec4 &o) { x *= o.x; y *= o.y; z *= o.z; w *= o.w; return *this; }
1001
1013 vec4 &mul(const vec &o) { x *= o.x; y *= o.y; z *= o.z; return *this; }
1014
1023 vec4 &square() { mul(*this); return *this; }
1024
1036 vec4 &div3(T f) { x /= f; y /= f; z /= f; return *this; }
1037
1048 vec4 &div(T f) { div3(f); w /= f; return *this; }
1049
1060 vec4 &div(const vec4 &o) { x /= o.x; y /= o.y; z /= o.z; w /= o.w; return *this; }
1061
1072 vec4 &div(const vec &o) { x /= o.x; y /= o.y; z /= o.z; return *this; }
1073
1082 vec4 &recip() { x = 1/x; y = 1/y; z = 1/z; w = 1/w; return *this; }
1083
1094 vec4 &add(const vec4 &o) { x += o.x; y += o.y; z += o.z; w += o.w; return *this; }
1095
1107 vec4 &add(const vec &o) { x += o.x; y += o.y; z += o.z; return *this; }
1108
1119 vec4 &add3(T f) { x += f; y += f; z += f; return *this; }
1120
1131 vec4 &add(T f) { add3(f); w += f; return *this; }
1132
1143 vec4 &addw(T f) { w += f; return *this; }
1144
1155 vec4 &sub(const vec4 &o) { x -= o.x; y -= o.y; z -= o.z; w -= o.w; return *this; }
1156
1167 vec4 &sub(const vec &o) { x -= o.x; y -= o.y; z -= o.z; return *this; }
1168
1180 {
1181 x -= f;
1182 y -= f;
1183 z -= f;
1184 return *this;
1185 }
1186
1187 vec4 &sub(T f)
1188 {
1189 sub3(f);
1190 w -= f;
1191 return *this;
1192 }
1193
1194 vec4 &subw(T f)
1195 {
1196 w -= f;
1197 return *this;
1198 }
1199
1200 vec4 &neg3()
1201 {
1202 x = -x;
1203 y = -y;
1204 z = -z;
1205 return *this;
1206 }
1207
1208 vec4 &neg()
1209 {
1210 neg3();
1211 w = -w;
1212 return *this;
1213 }
1214
1215 vec4 &clamp(T l, T h)
1216 {
1217 x = ::std::clamp(x, l, h);
1218 y = ::std::clamp(y, l, h);
1219 z = ::std::clamp(z, l, h);
1220 w = ::std::clamp(w, l, h);
1221 return *this;
1222 }
1223
1224 vec4 operator+(const vec4 &v2) const
1225 {
1226 return vec4(x+v2.x, y+v2.y, z+v2.z, w+v2.w);
1227 }
1228
1229 vec4 operator-(const vec4 &v2) const
1230 {
1231 return vec4(x-v2.x, y-v2.y, z-v2.z, w-v2.w);
1232 }
1233
1234 vec4 operator-() const
1235 {
1236 return vec4(-x, -y, -z, -w);
1237 }
1238
1239 template<typename U>
1240 vec4 operator*(const U &n) const
1241 {
1242 return vec4(n*x, n*y, n*z, n*w);
1243 }
1244
1245 vec4 operator*(const vec4 &v2) const
1246 {
1247 return vec4(x*v2.x, y*v2.y, z*v2.z, w*v2.w);
1248 }
1249
1250 template<typename U>
1251 vec4 operator/(const U &n) const
1252 {
1253 return vec4(x/n, y/n, z/n, w/n);
1254 }
1255
1256 vec4 operator/(const vec4 &v2) const
1257 {
1258 return vec4(x/v2.x, y/v2.y, z/v2.z, w/v2.w);
1259 }
1260
1261
1262 template<class A, class B>
1263 vec4 &cross(const A &a, const B &b)
1264 {
1265 x = a.y*b.z-a.z*b.y;
1266 y = a.z*b.x-a.x*b.z;
1267 z = a.x*b.y-a.y*b.x;
1268 return *this;
1269 }
1270
1271 vec4 &cross(const vec &o, const vec &a, const vec &b)
1272 {
1273 return cross(vec(a).sub(o), vec(b).sub(o));
1274 }
1275
1276 void setxyz(const vec &v)
1277 {
1278 x = v.x;
1279 y = v.y;
1280 z = v.z;
1281 }
1282
1293 {
1294 T rx = x,
1295 ry = y;
1296 x = c*rx-s*ry;
1297 y = c*ry+s*rx;
1298 return *this;
1299 }
1300
1311 {
1312 T ry = y,
1313 rz = z;
1314 y = c*ry-s*rz;
1315 z = c*rz+s*ry;
1316 return *this;
1317 }
1318
1329 {
1330 T rx = x,
1331 rz = z;
1332 x = c*rx-s*rz;
1333 z = c*rz+s*rx;
1334 return *this;
1335 }
1336
1337 vec4 &rotate_around_z(T angle)
1338 {
1339 return rotate_around_z(cosf(angle), std::sin(angle));
1340 }
1341
1342 vec4 &rotate_around_x(T angle)
1343 {
1344 return rotate_around_x(cosf(angle), std::sin(angle));
1345 }
1346
1347 vec4 &rotate_around_y(T angle)
1348 {
1349 return rotate_around_y(cosf(angle), std::sin(angle));
1350 }
1351
1352 vec4 &rotate_around_z(const vec2 &sc)
1353 {
1354 return rotate_around_z(sc.x, sc.y);
1355 }
1356
1357 vec4 &rotate_around_x(const vec2 &sc)
1358 {
1359 return rotate_around_x(sc.x, sc.y);
1360 }
1361
1362 vec4 &rotate_around_y(const vec2 &sc)
1363 {
1364 return rotate_around_y(sc.x, sc.y);
1365 }
1366
1367 vec tonormal() const
1368 {
1369 return vec(x*(2.0f/255.0f)-1.0f, y*(2.0f/255.0f)-1.0f, z*(2.0f/255.0f)-1.0f);
1370 }
1371
1372};
1373
1374inline vec2::vec2(const vec4<float> &v) : x(v.x), y(v.y) {}
1375inline vec::vec(const vec4<float> &v) : x(v.x), y(v.y), z(v.z) {}
1376
1388{
1389 public:
1397 vec a, b, c;
1398
1403
1411 matrix3(const vec &a, const vec &b, const vec &c);
1412
1422 explicit matrix3(float angle, const vec &axis);
1423
1432 explicit matrix3(const quat &q);
1433
1440 explicit matrix3(const matrix4x3 &m);
1441
1449 explicit matrix3(const matrix4 &m);
1450
1457 void mul(const matrix3 &m, const matrix3 &n);
1458
1466 void mul(const matrix3 &n);
1467
1473 void multranspose(const matrix3 &n);
1474
1481 void transposemul(const matrix3 &m, const matrix3 &n);
1482
1488 void transposemul(const matrix3 &n);
1489
1500
1508 void invert(const matrix3 &o);
1509
1516 void invert();
1517
1524
1530 void scale(float k);
1531
1538 void rotate(float angle, const vec &axis);
1539
1547 void rotate(float ck, float sk, const vec &axis);
1548
1563 void setyaw(float angle);
1564
1572 float trace() const;
1573
1598 bool calcangleaxis(float tr, float &angle, vec &axis, float threshold = 1e-16f) const;
1599
1614 bool calcangleaxis(float &angle, vec &axis, float threshold = 1e-16f) const;
1615
1623 vec transform(const vec &o) const;
1624
1632 vec transposedtransform(const vec &o) const;
1633
1641 vec abstransform(const vec &o) const;
1642
1651
1661 void identity();
1662
1668 void rotate_around_x(float angle);
1669
1675 void rotate_around_x(const vec2 &sc);
1676
1682 void rotate_around_y(float angle);
1683
1689 void rotate_around_y(const vec2 &sc);
1690
1696 void rotate_around_z(float angle);
1697
1703 void rotate_around_z(const vec2 &sc);
1704
1712 vec transform(const vec2 &o) const;
1713
1722
1728 vec rowx() const;
1729
1735 vec rowy() const;
1736
1742 vec rowz() const;
1743 private:
1744
1751 void multranspose(const matrix3 &m, const matrix3 &n);
1752
1766 void setyaw(float ck, float sk);
1767
1774 void rotate_around_x(float ck, float sk);
1775
1782 void rotate_around_y(float ck, float sk);
1783
1790 void rotate_around_z(float ck, float sk);
1791
1797 void transpose(const matrix3 &m);
1798};
1799
1811{
1812 vec a, b, c, d;
1813
1821
1832 matrix4x3(const vec &a, const vec &b, const vec &c, const vec &d);
1833
1843 matrix4x3(const matrix3 &rot, const vec &trans);
1844
1850 matrix4x3(const dualquat &dq);
1851
1859 explicit matrix4x3(const matrix4 &m);
1860
1866 void mul(float k);
1867
1877 void setscale(float x, float y, float z);
1878
1886 void setscale(const vec &v);
1887
1893 void setscale(float n);
1894
1904 void scale(float x, float y, float z);
1905
1913 void scale(const vec &v);
1914
1922 void scale(float n);
1923
1929 void settranslation(const vec &p);
1930
1938 void settranslation(float x, float y, float z);
1939 void translate(const vec &p);
1940 void translate(float x, float y, float z);
1941 void translate(const vec &p, float scale);
1942 void accumulate(const matrix4x3 &m, float k);
1943
1953
1963 void lerp(const matrix4x3 &to, float t);
1964
1975 void lerp(const matrix4x3 &from, const matrix4x3 &to, float t);
1976
1987 void identity();
1988 void mul(const matrix4x3 &m, const matrix4x3 &n);
1989 void mul(const matrix4x3 &n);
1990
1991 void mul(const matrix3 &m, const matrix4x3 &n);
1992
1993 void mul(const matrix3 &rot, const vec &trans, const matrix4x3 &n);
1994
1995 void transpose();
1996 void transpose(const matrix4x3 &o);
1997
1998 void transposemul(const matrix4x3 &m, const matrix4x3 &n);
1999
2000 void multranspose(const matrix4x3 &m, const matrix4x3 &n);
2001
2002 void invert(const matrix4x3 &o);
2003 void invert();
2004 void rotate(float angle, const vec &d);
2005
2006 void rotate(float ck, float sk, const vec &axis);
2007
2008 void rotate_around_x(float ck, float sk);
2009 void rotate_around_x(float angle);
2010
2011 void rotate_around_x(const vec2 &sc);
2012
2013 void rotate_around_y(float ck, float sk);
2014 void rotate_around_y(float angle);
2015 void rotate_around_y(const vec2 &sc);
2016
2017 void rotate_around_z(float ck, float sk);
2018 void rotate_around_z(float angle);
2019 void rotate_around_z(const vec2 &sc);
2020
2021 vec transposedtransform(const vec &o) const;
2022 vec transformnormal(const vec &o) const;
2023 vec transposedtransformnormal(const vec &o) const;
2024 vec transform(const vec &o) const;
2025 vec transform(const vec2 &o) const;
2026
2033
2040
2047};
2048
2049/*
2050
2051The engine uses 3 different linear coordinate systems
2052which are oriented around each of the axis dimensions.
2053
2054So any point within the game can be defined by four coordinates: (d, x, y, z)
2055
2056d is the reference axis dimension
2057x is the coordinate of the ROW dimension
2058y is the coordinate of the COL dimension
2059z is the coordinate of the reference dimension (DEPTH)
2060
2061typically, if d is not used, then it is implicitly the Z dimension.
2062ie: d=z => x=x, y=y, z=z
2063
2064*/
2065
2066// DIM: X=0 Y=1 Z=2.
2067const int R[3] = {1, 2, 0};
2068const int C[3] = {2, 0, 1};
2069const int D[3] = {0, 1, 2};
2071struct ivec2;
2072
2073//integer vector3
2074struct ivec
2075{
2076 union
2077 {
2078 struct
2079 {
2080 int x, y, z;
2081 };
2082 struct
2083 {
2084 int r, g, b;
2085 };
2086 int v[3];
2087 };
2088
2089 ivec() {}
2090 explicit ivec(const vec &v) : x(static_cast<int>(v.x)), y(static_cast<int>(v.y)), z(static_cast<int>(v.z)) {}
2091 ivec(int a, int b, int c) : x(a), y(b), z(c) {}
2092 ivec(int d, int row, int col, int depth)
2093 {
2094 v[R[d]] = row;
2095 v[C[d]] = col;
2096 v[D[d]] = depth;
2097 }
2098 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) {}
2099 explicit ivec(const ivec2 &v, int z = 0);
2100 explicit ivec(const svec &v);
2101
2102 int &operator[](int i) { return v[i]; }
2103 int operator[](int i) const { return v[i]; }
2104
2105 //int idx(int i) { return v[i]; }
2106 bool operator==(const ivec &v) const { return x==v.x && y==v.y && z==v.z; }
2107 bool operator!=(const ivec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
2108 ivec operator+(const ivec &v) const { return ivec(x+v.x, y+v.y, z+v.z); }
2116 explicit operator bool() const { return !(x==0 && y==0 && z==0); }
2117 ivec &shl(int n) { x<<= n; y<<= n; z<<= n; return *this; }
2118 ivec &shr(int n) { x>>= n; y>>= n; z>>= n; return *this; }
2119 ivec &mul(int n) { x *= n; y *= n; z *= n; return *this; }
2120 ivec &div(int n) { x /= n; y /= n; z /= n; return *this; }
2121 ivec &add(int n) { x += n; y += n; z += n; return *this; }
2122 ivec &sub(int n) { x -= n; y -= n; z -= n; return *this; }
2123 ivec &mul(const ivec &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
2124 ivec &div(const ivec &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
2125 ivec &add(const ivec &v) { x += v.x; y += v.y; z += v.z; return *this; }
2126 ivec &sub(const ivec &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
2127 ivec &mask(int n) { x &= n; y &= n; z &= n; return *this; }
2128 ivec &neg() { x = -x; y = -y; z = -z; return *this; }
2129 ivec &min(const ivec &o) { x = ::min(x, o.x); y = ::min(y, o.y); z = ::min(z, o.z); return *this; }
2130 ivec &max(const ivec &o) { x = ::max(x, o.x); y = ::max(y, o.y); z = ::max(z, o.z); return *this; }
2131 ivec &min(int n) { x = ::min(x, n); y = ::min(y, n); z = ::min(z, n); return *this; }
2132 ivec &max(int n) { x = ::max(x, n); y = ::max(y, n); z = ::max(z, n); return *this; }
2133 ivec &abs() { x = ::abs(x); y = ::abs(y); z = ::abs(z); return *this; }
2134 ivec &clamp(int l, int h) { x = ::std::clamp(x, l, h); y = ::std::clamp(y, l, h); z = ::std::clamp(z, l, h); return *this; }
2135 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; }
2136 int dot(const ivec &o) const { return x*o.x + y*o.y + z*o.z; }
2137 float dist(const plane &p) const;
2138
2139 static inline ivec floor(const vec &o) { return ivec(static_cast<int>(::floor(o.x)), static_cast<int>(::floor(o.y)), static_cast<int>(::floor(o.z))); }
2140 static inline ivec ceil(const vec &o) { return ivec(static_cast<int>(::ceil(o.x)), static_cast<int>(::ceil(o.y)), static_cast<int>(::ceil(o.z))); }
2141};
2142
2143inline vec::vec(const ivec &v) : x(v.x), y(v.y), z(v.z) {}
2144
2145template<>
2146struct std::hash<ivec>
2147{
2148 size_t operator()(const ivec &k) const
2149 {
2150 return k.x^k.y^k.z;
2151 }
2152};
2153
2157struct ivec2
2158{
2159 union
2160 {
2161 struct { int x, y; };
2162 int v[2];
2163 };
2164
2165 ivec2() {}
2166 ivec2(int x, int y) : x(x), y(y) {}
2167 explicit ivec2(const vec2 &v) : x(static_cast<int>(v.x)), y(static_cast<int>(v.y)) {}
2168 explicit ivec2(const ivec &v) : x(v.x), y(v.y) {}
2169
2170 int &operator[](int i) { return v[i]; }
2171 int operator[](int i) const { return v[i]; }
2172
2173 bool operator==(const ivec2 &o) const { return x == o.x && y == o.y; }
2174 bool operator!=(const ivec2 &o) const { return x != o.x || y != o.y; }
2175
2176 bool iszero() const { return x==0 && y==0; }
2177 ivec2 &shl(int n) { x<<= n; y<<= n; return *this; }
2178 ivec2 &shr(int n) { x>>= n; y>>= n; return *this; }
2179 ivec2 &mul(int n) { x *= n; y *= n; return *this; }
2180 ivec2 &div(int n) { x /= n; y /= n; return *this; }
2181 ivec2 &add(int n) { x += n; y += n; return *this; }
2182 ivec2 &sub(int n) { x -= n; y -= n; return *this; }
2183 ivec2 &mul(const ivec2 &v) { x *= v.x; y *= v.y; return *this; }
2184 ivec2 &div(const ivec2 &v) { x /= v.x; y /= v.y; return *this; }
2185 ivec2 &add(const ivec2 &v) { x += v.x; y += v.y; return *this; }
2186 ivec2 &sub(const ivec2 &v) { x -= v.x; y -= v.y; return *this; }
2187 ivec2 &mask(int n) { x &= n; y &= n; return *this; }
2188 ivec2 &neg() { x = -x; y = -y; return *this; }
2189 ivec2 &min(const ivec2 &o) { x = ::min(x, o.x); y = ::min(y, o.y); return *this; }
2190 ivec2 &max(const ivec2 &o) { x = ::max(x, o.x); y = ::max(y, o.y); return *this; }
2191 ivec2 &min(int n) { x = ::min(x, n); y = ::min(y, n); return *this; }
2192 ivec2 &max(int n) { x = ::max(x, n); y = ::max(y, n); return *this; }
2193 ivec2 &abs() { x = ::abs(x); y = ::abs(y); return *this; }
2194 int dot(const ivec2 &o) const { return x*o.x + y*o.y; }
2195 int cross(const ivec2 &o) const { return x*o.y - y*o.x; }
2196};
2197
2198inline ivec::ivec(const ivec2 &v, int z) : x(v.x), y(v.y), z(z) {}
2199
2200inline bvec::bvec(const vec4<uchar> &v) : x(v.x), y(v.y), z(v.z) {}
2201
2205struct svec
2206{
2207 union
2208 {
2209 struct { short x, y, z; };
2210 short v[3];
2211 };
2212
2213 svec() {}
2214 svec(short x, short y, short z) : x(x), y(y), z(z) {}
2215 explicit svec(const ivec &v) : x(v.x), y(v.y), z(v.z) {}
2216
2217 short &operator[](int i) { return v[i]; }
2218 short operator[](int i) const { return v[i]; }
2219};
2220
2221inline vec::vec(const svec &v) : x(v.x), y(v.y), z(v.z) {}
2222inline ivec::ivec(const svec &v) : x(v.x), y(v.y), z(v.z) {}
2223
2228{
2229 vec4<float> a, b, c, d;
2230
2231 template<class T, class U>
2232 T transformnormal(const U &in) const
2233 {
2234 T v;
2235 transformnormal(in, v);
2236 return v;
2237 }
2238
2239 template<class T, class U>
2240 T transform(const U &in) const
2241 {
2242 T v;
2243 transform(in, v);
2244 return v;
2245 }
2246
2247 template<class T>
2248 vec perspectivetransform(const T &in) const
2249 {
2250 vec4<float> v;
2251 transform(in, v);
2252 return vec(v).div(v.w);
2253 }
2254
2255 template<class T>
2256 void mult(const matrix4 &x, const matrix4 &y)
2257 {
2258 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);
2259 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);
2260 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);
2261 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);
2262 }
2263
2264 matrix4();
2265 matrix4(const float *m);
2266 matrix4(const vec &a, const vec &b, const vec &c = vec(0, 0, 1));
2267 matrix4(const vec4<float> &a, const vec4<float> &b, const vec4<float> &c, const vec4<float> &d = vec4<float>(0, 0, 0, 1));
2268 matrix4(const matrix4x3 &m);
2269 matrix4(const matrix3 &rot, const vec &trans);
2270 void mul(const matrix4 &x, const matrix3 &y);
2271 void mul(const matrix3 &y);
2272
2282 void mul(const matrix4 &x, const matrix4 &y);
2283
2292 void mul(const matrix4 &y);
2293
2303 void muld(const matrix4 &x, const matrix4 &y);
2304
2313 void muld(const matrix4 &y);
2314 void rotate_around_x(float ck, float sk);
2315 void rotate_around_x(float angle);
2316 void rotate_around_x(const vec2 &sc);
2317 void rotate_around_y(float ck, float sk);
2318 void rotate_around_y(float angle);
2319 void rotate_around_y(const vec2 &sc);
2320
2321 void rotate_around_z(float ck, float sk);
2322 void rotate_around_z(float angle);
2323 void rotate_around_z(const vec2 &sc);
2324
2325 void rotate(float ck, float sk, const vec &axis);
2326 void rotate(float angle, const vec &dir);
2327 void rotate(const vec2 &sc, const vec &dir);
2328
2341 void identity();
2342
2343 void settranslation(const vec &v);
2344 void settranslation(float x, float y, float z);
2345 void translate(const vec &p);
2346 void translate(float x, float y, float z);
2347 void translate(const vec &p, float scale);
2348 void setscale(float x, float y, float z);
2349 void setscale(const vec &v);
2350 void setscale(float n);
2351 void scale(float x, float y, float z);
2352 void scale(const vec &v);
2353 void scale(float n);
2354
2355 void scalez(float k);
2356
2357 void jitter(float x, float y);
2358
2371
2384 void transpose(const matrix4 &m);
2385 void frustum(float left, float right, float bottom, float top, float znear, float zfar);
2386 void perspective(float fovy, float aspect, float znear, float zfar);
2387
2388 void ortho(float left, float right, float bottom, float top, float znear, float zfar);
2389
2390 void transform(const vec &in, vec &out) const;
2391 void transform(const vec4<float> &in, vec &out) const;
2392
2393 void transform(const vec &in, vec4<float> &out) const;
2394 void transform(const vec4<float> &in, vec4<float> &out) const;
2395 void transformnormal(const vec &in, vec &out) const;
2396 void transformnormal(const vec &in, vec4<float> &out) const;
2397
2398 void transposedtransform(const vec &in, vec &out) const;
2399 void transposedtransformnormal(const vec &in, vec &out) const;
2400 void transposedtransform(const plane &in, plane &out) const;
2401
2402 vec gettranslation() const;
2403
2412
2421
2430
2439
2452 bool invert(const matrix4 &m, double mindet = 1.0e-12);
2453
2463 matrix4 inverse(double mindet = 1.0e-12) const;
2464
2465 vec2 lineardepthscale() const;
2466};
2467
2469 : a(m.a), b(m.b), c(m.c)
2470{}
2471
2473 : a(m.a), b(m.b), c(m.c), d(m.d)
2474{}
2475
2476inline matrix3::matrix3(const matrix4x3 &m) : a(m.a), b(m.b), c(m.c) {}
2477
2478//generic two dimensional vector
2479template<class T>
2481{
2482 T x,y;
2483
2484 GenericVec2() {}
2485 GenericVec2(T x, T y) : x(x), y(y) {}
2486 GenericVec2(const vec2 &v) : x(v.x), y(v.y) {}
2487
2488 bool operator==(const GenericVec2 &h) const { return x == h.x && y == h.y; }
2489 bool operator!=(const GenericVec2 &h) const { return x != h.x || y != h.y; }
2490};
2491
2492//generic three dmensional vector
2493template<class T>
2495{
2496 T x,y,z;
2497
2498 GenericVec3() {}
2499 GenericVec3(T x, T y, T z) : x(x), y(y), z(z) {}
2500 GenericVec3(const vec &v) : x(v.x), y(v.y), z(v.z) {}
2501
2502 GenericVec3<T> operator+(const GenericVec3<T> &h) const { return GenericVec3<T>(x+h.x, y+h.y,z+h.z); }
2503 GenericVec3<T> operator-(const GenericVec3<T> &h) const { return GenericVec3<T>(x-h.x, y-h.y, z-h.z); }
2504
2505 //comparison
2506 bool operator==(const GenericVec3<T> &h) const { return x == h.x && y == h.y && z == h.z; }
2507 bool operator!=(const GenericVec3<T> &h) const { return x != h.x || y != h.y || z != h.z; }
2508 bool operator>(const GenericVec3<T> &h) const { return x > h.x && y > h.y && z > h.z; }
2509 bool operator<(const GenericVec3<T> &h) const { return x < h.x && y < h.y && z < h.z; }
2510 bool operator>=(const GenericVec3<T> &h) const { return x >= h.x && y >= h.y && z >= h.z; }
2511 bool operator<=(const GenericVec3<T> &h) const { return x <= h.x && y <= h.y && z <= h.z; }
2512};
2513
2514extern bool raysphereintersect(const vec &center, float radius, const vec &o, const vec &ray, float &dist);
2515extern bool rayboxintersect(const vec &b, const vec &s, const vec &o, const vec &ray, float &dist, int &orient);
2516
2549extern bool linecylinderintersect(const vec &from, const vec &to, const vec &start, const vec &end, float radius, float &dist);
2550extern int polyclip(const vec *in, int numin, const vec &dir, float below, float above, vec *out);
2551
2552extern const vec2 sincos360[];
2563inline int mod360(int angle)
2564{
2565 if(angle < 0)
2566 {
2567 angle = 360 + (angle <= -360 ? angle%360 : angle);
2568 }
2569 else if(angle >= 360)
2570 {
2571 angle %= 360;
2572 }
2573 return angle;
2574}
2575
2583inline const vec2 &sincosmod360(int angle) { return sincos360[mod360(angle)]; }
2584
2594inline float cos360(int angle) { return sincos360[angle].x; }
2595
2605inline float sin360(int angle) { return sincos360[angle].y; }
2606
2616inline float tan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.y/sc.x; }
2617
2627inline float cotan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.x/sc.y; }
2628
2629#endif /* GEOM_H_ */
matrix3: 3x3 matrix comprised of three vec3 vectors arranged as follows: [ a1 b1 c1 a2 b2 c2 a3 b3 c3...
Definition geom.h:1388
matrix3(const vec &a, const vec &b, const vec &c)
Creates a new matrix with the given vectors.
bool calcangleaxis(float tr, float &angle, vec &axis, float threshold=1e-16f) const
Calculates the axis and angle from a rotation matrix.
void rotate_around_z(const vec2 &sc)
Rotates the matrix values around the Z axis.
vec rowx() const
Returns the first (top) row of the matrix.
void rotate_around_y(float angle)
Rotates the matrix values around the Y axis.
vec a
the three vectors making up the rows of the matrix
Definition geom.h:1397
void scale(float k)
Multiplies each element of the matrix by the scale factor given.
vec abstransform(const vec &o) const
Sets the matrix to the absolute value of the transform.
vec transform(const vec &o) const
Sets the matrix to the transform of the matrix.
void invert(const matrix3 &o)
Inverts the matrix using another matrix for the scale factor.
void rotate_around_x(float angle)
Rotates the matrix values around the X axis.
void identity()
Sets the matrix to be the identity matrix.
void normalize()
Normalizes each of the three rows to a magnitude of 1.
void rotate_around_z(float angle)
Rotates the matrix values around the Z axis.
void invert()
Inverts the matrix using itself for the scale factor.
vec transform(const vec2 &o) const
Returns the transform of the matrix.
float trace() const
Returns the trace of the matrix.
vec transposedtransform(const vec2 &o) const
Returns the transposed transform of the matrix.
bool calcangleaxis(float &angle, vec &axis, float threshold=1e-16f) const
Calculates the axis and angle from a rotation matrix.
void rotate(float ck, float sk, const vec &axis)
Rotates the matrix around the given axis by the given angle.
void transposemul(const matrix3 &m, const matrix3 &n)
Calculates the transpose-multiplication with another two matrices.
vec abstransposedtransform(const vec &o) const
Sets the matrix to the absolute value of the transpose-transform.
vec rowz() const
Returns the third (bottom) row of the matrix.
void rotate_around_x(const vec2 &sc)
Rotates the matrix values around the X axis.
matrix3()
Creates an empty matrix.
void mul(const matrix3 &m, const matrix3 &n)
Calculates the product of three matrices.
void setyaw(float angle)
Sets the matrix to a 2D rotation matrix.
void transpose()
Transposes the matrix.
void transposemul(const matrix3 &n)
Calculates the transpose-multiplication with another matrix.
void rotate(float angle, const vec &axis)
Rotates the matrix around the given axis by the given angle.
void mul(const matrix3 &n)
Multiplies the matrix by another.
vec transposedtransform(const vec &o) const
Sets the matrix to the transpose-transform.
matrix3(const quat &q)
Creates a 3d rotation matrix given a quaternion object.
matrix3(float angle, const vec &axis)
Creates a new matrix as a rotation matrix.
void multranspose(const matrix3 &n)
Calculates the multiplication-transpose with another matrix.
void rotate_around_y(const vec2 &sc)
Rotates the matrix values around the Y axis.
vec rowy() const
Returns the second (middle) row of the matrix.
float sin360(int angle)
Returns the sine for an angle (in degrees)
Definition geom.h:2605
int mod360(int angle)
Returns the angle passed to it, clamped to 0...360.
Definition geom.h:2563
const vec2 & sincosmod360(int angle)
Returns a vec2 containing (cos, sine) for a given integral angle.
Definition geom.h:2583
float cotan360(int angle)
Returns the cotangent for an angle (in degrees)
Definition geom.h:2627
float cos360(int angle)
Returns the cosine for an angle (in degrees)
Definition geom.h:2594
const int R[3]
Definition geom.h:2067
const int C[3]
Definition geom.h:2068
bool linecylinderintersect(const vec &from, const vec &to, const vec &start, const vec &end, float radius, float &dist)
Determines whether a line segment intersects a specified cylinder.
const int D[3]
Definition geom.h:2069
const vec2 sincos360[]
float tan360(int angle)
Returns the tangent for an angle (in degrees)
Definition geom.h:2616
float fovy
Definition geom.h:2481
Definition geom.h:2495
three dimensional Cartesian byte vector
Definition geom.h:637
integer vector2
Definition geom.h:2158
Definition geom.h:2075
floating point 4x4 array object
Definition geom.h:2228
vec4< float > rowz() const
Returns the third row of the matrix.
vec4< float > roww() const
Returns the fourth row of the matrix.
void transpose()
Transposes the matrix along the diagonal.
vec4< float > rowx() const
Returns the first row of the matrix.
void mul(const matrix4 &x, const matrix4 &y)
Sets this matrix to the product of the two matrices provided.
matrix4 inverse(double mindet=1.0e-12) const
Returns the inverse of the matrix.
void muld(const matrix4 &y)
Sets this matrix to the product of this and another matrix.
bool invert(const matrix4 &m, double mindet=1.0e-12)
Sets this matrix to the inverse of the provided matrix.
vec4< float > rowy() const
Returns the second row of the matrix.
void muld(const matrix4 &x, const matrix4 &y)
Sets this matrix to the product of the two matrices provided.
void identity()
Sets the matrix to I, the identity matrix.
void transpose(const matrix4 &m)
Copies the transpose of the given matrix4 to this
void mul(const matrix4 &y)
Sets this matrix to the product of this and another matrix.
floating point 4x3 matrix object defined as four column vectors, a-d takes the form as follows: [ a1 ...
Definition geom.h:1811
void setscale(float x, float y, float z)
Sets the diagonals a.x, b.y, c.z to the given values.
void lerp(const matrix4x3 &from, const matrix4x3 &to, float t)
Linearly interpolates between two other matrices according to scale t.
void setscale(const vec &v)
Sets the diagonals a.x, b.y, c.z to the given vector's x, y, z values.
vec4< float > rowz() const
Returns the z values of the four vectors as a four-vector.
matrix4x3(const dualquat &dq)
Creates a matrix4x3 that represents a dual quaternion transformation.
matrix4x3()
Creates an empty matrix4x3 object.
void setscale(float n)
Sets the diagonals a.x, b.y, c.z identically to a given value.
void settranslation(float x, float y, float z)
Copies x, y, z into the fourth column vector (d).
void scale(float x, float y, float z)
Scales the first three vectors by x, y, and z respectively.
matrix4x3(const vec &a, const vec &b, const vec &c, const vec &d)
Creates a matrix4x3 from four three-dimensional vec objects.
void normalize()
Normalizes the first three column vectors.
void scale(float n)
Scales the first three vector elements in the matrix by the specified amount.
void lerp(const matrix4x3 &to, float t)
Linearly interpolates between the two matrices according to scale t.
vec4< float > rowx() const
Returns the x values of the four vectors as a four-vector.
vec4< float > rowy() const
Returns the y values of the four vectors as a four-vector.
matrix4x3(const matrix3 &rot, const vec &trans)
Creates a matrix4x3 from a rotation matrix and a translation vector.
void settranslation(const vec &p)
Copies the p vector into the fourth column vector (d).
void identity()
Sets this matrix to the identity matrix.
void mul(float k)
Multiplies all values inside the matrix by a scalar constant.
void scale(const vec &v)
Multiplies the first three vectors by v.x, v.y, and v.z respectively.
short integer three-vector object
Definition geom.h:2206
two dimensional Cartesian vector object
Definition geom.h:34
vec2 & lerp(const vec2 &a, const vec2 &b, float t)
Linearly interpolates between two other vec2s according to scale t.
Definition geom.h:110
vec2 & lerp(const vec2 &b, float t)
Linearly interpolates between another vec2 according to scale t.
Definition geom.h:93
A four dimensional Cartesian-space vector template.
Definition geom.h:755
T dot3(const vec &o) const
Returns the 3 dimensional dot product between this and a 3D vec.
Definition geom.h:825
vec4 & safenormalize()
Scales the vector to have a magnitude of 1.
Definition geom.h:896
T dot(const vec &o) const
Returns the dot product of this and a vec3, assuming o.w = 1.
Definition geom.h:848
T dot(const vec4 &o) const
Returns the scalar product with another vec4.
Definition geom.h:837
T v[4]
Definition geom.h:760
vec4 & div(T f)
Calculates the elementwise quotient.
Definition geom.h:1048
vec4 & add(const vec4 &o)
Calculates the elementwise sum.
Definition geom.h:1094
void flip()
Flips a vec4<uchar> by using the mask type pun.
Definition geom.h:927
vec4 & normalize()
Scales the vector to have a magnitude of 1.
Definition geom.h:887
vec4 & sub(const vec4 &o)
Subtracts from this the vec4 passed.
Definition geom.h:1155
vec4 & recip()
Calculates the elementwise reciprocal.
Definition geom.h:1082
vec4 & div3(T f)
Calculates the elementwise quotient.
Definition geom.h:1036
vec4 & sub3(T f)
Subtracts from the first three entries this the svalue passed.
Definition geom.h:1179
T squaredlen() const
Returns the square of the magnitude of the vector.
Definition geom.h:858
vec4 & rotate_around_x(T c, T s)
Rotates the given 3-vector around the x-axis.
Definition geom.h:1310
vec4 & addw(T f)
Adds to the fourth value of the vector (w/a).
Definition geom.h:1143
vec4 & div(const vec &o)
Calculates the elementwise quotient.
Definition geom.h:1072
vec4 & mul(T f)
Calculates the elementwise product.
Definition geom.h:987
vec4 & sub(const vec &o)
Subtracts from this the vec passed.
Definition geom.h:1167
vec4 & mul3(T f)
Calculates the elementwise product.
Definition geom.h:975
vec4 & add(const vec &o)
Calculates the elementwise sum.
Definition geom.h:1107
vec4 & mul(const vec &o)
Calculates the elementwise product.
Definition geom.h:1013
T magnitude3() const
Returns the magnitude of the vector, ignoring the w dimension.
Definition geom.h:878
T dot3(const vec4 &o) const
Returns the 3 dimensional dot product between two 4-vecs.
Definition geom.h:813
vec4 & div(const vec4 &o)
Calculates the elementwise quotient.
Definition geom.h:1060
vec4 & rotate_around_y(T c, T s)
Rotates the given 3-vector around the y-axis.
Definition geom.h:1328
vec4 & rotate_around_z(T c, T s)
Rotates the given 3-vector around the z-axis.
Definition geom.h:1292
uint mask
Definition geom.h:761
vec4 & square()
Calculates the elementwise square.
Definition geom.h:1023
vec4 & add(T f)
Calculates the elementwise sum.
Definition geom.h:1131
T magnitude() const
Returns the magnitude of the vector.
Definition geom.h:868
vec4 & mul(const vec4 &o)
Calculates the elementwise product.
Definition geom.h:1000
vec4 & add3(T f)
Calculates the elementwise sum.
Definition geom.h:1119
vec4 & avg(const vec4 &b)
Calculates the elementwise arithmetic mean.
Definition geom.h:957
three dimensional Cartesian vector object
Definition geom.h:185
float squaredlen() const
Returns the square of this vec's magnitude.
Definition geom.h:278
vec & square()
Sets this vec to its elementwise square.
Definition geom.h:287
vec & lerp(const vec &a, const vec &b, float t)
Linearly interpolates between two other vecs according to scale t.
Definition geom.h:417
vec & lerp(const vec &b, float t)
Linearly interpolates between another vec2 according to scale t.
Definition geom.h:399
bool insidebb(const ivec &o, int size) const
Determines whether this vec is within the boundaries {o, o+size}.
bool reject(const vec &o, float r) const
Checks whether the x,y dimensions are outside a distance from a vec.
Definition geom.h:350
float scalartriple(const vec &a, const vec &b) const
scalar triple product A*(BxC)
Definition geom.h:363
bool iszero() const
Returns whether this vec is exactly zero in all axes.
Definition geom.h:267
bool insidebb(const ivec &o, int size, int margin) const
Determines whether this vec is within the boundaries {o-margin, o+size+margin}.
vec & avg(const vec &b)
Sets this vec to the arithmetic mean of itself and another vec.
Definition geom.h:432
float zscalartriple(const vec &a, const vec &b) const
z component only of scalar triple product (A*(BxC))
Definition geom.h:368
float project_bb(const ivec &min, const ivec &max) const
Returns the dot product of this and min/max, depending on sign.