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
785 void flip()
786 {
787 x ^= 0x80;
788 y ^= 0x80;
789 z ^= 0x80;
790 }
791
792 void scale(int k, int d)
793 {
794 x = static_cast<uchar>((x*k)/d);
795 y = static_cast<uchar>((y*k)/d);
796 z = static_cast<uchar>((z*k)/d);
797 }
798
799 bvec &shl(int n)
800 {
801 x <<= n;
802 y <<= n;
803 z <<= n;
804 return *this;
805 }
806 bvec &shr(int n)
807 {
808 x >>= n;
809 y >>= n;
810 z >>= n;
811 return *this;
812 }
813
814 static bvec fromcolor(const vec &v)
815 {
816 return bvec(static_cast<uchar>(v.x*255.0f), static_cast<uchar>(v.y*255.0f), static_cast<uchar>(v.z*255.0f));
817 }
818
819 vec tocolor() const
820 {
821 return vec(x*(1.0f/255.0f), y*(1.0f/255.0f), z*(1.0f/255.0f));
822 }
823
824 static bvec from565(ushort c)
825 {
826 return bvec((((c>>11)&0x1F)*527 + 15) >> 6, (((c>>5)&0x3F)*259 + 35) >> 6, ((c&0x1F)*527 + 15) >> 6);
827 }
828
829 static bvec hexcolor(int color)
830 {
831 return bvec((color>>16)&0xFF, (color>>8)&0xFF, color&0xFF);
832 }
833
834 int tohexcolor() const
835 {
836 return (static_cast<int>(x)<<16)|(static_cast<int>(y)<<8)|static_cast<int>(z);
837 }
838};
839
848template<typename T>
849struct vec4
850{
851
852 T x, y, z, w;
853
854 vec4() {}
855 explicit vec4(const vec &p, T w = 0) : x(p.x), y(p.y), z(p.z), w(w) {}
856 explicit vec4(const vec2 &p, T z = 0, T w = 0) : x(p.x), y(p.y), z(z), w(w) {}
857 vec4(T x, T y = 0, T z = 0, T w = 0) : x(x), y(y), z(z), w(w) {}
858 vec4(bvec v, uchar c)
859 {
860 x = v.x;
861 y = v.y;
862 z = v.z;
863 w = c;
864 }
865 vec4(bvec v)
866 {
867 x = v.x;
868 y = v.y;
869 z = v.z;
870 w = 0;
871 }
872
873 explicit vec4(const T *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) {}
874
875 template<class U>
876 vec4(const vec4<U> &p) : x(p.x), y(p.y), z(p.z), w(p.w) {}
877
878 template<class U>
879 operator vec4<U>()
880 {
881 return vec4<U>(static_cast<U>(this->x),
882 static_cast<U>(this->y),
883 static_cast<U>(this->z),
884 static_cast<U>(this->w));
885 }
886
901 T &operator[](int i)
902 {
903 switch(i)
904 {
905 case 1:
906 {
907 return y;
908 }
909 case 2:
910 {
911 return z;
912 }
913 case 3:
914 {
915 return w;
916 }
917 default:
918 {
919 return x;
920 }
921 }
922 }
923
938 T operator[](int i) const
939 {
940 switch(i)
941 {
942 case 1:
943 {
944 return y;
945 }
946 case 2:
947 {
948 return z;
949 }
950 case 3:
951 {
952 return w;
953 }
954 default:
955 {
956 return x;
957 }
958 }
959 }
960
961
967 T &r() { return x; }
968
974 T &g() { return y; }
975
981 T &b() { return z; }
982
988 T &a() { return w; }
989
995 T r() const { return x; }
996
1002 T g() const { return y; }
1003
1009 T b() const { return z; }
1010
1016 T a() const { return w; }
1017
1023 const T *data() const { return &x; }
1024
1030 uint *mask()
1031 {
1032 return reinterpret_cast<uint *>(&x);
1033 }
1034
1046 bool operator==(const vec4 &o) const { return x == o.x && y == o.y && z == o.z && w == o.w; }
1047
1059 bool operator!=(const vec4 &o) const { return x != o.x || y != o.y || z != o.z || w != o.w; }
1060
1071 T dot3(const vec4 &o) const { return x*o.x + y*o.y + z*o.z; }
1072
1083 T dot3(const vec &o) const { return x*o.x + y*o.y + z*o.z; }
1084
1095 T dot(const vec4 &o) const { return dot3(o) + w*o.w; }
1096
1106 T dot(const vec &o) const { return x*o.x + y*o.y + z*o.z + w; }
1107
1116 T squaredlen() const { return dot(*this); }
1117
1126 T magnitude() const { return sqrtf(squaredlen()); }
1127
1136 T magnitude3() const { return sqrtf(dot3(*this)); }
1137
1145 vec4 &normalize() { mul(1/magnitude()); return *this; }
1146
1154 vec4 &safenormalize() { T m = magnitude(); if(m) mul(1/m); return *this; }
1155
1156 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, float t)
1157 {
1158 x = static_cast<uchar>(a.x + (b.x-a.x)*t);
1159 y = static_cast<uchar>(a.y + (b.y-a.y)*t);
1160 z = static_cast<uchar>(a.z + (b.z-a.z)*t);
1161 w = a.w;
1162 }
1163
1164 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, int ka, int kb, int d)
1165 {
1166 x = static_cast<uchar>((a.x*ka + b.x*kb)/d);
1167 y = static_cast<uchar>((a.y*ka + b.y*kb)/d);
1168 z = static_cast<uchar>((a.z*ka + b.z*kb)/d);
1169 w = a.w;
1170 }
1171
1172 void lerp(const vec4<uchar> &a, const vec4<uchar> &b, const vec4<uchar> &c, float ta, float tb, float tc)
1173 {
1174 x = static_cast<uchar>(a.x*ta + b.x*tb + c.x*tc);
1175 y = static_cast<uchar>(a.y*ta + b.y*tb + c.y*tc);
1176 z = static_cast<uchar>(a.z*ta + b.z*tb + c.z*tc);
1177 w = static_cast<uchar>(a.w*ta + b.w*tb + c.w*tc);
1178 }
1179
1188 void flip() { *mask() ^= 0x80808080; }
1189
1190 vec4 &lerp(const vec4 &b, T t)
1191 {
1192 x += (b.x-x)*t;
1193 y += (b.y-y)*t;
1194 z += (b.z-z)*t;
1195 w += (b.w-w)*t;
1196 return *this;
1197 }
1198 vec4 &lerp(const vec4 &a, const vec4 &b, T t)
1199 {
1200 x = a.x+(b.x-a.x)*t;
1201 y = a.y+(b.y-a.y)*t;
1202 z = a.z+(b.z-a.z)*t;
1203 w = a.w+(b.w-a.w)*t;
1204 return *this;
1205 }
1206
1218 vec4 &avg(const vec4 &b) { add(b); mul(0.5f); return *this; }
1219
1230 template<class B>
1231 vec4 &madd(const vec4 &a, const B &b) { return add(vec4(a).mul(b)); }
1232
1243 template<class B>
1244 vec4 &msub(const vec4 &a, const B &b) { return sub(vec4(a).mul(b)); }
1245
1256 vec4 &mul3(T f) { x *= f; y *= f; z *= f; return *this; }
1257
1268 vec4 &mul(T f) { mul3(f); w *= f; return *this; }
1269
1281 vec4 &mul(const vec4 &o) { x *= o.x; y *= o.y; z *= o.z; w *= o.w; return *this; }
1282
1294 vec4 &mul(const vec &o) { x *= o.x; y *= o.y; z *= o.z; return *this; }
1295
1304 vec4 &square() { mul(*this); return *this; }
1305
1317 vec4 &div3(T f) { x /= f; y /= f; z /= f; return *this; }
1318
1329 vec4 &div(T f) { div3(f); w /= f; return *this; }
1330
1341 vec4 &div(const vec4 &o) { x /= o.x; y /= o.y; z /= o.z; w /= o.w; return *this; }
1342
1353 vec4 &div(const vec &o) { x /= o.x; y /= o.y; z /= o.z; return *this; }
1354
1363 vec4 &recip() { x = 1/x; y = 1/y; z = 1/z; w = 1/w; return *this; }
1364
1375 vec4 &add(const vec4 &o) { x += o.x; y += o.y; z += o.z; w += o.w; return *this; }
1376
1388 vec4 &add(const vec &o) { x += o.x; y += o.y; z += o.z; return *this; }
1389
1400 vec4 &add3(T f) { x += f; y += f; z += f; return *this; }
1401
1412 vec4 &add(T f) { add3(f); w += f; return *this; }
1413
1424 vec4 &addw(T f) { w += f; return *this; }
1425
1436 vec4 &sub(const vec4 &o) { x -= o.x; y -= o.y; z -= o.z; w -= o.w; return *this; }
1437
1448 vec4 &sub(const vec &o) { x -= o.x; y -= o.y; z -= o.z; return *this; }
1449
1461 {
1462 x -= f;
1463 y -= f;
1464 z -= f;
1465 return *this;
1466 }
1467
1478 vec4 &sub(T f)
1479 {
1480 sub3(f);
1481 w -= f;
1482 return *this;
1483 }
1484
1496 {
1497 w -= f;
1498 return *this;
1499 }
1500
1509 {
1510 x = -x;
1511 y = -y;
1512 z = -z;
1513 return *this;
1514 }
1515
1522 {
1523 neg3();
1524 w = -w;
1525 return *this;
1526 }
1527
1536 vec4 &clamp(T l, T h)
1537 {
1538 x = ::std::clamp(x, l, h);
1539 y = ::std::clamp(y, l, h);
1540 z = ::std::clamp(z, l, h);
1541 w = ::std::clamp(w, l, h);
1542 return *this;
1543 }
1544
1552 vec4 operator+(const vec4 &v2) const
1553 {
1554 return vec4(x+v2.x, y+v2.y, z+v2.z, w+v2.w);
1555 }
1556
1564 vec4 operator-(const vec4 &v2) const
1565 {
1566 return vec4(x-v2.x, y-v2.y, z-v2.z, w-v2.w);
1567 }
1568
1575 {
1576 return vec4(-x, -y, -z, -w);
1577 }
1578
1587 template<typename U>
1588 vec4 operator*(const U &n) const
1589 {
1590 return vec4(n*x, n*y, n*z, n*w);
1591 }
1592
1600 vec4 operator*(const vec4 &v2) const
1601 {
1602 return vec4(x*v2.x, y*v2.y, z*v2.z, w*v2.w);
1603 }
1604
1613 template<typename U>
1614 vec4 operator/(const U &n) const
1615 {
1616 return vec4(x/n, y/n, z/n, w/n);
1617 }
1618
1619
1627 vec4 operator/(const vec4 &v2) const
1628 {
1629 return vec4(x/v2.x, y/v2.y, z/v2.z, w/v2.w);
1630 }
1631
1632
1645 template<class A, class B>
1646 vec4 &cross(const A &a, const B &b)
1647 {
1648 x = a.y*b.z-a.z*b.y;
1649 y = a.z*b.x-a.x*b.z;
1650 z = a.x*b.y-a.y*b.x;
1651 return *this;
1652 }
1653
1663 vec4 &cross(const vec &o, const vec &a, const vec &b)
1664 {
1665 return cross(vec(a).sub(o), vec(b).sub(o));
1666 }
1667
1673 void setxyz(const vec &v)
1674 {
1675 x = v.x;
1676 y = v.y;
1677 z = v.z;
1678 }
1679
1690 {
1691 T rx = x,
1692 ry = y;
1693 x = c*rx-s*ry;
1694 y = c*ry+s*rx;
1695 return *this;
1696 }
1697
1708 {
1709 T ry = y,
1710 rz = z;
1711 y = c*ry-s*rz;
1712 z = c*rz+s*ry;
1713 return *this;
1714 }
1715
1726 {
1727 T rx = x,
1728 rz = z;
1729 x = c*rx-s*rz;
1730 z = c*rz+s*rx;
1731 return *this;
1732 }
1733
1745 {
1746 return rotate_around_z(cosf(angle), std::sin(angle));
1747 }
1748
1760 {
1761 return rotate_around_x(cosf(angle), std::sin(angle));
1762 }
1763
1775 {
1776 return rotate_around_y(cosf(angle), std::sin(angle));
1777 }
1778
1790 {
1791 return rotate_around_z(sc.x, sc.y);
1792 }
1793
1805 {
1806 return rotate_around_x(sc.x, sc.y);
1807 }
1808
1820 {
1821 return rotate_around_y(sc.x, sc.y);
1822 }
1823
1832 {
1833 return vec(x*(2.0f/255.0f)-1.0f, y*(2.0f/255.0f)-1.0f, z*(2.0f/255.0f)-1.0f);
1834 }
1835
1836};
1837
1838inline vec2::vec2(const vec4<float> &v) : x(v.x), y(v.y) {}
1839inline vec::vec(const vec4<float> &v) : x(v.x), y(v.y), z(v.z) {}
1840
1852{
1853 public:
1861 vec a, b, c;
1862
1867
1875 matrix3(const vec &a, const vec &b, const vec &c);
1876
1886 explicit matrix3(float angle, const vec &axis);
1887
1896 explicit matrix3(const quat &q);
1897
1904 explicit matrix3(const matrix4x3 &m);
1905
1913 explicit matrix3(const matrix4 &m);
1914
1921 void mul(const matrix3 &m, const matrix3 &n);
1922
1930 void mul(const matrix3 &n);
1931
1937 void multranspose(const matrix3 &n);
1938
1945 void transposemul(const matrix3 &m, const matrix3 &n);
1946
1952 void transposemul(const matrix3 &n);
1953
1964
1972 void invert(const matrix3 &o);
1973
1980 void invert();
1981
1988
1994 void scale(float k);
1995
2002 void rotate(float angle, const vec &axis);
2003
2011 void rotate(float ck, float sk, const vec &axis);
2012
2027 void setyaw(float angle);
2028
2036 float trace() const;
2037
2062 bool calcangleaxis(float tr, float &angle, vec &axis, float threshold = 1e-16f) const;
2063
2078 bool calcangleaxis(float &angle, vec &axis, float threshold = 1e-16f) const;
2079
2087 vec transform(const vec &o) const;
2088
2096 vec transposedtransform(const vec &o) const;
2097
2105 vec abstransform(const vec &o) const;
2106
2115
2125 void identity();
2126
2132 void rotate_around_x(float angle);
2133
2139 void rotate_around_x(const vec2 &sc);
2140
2146 void rotate_around_y(float angle);
2147
2153 void rotate_around_y(const vec2 &sc);
2154
2160 void rotate_around_z(float angle);
2161
2167 void rotate_around_z(const vec2 &sc);
2168
2176 vec transform(const vec2 &o) const;
2177
2186
2192 vec rowx() const;
2193
2199 vec rowy() const;
2200
2206 vec rowz() const;
2207 private:
2208
2215 void multranspose(const matrix3 &m, const matrix3 &n);
2216
2230 void setyaw(float ck, float sk);
2231
2238 void rotate_around_x(float ck, float sk);
2239
2246 void rotate_around_y(float ck, float sk);
2247
2254 void rotate_around_z(float ck, float sk);
2255
2261 void transpose(const matrix3 &m);
2262};
2263
2275{
2276 vec a, b, c, d;
2277
2285
2296 matrix4x3(const vec &a, const vec &b, const vec &c, const vec &d);
2297
2307 matrix4x3(const matrix3 &rot, const vec &trans);
2308
2314 matrix4x3(const dualquat &dq);
2315
2323 explicit matrix4x3(const matrix4 &m);
2324
2330 void mul(float k);
2331
2341 void setscale(float x, float y, float z);
2342
2350 void setscale(const vec &v);
2351
2357 void setscale(float n);
2358
2368 void scale(float x, float y, float z);
2369
2377 void scale(const vec &v);
2378
2386 void scale(float n);
2387
2393 void settranslation(const vec &p);
2394
2402 void settranslation(float x, float y, float z);
2403 void translate(const vec &p);
2404 void translate(float x, float y, float z);
2405 void translate(const vec &p, float scale);
2406 void accumulate(const matrix4x3 &m, float k);
2407
2417
2427 void lerp(const matrix4x3 &to, float t);
2428
2439 void lerp(const matrix4x3 &from, const matrix4x3 &to, float t);
2440
2451 void identity();
2452 void mul(const matrix4x3 &m, const matrix4x3 &n);
2453 void mul(const matrix4x3 &n);
2454
2455 void mul(const matrix3 &m, const matrix4x3 &n);
2456
2457 void mul(const matrix3 &rot, const vec &trans, const matrix4x3 &n);
2458
2459 void transpose();
2460 void transpose(const matrix4x3 &o);
2461
2462 void transposemul(const matrix4x3 &m, const matrix4x3 &n);
2463
2464 void multranspose(const matrix4x3 &m, const matrix4x3 &n);
2465
2466 void invert(const matrix4x3 &o);
2467 void invert();
2468 void rotate(float angle, const vec &d);
2469
2470 void rotate(float ck, float sk, const vec &axis);
2471
2472 void rotate_around_x(float ck, float sk);
2473 void rotate_around_x(float angle);
2474
2475 void rotate_around_x(const vec2 &sc);
2476
2477 void rotate_around_y(float ck, float sk);
2478 void rotate_around_y(float angle);
2479 void rotate_around_y(const vec2 &sc);
2480
2481 void rotate_around_z(float ck, float sk);
2482 void rotate_around_z(float angle);
2483 void rotate_around_z(const vec2 &sc);
2484
2485 vec transposedtransform(const vec &o) const;
2486 vec transformnormal(const vec &o) const;
2487 vec transposedtransformnormal(const vec &o) const;
2488 vec transform(const vec &o) const;
2489 vec transform(const vec2 &o) const;
2490
2497
2504
2511};
2512
2513/*
2514
2515The engine uses 3 different linear coordinate systems
2516which are oriented around each of the axis dimensions.
2517
2518So any point within the game can be defined by four coordinates: (d, x, y, z)
2519
2520d is the reference axis dimension
2521x is the coordinate of the ROW dimension
2522y is the coordinate of the COL dimension
2523z is the coordinate of the reference dimension (DEPTH)
2524
2525typically, if d is not used, then it is implicitly the Z dimension.
2526ie: d=z => x=x, y=y, z=z
2527
2528*/
2529
2530// DIM: X=0 Y=1 Z=2.
2531const int R[3] = {1, 2, 0};
2532const int C[3] = {2, 0, 1};
2533const int D[3] = {0, 1, 2};
2534
2535struct ivec2;
2536
2537//integer vector3
2538struct ivec
2539{
2540 int x, y, z;
2541
2542 ivec() {}
2543 explicit ivec(const vec &v) : x(static_cast<int>(v.x)), y(static_cast<int>(v.y)), z(static_cast<int>(v.z)) {}
2544 ivec(int a, int b, int c) : x(a), y(b), z(c) {}
2545 ivec(int d, int row, int col, int depth)
2546 {
2547 (*this)[R[d]] = row;
2548 (*this)[C[d]] = col;
2549 (*this)[D[d]] = depth;
2550 }
2551 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) {}
2552 explicit ivec(const ivec2 &v, int z = 0);
2553 explicit ivec(const svec &v);
2554
2555 int &operator[](int i)
2556 {
2557 switch(i)
2558 {
2559 case 1:
2560 {
2561 return y;
2562 }
2563 case 2:
2564 {
2565 return z;
2566 }
2567 default:
2568 {
2569 return x;
2570 }
2571 }
2572 }
2573
2574 int operator[](int i) const
2575 {
2576 switch(i)
2577 {
2578 case 1:
2579 {
2580 return y;
2581 }
2582 case 2:
2583 {
2584 return z;
2585 }
2586 default:
2587 {
2588 return x;
2589 }
2590 }
2591 }
2592
2593 //int idx(int i) { return v[i]; }
2594 bool operator==(const ivec &v) const { return x==v.x && y==v.y && z==v.z; }
2595 bool operator!=(const ivec &v) const { return x!=v.x || y!=v.y || z!=v.z; }
2596 ivec operator+(const ivec &v) const { return ivec(x+v.x, y+v.y, z+v.z); }
2604 explicit operator bool() const { return !(x==0 && y==0 && z==0); }
2605 ivec &shl(int n) { x<<= n; y<<= n; z<<= n; return *this; }
2606 ivec &shr(int n) { x>>= n; y>>= n; z>>= n; return *this; }
2607 ivec &mul(int n) { x *= n; y *= n; z *= n; return *this; }
2608 ivec &div(int n) { x /= n; y /= n; z /= n; return *this; }
2609 ivec &add(int n) { x += n; y += n; z += n; return *this; }
2610 ivec &sub(int n) { x -= n; y -= n; z -= n; return *this; }
2611 ivec &mul(const ivec &v) { x *= v.x; y *= v.y; z *= v.z; return *this; }
2612 ivec &div(const ivec &v) { x /= v.x; y /= v.y; z /= v.z; return *this; }
2613 ivec &add(const ivec &v) { x += v.x; y += v.y; z += v.z; return *this; }
2614 ivec &sub(const ivec &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }
2615 ivec &mask(int n) { x &= n; y &= n; z &= n; return *this; }
2616 ivec &neg() { x = -x; y = -y; z = -z; return *this; }
2617 ivec &min(const ivec &o) { x = ::min(x, o.x); y = ::min(y, o.y); z = ::min(z, o.z); return *this; }
2618 ivec &max(const ivec &o) { x = ::max(x, o.x); y = ::max(y, o.y); z = ::max(z, o.z); return *this; }
2619 ivec &min(int n) { x = ::min(x, n); y = ::min(y, n); z = ::min(z, n); return *this; }
2620 ivec &max(int n) { x = ::max(x, n); y = ::max(y, n); z = ::max(z, n); return *this; }
2621 ivec &abs() { x = ::abs(x); y = ::abs(y); z = ::abs(z); return *this; }
2622 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; }
2623 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; }
2624 int dot(const ivec &o) const { return x*o.x + y*o.y + z*o.z; }
2625 float dist(const plane &p) const;
2626
2627 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))); }
2628 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))); }
2629};
2630
2631inline vec::vec(const ivec &v) : x(v.x), y(v.y), z(v.z) {}
2632
2633template<>
2634struct std::hash<ivec>
2635{
2636 size_t operator()(const ivec &k) const
2637 {
2638 return k.x^k.y^k.z;
2639 }
2640};
2641
2645struct ivec2
2646{
2647 union
2648 {
2649 struct { int x, y; } coord;
2650 int v[2];
2651 };
2652
2653 ivec2() {}
2654 ivec2(int x, int y)
2655 {
2656 coord.x = x;
2657 coord.y = y;
2658 }
2659
2660 explicit ivec2(const vec2 &v)
2661 {
2662 coord.x = static_cast<int>(v.x);
2663 coord.y = static_cast<int>(v.y);
2664 }
2665
2666 explicit ivec2(const ivec &v)
2667 {
2668 coord.x = v.x;
2669 coord.y = v.y;
2670 }
2671
2672 int &operator[](int i) { return v[i]; }
2673 int operator[](int i) const { return v[i]; }
2674
2675 bool operator==(const ivec2 &o) const { return coord.x == o.coord.x && coord.y == o.coord.y; }
2676 bool operator!=(const ivec2 &o) const { return coord.x != o.coord.x || coord.y != o.coord.y; }
2677
2678 int &x() { return coord.x; }
2679 int &y() { return coord.y; }
2680 int x() const { return coord.x; }
2681 int y() const { return coord.y; }
2682
2683 bool iszero() const { return coord.x==0 && coord.y==0; }
2684 ivec2 &shl(int n) { coord.x<<= n; coord.y<<= n; return *this; }
2685 ivec2 &shr(int n) { coord.x>>= n; coord.y>>= n; return *this; }
2686 ivec2 &mul(int n) { coord.x *= n; coord.y *= n; return *this; }
2687 ivec2 &div(int n) { coord.x /= n; coord.y /= n; return *this; }
2688 ivec2 &add(int n) { coord.x += n; coord.y += n; return *this; }
2689 ivec2 &sub(int n) { coord.x -= n; coord.y -= n; return *this; }
2690 ivec2 &mul(const ivec2 &v) { coord.x *= v.coord.x; coord.y *= v.coord.y; return *this; }
2691 ivec2 &div(const ivec2 &v) { coord.x /= v.coord.x; coord.y /= v.coord.y; return *this; }
2692 ivec2 &add(const ivec2 &v) { coord.x += v.coord.x; coord.y += v.coord.y; return *this; }
2693 ivec2 &sub(const ivec2 &v) { coord.x -= v.coord.x; coord.y -= v.coord.y; return *this; }
2694 ivec2 &mask(int n) { coord.x &= n; coord.y &= n; return *this; }
2695 ivec2 &neg() { coord.x = -coord.x; coord.y = -coord.y; return *this; }
2696 ivec2 &min(const ivec2 &o) { coord.x = ::min(coord.x, o.coord.x); coord.y = ::min(coord.y, o.coord.y); return *this; }
2697 ivec2 &max(const ivec2 &o) { coord.x = ::max(coord.x, o.coord.x); coord.y = ::max(coord.y, o.coord.y); return *this; }
2698 ivec2 &min(int n) { coord.x = ::min(coord.x, n); coord.y = ::min(coord.y, n); return *this; }
2699 ivec2 &max(int n) { coord.x = ::max(coord.x, n); coord.y = ::max(coord.y, n); return *this; }
2700 ivec2 &abs() { coord.x = ::abs(coord.x); coord.y = ::abs(coord.y); return *this; }
2701 int dot(const ivec2 &o) const { return coord.x*o.coord.x + coord.y*o.coord.y; }
2702 int cross(const ivec2 &o) const { return coord.x*o.coord.y - coord.y*o.coord.x; }
2703};
2704
2705inline ivec::ivec(const ivec2 &v, int z) : x(v.x()), y(v.y()), z(z) {}
2706
2707inline bvec::bvec(const vec4<uchar> &v) : x(v.x), y(v.y), z(v.z) {}
2708
2712struct svec
2713{
2714 union
2715 {
2716 struct { short x, y, z; } coord;
2717 short v[3];
2718 };
2719
2720 svec() {}
2721 svec(short x, short y, short z)
2722 {
2723 coord.x = x;
2724 coord.y = y;
2725 coord.z = z;
2726 }
2727 explicit svec(const ivec &v)
2728 {
2729 coord.x = v.x;
2730 coord.y = v.y;
2731 coord.z = v.z;
2732 }
2733
2734 short &operator[](int i) { return v[i]; }
2735 short operator[](int i) const { return v[i]; }
2736};
2737
2738inline vec::vec(const svec &v)
2739{
2740 x = v.coord.x;
2741 y = v.coord.y;
2742 z = v.coord.z;
2743}
2744
2745inline ivec::ivec(const svec &v)
2746{
2747 x = v.coord.x;
2748 y = v.coord.y;
2749 z = v.coord.z;
2750}
2751
2755struct matrix4
2756{
2757 vec4<float> a, b, c, d;
2758
2759 template<class T, class U>
2760 T transformnormal(const U &in) const
2761 {
2762 T v;
2763 transformnormal(in, v);
2764 return v;
2765 }
2766
2767 template<class T, class U>
2768 T transform(const U &in) const
2769 {
2770 T v;
2771 transform(in, v);
2772 return v;
2773 }
2774
2775 template<class T>
2776 vec perspectivetransform(const T &in) const
2777 {
2778 vec4<float> v;
2779 transform(in, v);
2780 return vec(v).div(v.w);
2781 }
2782
2783 template<class T>
2784 void mult(const matrix4 &x, const matrix4 &y)
2785 {
2786 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);
2787 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);
2788 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);
2789 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);
2790 }
2791
2792 matrix4();
2793 matrix4(const float *m);
2794 matrix4(const vec &a, const vec &b, const vec &c = vec(0, 0, 1));
2795 matrix4(const vec4<float> &a, const vec4<float> &b, const vec4<float> &c, const vec4<float> &d = vec4<float>(0, 0, 0, 1));
2796 matrix4(const matrix4x3 &m);
2797 matrix4(const matrix3 &rot, const vec &trans);
2798 void mul(const matrix4 &x, const matrix3 &y);
2799 void mul(const matrix3 &y);
2800
2810 void mul(const matrix4 &x, const matrix4 &y);
2811
2820 void mul(const matrix4 &y);
2821
2831 void muld(const matrix4 &x, const matrix4 &y);
2832
2841 void muld(const matrix4 &y);
2842 void rotate_around_x(float ck, float sk);
2843 void rotate_around_x(float angle);
2844 void rotate_around_x(const vec2 &sc);
2845 void rotate_around_y(float ck, float sk);
2846 void rotate_around_y(float angle);
2847 void rotate_around_y(const vec2 &sc);
2848
2849 void rotate_around_z(float ck, float sk);
2850 void rotate_around_z(float angle);
2851 void rotate_around_z(const vec2 &sc);
2852
2853 void rotate(float ck, float sk, const vec &axis);
2854 void rotate(float angle, const vec &dir);
2855 void rotate(const vec2 &sc, const vec &dir);
2856
2869 void identity();
2870
2871 void settranslation(const vec &v);
2872 void settranslation(float x, float y, float z);
2873 void translate(const vec &p);
2874 void translate(float x, float y, float z);
2875 void translate(const vec &p, float scale);
2876 void setscale(float x, float y, float z);
2877 void setscale(const vec &v);
2878 void setscale(float n);
2879 void scale(float x, float y, float z);
2880 void scale(const vec &v);
2881 void scale(float n);
2882
2883 void scalez(float k);
2884
2885 void jitter(float x, float y);
2886
2899
2912 void transpose(const matrix4 &m);
2913 void frustum(float left, float right, float bottom, float top, float znear, float zfar);
2914 void perspective(float fovy, float aspect, float znear, float zfar);
2915
2916 void ortho(float left, float right, float bottom, float top, float znear, float zfar);
2917
2918 void transform(const vec &in, vec &out) const;
2919 void transform(const vec4<float> &in, vec &out) const;
2920
2921 void transform(const vec &in, vec4<float> &out) const;
2922 void transform(const vec4<float> &in, vec4<float> &out) const;
2923 void transformnormal(const vec &in, vec &out) const;
2924 void transformnormal(const vec &in, vec4<float> &out) const;
2925
2926 void transposedtransform(const vec &in, vec &out) const;
2927 void transposedtransformnormal(const vec &in, vec &out) const;
2928 void transposedtransform(const plane &in, plane &out) const;
2929
2930 vec gettranslation() const;
2931
2940
2949
2958
2967
2980 bool invert(const matrix4 &m, double mindet = 1.0e-12);
2981
2991 matrix4 inverse(double mindet = 1.0e-12) const;
2992
2993 vec2 lineardepthscale() const;
2994};
2995
2997 : a(m.a), b(m.b), c(m.c)
2998{}
2999
3001 : a(m.a), b(m.b), c(m.c), d(m.d)
3002{}
3003
3004inline matrix3::matrix3(const matrix4x3 &m) : a(m.a), b(m.b), c(m.c) {}
3005
3006//generic two dimensional vector
3007template<class T>
3008struct GenericVec2
3009{
3010 T x,y;
3011
3012 GenericVec2() {}
3013 GenericVec2(T x, T y) : x(x), y(y) {}
3014 GenericVec2(const vec2 &v) : x(v.x), y(v.y) {}
3015
3016 bool operator==(const GenericVec2 &h) const { return x == h.x && y == h.y; }
3017 bool operator!=(const GenericVec2 &h) const { return x != h.x || y != h.y; }
3018};
3019
3020//generic three dmensional vector
3021template<class T>
3022struct GenericVec3
3023{
3024 T x,y,z;
3025
3026 GenericVec3() {}
3027 GenericVec3(T x, T y, T z) : x(x), y(y), z(z) {}
3028 GenericVec3(const vec &v) : x(v.x), y(v.y), z(v.z) {}
3029
3030 GenericVec3<T> operator+(const GenericVec3<T> &h) const { return GenericVec3<T>(x+h.x, y+h.y,z+h.z); }
3031 GenericVec3<T> operator-(const GenericVec3<T> &h) const { return GenericVec3<T>(x-h.x, y-h.y, z-h.z); }
3032
3033 //comparison
3034 bool operator==(const GenericVec3<T> &h) const { return x == h.x && y == h.y && z == h.z; }
3035 bool operator!=(const GenericVec3<T> &h) const { return x != h.x || y != h.y || z != h.z; }
3036 bool operator>(const GenericVec3<T> &h) const { return x > h.x && y > h.y && z > h.z; }
3037 bool operator<(const GenericVec3<T> &h) const { return x < h.x && y < h.y && z < h.z; }
3038 bool operator>=(const GenericVec3<T> &h) const { return x >= h.x && y >= h.y && z >= h.z; }
3039 bool operator<=(const GenericVec3<T> &h) const { return x <= h.x && y <= h.y && z <= h.z; }
3040};
3041
3042extern bool raysphereintersect(const vec &center, float radius, const vec &o, const vec &ray, float &dist);
3043extern bool rayboxintersect(const vec &b, const vec &s, const vec &o, const vec &ray, float &dist, int &orient);
3044
3077extern bool linecylinderintersect(const vec &from, const vec &to, const vec &start, const vec &end, float radius, float &dist);
3078extern int polyclip(const vec *in, int numin, const vec &dir, float below, float above, vec *out);
3079
3080extern const vec2 sincos360[];
3081
3091inline int mod360(int angle)
3092{
3093 if(angle < 0)
3094 {
3095 angle = 360 + (angle <= -360 ? angle%360 : angle);
3096 }
3097 else if(angle >= 360)
3098 {
3099 angle %= 360;
3100 }
3101 return angle;
3102}
3103
3111inline const vec2 &sincosmod360(int angle) { return sincos360[mod360(angle)]; }
3112
3122inline float cos360(int angle) { return sincos360[angle].x; }
3123
3133inline float sin360(int angle) { return sincos360[angle].y; }
3134
3144inline float tan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.y/sc.x; }
3145
3155inline float cotan360(int angle) { const vec2 &sc = sincos360[angle]; return sc.x/sc.y; }
3156
3157#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:1852
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:1861
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:3133
int mod360(int angle)
Returns the angle passed to it, clamped to 0...360.
Definition geom.h:3091
const vec2 & sincosmod360(int angle)
Returns a vec2 containing (cos, sine) for a given integral angle.
Definition geom.h:3111
float cotan360(int angle)
Returns the cotangent for an angle (in degrees)
Definition geom.h:3155
float cos360(int angle)
Returns the cosine for an angle (in degrees)
Definition geom.h:3122
const int R[3]
Definition geom.h:2531
const int C[3]
Definition geom.h:2532
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:2533
const vec2 sincos360[]
float tan360(int angle)
Returns the tangent for an angle (in degrees)
Definition geom.h:3144
float fovy
void flip()
Flips this byte vec by using the mask type pun.
Definition geom.h:785
integer vector2
Definition geom.h:2646
Definition geom.h:2539
floating point 4x4 array object
Definition geom.h:2756
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:2275
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:2713
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:850
T dot3(const vec &o) const
Returns the 3 dimensional dot product between this and a 3D vec.
Definition geom.h:1083
vec4 & safenormalize()
Scales the vector to have a magnitude of 1.
Definition geom.h:1154
bool operator!=(const vec4 &o) const
Returns whether two vec objects do not match.
Definition geom.h:1059
vec4 & clamp(T l, T h)
Clamps the elements individualy to the specified bounds.
Definition geom.h:1536
T dot(const vec &o) const
Returns the dot product of this and a vec3, assuming o.w = 1.
Definition geom.h:1106
T dot(const vec4 &o) const
Returns the scalar product with another vec4.
Definition geom.h:1095
uint * mask()
Returns a raw unsigned int pointer to the data in this vec4.
Definition geom.h:1030
T b() const
Returns the z coordinate of this vec4.
Definition geom.h:1009
vec4 & div(T f)
Calculates the elementwise quotient.
Definition geom.h:1329
T r() const
Returns the x coordinate of this vec4.
Definition geom.h:995
vec4 operator-() const
Returns a new vec4 object equal to the arithmetic inverse of this
Definition geom.h:1574
vec4 & add(const vec4 &o)
Calculates the elementwise sum.
Definition geom.h:1375
void flip()
Flips a vec4<uchar> by using the mask type pun.
Definition geom.h:1188
vec4 & normalize()
Scales the vector to have a magnitude of 1.
Definition geom.h:1145
vec4 & sub(const vec4 &o)
Subtracts from this the vec4 passed.
Definition geom.h:1436
T & a()
References the w coordinate of this vec4.
Definition geom.h:988
vec4 & recip()
Calculates the elementwise reciprocal.
Definition geom.h:1363
T a() const
Returns the w coordinate of this vec4.
Definition geom.h:1016
T g() const
Returns the y coordinate of this vec4.
Definition geom.h:1002
vec4 & rotate_around_z(T angle)
Conducts a rotation around the z-axis.
Definition geom.h:1744
vec4 & div3(T f)
Calculates the elementwise quotient.
Definition geom.h:1317
vec4 & sub3(T f)
Subtracts from the first three entries this the value passed.
Definition geom.h:1460
T squaredlen() const
Returns the square of the magnitude of the vector.
Definition geom.h:1116
T & r()
References the x coordinate of this vec4.
Definition geom.h:967
vec4 & rotate_around_x(T c, T s)
Rotates the given 3-vector around the x-axis.
Definition geom.h:1707
vec4 & addw(T f)
Adds to the fourth value of the vector (w/a).
Definition geom.h:1424
const T * data() const
Returns a raw pointer to the data of this vec4.
Definition geom.h:1023
vec4()
Definition geom.h:854
T & operator[](int i)
Returns the i-th dimension of this vec4.
Definition geom.h:901
vec4 & div(const vec &o)
Calculates the elementwise quotient.
Definition geom.h:1353
vec4 operator+(const vec4 &v2) const
Returns a new vec4 object equal to the sum of the passed object and this
Definition geom.h:1552
vec4 & mul(T f)
Calculates the elementwise product.
Definition geom.h:1268
vec tonormal() const
Returns a new vec containing values normalized to 0...255 (e.g. colors).
Definition geom.h:1831
vec4 & sub(T f)
Subtracts from the entries this the value passed.
Definition geom.h:1478
vec4 & rotate_around_z(const vec2 &sc)
Conducts a rotation around the z-axis.
Definition geom.h:1789
vec4 operator/(const U &n) const
Returns a new vec4 object equal to the scalar division by a value.
Definition geom.h:1614
vec4 & sub(const vec &o)
Subtracts from this the vec passed.
Definition geom.h:1448
vec4 & mul3(T f)
Calculates the elementwise product.
Definition geom.h:1256
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:1231
vec4 operator/(const vec4 &v2) const
Returns a new vec4 equal to the elementwise division of this and the passed vec4.
Definition geom.h:1627
vec4 & rotate_around_y(const vec2 &sc)
Conducts a rotation around the y-axis.
Definition geom.h:1819
vec4 & add(const vec &o)
Calculates the elementwise sum.
Definition geom.h:1388
T & b()
References the z coordinate of this vec4.
Definition geom.h:981
vec4 & mul(const vec &o)
Calculates the elementwise product.
Definition geom.h:1294
T magnitude3() const
Returns the magnitude of the vector, ignoring the w dimension.
Definition geom.h:1136
T dot3(const vec4 &o) const
Returns the 3 dimensional dot product between two 4-vecs.
Definition geom.h:1071
vec4 & div(const vec4 &o)
Calculates the elementwise quotient.
Definition geom.h:1341
vec4 & cross(const A &a, const B &b)
Sets this vec to the cross product of two passed objects.
Definition geom.h:1646
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:1663
vec4 & rotate_around_x(const vec2 &sc)
Conducts a rotation around the x-axis.
Definition geom.h:1804
vec4 & rotate_around_y(T c, T s)
Rotates the given 3-vector around the y-axis.
Definition geom.h:1725
vec4 & subw(T f)
Subtracts from the last element only.
Definition geom.h:1495
vec4 operator*(const U &n) const
Returns a new vec4 object equal to the scalar multiplication by a value.
Definition geom.h:1588
vec4 operator*(const vec4 &v2) const
Returns a new vec4 equal to the elementwise product of this and the passed vec4.
Definition geom.h:1600
vec4 & rotate_around_z(T c, T s)
Rotates the given 3-vector around the z-axis.
Definition geom.h:1689
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:1244
T operator[](int i) const
Returns the i-th dimension of this vec4.
Definition geom.h:938
vec4 & square()
Calculates the elementwise square.
Definition geom.h:1304
vec4 & add(T f)
Calculates the elementwise sum.
Definition geom.h:1412
vec4 operator-(const vec4 &v2) const
Returns a new vec4 object equal to this minus the passed object.
Definition geom.h:1564
vec4 & neg3()
Negates the first three elements.
Definition geom.h:1508
bool operator==(const vec4 &o) const
Returns whether two vec objects exactly match.
Definition geom.h:1046
T magnitude() const
Returns the magnitude of the vector.
Definition geom.h:1126
void setxyz(const vec &v)
Replaces the first three values of this with the passed vec.
Definition geom.h:1673
vec4 & neg()
Negates all of the elements.
Definition geom.h:1521
vec4 & mul(const vec4 &o)
Calculates the elementwise product.
Definition geom.h:1281
vec4 & rotate_around_y(T angle)
Conducts a rotation around the y-axis.
Definition geom.h:1774
vec4 & add3(T f)
Calculates the elementwise sum.
Definition geom.h:1400
vec4 & avg(const vec4 &b)
Calculates the elementwise arithmetic mean.
Definition geom.h:1218
T & g()
References the y coordinate of this vec4.
Definition geom.h:974
vec4 & rotate_around_x(T angle)
Conducts a rotation around the x-axis.
Definition geom.h:1759
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.