Libprimis
Imprimis' 3D destroyable world engine
Loading...
Searching...
No Matches
geom.h
Go to the documentation of this file.
1
9
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 float x, y;
36
37 vec2() {}
38 vec2(float x, float y) : x(x), y(y) {}
39 explicit vec2(const vec &v);
40 explicit vec2(const vec4<float> &v);
41
42 float &operator[](int i)
43 {
44 switch(i)
45 {
46 case 1:
47 {
48 return y;
49 }
50 default:
51 {
52 return x;
53 }
54 }
55 }
56
57 float operator[](int i) const
58 {
59 switch(i)
60 {
61 case 1:
62 {
63 return y;
64 }
65 default:
66 {
67 return x;
68 }
69 }
70 }
71
72 bool operator==(const vec2 &o) const { return x == o.x && y == o.y; }
73 bool operator!=(const vec2 &o) const { return x != o.x || y != o.y; }
74
75 const float *data() const { return &x; }
76
77 bool iszero() const { return x==0 && y==0; }
78 float dot(const vec2 &o) const { return x*o.x + y*o.y; }
79 float squaredlen() const { return dot(*this); }
80 float magnitude() const { return sqrtf(squaredlen()); }
81 vec2 &normalize() { mul(1/magnitude()); return *this; }
82 vec2 &safenormalize() { float m = magnitude(); if(m) mul(1/m); return *this; }
83 float cross(const vec2 &o) const { return x*o.y - y*o.x; }
84 float squaredist(const vec2 &e) const { return vec2(*this).sub(e).squaredlen(); }
85 float dist(const vec2 &e) const { return sqrtf(squaredist(e)); }
86
87 vec2 &mul(float f) { x *= f; y *= f; return *this; }
88 vec2 &mul(const vec2 &o) { x *= o.x; y *= o.y; return *this; }
89 vec2 &square() { mul(*this); return *this; }
90 vec2 &div(float f) { x /= f; y /= f; return *this; }
91 vec2 &div(const vec2 &o) { x /= o.x; y /= o.y; return *this; }
92 vec2 &recip() { x = 1/x; y = 1/y; return *this; }
93 vec2 &add(float f) { x += f; y += f; return *this; }
94 vec2 &add(const vec2 &o) { x += o.x; y += o.y; return *this; }
95 vec2 &sub(float f) { x -= f; y -= f; return *this; }
96 vec2 &sub(const vec2 &o) { x -= o.x; y -= o.y; return *this; }
97 vec2 &neg() { x = -x; y = -y; return *this; }
98 vec2 &min(const vec2 &o) { x = ::min(x, o.x); y = ::min(y, o.y); return *this; }
99 vec2 &max(const vec2 &o) { x = ::max(x, o.x); y = ::max(y, o.y); return *this; }
100 vec2 &min(float f) { x = ::min(x, f); y = ::min(y, f); return *this; }
101 vec2 &max(float f) { x = ::max(x, f); y = ::max(y, f); return *this; }
102 vec2 &abs() { x = fabs(x); y = fabs(y); return *this; }
103 vec2 &clamp(float l, float h) { x = ::std::clamp(x, l, h); y = ::std::clamp(y, l, h); return *this; }
104 vec2 &reflect(const vec2 &n) { float k = 2*dot(n); x -= k*n.x; y -= k*n.y; return *this; }
105
115 vec2 &lerp(const vec2 &b, float t)
116 {
117 x += (b.x-x)*t;
118 y += (b.y-y)*t;
119 return *this;
120 }
121
132 vec2 &lerp(const vec2 &a, const vec2 &b, float t)
133 {
134 x = a.x + (b.x-a.x)*t;
135 y = a.y + (b.y-a.y)*t;
136 return *this;
137 }
138
139 vec2 &avg(const vec2 &b) { add(b); mul(0.5f); return *this; }
140
141 vec2 operator+(const vec2 &v2) const
142 {
143 return vec2(x+v2.x, y+v2.y);
144 }
145
146 vec2 operator-(const vec2 &v2) const
147 {
148 return vec2(x-v2.x, y-v2.y);
149 }
150
151 vec2 operator-() const
152 {
153 return vec2(-x, -y);
154 }
155
156 template<typename T>
157 vec2 operator*(const T &n)
158 {
159 return vec2(n*x, n*y);
160 }
161
162 vec2 operator*(const vec2 &v2)
163 {
164 return vec2(x*v2.x, y*v2.y);
165 }
166
167 template<typename T>
168 vec2 operator/(const T &n)
169 {
170 return vec2(x/n, y/n);
171 }
172
173 vec2 operator/(const vec2 &v2)
174 {
175 return vec2(x/v2.x, y/v2.y);
176 }
177
178 template<class B>
179 vec2 &madd(const vec2 &a, const B &b) { return add(vec2(a).mul(b)); }
180
181 template<class B>
182 vec2 &msub(const vec2 &a, const B &b) { return sub(vec2(a).mul(b)); }
183
184 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; }
185 vec2 &rotate_around_z(float angle) { return rotate_around_z(cosf(angle), std::sin(angle)); }
186 vec2 &rotate_around_z(const vec2 &sc) { return rotate_around_z(sc.x, sc.y); }
187};
188
189struct ivec;
190struct svec;
191
206struct vec
207{
208 float x, y, z;
209
210 vec() {}
211 explicit vec(int a) : x(a), y(a), z(a) {}
212 explicit vec(float a) : x(a), y(a), z(a) {}
213 vec(float a, float b, float c) : x(a), y(b), z(c) {}
214 explicit vec(int v[3]) : x(v[0]), y(v[1]), z(v[2]) {}
215 explicit vec(const float *v) : x(v[0]), y(v[1]), z(v[2]) {}
216 explicit vec(const vec2 &v, float z = 0) : x(v.x), y(v.y), z(z) {}
217 explicit vec(const vec4<float> &v);
218 explicit vec(const ivec &v);
219 explicit vec(const svec &v);
220
221 vec(float yaw, float pitch) : x(-std::sin(yaw)*cosf(pitch)), y(cosf(yaw)*cosf(pitch)), z(std::sin(pitch)) {}
222 vec &set(int i, float f)
223 {
224 (*this)[i] = f; return *this;
225 }
226
227 float &r() {return x;}
228 float &g() {return y;}
229 float &b() {return z;}
230 float r() const {return x;}
231 float g() const {return y;}
232 float b() const {return z;}
233
234 const float *data() const {return &x;}
235
236 //operator overloads
237 float &operator[](int i)
238 {
239 switch(i)
240 {
241 case 1:
242 {
243 return y;
244 }
245 case 2:
246 {
247 return z;
248 }
249 default:
250 {
251 return x;
252 }
253 }
254 }
255
256 float operator[](int i) const
257 {
258 switch(i)
259 {
260 case 1:
261 {
262 return y;
263 }
264 case 2:
265 {
266 return z;
267 }
268 default:
269 {
270 return x;
271 }
272 }
273 }
274
275 bool operator==(const vec &o) const { return x == o.x && y == o.y && z == o.z; }
276 bool operator!=(const vec &o) const { return x != o.x || y != o.y || z != o.z; }
277
278 vec operator+(const vec &v2)
279 {
280 return vec(x+v2.x, y+v2.y, z+v2.z);
281 }
282
283 vec operator-(const vec &v2)
284 {
285 return vec(x-v2.x, y-v2.y, z-v2.z);
286 }
287
288 vec operator-()
289 {
290 return vec(-x, -y, -z);
291 }
292
293 template<typename T>
294 vec operator*(const T &n)
295 {
296 return vec(n*x, n*y, n*z);
297 }
298
299 vec operator*(const vec &v2)
300 {
301 return vec(x*v2.x, y*v2.y, z*v2.z);
302 }
303
304 template<typename T>
305 vec operator/(const T &n)
306 {
307 return vec(x/n, y/n, z/n);
308 }
309
310 vec operator/(const vec &v2)
311 {
312 return vec(x/v2.x, y/v2.y, z/v2.z);
313 }
314
315
316 //unary operators
326 bool iszero() const
327 {
328 return x==0 && y==0 && z==0;
329 }
330
337 float squaredlen() const { return x*x + y*y + z*z; }
338
346 vec &square() { mul(*this); return *this; }
347 vec &neg2() { x = -x; y = -y; return *this; } //unused
348 vec &neg() { x = -x; y = -y; z = -z; return *this; } //overloaded by operator-()
349 vec &abs() { x = fabs(x); y = fabs(y); z = fabs(z); return *this; }
350 vec &recip() { x = 1/x; y = 1/y; z = 1/z; return *this; } //used twice
351 float magnitude2() const { return sqrtf(dot2(*this)); }
352 float magnitude() const { return sqrtf(squaredlen()); }
353 vec &normalize() { div(magnitude()); return *this; }
354 vec &safenormalize() { float m = magnitude(); if(m) div(m); return *this; }
355 bool isnormalized() const { float m = squaredlen(); return (m>0.99f && m<1.01f); }
356
357 //elementwise float operators
358 vec &mul(float f) { x *= f; y *= f; z *= f; return *this; }
359 vec &mul2(float f) { x *= f; y *= f; return *this; } //unused
360 vec &div(float f) { x /= f; y /= f; z /= f; return *this; }
361 vec &div2(float f) { x /= f; y /= f; return *this; } //unused
362 vec &add(float f) { x += f; y += f; z += f; return *this; }
363 vec &add2(float f) { x += f; y += f; return *this; } //used once
364 vec &addz(float f) { z += f; return *this; } //unused
365 vec &sub(float f) { x -= f; y -= f; z -= f; return *this; }
366 vec &sub2(float f) { x -= f; y -= f; return *this; } //unused
367 vec &subz(float f) { z -= f; return *this; } //unused
368 vec &min(float f) { x = ::min(x, f); y = ::min(y, f); z = ::min(z, f); return *this; }
369 vec &max(float f) { x = ::max(x, f); y = ::max(y, f); z = ::max(z, f); return *this; }
370 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; }
371
372 //elementwise vector operators
373 vec &mul(const vec &o) { x *= o.x; y *= o.y; z *= o.z; return *this; }
374 vec &div(const vec &o) { x /= o.x; y /= o.y; z /= o.z; return *this; }
375 vec &add(const vec &o) { x += o.x; y += o.y; z += o.z; return *this; }
376 vec &sub(const vec &o) { x -= o.x; y -= o.y; z -= o.z; return *this; }
377 vec &min(const vec &o) { x = ::min(x, o.x); y = ::min(y, o.y); z = ::min(z, o.z); return *this; }
378 vec &max(const vec &o) { x = ::max(x, o.x); y = ::max(y, o.y); z = ::max(z, o.z); return *this; }
379
380 //dot products
381 float dot2(const vec2 &o) const { return x*o.x + y*o.y; }
382 float dot2(const vec &o) const { return x*o.x + y*o.y; }
383 float dot(const vec &o) const { return x*o.x + y*o.y + z*o.z; }
384 float squaredot(const vec &o) const { float k = dot(o); return k*k; } //unused
385 float absdot(const vec &o) const { return fabs(x*o.x) + fabs(y*o.y) + fabs(z*o.z); } //used once
386 float zdot(const vec &o) const { return z*o.z; } //unused
387
388 //distances
389 float squaredist(const vec &e) const { return vec(*this).sub(e).squaredlen(); }
390 float dist(const vec &e) const { return sqrtf(squaredist(e)); }
391 float dist(const vec &e, vec &t) const { t = *this; t.sub(e); return t.magnitude(); }
392 float dist2(const vec &o) const { float dx = x-o.x, dy = y-o.y; return sqrtf(dx*dx + dy*dy); }
393
394 //cross products
395
409 bool reject(const vec &o, float r) const
410 {
411 return x>o.x+r || x<o.x-r || y>o.y+r || y<o.y-r;
412 }
413
414 template<class A, class B>
415 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; }
416
417 vec &cross(const vec &o, const vec &a, const vec &b) { return cross(vec(a).sub(o), vec(b).sub(o)); }
418
422 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); }
423
427 float zscalartriple(const vec &a, const vec &b) const { return z*(a.x*b.y-a.y*b.x); } //unused
428
429 //transformations
430 vec &reflectz(float rz) { z = 2*rz - z; return *this; }
431 vec &reflect(const vec &n) { float k = 2*dot(n); x -= k*n.x; y -= k*n.y; z -= k*n.z; return *this; }
432 vec &project(const vec &n) { float k = dot(n); x -= k*n.x; y -= k*n.y; z -= k*n.z; return *this; }
433 vec &projectxydir(const vec &n) { if(n.z) z = -(x*n.x/n.z + y*n.y/n.z); return *this; } //used once
434 vec &projectxy(const vec &n)
435 {
436 float m = squaredlen(), k = dot(n);
437 projectxydir(n);
438 rescale(sqrtf(::max(m - k*k, 0.0f)));
439 return *this;
440 } //used once
441 vec &projectxy(const vec &n, float threshold)
442 {
443 float m = squaredlen(), k = ::min(dot(n), threshold);
444 projectxydir(n);
445 rescale(sqrtf(::max(m - k*k, 0.0f)));
446 return *this;
447 } //used once
448
458 vec &lerp(const vec &b, float t)
459 {
460 x += (b.x-x)*t;
461 y += (b.y-y)*t;
462 z += (b.z-z)*t;
463 return *this;
464 }
465
476 vec &lerp(const vec &a, const vec &b, float t)
477 {
478 x = a.x + (b.x-a.x)*t;
479 y = a.y + (b.y-a.y)*t;
480 z = a.z + (b.z-a.z)*t;
481 return *this;
482 }
483
491 vec &avg(const vec &b)
492 {
493 add(b);
494 mul(0.5f);
495 return *this;
496 }
497
498 template<class B>
499 vec &madd(const vec &a, const B &b) { return add(vec(a).mul(b)); }
500
501 template<class B>
502 vec &msub(const vec &a, const B &b) { return sub(vec(a).mul(b)); }
503
504 vec &rescale(float k)
505 {
506 float mag = magnitude();
507 if(mag > 1e-6f) mul(k / mag);
508 return *this;
509 }
510
511 //all rotate_around functions use RH coordinates (positive rotation in CCW direction)
512 vec &rotate_around_z(float c, float s)
513 {
514 float rx = x,
515 ry = y;
516 x = c*rx-s*ry;
517 y = c*ry+s*rx;
518 return *this;
519 }
520
521 vec &rotate_around_x(float c, float s)
522 {
523 float ry = y,
524 rz = z;
525 y = c*ry-s*rz;
526 z = c*rz+s*ry;
527 return *this;
528 }
529
530 vec &rotate_around_y(float c, float s)
531 {
532 float rx = x,
533 rz = z;
534 x = c*rx-s*rz;
535 z = c*rz+s*rx;
536 return *this;
537 }
538
539 vec &rotate_around_z(float angle)
540 {
541 return rotate_around_z(cosf(angle), std::sin(angle));
542 }
543
544 vec &rotate_around_x(float angle)
545 {
546 return rotate_around_x(cosf(angle), std::sin(angle));
547 }
548
549 vec &rotate_around_y(float angle)
550 {
551 return rotate_around_y(cosf(angle), std::sin(angle));
552 }
553
554 vec &rotate_around_z(const vec2 &sc)
555 {
556 return rotate_around_z(sc.x, sc.y);
557 }
558
559 vec &rotate_around_x(const vec2 &sc)
560 {
561 return rotate_around_x(sc.x, sc.y);
562 }
563
564 vec &rotate_around_y(const vec2 &sc)
565 {
566 return rotate_around_y(sc.x, sc.y);
567 }
568
569 vec &rotate(float c, float s, const vec &d)
570 {
571 *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),
572 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),
573 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));
574 return *this;
575 }
576 vec &rotate(float angle, const vec &d)
577 {
578 return rotate(cosf(angle), std::sin(angle), d);
579 }
580
581 vec &rotate(const vec2 &sc, const vec &d)
582 {
583 return rotate(sc.x, sc.y, d);
584 }
585
586 void orthogonal(const vec &d)
587 {
588 *this = fabs(d.x) > fabs(d.z) ? vec(-d.y, d.x, 0) : vec(0, -d.z, d.y);
589 }
590
591 void orthonormalize(vec &s, vec &t) const
592 {
593 s.project(*this);
594 t.project(*this).project(s);
595 } //unused
596
597 template<class T>
598 bool insidebb(const T &bbmin, const T &bbmax) const
599 {
600 return x >= bbmin.x && x <= bbmax.x && y >= bbmin.y && y <= bbmax.y && z >= bbmin.z && z <= bbmax.z;
601 }
602
603 template<class T, class U>
604 bool insidebb(const T &bbmin, const T &bbmax, U margin) const
605 {
606 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;
607 }
608
621 bool insidebb(const ivec &o, int size) const;
622
637 bool insidebb(const ivec &o, int size, int margin) const;
638 float dist_to_bb(const ivec &min, const ivec &max) const;
639
653 float project_bb(const ivec &min, const ivec &max) const;
654
655 static vec hexcolor(int color)
656 {
657 return vec(((color>>16)&0xFF)*(1.0f/255.0f), ((color>>8)&0xFF)*(1.0f/255.0f), (color&0xFF)*(1.0f/255.0f));
658 }
659
660 int tohexcolor() const
661 {
662 return (static_cast<int>(::std::clamp(r(), 0.0f, 1.0f)*255)<<16) |
663 (static_cast<int>(::std::clamp(g(), 0.0f, 1.0f)*255)<<8) |
664 static_cast<int>(::std::clamp(b(), 0.0f, 1.0f)*255);
665 }
666};
667
668inline vec2::vec2(const vec &v) : x(v.x), y(v.y) {}
669
670template<>
671struct std::hash<vec>
672{
673 size_t operator()(const vec& k) const
674 {
675 union { uint i; float f; } x, y, z;
676 x.f = k.x;
677 y.f = k.y;
678 z.f = k.z;
679 uint v = x.i^y.i^z.i;
680 return v + (v>>12);
681 }
682};
683
695struct bvec
696{
697 uchar x, y, z;
698
699 bvec() {}
700 bvec(uchar x, uchar y, uchar z) : x(x), y(y), z(z) {}
701 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))) {}
702 explicit bvec(const vec4<uchar> &v);
703
704 uchar &r() {return x;}
705 uchar &g() {return y;}
706 uchar &b() {return z;}
707 uchar r() const {return x;}
708 uchar g() const {return y;}
709 uchar b() const {return z;}
710
711 uchar &operator[](int i)
712 {
713 switch(i)
714 {
715 case 1:
716 {
717 return y;
718 }
719 case 2:
720 {
721 return z;
722 }
723 default:
724 {
725 return x;
726 }
727 }
728 }
729 uchar operator[](int i) const
730 {
731 switch(i)
732 {
733 case 1:
734 {
735 return y;
736 }
737 case 2:
738 {
739 return z;
740 }
741 default:
742 {
743 return x;
744 }
745 }
746 }
747
748 bool operator==(const bvec &v) const { return x==v.x && y==v.y && z==v.z; }
749 bool operator!=(const bvec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
750
751 bool iszero() const { return x==0 && y==0 && z==0; }
752
753 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); }
754
755 bvec &normalize()
756 {
757 vec n(x-127.5f, y-127.5f, z-127.5f);
758 float mag = 127.5f/n.magnitude();
759 x = static_cast<uchar>(n.x*mag+127.5f);
760 y = static_cast<uchar>(n.y*mag+127.5f);
761 z = static_cast<uchar>(n.z*mag+127.5f);
762 return *this;
763 }
764
765 void lerp(const bvec &a, const bvec &b, float t)
766 {
767 x = static_cast<uchar>(a.x + (b.x-a.x)*t);
768 y = static_cast<uchar>(a.y + (b.y-a.y)*t);
769 z = static_cast<uchar>(a.z + (b.z-a.z)*t);
770 }
771
772 void lerp(const bvec &a, const bvec &b, int ka, int kb, int d)
773 {
774 x = static_cast<uchar>((a.x*ka + b.x*kb)/d);
775 y = static_cast<uchar>((a.y*ka + b.y*kb)/d);
776 z = static_cast<uchar>((a.z*ka + b.z*kb)/d);
777 }
778
779 void flip()
780 {
781 x ^= 0x80;
782 y ^= 0x80;
783 z ^= 0x80;
784 }
785
786 void scale(int k, int d)
787 {
788 x = static_cast<uchar>((x*k)/d);
789 y = static_cast<uchar>((y*k)/d);
790 z = static_cast<uchar>((z*k)/d);
791 }
792
793 bvec &shl(int n)
794 {
795 x <<= n;
796 y <<= n;
797 z <<= n;
798 return *this;
799 }
800 bvec &shr(int n)
801 {
802 x >>= n;
803 y >>= n;
804 z >>= n;
805 return *this;
806 }
807
808 static bvec fromcolor(const vec &v)
809 {
810 return bvec(static_cast<uchar>(v.x*255.0f), static_cast<uchar>(v.y*255.0f), static_cast<uchar>(v.z*255.0f));
811 }
812
813 vec tocolor() const
814 {
815 return vec(x*(1.0f/255.0f), y*(1.0f/255.0f), z*(1.0f/255.0f));
816 }
817
818 static bvec from565(ushort c)
819 {
820 return bvec((((c>>11)&0x1F)*527 + 15) >> 6, (((c>>5)&0x3F)*259 + 35) >> 6, ((c&0x1F)*527 + 15) >> 6);
821 }
822
823 static bvec hexcolor(int color)
824 {
825 return bvec((color>>16)&0xFF, (color>>8)&0xFF, color&0xFF);
826 }
827
828 int tohexcolor() const
829 {
830 return (static_cast<int>(x)<<16)|(static_cast<int>(y)<<8)|static_cast<int>(z);
831 }
832};
833
842template<typename T>
843struct vec4
844{
845
846 T x, y, z, w;
847
848 vec4() {}
849 explicit vec4(const vec &p, T w = 0) : x(p.x), y(p.y), z(p.z), w(w) {}
850 explicit vec4(const vec2 &p, T z = 0, T w = 0) : x(p.x), y(p.y), z(z), w(w) {}
851 vec4(T x, T y = 0, T z = 0, T w = 0) : x(x), y(y), z(z), w(w) {}
852 vec4(bvec v, uchar c)
853 {
854 x = v.x;
855 y = v.y;
856 z = v.z;
857 w = c;
858 }
859 vec4(bvec v)
860 {
861 x = v.x;
862 y = v.y;
863 z = v.z;
864 w = 0;
865 }
866
867 explicit vec4(const T *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
868
869 template<class U>
870 vec4(const vec4<U> &p) : x(p.x), y(p.y), z(p.z), w(p.w) {}
871
872 template<class U>
873 operator vec4<U>()
874 {
875 return vec4<U>(static_cast<U>(this->x),
876 static_cast<U>(this->y),
877 static_cast<U>(this->z),
878 static_cast<U>(this->w));
879 }
880
895 T &operator[](int i)
896 {
897 switch(i)
898 {
899 case 1:
900 {
901 return y;
902 }
903 case 2:
904 {
905 return z;
906 }
907 case 3:
908 {
909 return w;
910 }
911 default:
912 {
913 return x;
914 }
915 }
916 }
917
932 T operator[](int i) const
933 {
934 switch(i)
935 {
936 case 1:
937 {
938 return y;
939 }
940 case 2:
941 {
942 return z;
943 }
944 case 3:
945 {
946 return w;
947 }
948 default:
949 {
950 return x;
951 }
952 }
953 }
954
955
961 T &r() { return x; }
962
968 T &g() { return y; }
969
975 T &b() { return z; }
976
982 T &a() { return w; }
983
989 T r() const { return x; }
990
996 T g() const { return y; }
997
1003 T b() const { return z; }
1004
1010 T a() const { return w; }
1011
1017 const T *data() const { return &x; }
1018
1024 uint *mask()
1025 {
1026 return reinterpret_cast<uint *>(&x);
1027 }
1028
1040 bool operator==(const vec4 &o) const { return x == o.x && y == o.y && z == o.z && w == o.w; }
1041
1053 bool operator!=(const vec4 &o) const { return x != o.x || y != o.y || z != o.z || w != o.w; }
1054
1065 T dot3(const vec4 &o) const { return x*o.x + y*o.y + z*o.z; }
1066
1077 T dot3(const vec &o) const { return x*o.x + y*o.y + z*o.z; }
1078
1089 T dot(const vec4 &o) const { return dot3(o) + w*o.w; }
1090
1100 T dot(const vec &o) const { return x*o.x + y*o.y + z*o.z + w; }
1101
1110 T squaredlen() const { return dot(*this); }
1111
1120 T magnitude() const { return sqrtf(squaredlen()); }
1121
1130 T magnitude3() const { return sqrtf(dot3(*this)); }
1131
1139 vec4 &normalize() { mul(1/magnitude()); return *this; }
1140
1148 vec4 &safenormalize() { T m = magnitude(); if(m) mul(1/m); return *this; }
1149
1150 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, float t)
1151 {
1152 x = static_cast<uchar>(a.x + (b.x-a.x)*t);
1153 y = static_cast<uchar>(a.y + (b.y-a.y)*t);
1154 z = static_cast<uchar>(a.z + (b.z-a.z)*t);
1155 w = a.w;
1156 }
1157
1158 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, int ka, int kb, int d)
1159 {
1160 x = static_cast<uchar>((a.x*ka + b.x*kb)/d);
1161 y = static_cast<uchar>((a.y*ka + b.y*kb)/d);
1162 z = static_cast<uchar>((a.z*ka + b.z*kb)/d);
1163 w = a.w;
1164 }
1165
1166 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, const vec4<uchar> &c, float ta, float tb, float tc)
1167 {
1168 x = static_cast<uchar>(a.x*ta + b.x*tb + c.x*tc);
1169 y = static_cast<uchar>(a.y*ta + b.y*tb + c.y*tc);
1170 z = static_cast<uchar>(a.z*ta + b.z*tb + c.z*tc);
1171 w = static_cast<uchar>(a.w*ta + b.w*tb + c.w*tc);
1172 }
1173
1179 void flip() { *mask() ^= 0x80808080; }
1180
1181 vec4 &lerp(const vec4 &b, T t)
1182 {
1183 x += (b.x-x)*t;
1184 y += (b.y-y)*t;
1185 z += (b.z-z)*t;
1186 w += (b.w-w)*t;
1187 return *this;
1188 }
1189 vec4 &lerp(const vec4 &a, const vec4 &b, T t)
1190 {
1191 x = a.x+(b.x-a.x)*t;
1192 y = a.y+(b.y-a.y)*t;
1193 z = a.z+(b.z-a.z)*t;
1194 w = a.w+(b.w-a.w)*t;
1195 return *this;
1196 }
1197
1209 vec4 &avg(const vec4 &b) { add(b); mul(0.5f); return *this; }
1210
1221 template<class B>
1222 vec4 &madd(const vec4 &a, const B &b) { return add(vec4(a).mul(b)); }
1223
1234 template<class B>
1235 vec4 &msub(const vec4 &a, const B &b) { return sub(vec4(a).mul(b)); }
1236
1247 vec4 &mul3(T f) { x *= f; y *= f; z *= f; return *this; }
1248
1259 vec4 &mul(T f) { mul3(f); w *= f; return *this; }
1260
1272 vec4 &mul(const vec4 &o) { x *= o.x; y *= o.y; z *= o.z; w *= o.w; return *this; }
1273
1285 vec4 &mul(const vec &o) { x *= o.x; y *= o.y; z *= o.z; return *this; }
1286
1295 vec4 &square() { mul(*this); return *this; }
1296
1308 vec4 &div3(T f) { x /= f; y /= f; z /= f; return *this; }
1309
1320 vec4 &div(T f) { div3(f); w /= f; return *this; }
1321
1332 vec4 &div(const vec4 &o) { x /= o.x; y /= o.y; z /= o.z; w /= o.w; return *this; }
1333
1344 vec4 &div(const vec &o) { x /= o.x; y /= o.y; z /= o.z; return *this; }
1345
1354 vec4 &recip() { x = 1/x; y = 1/y; z = 1/z; w = 1/w; return *this; }
1355
1366 vec4 &add(const vec4 &o) { x += o.x; y += o.y; z += o.z; w += o.w; return *this; }
1367
1379 vec4 &add(const vec &o) { x += o.x; y += o.y; z += o.z; return *this; }
1380
1391 vec4 &add3(T f) { x += f; y += f; z += f; return *this; }
1392
1403 vec4 &add(T f) { add3(f); w += f; return *this; }
1404
1415 vec4 &addw(T f) { w += f; return *this; }
1416
1427 vec4 &sub(const vec4 &o) { x -= o.x; y -= o.y; z -= o.z; w -= o.w; return *this; }
1428
1439 vec4 &sub(const vec &o) { x -= o.x; y -= o.y; z -= o.z; return *this; }
1440
1452 {
1453 x -= f;
1454 y -= f;
1455 z -= f;
1456 return *this;
1457 }
1458
1469 vec4 &sub(T f)
1470 {
1471 sub3(f);
1472 w -= f;
1473 return *this;
1474 }
1475
1487 {
1488 w -= f;
1489 return *this;
1490 }
1491
1500 {
1501 x = -x;
1502 y = -y;
1503 z = -z;
1504 return *this;
1505 }
1506
1513 {
1514 neg3();
1515 w = -w;
1516 return *this;
1517 }
1518
1527 vec4 &clamp(T l, T h)
1528 {
1529 x = ::std::clamp(x, l, h);
1530 y = ::std::clamp(y, l, h);
1531 z = ::std::clamp(z, l, h);
1532 w = ::std::clamp(w, l, h);
1533 return *this;
1534 }
1535
1543 vec4 operator+(const vec4 &v2) const
1544 {
1545 return vec4(x+v2.x, y+v2.y, z+v2.z, w+v2.w);
1546 }
1547
1555 vec4 operator-(const vec4 &v2) const
1556 {
1557 return vec4(x-v2.x, y-v2.y, z-v2.z, w-v2.w);
1558 }
1559
1566 {
1567 return vec4(-x, -y, -z, -w);
1568 }
1569
1578 template<typename U>
1579 vec4 operator*(const U &n) const
1580 {
1581 return vec4(n*x, n*y, n*z, n*w);
1582 }
1583
1591 vec4 operator*(const vec4 &v2) const
1592 {
1593 return vec4(x*v2.x, y*v2.y, z*v2.z, w*v2.w);
1594 }
1595
1604 template<typename U>
1605 vec4 operator/(const U &n) const
1606 {
1607 return vec4(x/n, y/n, z/n, w/n);
1608 }
1609
1610
1618 vec4 operator/(const vec4 &v2) const
1619 {
1620 return vec4(x/v2.x, y/v2.y, z/v2.z, w/v2.w);
1621 }
1622
1623
1636 template<class A, class B>
1637 vec4 &cross(const A &a, const B &b)
1638 {
1639 x = a.y*b.z-a.z*b.y;
1640 y = a.z*b.x-a.x*b.z;
1641 z = a.x*b.y-a.y*b.x;
1642 return *this;
1643 }
1644
1654 vec4 &cross(const vec &o, const vec &a, const vec &b)
1655 {
1656 return cross(vec(a).sub(o), vec(b).sub(o));
1657 }
1658
1664 void setxyz(const vec &v)
1665 {
1666 x = v.x;
1667 y = v.y;
1668 z = v.z;
1669 }
1670
1681 {
1682 T rx = x,
1683 ry = y;
1684 x = c*rx-s*ry;
1685 y = c*ry+s*rx;
1686 return *this;
1687 }
1688
1699 {
1700 T ry = y,
1701 rz = z;
1702 y = c*ry-s*rz;
1703 z = c*rz+s*ry;
1704 return *this;
1705 }
1706
1717 {
1718 T rx = x,
1719 rz = z;
1720 x = c*rx-s*rz;
1721 z = c*rz+s*rx;
1722 return *this;
1723 }
1724
1736 {
1737 return rotate_around_z(cosf(angle), std::sin(angle));
1738 }
1739
1751 {
1752 return rotate_around_x(cosf(angle), std::sin(angle));
1753 }
1754
1766 {
1767 return rotate_around_y(cosf(angle), std::sin(angle));
1768 }
1769
1781 {
1782 return rotate_around_z(sc.x, sc.y);
1783 }
1784
1796 {
1797 return rotate_around_x(sc.x, sc.y);
1798 }
1799
1811 {
1812 return rotate_around_y(sc.x, sc.y);
1813 }
1814
1823 {
1824 return vec(x*(2.0f/255.0f)-1.0f, y*(2.0f/255.0f)-1.0f, z*(2.0f/255.0f)-1.0f);
1825 }
1826
1827};
1828
1829inline vec2::vec2(const vec4<float> &v) : x(v.x), y(v.y) {}
1830inline vec::vec(const vec4<float> &v) : x(v.x), y(v.y), z(v.z) {}
1831
1843{
1844 public:
1852 vec a, b, c;
1853
1858
1866 matrix3(const vec &a, const vec &b, const vec &c);
1867
1877 explicit matrix3(float angle, const vec &axis);
1878
1887 explicit matrix3(const quat &q);
1888
1895 explicit matrix3(const matrix4x3 &m);
1896
1904 explicit matrix3(const matrix4 &m);
1905
1912 void mul(const matrix3 &m, const matrix3 &n);
1913
1921 void mul(const matrix3 &n);
1922
1928 void multranspose(const matrix3 &n);
1929
1936 void transposemul(const matrix3 &m, const matrix3 &n);
1937
1943 void transposemul(const matrix3 &n);
1944
1955
1963 void invert(const matrix3 &o);
1964
1971 void invert();
1972
1979
1985 void scale(float k);
1986
1993 void rotate(float angle, const vec &axis);
1994
2002 void rotate(float ck, float sk, const vec &axis);
2003
2018 void setyaw(float angle);
2019
2027 float trace() const;
2028
2053 bool calcangleaxis(float tr, float &angle, vec &axis, float threshold = 1e-16f) const;
2054
2069 bool calcangleaxis(float &angle, vec &axis, float threshold = 1e-16f) const;
2070
2078 vec transform(const vec &o) const;
2079
2087 vec transposedtransform(const vec &o) const;
2088
2096 vec abstransform(const vec &o) const;
2097
2106
2116 void identity();
2117
2123 void rotate_around_x(float angle);
2124
2130 void rotate_around_x(const vec2 &sc);
2131
2137 void rotate_around_y(float angle);
2138
2144 void rotate_around_y(const vec2 &sc);
2145
2151 void rotate_around_z(float angle);
2152
2158 void rotate_around_z(const vec2 &sc);
2159
2167 vec transform(const vec2 &o) const;
2168
2177
2183 vec rowx() const;
2184
2190 vec rowy() const;
2191
2197 vec rowz() const;
2198 private:
2199
2206 void multranspose(const matrix3 &m, const matrix3 &n);
2207
2221 void setyaw(float ck, float sk);
2222
2229 void rotate_around_x(float ck, float sk);
2230
2237 void rotate_around_y(float ck, float sk);
2238
2245 void rotate_around_z(float ck, float sk);
2246
2252 void transpose(const matrix3 &m);
2253};
2254
2266{
2267 vec a, b, c, d;
2268
2276
2287 matrix4x3(const vec &a, const vec &b, const vec &c, const vec &d);
2288
2298 matrix4x3(const matrix3 &rot, const vec &trans);
2299
2305 matrix4x3(const dualquat &dq);
2306
2314 explicit matrix4x3(const matrix4 &m);
2315
2321 void mul(float k);
2322
2332 void setscale(float x, float y, float z);
2333
2341 void setscale(const vec &v);
2342
2348 void setscale(float n);
2349
2359 void scale(float x, float y, float z);
2360
2368 void scale(const vec &v);
2369
2377 void scale(float n);
2378
2384 void settranslation(const vec &p);
2385
2393 void settranslation(float x, float y, float z);
2394 void translate(const vec &p);
2395 void translate(float x, float y, float z);
2396 void translate(const vec &p, float scale);
2397 void accumulate(const matrix4x3 &m, float k);
2398
2408
2418 void lerp(const matrix4x3 &to, float t);
2419
2430 void lerp(const matrix4x3 &from, const matrix4x3 &to, float t);
2431
2442 void identity();
2443 void mul(const matrix4x3 &m, const matrix4x3 &n);
2444 void mul(const matrix4x3 &n);
2445
2446 void mul(const matrix3 &m, const matrix4x3 &n);
2447
2448 void mul(const matrix3 &rot, const vec &trans, const matrix4x3 &n);
2449
2450 void transpose();
2451 void transpose(const matrix4x3 &o);
2452
2453 void transposemul(const matrix4x3 &m, const matrix4x3 &n);
2454
2455 void multranspose(const matrix4x3 &m, const matrix4x3 &n);
2456
2457 void invert(const matrix4x3 &o);
2458 void invert();
2459 void rotate(float angle, const vec &d);
2460
2461 void rotate(float ck, float sk, const vec &axis);
2462
2463 void rotate_around_x(float ck, float sk);
2464 void rotate_around_x(float angle);
2465
2466 void rotate_around_x(const vec2 &sc);
2467
2468 void rotate_around_y(float ck, float sk);
2469 void rotate_around_y(float angle);
2470 void rotate_around_y(const vec2 &sc);
2471
2472 void rotate_around_z(float ck, float sk);
2473 void rotate_around_z(float angle);
2474 void rotate_around_z(const vec2 &sc);
2475
2476 vec transposedtransform(const vec &o) const;
2477 vec transformnormal(const vec &o) const;
2478 vec transposedtransformnormal(const vec &o) const;
2479 vec transform(const vec &o) const;
2480 vec transform(const vec2 &o) const;
2481
2488
2495
2502};
2503
2504/*
2505
2506The engine uses 3 different linear coordinate systems
2507which are oriented around each of the axis dimensions.
2508
2509So any point within the game can be defined by four coordinates: (d, x, y, z)
2510
2511d is the reference axis dimension
2512x is the coordinate of the ROW dimension
2513y is the coordinate of the COL dimension
2514z is the coordinate of the reference dimension (DEPTH)
2515
2516typically, if d is not used, then it is implicitly the Z dimension.
2517ie: d=z => x=x, y=y, z=z
2518
2519*/
2520
2521// DIM: X=0 Y=1 Z=2.
2522const int R[3] = {1, 2, 0};
2523const int C[3] = {2, 0, 1};
2524const int D[3] = {0, 1, 2};
2525
2526struct ivec2;
2527
2528//integer vector3
2529struct ivec
2530{
2531 int x, y, z;
2532
2533 ivec() {}
2534 explicit ivec(const vec &v) : x(static_cast<int>(v.x)), y(static_cast<int>(v.y)), z(static_cast<int>(v.z)) {}
2535 ivec(int a, int b, int c) : x(a), y(b), z(c) {}
2536 ivec(int d, int row, int col, int depth)
2537 {
2538 (*this)[R[d]] = row;
2539 (*this)[C[d]] = col;
2540 (*this)[D[d]] = depth;
2541 }
2542 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) {}
2543 explicit ivec(const ivec2 &v, int z = 0);
2544 explicit ivec(const svec &v);
2545
2546 int &operator[](int i)
2547 {
2548 switch(i)
2549 {
2550 case 1:
2551 {
2552 return y;
2553 }
2554 case 2:
2555 {
2556 return z;
2557 }
2558 default:
2559 {
2560 return x;
2561 }
2562 }
2563 }
2564
2565 int operator[](int i) const
2566 {
2567 switch(i)
2568 {
2569 case 1:
2570 {
2571 return y;
2572 }
2573 case 2:
2574 {
2575 return z;
2576 }
2577 default:
2578 {
2579 return x;
2580 }
2581 }
2582 }
2583
2584 //int idx(int i) { return v[i]; }
2585 bool operator==(const ivec &v) const { return x==v.x && y==v.y && z==v.z; }
2586 bool operator!=(const ivec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
2587 ivec operator+(const ivec &v) const { return ivec(x+v.x, y+v.y, z+v.z); }
2595 explicit operator bool() const { return !(x==0 && y==0 && z==0); }
2596 ivec &shl(int n) { x<<= n; y<<= n; z<<= n; return *this; }
2597 ivec &shr(int n) { x>>= n; y>>= n; z>>= n; return *this; }
2598 ivec &mul(int n) { x *= n; y *= n; z *= n; return *this; }
2599 ivec &div(int n) { x /= n; y /= n; z /= n; return *this; }
2600 ivec &add(int n) { x += n; y += n; z += n; return *this; }
2601 ivec &sub(int n) { x -= n; y -= n; z -= n; return *this; }
2602 ivec &mul(const ivec &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
2603 ivec &div(const ivec &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
2604 ivec &add(const ivec &v) { x += v.x; y += v.y; z += v.z; return *this; }
2605 ivec &sub(const ivec &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
2606 ivec &mask(int n) { x &= n; y &= n; z &= n; return *this; }
2607 ivec &neg() { x = -x; y = -y; z = -z; return *this; }
2608 ivec &min(const ivec &o) { x = ::min(x, o.x); y = ::min(y, o.y); z = ::min(z, o.z); return *this; }
2609 ivec &max(const ivec &o) { x = ::max(x, o.x); y = ::max(y, o.y); z = ::max(z, o.z); return *this; }
2610 ivec &min(int n) { x = ::min(x, n); y = ::min(y, n); z = ::min(z, n); return *this; }
2611 ivec &max(int n) { x = ::max(x, n); y = ::max(y, n); z = ::max(z, n); return *this; }
2612 ivec &abs() { x = ::abs(x); y = ::abs(y); z = ::abs(z); return *this; }
2613 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; }
2614 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; }
2615 int dot(const ivec &o) const { return x*o.x + y*o.y + z*o.z; }
2616 float dist(const plane &p) const;
2617
2618 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))); }
2619 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))); }
2620};
2621
2622inline vec::vec(const ivec &v) : x(v.x), y(v.y), z(v.z) {}
2623
2624template<>
2625struct std::hash<ivec>
2626{
2627 size_t operator()(const ivec &k) const
2628 {
2629 return k.x^k.y^k.z;
2630 }
2631};
2632
2636struct ivec2
2637{
2638 union
2639 {
2640 struct { int x, y; } coord;
2641 int v[2];
2642 };
2643
2644 ivec2() {}
2645 ivec2(int x, int y)
2646 {
2647 coord.x = x;
2648 coord.y = y;
2649 }
2650
2651 explicit ivec2(const vec2 &v)
2652 {
2653 coord.x = static_cast<int>(v.x);
2654 coord.y = static_cast<int>(v.y);
2655 }
2656
2657 explicit ivec2(const ivec &v)
2658 {
2659 coord.x = v.x;
2660 coord.y = v.y;
2661 }
2662
2663 int &operator[](int i) { return v[i]; }
2664 int operator[](int i) const { return v[i]; }
2665
2666 bool operator==(const ivec2 &o) const { return coord.x == o.coord.x && coord.y == o.coord.y; }
2667 bool operator!=(const ivec2 &o) const { return coord.x != o.coord.x || coord.y != o.coord.y; }
2668
2669 int &x() { return coord.x; }
2670 int &y() { return coord.y; }
2671 int x() const { return coord.x; }
2672 int y() const { return coord.y; }
2673
2674 bool iszero() const { return coord.x==0 && coord.y==0; }
2675 ivec2 &shl(int n) { coord.x<<= n; coord.y<<= n; return *this; }
2676 ivec2 &shr(int n) { coord.x>>= n; coord.y>>= n; return *this; }
2677 ivec2 &mul(int n) { coord.x *= n; coord.y *= n; return *this; }
2678 ivec2 &div(int n) { coord.x /= n; coord.y /= n; return *this; }
2679 ivec2 &add(int n) { coord.x += n; coord.y += n; return *this; }
2680 ivec2 &sub(int n) { coord.x -= n; coord.y -= n; return *this; }
2681 ivec2 &mul(const ivec2 &v) { coord.x *= v.coord.x; coord.y *= v.coord.y; return *this; }
2682 ivec2 &div(const ivec2 &v) { coord.x /= v.coord.x; coord.y /= v.coord.y; return *this; }
2683 ivec2 &add(const ivec2 &v) { coord.x += v.coord.x; coord.y += v.coord.y; return *this; }
2684 ivec2 &sub(const ivec2 &v) { coord.x -= v.coord.x; coord.y -= v.coord.y; return *this; }
2685 ivec2 &mask(int n) { coord.x &= n; coord.y &= n; return *this; }
2686 ivec2 &neg() { coord.x = -coord.x; coord.y = -coord.y; return *this; }
2687 ivec2 &min(const ivec2 &o) { coord.x = ::min(coord.x, o.coord.x); coord.y = ::min(coord.y, o.coord.y); return *this; }
2688 ivec2 &max(const ivec2 &o) { coord.x = ::max(coord.x, o.coord.x); coord.y = ::max(coord.y, o.coord.y); return *this; }
2689 ivec2 &min(int n) { coord.x = ::min(coord.x, n); coord.y = ::min(coord.y, n); return *this; }
2690 ivec2 &max(int n) { coord.x = ::max(coord.x, n); coord.y = ::max(coord.y, n); return *this; }
2691 ivec2 &abs() { coord.x = ::abs(coord.x); coord.y = ::abs(coord.y); return *this; }
2692 int dot(const ivec2 &o) const { return coord.x*o.coord.x + coord.y*o.coord.y; }
2693 int cross(const ivec2 &o) const { return coord.x*o.coord.y - coord.y*o.coord.x; }
2694};
2695
2696inline ivec::ivec(const ivec2 &v, int z) : x(v.x()), y(v.y()), z(z) {}
2697
2698inline bvec::bvec(const vec4<uchar> &v) : x(v.x), y(v.y), z(v.z) {}
2699
2703struct svec
2704{
2705 union
2706 {
2707 struct { short x, y, z; } coord;
2708 short v[3];
2709 };
2710
2711 svec() {}
2712 svec(short x, short y, short z)
2713 {
2714 coord.x = x;
2715 coord.y = y;
2716 coord.z = z;
2717 }
2718 explicit svec(const ivec &v)
2719 {
2720 coord.x = v.x;
2721 coord.y = v.y;
2722 coord.z = v.z;
2723 }
2724
2725 short &operator[](int i) { return v[i]; }
2726 short operator[](int i) const { return v[i]; }
2727};
2728
2729inline vec::vec(const svec &v)
2730{
2731 x = v.coord.x;
2732 y = v.coord.y;
2733 z = v.coord.z;
2734}
2735
2736inline ivec::ivec(const svec &v)
2737{
2738 x = v.coord.x;
2739 y = v.coord.y;
2740 z = v.coord.z;
2741}
2742
2746struct matrix4
2747{
2748 vec4<float> a, b, c, d;
2749
2750 template<class T, class U>
2751 T transformnormal(const U &in) const
2752 {
2753 T v;
2754 transformnormal(in, v);
2755 return v;
2756 }
2757
2758 template<class T, class U>
2759 T transform(const U &in) const
2760 {
2761 T v;
2762 transform(in, v);
2763 return v;
2764 }
2765
2766 template<class T>
2767 vec perspectivetransform(const T &in) const
2768 {
2769 vec4<float> v;
2770 transform(in, v);
2771 return vec(v).div(v.w);
2772 }
2773
2774 template<class T>
2775 void mult(const matrix4 &x, const matrix4 &y)
2776 {
2777 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);
2778 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);
2779 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);
2780 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);
2781 }
2782
2783 matrix4();
2784 matrix4(const float *m);
2785 matrix4(const vec &a, const vec &b, const vec &c = vec(0, 0, 1));
2786 matrix4(const vec4<float> &a, const vec4<float> &b, const vec4<float> &c, const vec4<float> &d = vec4<float>(0, 0, 0, 1));
2787 matrix4(const matrix4x3 &m);
2788 matrix4(const matrix3 &rot, const vec &trans);
2789 void mul(const matrix4 &x, const matrix3 &y);
2790 void mul(const matrix3 &y);
2791
2801 void mul(const matrix4 &x, const matrix4 &y);
2802
2811 void mul(const matrix4 &y);
2812
2822 void muld(const matrix4 &x, const matrix4 &y);
2823
2832 void muld(const matrix4 &y);
2833 void rotate_around_x(float ck, float sk);
2834 void rotate_around_x(float angle);
2835 void rotate_around_x(const vec2 &sc);
2836 void rotate_around_y(float ck, float sk);
2837 void rotate_around_y(float angle);
2838 void rotate_around_y(const vec2 &sc);
2839
2840 void rotate_around_z(float ck, float sk);
2841 void rotate_around_z(float angle);
2842 void rotate_around_z(const vec2 &sc);
2843
2844 void rotate(float ck, float sk, const vec &axis);
2845 void rotate(float angle, const vec &dir);
2846 void rotate(const vec2 &sc, const vec &dir);
2847
2860 void identity();
2861
2862 void settranslation(const vec &v);
2863 void settranslation(float x, float y, float z);
2864 void translate(const vec &p);
2865 void translate(float x, float y, float z);
2866 void translate(const vec &p, float scale);
2867 void setscale(float x, float y, float z);
2868 void setscale(const vec &v);
2869 void setscale(float n);
2870 void scale(float x, float y, float z);
2871 void scale(const vec &v);
2872 void scale(float n);
2873
2874 void scalez(float k);
2875
2876 void jitter(float x, float y);
2877
2890
2903 void transpose(const matrix4 &m);
2904 void frustum(float left, float right, float bottom, float top, float znear, float zfar);
2905 void perspective(float fovy, float aspect, float znear, float zfar);
2906
2907 void ortho(float left, float right, float bottom, float top, float znear, float zfar);
2908
2909 void transform(const vec &in, vec &out) const;
2910 void transform(const vec4<float> &in, vec &out) const;
2911
2912 void transform(const vec &in, vec4<float> &out) const;
2913 void transform(const vec4<float> &in, vec4<float> &out) const;
2914 void transformnormal(const vec &in, vec &out) const;
2915 void transformnormal(const vec &in, vec4<float> &out) const;
2916
2917 void transposedtransform(const vec &in, vec &out) const;
2918 void transposedtransformnormal(const vec &in, vec &out) const;
2919 void transposedtransform(const plane &in, plane &out) const;
2920
2921 vec gettranslation() const;
2922
2931
2940
2949
2958
2971 bool invert(const matrix4 &m, double mindet = 1.0e-12);
2972
2982 matrix4 inverse(double mindet = 1.0e-12) const;
2983
2984 vec2 lineardepthscale() const;
2985};
2986
2988 : a(m.a), b(m.b), c(m.c)
2989{}
2990
2992 : a(m.a), b(m.b), c(m.c), d(m.d)
2993{}
2994
2995inline matrix3::matrix3(const matrix4x3 &m) : a(m.a), b(m.b), c(m.c) {}
2996
2997//generic two dimensional vector
2998template<class T>
2999struct GenericVec2
3000{
3001 T x,y;
3002
3003 GenericVec2() {}
3004 GenericVec2(T x, T y) : x(x), y(y) {}
3005 GenericVec2(const vec2 &v) : x(v.x), y(v.y) {}
3006
3007 bool operator==(const GenericVec2 &h) const { return x == h.x && y == h.y; }
3008 bool operator!=(const GenericVec2 &h) const { return x != h.x || y != h.y; }
3009};
3010
3011//generic three dmensional vector
3012template<class T>
3013struct GenericVec3
3014{
3015 T x,y,z;
3016
3017 GenericVec3() {}
3018 GenericVec3(T x, T y, T z) : x(x), y(y), z(z) {}
3019 GenericVec3(const vec &v) : x(v.x), y(v.y), z(v.z) {}
3020
3021 GenericVec3<T> operator+(const GenericVec3<T> &h) const { return GenericVec3<T>(x+h.x, y+h.y,z+h.z); }
3022 GenericVec3<T> operator-(const GenericVec3<T> &h) const { return GenericVec3<T>(x-h.x, y-h.y, z-h.z); }
3023
3024 //comparison
3025 bool operator==(const GenericVec3<T> &h) const { return x == h.x && y == h.y && z == h.z; }
3026 bool operator!=(const GenericVec3<T> &h) const { return x != h.x || y != h.y || z != h.z; }
3027 bool operator>(const GenericVec3<T> &h) const { return x > h.x && y > h.y && z > h.z; }
3028 bool operator<(const GenericVec3<T> &h) const { return x < h.x && y < h.y && z < h.z; }
3029 bool operator>=(const GenericVec3<T> &h) const { return x >= h.x && y >= h.y && z >= h.z; }
3030 bool operator<=(const GenericVec3<T> &h) const { return x <= h.x && y <= h.y && z <= h.z; }
3031};
3032
3033extern bool raysphereintersect(const vec &center, float radius, const vec &o, const vec &ray, float &dist);
3034extern bool rayboxintersect(const vec &b, const vec &s, const vec &o, const vec &ray, float &dist, int &orient);
3035
3068extern bool linecylinderintersect(const vec &from, const vec &to, const vec &start, const vec &end, float radius, float &dist);
3069extern int polyclip(const vec *in, int numin, const vec &dir, float below, float above, vec *out);
3070
3071extern const vec2 sincos360[];
3072
3082inline int mod360(int angle)
3083{
3084 if(angle < 0)
3085 {
3086 angle = 360 + (angle <= -360 ? angle%360 : angle);
3087 }
3088 else if(angle >= 360)
3089 {
3090 angle %= 360;
3091 }
3092 return angle;
3093}
3094
3102inline const vec2 &sincosmod360(int angle) { return sincos360[mod360(angle)]; }
3103
3113inline float cos360(int angle) { return sincos360[angle].x; }
3114
3124inline float sin360(int angle) { return sincos360[angle].y; }
3125
3135inline float tan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.y/sc.x; }
3136
3146inline float cotan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.x/sc.y; }
3147
3148#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:1843
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:1852
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:3124
int mod360(int angle)
Returns the angle passed to it, clamped to 0...360.
Definition geom.h:3082
const vec2 & sincosmod360(int angle)
Returns a vec2 containing (cos, sine) for a given integral angle.
Definition geom.h:3102
float cotan360(int angle)
Returns the cotangent for an angle (in degrees)
Definition geom.h:3146
float cos360(int angle)
Returns the cosine for an angle (in degrees)
Definition geom.h:3113
const int R[3]
Definition geom.h:2522
const int C[3]
Definition geom.h:2523
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:2524
const vec2 sincos360[]
float tan360(int angle)
Returns the tangent for an angle (in degrees)
Definition geom.h:3135
float fovy
integer vector2
Definition geom.h:2637
Definition geom.h:2530
floating point 4x4 array object
Definition geom.h:2747
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:2266
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:2704
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:132
vec2 & lerp(const vec2 &b, float t)
Linearly interpolates between another vec2 according to scale t.
Definition geom.h:115
A four dimensional Cartesian-space vector template.
Definition geom.h:844
T dot3(const vec &o) const
Returns the 3 dimensional dot product between this and a 3D vec.
Definition geom.h:1077
vec4 & safenormalize()
Scales the vector to have a magnitude of 1.
Definition geom.h:1148
bool operator!=(const vec4 &o) const
Returns whether two vec objects do not match.
Definition geom.h:1053
vec4 & clamp(T l, T h)
Clamps the elements individualy to the specified bounds.
Definition geom.h:1527
T dot(const vec &o) const
Returns the dot product of this and a vec3, assuming o.w = 1.
Definition geom.h:1100
T dot(const vec4 &o) const
Returns the scalar product with another vec4.
Definition geom.h:1089
uint * mask()
Returns a raw unsigned int pointer to the data in this vec4.
Definition geom.h:1024
T b() const
Returns the z coordinate of this vec4.
Definition geom.h:1003
vec4 & div(T f)
Calculates the elementwise quotient.
Definition geom.h:1320
T r() const
Returns the x coordinate of this vec4.
Definition geom.h:989
vec4 operator-() const
Returns a new vec4 object equal to the arithmetic inverse of this
Definition geom.h:1565
vec4 & add(const vec4 &o)
Calculates the elementwise sum.
Definition geom.h:1366
void flip()
Flips a vec4<uchar> by using the mask type pun.
Definition geom.h:1179
vec4 & normalize()
Scales the vector to have a magnitude of 1.
Definition geom.h:1139
vec4 & sub(const vec4 &o)
Subtracts from this the vec4 passed.
Definition geom.h:1427
T & a()
References the w coordinate of this vec4.
Definition geom.h:982
vec4 & recip()
Calculates the elementwise reciprocal.
Definition geom.h:1354
T a() const
Returns the w coordinate of this vec4.
Definition geom.h:1010
T g() const
Returns the y coordinate of this vec4.
Definition geom.h:996
vec4 & rotate_around_z(T angle)
Conducts a rotation around the z-axis.
Definition geom.h:1735
vec4 & div3(T f)
Calculates the elementwise quotient.
Definition geom.h:1308
vec4 & sub3(T f)
Subtracts from the first three entries this the value passed.
Definition geom.h:1451
T squaredlen() const
Returns the square of the magnitude of the vector.
Definition geom.h:1110
T & r()
References the x coordinate of this vec4.
Definition geom.h:961
vec4 & rotate_around_x(T c, T s)
Rotates the given 3-vector around the x-axis.
Definition geom.h:1698
vec4 & addw(T f)
Adds to the fourth value of the vector (w/a).
Definition geom.h:1415
const T * data() const
Returns a raw pointer to the data of this vec4.
Definition geom.h:1017
vec4()
Definition geom.h:848
T & operator[](int i)
Returns the i-th dimension of this vec4.
Definition geom.h:895
vec4 & div(const vec &o)
Calculates the elementwise quotient.
Definition geom.h:1344
vec4 operator+(const vec4 &v2) const
Returns a new vec4 object equal to the sum of the passed object and this
Definition geom.h:1543
vec4 & mul(T f)
Calculates the elementwise product.
Definition geom.h:1259
vec tonormal() const
Returns a new vec containing values normalized to 0...255 (e.g. colors).
Definition geom.h:1822
vec4 & sub(T f)
Subtracts from the entries this the value passed.
Definition geom.h:1469
vec4 & rotate_around_z(const vec2 &sc)
Conducts a rotation around the z-axis.
Definition geom.h:1780
vec4 operator/(const U &n) const
Returns a new vec4 object equal to the scalar division by a value.
Definition geom.h:1605
vec4 & sub(const vec &o)
Subtracts from this the vec passed.
Definition geom.h:1439
vec4 & mul3(T f)
Calculates the elementwise product.
Definition geom.h:1247
vec4 & madd(const vec4 &a, const B &b)
Sets this vec4 to the result of the multiply add of this with a,b
Definition geom.h:1222
vec4 operator/(const vec4 &v2) const
Returns a new vec4 equal to the elementwise division of this and the passed vec4.
Definition geom.h:1618
vec4 & rotate_around_y(const vec2 &sc)
Conducts a rotation around the y-axis.
Definition geom.h:1810
vec4 & add(const vec &o)
Calculates the elementwise sum.
Definition geom.h:1379
T & b()
References the z coordinate of this vec4.
Definition geom.h:975
vec4 & mul(const vec &o)
Calculates the elementwise product.
Definition geom.h:1285
T magnitude3() const
Returns the magnitude of the vector, ignoring the w dimension.
Definition geom.h:1130
T dot3(const vec4 &o) const
Returns the 3 dimensional dot product between two 4-vecs.
Definition geom.h:1065
vec4 & div(const vec4 &o)
Calculates the elementwise quotient.
Definition geom.h:1332
vec4 & cross(const A &a, const B &b)
Sets this vec to the cross product of two passed objects.
Definition geom.h:1637
vec4 & cross(const vec &o, const vec &a, const vec &b)
Sets this vec4 to the cross product of a,b relative to an offset c.
Definition geom.h:1654
vec4 & rotate_around_x(const vec2 &sc)
Conducts a rotation around the x-axis.
Definition geom.h:1795
vec4 & rotate_around_y(T c, T s)
Rotates the given 3-vector around the y-axis.
Definition geom.h:1716
vec4 & subw(T f)
Subtracts from the last element only.
Definition geom.h:1486
vec4 operator*(const U &n) const
Returns a new vec4 object equal to the scalar multiplication by a value.
Definition geom.h:1579
vec4 operator*(const vec4 &v2) const
Returns a new vec4 equal to the elementwise product of this and the passed vec4.
Definition geom.h:1591
vec4 & rotate_around_z(T c, T s)
Rotates the given 3-vector around the z-axis.
Definition geom.h:1680
vec4 & msub(const vec4 &a, const B &b)
Sets this vec4 to the result of the multiply subtract of this with a,b
Definition geom.h:1235
T operator[](int i) const
Returns the i-th dimension of this vec4.
Definition geom.h:932
vec4 & square()
Calculates the elementwise square.
Definition geom.h:1295
vec4 & add(T f)
Calculates the elementwise sum.
Definition geom.h:1403
vec4 operator-(const vec4 &v2) const
Returns a new vec4 object equal to this minus the passed object.
Definition geom.h:1555
vec4 & neg3()
Negates the first three elements.
Definition geom.h:1499
bool operator==(const vec4 &o) const
Returns whether two vec objects exactly match.
Definition geom.h:1040
T magnitude() const
Returns the magnitude of the vector.
Definition geom.h:1120
void setxyz(const vec &v)
Replaces the first three values of this with the passed vec.
Definition geom.h:1664
vec4 & neg()
Negates all of the elements.
Definition geom.h:1512
vec4 & mul(const vec4 &o)
Calculates the elementwise product.
Definition geom.h:1272
vec4 & rotate_around_y(T angle)
Conducts a rotation around the y-axis.
Definition geom.h:1765
vec4 & add3(T f)
Calculates the elementwise sum.
Definition geom.h:1391
vec4 & avg(const vec4 &b)
Calculates the elementwise arithmetic mean.
Definition geom.h:1209
T & g()
References the y coordinate of this vec4.
Definition geom.h:968
vec4 & rotate_around_x(T angle)
Conducts a rotation around the x-axis.
Definition geom.h:1750
three dimensional Cartesian vector object
Definition geom.h:207
float squaredlen() const
Returns the square of this vec's magnitude.
Definition geom.h:337
vec & square()
Sets this vec to its elementwise square.
Definition geom.h:346
vec & lerp(const vec &a, const vec &b, float t)
Linearly interpolates between two other vecs according to scale t.
Definition geom.h:476
vec & lerp(const vec &b, float t)
Linearly interpolates between another vec2 according to scale t.
Definition geom.h:458
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:409
float scalartriple(const vec &a, const vec &b) const
scalar triple product A*(BxC)
Definition geom.h:422
bool iszero() const
Returns whether this vec is exactly zero in all axes.
Definition geom.h:326
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:491
float zscalartriple(const vec &a, const vec &b) const
z component only of scalar triple product (A*(BxC))
Definition geom.h:427
float project_bb(const ivec &min, const ivec &max) const
Returns the dot product of this and min/max, depending on sign.