glVertex  5.5.2
glslmath.h
Go to the documentation of this file.
1 // (c) by Stefan Roettger, licensed under MIT license
2 // glslmath: header-only single-module library that simulates glsl math
3 
6 #ifndef GLSLMATH_H
7 #define GLSLMATH_H
8 
9 #include <math.h>
10 #include <float.h>
11 #include <assert.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <ctype.h>
15 
16 #include <string>
17 #include <iostream>
18 #include <iomanip>
19 #include <vector>
20 #include <limits>
21 
22 #ifndef PI
23 # define PI (3.14159265358979323846264338327950288)
24 #endif
25 
26 #ifndef NAN
27 # define NAN (std::numeric_limits<double>::quiet_NaN())
28 #endif
29 
30 #ifdef _WIN32
31 #define drand48() ((double)rand()/RAND_MAX)
32 #define srand48(s) srand(s)
33 #endif
34 
35 #ifdef _MSC_VER
36 # define snprintf _snprintf
37 #endif
38 
39 #define GLSLMATH_PRECISION 7
40 
41 namespace glslmath {
42 
43 inline std::string to_space(int space=0)
44  {
45  std::string s;
46  for (int i=0; i<space; i++) s += " ";
47  return(s);
48  }
49 
50 inline std::string to_string(int v,int space=0)
51  {
52  char buf[32];
53  snprintf(buf,sizeof(buf),"%i",v);
54  std::string s(buf);
55 
56  if ((unsigned int)space > s.size())
57  {
58  int pad_left = (space-s.size())/2;
59  int pad_right = space-pad_left-s.size();
60 
61  return(to_space(pad_left) + s + to_space(pad_right));
62  }
63 
64  return(s);
65  }
66 
67 inline std::string to_string(unsigned int v,int space=0)
68  {
69  char buf[32];
70  snprintf(buf,sizeof(buf),"%u",v);
71  std::string s(buf);
72 
73  if ((unsigned int)space > s.size())
74  {
75  int pad_left = (space-s.size())/2;
76  int pad_right = space-pad_left-s.size();
77 
78  return(to_space(pad_left) + s + to_space(pad_right));
79  }
80 
81  return(s);
82  }
83 
84 inline std::string to_string(double v,int space=0)
85  {
86  char buf[32];
87  snprintf(buf,sizeof(buf),"%.7g",v);
88  std::string s(buf);
89 
90  if ((unsigned int)space > s.size())
91  {
92  int pad_left = (space-s.size())/2;
93  int pad_right = space-pad_left-s.size();
94 
95  return(to_space(pad_left) + s + to_space(pad_right));
96  }
97 
98  return(s);
99  }
100 
101 }
102 
108 class vec2
109  {
110  public:
111 
113  vec2() {}
114 
116  vec2(const vec2 &v) {x=v.x; y=v.y;}
117 
119  vec2(const double vx,const double vy) {x=vx; y=vy;}
120 
122  vec2(const double v) {x=y=v;}
123 
125  const double *c_ptr() const
126  {return(pointer);}
127 
129  operator const double *() const
130  {return(pointer);}
131 
133  double length() const {return(sqrt(x*x+y*y));}
134 
136  double norm() const {return(x*x+y*y);}
137 
139  vec2 normalize() const;
140 
142  double dot(const vec2 &v) const
143  {return(x*v.x+y*v.y);}
144 
146  bool approx(const vec2 &v,const double e=1E-10) const
147  {return((v.x-x)*(v.x-x)+(v.y-y)*(v.y-y)<e*e);}
148 
150  vec2& operator += (const vec2 &v)
151  {x+=v.x; y+=v.y; return(*this);}
152 
154  vec2& operator -= (const vec2 &v)
155  {x-=v.x; y-=v.y; return(*this);}
156 
158  vec2& operator *= (double v)
159  {x*=v; y*=v; return(*this);}
160 
162  vec2& operator *= (const vec2 &v)
163  {x*=v.x; y*=v.y; return(*this);}
164 
166  vec2 yx() const
167  {return(vec2(y,x));}
168 
170  operator std::string()
171  {return("(" + glslmath::to_string(x) + ", " + glslmath::to_string(y) + ")");}
172 
174  std::string to_string(std::string delimiter = ", ",int space=0)
175  {return(glslmath::to_string(x,space) + delimiter + glslmath::to_string(y,space));}
176 
178  union {
179  struct {double x,y;};
180  double pointer[2];
181  };
182  };
183 
185 inline vec2 operator + (const vec2 &a,const vec2 &b)
186  {return(vec2(a.x+b.x,a.y+b.y));}
187 
189 inline vec2 operator - (const vec2 &a,const vec2 &b)
190  {return(vec2(a.x-b.x,a.y-b.y));}
191 
193 inline vec2 operator - (const vec2 &v)
194  {return(vec2(-v.x,-v.y));}
195 
197 inline vec2 operator * (const double a,const vec2 &b)
198  {return(vec2(a*b.x,a*b.y));}
199 
201 inline vec2 operator * (const vec2 &a,const double b)
202  {return(vec2(a.x*b,a.y*b));}
203 
205 inline vec2 operator / (const vec2 &a,const double b)
206  {return(vec2(a.x/b,a.y/b));}
207 
209 inline vec2 operator * (const vec2 &a,const vec2 &b)
210  {return(vec2(a.x*b.x,a.y*b.y));}
211 
213 inline bool operator == (const vec2 &a,const vec2 &b)
214  {return(a.x==b.x && a.y==b.y);}
215 
217 inline bool operator != (const vec2 &a,const vec2 &b)
218  {return(a.x!=b.x || a.y!=b.y);}
219 
221 inline double length(const vec2 &v)
222  {return(v.length());}
223 
225 inline double norm(const vec2 &v)
226  {return(v.norm());}
227 
229 inline vec2 vec2::normalize() const
230  {
231  double l2=norm();
232  if (l2>0.0 && l2!=1.0) return(*this/sqrt(l2));
233  return(*this);
234  }
235 
237 inline vec2 normalize(const vec2 &v)
238  {return(v.normalize());}
239 
241 inline double dot(const vec2 &a,const vec2 &b)
242  {return(a.dot(b));}
243 
245 inline vec2 lerp(double w, const vec2 &a,const vec2 &b)
246  {return((1-w)*a+w*b);}
247 
249 inline vec2 mix(const vec2 &a,const vec2 &b, double w)
250  {return((1-w)*a+w*b);}
251 
253 inline std::ostream& operator << (std::ostream &out,const vec2 &v)
254  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << v.x << ", " << v.y << ")");}
255 
261 class vec2f
262  {
263  public:
264 
266  vec2f() {}
267 
269  vec2f(const vec2f &v) {x=v.x; y=v.y;}
270 
272  vec2f(const vec2 &v) {x=(float)v.x; y=(float)v.y;}
273 
275  vec2f(const float vx,const float vy) {x=vx; y=vy;}
276 
278  vec2f(const float v) {x=y=v;}
279 
281  operator vec2() const
282  {return(vec2(x,y));}
283 
285  const float *c_ptr() const
286  {return(pointer);}
287 
289  operator const float *() const
290  {return(pointer);}
291 
294  {x+=v.x; y+=v.y; return(*this);}
295 
298  {x-=v.x; y-=v.y; return(*this);}
299 
301  vec2f& operator *= (float v)
302  {x*=v; y*=v; return(*this);}
303 
306  {x*=v.x; y*=v.y; return(*this);}
307 
309  vec2f yx() const
310  {return(vec2f(y,x));}
311 
313  operator std::string()
314  {return("(" + glslmath::to_string(x) + ", " + glslmath::to_string(y) + ")");}
315 
317  std::string to_string(std::string delimiter = ", ",int space=0)
318  {return(glslmath::to_string(x,space) + delimiter + glslmath::to_string(y,space));}
319 
321  union {
322  struct {float x,y;};
323  float pointer[2];
324  };
325  };
326 
328 inline vec2f operator + (const vec2f &a,const vec2f &b)
329  {return(vec2f(a.x+b.x,a.y+b.y));}
330 
332 inline vec2f operator - (const vec2f &a,const vec2f &b)
333  {return(vec2f(a.x-b.x,a.y-b.y));}
334 
336 inline vec2f operator - (const vec2f &v)
337  {return(vec2f(-v.x,-v.y));}
338 
340 inline vec2f operator * (const float a,const vec2f &b)
341  {return(vec2f(a*b.x,a*b.y));}
342 
344 inline vec2f operator * (const vec2f &a,const float b)
345  {return(vec2f(a.x*b,a.y*b));}
346 
348 inline vec2f operator / (const vec2f &a,const float b)
349  {return(vec2f(a.x/b,a.y/b));}
350 
352 inline vec2f operator * (const vec2f &a,const vec2f &b)
353  {return(vec2f(a.x*b.x,a.y*b.y));}
354 
356 inline bool operator == (const vec2f &a,const vec2f &b)
357  {return(a.x==b.x && a.y==b.y);}
358 
360 inline bool operator != (const vec2f &a,const vec2f &b)
361  {return(a.x!=b.x || a.y!=b.y);}
362 
364 inline std::ostream& operator << (std::ostream &out,const vec2f &v)
365  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << v.x << ", " << v.y << ")");}
366 
372 class vec3
373  {
374  public:
375 
377  vec3() {}
378 
380  vec3(const vec3 &v) {x=v.x; y=v.y; z=v.z;}
381 
383  vec3(const vec2 &v,const double vz=0.0) {x=v.x; y=v.y; z=vz;}
384 
386  vec3(const double vx,const double vy,const double vz) {x=vx; y=vy; z=vz;}
387 
389  vec3(const double v) {x=y=z=v;}
390 
392  operator vec2() const
393  {return(vec2(x,y));}
394 
396  const double *c_ptr() const
397  {return(pointer);}
398 
400  operator const double *() const
401  {return(pointer);}
402 
404  vec3& operator += (const vec3 &v)
405  {x+=v.x; y+=v.y; z+=v.z; return(*this);}
406 
408  vec3& operator -= (const vec3 &v)
409  {x-=v.x; y-=v.y; z-=v.z; return(*this);}
410 
412  vec3& operator *= (double v)
413  {x*=v; y*=v; z*=v; return(*this);}
414 
416  vec3& operator *= (const vec3 &v)
417  {x*=v.x; y*=v.y; z*=v.z; return(*this);}
418 
420  double length() const {return(sqrt(x*x+y*y+z*z));}
421 
423  double norm() const {return(x*x+y*y+z*z);}
424 
426  vec3 normalize() const;
427 
429  double dot(const vec3 &v) const
430  {return(x*v.x+y*v.y+z*v.z);}
431 
433  vec3 cross(const vec3 &v) const
434  {return(vec3(y*v.z-z*v.y,z*v.x-x*v.z,x*v.y-y*v.x));}
435 
437  vec3 reflect(const vec3 &n) const;
438 
440  static vec3 normal(const vec3 &a,const vec3 &b,const vec3 &c);
441 
443  static double area(const vec3 &a,const vec3 &b,const vec3 &c);
444 
446  bool approx(const vec3 &v,const double e=1E-10) const
447  {return((v.x-x)*(v.x-x)+(v.y-y)*(v.y-y)+(v.z-z)*(v.z-z)<e*e);}
448 
450  vec2 xy() const
451  {return(vec2(x,y));}
452 
454  vec3 zyx() const
455  {return(vec3(z,y,x));}
456 
458  vec3 bgr() const
459  {return(vec3(b,g,r));}
460 
462  vec3 blend(const vec3 &rgb,double alpha) const;
463 
465  operator std::string()
466  {return("(" + glslmath::to_string(x) + ", " + glslmath::to_string(y) + ", " + glslmath::to_string(z) + ")");}
467 
469  std::string to_string(std::string delimiter = ", ",int space=0)
470  {return(glslmath::to_string(x,space) + delimiter + glslmath::to_string(y,space) + delimiter + glslmath::to_string(z,space));}
471 
473  union {
474  struct {
475  union {double x; double r;};
476  union {double y; double g;};
477  union {double z; double b;};
478  };
479  double pointer[3];
480  };
481  };
482 
484 inline vec3 operator + (const vec3 &a,const vec3 &b)
485  {return(vec3(a.x+b.x,a.y+b.y,a.z+b.z));}
486 
488 inline vec3 operator - (const vec3 &a,const vec3 &b)
489  {return(vec3(a.x-b.x,a.y-b.y,a.z-b.z));}
490 
492 inline vec3 operator - (const vec3 &v)
493  {return(vec3(-v.x,-v.y,-v.z));}
494 
496 inline vec3 operator * (const double a,const vec3 &b)
497  {return(vec3(a*b.x,a*b.y,a*b.z));}
498 
500 inline vec3 operator * (const vec3 &a,const double b)
501  {return(vec3(a.x*b,a.y*b,a.z*b));}
502 
504 inline vec3 operator / (const vec3 &a,const double b)
505  {return(vec3(a.x/b,a.y/b,a.z/b));}
506 
508 inline vec3 operator * (const vec3 &a,const vec3 &b)
509  {return(vec3(a.x*b.x,a.y*b.y,a.z*b.z));}
510 
512 inline bool operator == (const vec3 &a,const vec3 &b)
513  {return(a.x==b.x && a.y==b.y && a.z==b.z);}
514 
516 inline bool operator != (const vec3 &a,const vec3 &b)
517  {return(a.x!=b.x || a.y!=b.y || a.z!=b.z);}
518 
520 inline double length(const vec3 &v)
521  {return(v.length());}
522 
524 inline double norm(const vec3 &v)
525  {return(v.norm());}
526 
528 inline vec3 vec3::normalize() const
529  {
530  double l2=norm();
531  if (l2>0.0 && l2!=1.0) return(*this/sqrt(l2));
532  return(*this);
533  }
534 
536 inline vec3 normalize(const vec3 &v)
537  {return(v.normalize());}
538 
540 inline double dot(const vec3 &a,const vec3 &b)
541  {return(a.dot(b));}
542 
544 inline vec3 cross(const vec3 &a,const vec3 &b)
545  {return(a.cross(b));}
546 
548 inline vec3 lerp(double w, const vec3 &a,const vec3 &b)
549  {return((1-w)*a+w*b);}
550 
552 inline vec3 mix(const vec3 &a,const vec3 &b, double w)
553  {return((1-w)*a+w*b);}
554 
556 inline vec3 vec3::reflect(const vec3 &n) const
557  {return((*this)-2*n*dot(n));}
558 
560 inline vec3 reflect(const vec3 &v,const vec3 &n)
561  {return(v.reflect(n));}
562 
564 inline vec3 vec3::normal(const vec3 &a,const vec3 &b,const vec3 &c)
565  {return((b-a).cross(c-a).normalize());}
566 
568 inline double vec3::area(const vec3 &a,const vec3 &b,const vec3 &c)
569  {return(fabs((b-a).cross(c-a).length()/2));}
570 
572 inline vec3 vec3::blend(const vec3 &rgb,double alpha) const
573  {return((1-alpha)*(*this)+alpha*rgb);}
574 
576 inline std::ostream& operator << (std::ostream &out,const vec3 &v)
577  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << v.x << ", " << v.y << ", " << v.z << ")");}
578 
584 class vec3f
585  {
586  public:
587 
589  vec3f() {}
590 
592  vec3f(const vec3f &v) {x=v.x; y=v.y; z=v.z;}
593 
595  vec3f(const vec3 &v) {x=(float)v.x; y=(float)v.y; z=(float)v.z;}
596 
598  vec3f(const vec2f &v,const float vz=0.0f) {x=v.x; y=v.y; z=vz;}
599 
601  vec3f(const vec2 &v,const float vz=0.0f) {x=(float)v.x; y=(float)v.y; z=vz;}
602 
604  vec3f(const float vx,const float vy,const float vz) {x=vx; y=vy; z=vz;}
605 
607  vec3f(const float v) {x=y=z=v;}
608 
610  operator vec3() const
611  {return(vec3(x,y,z));}
612 
614  const float *c_ptr() const
615  {return(pointer);}
616 
618  operator const float *() const
619  {return(pointer);}
620 
623  {x+=v.x; y+=v.y; z+=v.z; return(*this);}
624 
627  {x-=v.x; y-=v.y; z-=v.z; return(*this);}
628 
630  vec3f& operator *= (float v)
631  {x*=v; y*=v; z*=v; return(*this);}
632 
635  {x*=v.x; y*=v.y; z*=v.z; return(*this);}
636 
638  vec2f xy() const
639  {return(vec2f(x,y));}
640 
642  vec3f zyx() const
643  {return(vec3f(z,y,x));}
644 
646  vec3f bgr() const
647  {return(vec3f(b,g,r));}
648 
650  operator std::string()
651  {return("(" + glslmath::to_string(x) + ", " + glslmath::to_string(y) + ", " + glslmath::to_string(z) + ")");}
652 
654  std::string to_string(std::string delimiter = ", ",int space=0)
655  {return(glslmath::to_string(x,space) + delimiter + glslmath::to_string(y,space) + delimiter + glslmath::to_string(z,space));}
656 
658  union {
659  struct {
660  union {float x; float r;};
661  union {float y; float g;};
662  union {float z; float b;};
663  };
664  float pointer[3];
665  };
666  };
667 
669 inline vec3f operator + (const vec3f &a,const vec3f &b)
670  {return(vec3f(a.x+b.x,a.y+b.y,a.z+b.z));}
671 
673 inline vec3f operator - (const vec3f &a,const vec3f &b)
674  {return(vec3f(a.x-b.x,a.y-b.y,a.z-b.z));}
675 
677 inline vec3f operator - (const vec3f &v)
678  {return(vec3f(-v.x,-v.y,-v.z));}
679 
681 inline vec3f operator * (const float a,const vec3f &b)
682  {return(vec3f(a*b.x,a*b.y,a*b.z));}
683 
685 inline vec3f operator * (const vec3f &a,const float b)
686  {return(vec3f(a.x*b,a.y*b,a.z*b));}
687 
689 inline vec3f operator / (const vec3f &a,const float b)
690  {return(vec3f(a.x/b,a.y/b,a.z/b));}
691 
693 inline vec3f operator * (const vec3f &a,const vec3f &b)
694  {return(vec3f(a.x*b.x,a.y*b.y,a.z*b.z));}
695 
697 inline bool operator == (const vec3f &a,const vec3f &b)
698  {return(a.x==b.x && a.y==b.y && a.z==b.z);}
699 
701 inline bool operator != (const vec3f &a,const vec3f &b)
702  {return(a.x!=b.x || a.y!=b.y || a.z!=b.z);}
703 
705 inline std::ostream& operator << (std::ostream &out,const vec3f &v)
706  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << v.x << ", " << v.y << ", " << v.z << ")");}
707 
713 class vec4
714  {
715  public:
716 
718  vec4() {}
719 
721  vec4(const vec4 &v) {x=v.x; y=v.y; z=v.z; w=v.w;}
722 
724  vec4(const vec3 &v,const double vw=1.0) {x=v.x; y=v.y; z=v.z; w=vw;}
725 
727  vec4(const vec2 &v,const double vz=0.0,const double vw=1.0) {x=v.x; y=v.y; z=vz; w=vw;}
728 
730  vec4(const vec2 &xy,const vec2 &zw) {x=xy.x; y=xy.y; z=zw.x; w=zw.y;}
731 
733  vec4(const double vx,const double vy,const double vz,const double vw=1.0) {x=vx; y=vy; z=vz; w=vw;}
734 
736  vec4(const double v,const double vw=1.0) {x=y=z=v; w=vw;}
737 
739  operator vec3() const
740  {
741  double c;
742 
743  if (w!=0.0)
744  if (w!=1.0)
745  {
746  c=1.0/w;
747  return(vec3(x*c,y*c,z*c));
748  }
749 
750  return(vec3(x,y,z));
751  }
752 
754  const double *c_ptr() const
755  {return(pointer);}
756 
758  operator const double *() const
759  {return(pointer);}
760 
762  vec4& operator += (const vec4 &v)
763  {x+=v.x; y+=v.y; z+=v.z; w+=v.w; return(*this);}
764 
766  vec4& operator -= (const vec4 &v)
767  {x-=v.x; y-=v.y; z-=v.z; w-=v.w; return(*this);}
768 
770  vec4& operator *= (double v)
771  {x*=v; y*=v; z*=v; w*=v; return(*this);}
772 
774  vec4& operator *= (const vec4 &v)
775  {x*=v.x; y*=v.y; z*=v.z; w*=v.w; return(*this);}
776 
778  double length() const {return(sqrt(x*x+y*y+z*z+w*w));}
779 
781  double norm() const {return(x*x+y*y+z*z+w*w);}
782 
784  vec4 normalize() const;
785 
787  double dot(const vec4 &v) const
788  {return(x*v.x+y*v.y+z*v.z+w*v.w);}
789 
791  vec4 cross(const vec4 &v) const
792  {
793  assert(w==0.0 && v.w==0.0);
794  return(vec4(y*v.z-z*v.y,z*v.x-x*v.z,x*v.y-y*v.x,0.0));
795  }
796 
798  vec4 reflect(const vec4 &n) const;
799 
801  static vec4 normal(const vec4 &a,const vec4 &b,const vec4 &c);
802 
804  static double area(const vec4 &a,const vec4 &b,const vec4 &c);
805 
807  bool approx(const vec4 &v,const double e=1E-10) const
808  {return((v.x-x)*(v.x-x)+(v.y-y)*(v.y-y)+(v.z-z)*(v.z-z)+(v.w-w)*(v.w-w)<e*e);}
809 
811  vec2 xy() const
812  {return(vec2(x,y));}
813 
815  vec2 zw() const
816  {return(vec2(z,w));}
817 
819  vec3 xyz() const
820  {return(vec3(x,y,z));}
821 
823  vec3 rgb() const
824  {return(vec3(r,g,b));}
825 
827  vec4 wzyx() const
828  {return(vec4(w,z,y,x));}
829 
831  vec4 bgra() const
832  {return(vec4(b,g,r,a));}
833 
835  vec4 blend(const vec4 &rgba) const;
836 
838  operator std::string()
839  {return("(" + glslmath::to_string(x) + ", " + glslmath::to_string(y) + ", " + glslmath::to_string(z) + ", " + glslmath::to_string(w) + ")");}
840 
842  std::string to_string(std::string delimiter = ", ",int space=0)
843  {return(glslmath::to_string(x,space) + delimiter + glslmath::to_string(y,space) + delimiter + glslmath::to_string(z,space) + delimiter + glslmath::to_string(w,space));}
844 
846  union {
847  struct {
848  union {double x; double r;};
849  union {double y; double g;};
850  union {double z; double b;};
851  union {double w; double a;};
852  };
853  double pointer[4];
854  };
855  };
856 
858 inline vec4 operator + (const vec4 &a,const vec4 &b)
859  {return(vec4(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w));}
860 
862 inline vec4 operator - (const vec4 &a,const vec4 &b)
863  {return(vec4(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w));}
864 
866 inline vec4 operator - (const vec4 &v)
867  {return(vec4(-v.x,-v.y,-v.z,-v.w));}
868 
870 inline vec4 operator * (const double a,const vec4 &b)
871  {return(vec4(a*b.x,a*b.y,a*b.z,a*b.w));}
872 
874 inline vec4 operator * (const vec4 &a,const double b)
875  {return(vec4(a.x*b,a.y*b,a.z*b,a.w*b));}
876 
878 inline vec4 operator / (const vec4 &a,const double b)
879  {return(vec4(a.x/b,a.y/b,a.z/b,a.w/b));}
880 
882 inline vec4 operator * (const vec4 &a,const vec4 &b)
883  {return(vec4(a.x*b.x,a.y*b.y,a.z*b.z,a.w*b.w));}
884 
886 inline bool operator == (const vec4 &a,const vec4 &b)
887  {return(a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);}
888 
890 inline bool operator != (const vec4 &a,const vec4 &b)
891  {return(a.x!=b.x || a.y!=b.y || a.z!=b.z || a.w!=b.w);}
892 
894 inline double length(const vec4 &v)
895  {return(v.length());}
896 
898 inline double norm(const vec4 &v)
899  {return(v.norm());}
900 
902 inline vec4 vec4::normalize() const
903  {
904  double l2=norm();
905  if (l2>0.0 && l2!=1.0) return(*this/sqrt(l2));
906  return(*this);
907  }
908 
910 inline vec4 normalize(const vec4 &v)
911  {return(v.normalize());}
912 
914 inline double dot(const vec4 &a,const vec4 &b)
915  {return(a.dot(b));}
916 
918 inline vec4 cross(const vec4 &a,const vec4 &b)
919  {return(a.cross(b));}
920 
922 inline vec4 lerp(double w, const vec4 &a,const vec4 &b)
923  {return((1-w)*a+w*b);}
924 
926 inline vec4 mix(const vec4 &a,const vec4 &b, double w)
927  {return((1-w)*a+w*b);}
928 
930 inline vec4 vec4::reflect(const vec4 &n) const
931  {
932  assert(w==0.0 && n.w==0.0);
933  return((*this)-2*n*dot(n));
934  }
935 
937 inline vec4 reflect(const vec4 &v,const vec4 &n)
938  {return(v.reflect(n));}
939 
941 inline vec4 vec4::normal(const vec4 &a,const vec4 &b,const vec4 &c)
942  {return((b-a).cross(c-a).normalize());}
943 
945 inline double vec4::area(const vec4 &a,const vec4 &b,const vec4 &c)
946  {return(fabs((b-a).cross(c-a).length()/2));}
947 
949 inline vec4 vec4::blend(const vec4 &rgba) const
950  {return(vec4((1-rgba.a)*this->rgb()+rgba.a*rgba.rgb(),1-(1-rgba.a)*(1-a)));}
951 
953 inline std::ostream& operator << (std::ostream &out,const vec4 &v)
954  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")");}
955 
961 class vec4f
962  {
963  public:
964 
966  vec4f() {}
967 
969  vec4f(const vec4f &v) {x=v.x; y=v.y; z=v.z; w=v.w;}
970 
972  vec4f(const vec4 &v) {x=(float)v.x; y=(float)v.y; z=(float)v.z; w=(float)v.w;}
973 
975  vec4f(const vec3f &v,const float vw=1.0f) {x=v.x; y=v.y; z=v.z; w=vw;}
976 
978  vec4f(const vec3 &v,const float vw=1.0f) {x=(float)v.x; y=(float)v.y; z=(float)v.z; w=vw;}
979 
981  vec4f(const vec2f &v,const float vz=0.0f,const float vw=1.0f) {x=v.x; y=v.y; z=vz; w=vw;}
982 
984  vec4f(const vec2 &v,const float vz=0.0f,const float vw=1.0f) {x=(float)v.x; y=(float)v.y; z=vz; w=vw;}
985 
987  vec4f(const vec2f &xy,const vec2f &zw) {x=xy.x; y=xy.y; z=zw.x; w=zw.y;}
988 
990  vec4f(const vec2 &xy,const vec2 &zw) {x=(float)xy.x; y=(float)xy.y; z=(float)zw.x; w=(float)zw.y;}
991 
993  vec4f(const float vx,const float vy,const float vz,const float vw=1.0f) {x=vx; y=vy; z=vz; w=vw;}
994 
996  vec4f(const float v,const float vw=1.0f) {x=y=z=v; w=vw;}
997 
999  operator vec4() const
1000  {return(vec4(x,y,z,w));}
1001 
1003  operator vec3f() const
1004  {
1005  float c;
1006 
1007  if (w!=0.0f)
1008  if (w!=1.0f)
1009  {
1010  c=1.0f/w;
1011  return(vec3f(x*c,y*c,z*c));
1012  }
1013 
1014  return(vec3f(x,y,z));
1015  }
1016 
1018  const float *c_ptr() const
1019  {return(pointer);}
1020 
1022  operator const float *() const
1023  {return(pointer);}
1024 
1027  {x+=v.x; y+=v.y; z+=v.z; w+=v.w; return(*this);}
1028 
1031  {x-=v.x; y-=v.y; z-=v.z; w-=v.w; return(*this);}
1032 
1035  {x*=v; y*=v; z*=v; w*=v; return(*this);}
1036 
1039  {x*=v.x; y*=v.y; z*=v.z; w*=v.w; return(*this);}
1040 
1042  vec2f xy() const
1043  {return(vec2f(x,y));}
1044 
1046  vec2f zw() const
1047  {return(vec2f(z,w));}
1048 
1050  vec3f xyz() const
1051  {return(vec3f(x,y,z));}
1052 
1054  vec3f rgb() const
1055  {return(vec3f(r,g,b));}
1056 
1058  vec4f wzyx() const
1059  {return(vec4f(w,z,y,x));}
1060 
1062  vec4f bgra() const
1063  {return(vec4f(b,g,r,a));}
1064 
1066  operator std::string()
1067  {return("(" + glslmath::to_string(x) + ", " + glslmath::to_string(y) + ", " + glslmath::to_string(z) + ", " + glslmath::to_string(w) + ")");}
1068 
1070  std::string to_string(std::string delimiter = ", ",int space=0)
1071  {return(glslmath::to_string(x,space) + delimiter + glslmath::to_string(y,space) + delimiter + glslmath::to_string(z,space) + delimiter + glslmath::to_string(w,space));}
1072 
1074  union {
1075  struct {
1076  union {float x; float r;};
1077  union {float y; float g;};
1078  union {float z; float b;};
1079  union {float w; float a;};
1080  };
1081  float pointer[4];
1082  };
1083  };
1084 
1086 inline vec4f operator + (const vec4f &a,const vec4f &b)
1087  {return(vec4f(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w));}
1088 
1090 inline vec4f operator - (const vec4f &a,const vec4f &b)
1091  {return(vec4f(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w));}
1092 
1094 inline vec4f operator - (const vec4f &v)
1095  {return(vec4f(-v.x,-v.y,-v.z,-v.w));}
1096 
1098 inline vec4f operator * (const float a,const vec4f &b)
1099  {return(vec4f(a*b.x,a*b.y,a*b.z,a*b.w));}
1100 
1102 inline vec4f operator * (const vec4f &a,const float b)
1103  {return(vec4f(a.x*b,a.y*b,a.z*b,a.w*b));}
1104 
1106 inline vec4f operator / (const vec4f &a,const float b)
1107  {return(vec4f(a.x/b,a.y/b,a.z/b,a.w/b));}
1108 
1110 inline vec4f operator * (const vec4f &a,const vec4f &b)
1111  {return(vec4f(a.x*b.x,a.y*b.y,a.z*b.z,a.w*b.w));}
1112 
1114 inline bool operator == (const vec4f &a,const vec4f &b)
1115  {return(a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);}
1116 
1118 inline bool operator != (const vec4f &a,const vec4f &b)
1119  {return(a.x!=b.x || a.y!=b.y || a.z!=b.z || a.w!=b.w);}
1120 
1122 inline std::ostream& operator << (std::ostream &out,const vec4f &v)
1123  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ")");}
1124 
1125 class mat2f;
1126 
1130 class mat2
1131  {
1132  public:
1133 
1135  mat2(double diag=1.0)
1136  {
1137  mtx[0][0]=diag;
1138  mtx[0][1]=0.0;
1139 
1140  mtx[1][0]=0.0;
1141  mtx[1][1]=diag;
1142  }
1143 
1145  mat2(const vec2 &diag)
1146  {
1147  mtx[0][0]=diag.x;
1148  mtx[0][1]=0.0;
1149 
1150  mtx[1][0]=0.0;
1151  mtx[1][1]=diag.y;
1152  }
1153 
1155  mat2(const vec2 &r1,
1156  const vec2 &r2)
1157  {
1158  mtx[0][0]=r1.x;
1159  mtx[0][1]=r2.x;
1160 
1161  mtx[1][0]=r1.y;
1162  mtx[1][1]=r2.y;
1163  }
1164 
1166  mat2(const mat2f &m);
1167 
1169  static mat2 columns(const vec2 &c1,const vec2 &c2)
1170  {
1171  return(mat2(vec2(c1.x,c2.x),
1172  vec2(c1.y,c2.y)));
1173  }
1174 
1176  static mat2 columns(double a,double b,
1177  double c,double d)
1178  {
1179  return(mat2(vec2(a,c),
1180  vec2(b,d)));
1181  }
1182 
1184  static mat2 rows(const vec2 &r1,const vec2 &r2)
1185  {
1186  return(mat2(r1,
1187  r2));
1188  }
1189 
1191  static mat2 rows(double a,double b,
1192  double c,double d)
1193  {
1194  return(mat2(vec2(a,b),
1195  vec2(c,d)));
1196  }
1197 
1199  vec2 operator[] (const int i) const
1200  {
1201  assert(i>=0 && i<2);
1202  return(vec2(mtx[i][0],mtx[i][1]));
1203  }
1204 
1206  vec2 row(const int i) const
1207  {
1208  assert(i>=0 && i<2);
1209  return(vec2(mtx[0][i],mtx[1][i]));
1210  }
1211 
1213  vec2 col(const int i) const
1214  {
1215  assert(i>=0 && i<2);
1216  return(vec2(mtx[i][0],mtx[i][1]));
1217  }
1218 
1220  const double *c_ptr() const
1221  {return(pointer);}
1222 
1224  operator const double *() const
1225  {return(pointer);}
1226 
1228  void fromOpenGL(const double m[4])
1229  {
1230  mtx[0][0]=m[0];
1231  mtx[0][1]=m[1];
1232 
1233  mtx[1][0]=m[2];
1234  mtx[1][1]=m[3];
1235  }
1236 
1238  double det() const
1239  {return(mtx[0][0]*mtx[1][1]-mtx[0][1]*mtx[1][0]);}
1240 
1242  static double det(const mat2 &m)
1243  {return(m.det());}
1244 
1246  mat2 transpose() const
1247  {return(mat2(col(0),col(1)));}
1248 
1250  static mat2 transpose(const mat2 &m)
1251  {return(m.transpose());}
1252 
1254  mat2 invert() const
1255  {
1256  mat2 m;
1257  double d;
1258 
1259  // calculate determinant
1260  d=det();
1261 
1262  // check determinant
1263  if (d==0.0) return(mat2(0));
1264 
1265  // calculate inverse
1266  d=1.0/d;
1267  m.mtx[0][0]=d*mtx[1][1];
1268  m.mtx[1][0]=-d*mtx[1][0];
1269  m.mtx[0][1]=-d*mtx[0][1];
1270  m.mtx[1][1]=d*mtx[0][0];
1271 
1272  return(m);
1273  }
1274 
1276  static mat2 invert(const mat2 &m)
1277  {return(m.invert());}
1278 
1280  static mat2 scale(double s,double t)
1281  {
1282  return(mat2(vec2(s,0),
1283  vec2(0,t)));
1284  }
1285 
1287  static mat2 scale(const vec2 &c)
1288  {
1289  return(mat2(vec2(c.x,0),
1290  vec2(0,c.y)));
1291  }
1292 
1295  static mat2 rotate(double angle)
1296  {
1297  double c,s;
1298 
1299  angle*=PI/180;
1300 
1301  c=cos(angle);
1302  s=sin(angle);
1303 
1304  return(mat2(vec2(c,s),
1305  vec2(-s,c)));
1306  }
1307 
1309  mat2& operator += (const mat2 &m);
1310 
1312  mat2& operator *= (const mat2 &m);
1313 
1315  mat2& operator <<= (const mat2 &m);
1316 
1318  mat2& operator >>= (const mat2 &m);
1319 
1321  operator std::string()
1322  {return("(" + std::string(row(0)) + ", " + std::string(row(1)) + ")");}
1323 
1324  protected:
1325 
1327  union {
1328  double mtx[2][2];
1329  double pointer[4];
1330  };
1331  };
1332 
1334 inline mat2 operator + (const mat2 &m1,const mat2 &m2)
1335  {
1336  return(mat2(m1[0]+m2[0],
1337  m1[1]+m2[1]));
1338  }
1339 
1341 inline mat2 operator * (const mat2 &m1,const mat2 &m2)
1342  {
1343  return(mat2(vec2(m1.row(0).dot(m2[0]),m1.row(0).dot(m2[1])),
1344  vec2(m1.row(1).dot(m2[0]),m1.row(1).dot(m2[1]))));
1345  }
1346 
1348 inline mat2& mat2::operator += (const mat2 &m)
1349  {
1350  *this = (*this)+m;
1351  return(*this);
1352  }
1353 
1355 inline mat2& mat2::operator *= (const mat2 &m)
1356  {
1357  *this = (*this)*m;
1358  return(*this);
1359  }
1360 
1362 inline mat2& mat2::operator <<= (const mat2 &m)
1363  {
1364  *this = m*(*this);
1365  return(*this);
1366  }
1367 
1369 inline mat2& mat2::operator >>= (const mat2 &m)
1370  {
1371  *this = (*this)*m;
1372  return(*this);
1373  }
1374 
1376 inline bool operator == (const mat2 &a,const mat2 &b)
1377  {
1378  unsigned int i;
1379 
1380  for (i=0; i<4; i++)
1381  if (((const double *)a)[i]!=((const double *)b)[i]) return(false);
1382 
1383  return(true);
1384  }
1385 
1387 inline bool operator != (const mat2 &a,const mat2 &b)
1388  {
1389  unsigned int i;
1390 
1391  for (i=0; i<4; i++)
1392  if (((const double *)a)[i]!=((const double *)b)[i]) return(true);
1393 
1394  return(false);
1395  }
1396 
1398 inline vec2 operator * (const mat2 &m,const vec2 &v)
1399  {return(vec2(m.row(0).dot(v),m.row(1).dot(v)));}
1400 
1402 inline std::ostream& operator << (std::ostream &out,const mat2 &m)
1403  {return(out << "(" << m.row(0) << ", " << m.row(1) << ")");}
1404 
1408 class mat2f
1409  {
1410  public:
1411 
1413  mat2f(float diag=1.0f)
1414  {
1415  mtx[0][0]=diag;
1416  mtx[0][1]=0.0f;
1417 
1418  mtx[1][0]=0.0f;
1419  mtx[1][1]=diag;
1420  }
1421 
1423  mat2f(const vec2f &r1,
1424  const vec2f &r2)
1425  {
1426  mtx[0][0]=r1.x;
1427  mtx[0][1]=r2.x;
1428 
1429  mtx[1][0]=r1.y;
1430  mtx[1][1]=r2.y;
1431  }
1432 
1434  mat2f(const mat2 &m)
1435  {
1436  mtx[0][0]=(float)m[0][0];
1437  mtx[0][1]=(float)m[0][1];
1438 
1439  mtx[1][0]=(float)m[1][0];
1440  mtx[1][1]=(float)m[1][1];
1441  }
1442 
1444  static mat2f columns(const vec2f &c1,const vec2f &c2)
1445  {
1446  return(mat2f(vec2f(c1.x,c2.x),
1447  vec2f(c1.y,c2.y)));
1448  }
1449 
1451  static mat2f columns(float a,float b,
1452  float c,float d)
1453  {
1454  return(mat2f(vec2f(a,c),
1455  vec2f(b,d)));
1456  }
1457 
1459  static mat2f rows(const vec2f &r1,const vec2f &r2)
1460  {
1461  return(mat2f(r1,
1462  r2));
1463  }
1464 
1466  static mat2f rows(float a,float b,
1467  float c,float d)
1468  {
1469  return(mat2f(vec2f(a,b),
1470  vec2f(c,d)));
1471  }
1472 
1474  vec2f operator[] (const int i) const
1475  {
1476  assert(i>=0 && i<2);
1477  return(vec2f(mtx[i][0],mtx[i][1]));
1478  }
1479 
1481  vec2f row(const int i) const
1482  {
1483  assert(i>=0 && i<2);
1484  return(vec2f(mtx[0][i],mtx[1][i]));
1485  }
1486 
1488  vec2f col(const int i) const
1489  {
1490  assert(i>=0 && i<2);
1491  return(vec2f(mtx[i][0],mtx[i][1]));
1492  }
1493 
1495  const float *c_ptr() const
1496  {return(pointer);}
1497 
1499  operator const float *() const
1500  {return(pointer);}
1501 
1503  void fromOpenGL(const float m[4])
1504  {
1505  mtx[0][0]=m[0];
1506  mtx[0][1]=m[1];
1507 
1508  mtx[1][0]=m[2];
1509  mtx[1][1]=m[3];
1510  }
1511 
1513  operator std::string()
1514  {return("(" + std::string(row(0)) + ", " + std::string(row(1)) + ")");}
1515 
1516  protected:
1517 
1519  union {
1520  float mtx[2][2];
1521  float pointer[4];
1522  };
1523  };
1524 
1526 inline std::ostream& operator << (std::ostream &out,const mat2f &m)
1527  {return(out << "(" << m.row(0) << ", " << m.row(1) << ")");}
1528 
1530 inline mat2::mat2(const mat2f &m)
1531  {
1532  mtx[0][0]=m[0][0];
1533  mtx[0][1]=m[0][1];
1534 
1535  mtx[1][0]=m[1][0];
1536  mtx[1][1]=m[1][1];
1537  }
1538 
1539 class mat3f;
1540 
1544 class mat3
1545  {
1546  public:
1547 
1549  mat3(double diag=1.0)
1550  {
1551  mtx[0][0]=diag;
1552  mtx[0][1]=0.0;
1553  mtx[0][2]=0.0;
1554 
1555  mtx[1][0]=0.0;
1556  mtx[1][1]=diag;
1557  mtx[1][2]=0.0;
1558 
1559  mtx[2][0]=0.0;
1560  mtx[2][1]=0.0;
1561  mtx[2][2]=diag;
1562  }
1563 
1565  mat3(const vec3 &diag)
1566  {
1567  mtx[0][0]=diag.x;
1568  mtx[0][1]=0.0;
1569  mtx[0][2]=0.0;
1570 
1571  mtx[1][0]=0.0;
1572  mtx[1][1]=diag.y;
1573  mtx[1][2]=0.0;
1574 
1575  mtx[2][0]=0.0;
1576  mtx[2][1]=0.0;
1577  mtx[2][2]=diag.z;
1578  }
1579 
1581  mat3(const vec3 &r1,
1582  const vec3 &r2,
1583  const vec3 &r3=vec3(0,0,1))
1584  {
1585  mtx[0][0]=r1.x;
1586  mtx[0][1]=r2.x;
1587  mtx[0][2]=r3.x;
1588 
1589  mtx[1][0]=r1.y;
1590  mtx[1][1]=r2.y;
1591  mtx[1][2]=r3.y;
1592 
1593  mtx[2][0]=r1.z;
1594  mtx[2][1]=r2.z;
1595  mtx[2][2]=r3.z;
1596  }
1597 
1599  mat3(const mat2 &m)
1600  {
1601  mtx[0][0]=m[0][0];
1602  mtx[0][1]=m[0][1];
1603  mtx[0][2]=0.0;
1604 
1605  mtx[1][0]=m[1][0];
1606  mtx[1][1]=m[1][1];
1607  mtx[1][2]=0.0;
1608 
1609  mtx[2][0]=0.0;
1610  mtx[2][1]=0.0;
1611  mtx[2][2]=1.0;
1612  }
1613 
1615  mat3(const mat3f &m);
1616 
1618  static mat3 columns(const vec3 &c1,const vec3 &c2,const vec3 &c3)
1619  {
1620  return(mat3(vec3(c1.x,c2.x,c3.x),
1621  vec3(c1.y,c2.y,c3.y),
1622  vec3(c1.z,c2.z,c3.z)));
1623  }
1624 
1626  static mat3 columns(double a,double b,double c,
1627  double d,double e,double f,
1628  double g,double h,double i)
1629  {
1630  return(mat3(vec3(a,d,g),
1631  vec3(b,e,h),
1632  vec3(c,f,i)));
1633  }
1634 
1636  static mat3 rows(const vec3 &r1,const vec3 &r2,const vec3 &r3)
1637  {
1638  return(mat3(r1,
1639  r2,
1640  r3));
1641  }
1642 
1644  static mat3 rows(double a,double b,double c,
1645  double d,double e,double f,
1646  double g,double h,double i)
1647  {
1648  return(mat3(vec3(a,b,c),
1649  vec3(d,e,f),
1650  vec3(g,h,i)));
1651  }
1652 
1654  vec3 operator[] (const int i) const
1655  {
1656  assert(i>=0 && i<3);
1657  return(vec3(mtx[i][0],mtx[i][1],mtx[i][2]));
1658  }
1659 
1661  vec3 row(const int i) const
1662  {
1663  assert(i>=0 && i<3);
1664  return(vec3(mtx[0][i],mtx[1][i],mtx[2][i]));
1665  }
1666 
1668  vec3 col(const int i) const
1669  {
1670  assert(i>=0 && i<3);
1671  return(vec3(mtx[i][0],mtx[i][1],mtx[i][2]));
1672  }
1673 
1675  operator mat2() const
1676  {return(mat2(row(0).xy(),row(1).xy()));}
1677 
1679  const double *c_ptr() const
1680  {return(pointer);}
1681 
1683  operator const double *() const
1684  {return(pointer);}
1685 
1687  void fromOpenGL(const double m[9])
1688  {
1689  mtx[0][0]=m[0];
1690  mtx[0][1]=m[1];
1691  mtx[0][2]=m[2];
1692 
1693  mtx[1][0]=m[3];
1694  mtx[1][1]=m[4];
1695  mtx[1][2]=m[5];
1696 
1697  mtx[2][0]=m[6];
1698  mtx[2][1]=m[7];
1699  mtx[2][2]=m[8];
1700  }
1701 
1703  double det() const
1704  {
1705  return(mtx[0][0]*(mtx[1][1]*mtx[2][2]-mtx[2][1]*mtx[1][2])+
1706  mtx[0][1]*(mtx[2][0]*mtx[1][2]-mtx[1][0]*mtx[2][2])+
1707  mtx[0][2]*(mtx[1][0]*mtx[2][1]-mtx[2][0]*mtx[1][1]));
1708  }
1709 
1711  static double det(const mat3 &m)
1712  {return(m.det());}
1713 
1715  mat3 transpose() const
1716  {return(mat3(col(0),col(1),col(2)));}
1717 
1719  static mat3 transpose(const mat3 &m)
1720  {return(m.transpose());}
1721 
1723  mat3 invert() const
1724  {
1725  mat3 m;
1726  double d;
1727 
1728  // calculate determinant
1729  d=det();
1730 
1731  // check determinant
1732  if (d==0.0) return(mat3(0));
1733 
1734  // calculate inverse
1735  d=1.0/d;
1736  m.mtx[0][0]=d*(mtx[1][1]*mtx[2][2]-mtx[2][1]*mtx[1][2]);
1737  m.mtx[1][0]=d*(mtx[2][0]*mtx[1][2]-mtx[1][0]*mtx[2][2]);
1738  m.mtx[2][0]=d*(mtx[1][0]*mtx[2][1]-mtx[2][0]*mtx[1][1]);
1739  m.mtx[0][1]=d*(mtx[2][1]*mtx[0][2]-mtx[0][1]*mtx[2][2]);
1740  m.mtx[1][1]=d*(mtx[0][0]*mtx[2][2]-mtx[2][0]*mtx[0][2]);
1741  m.mtx[2][1]=d*(mtx[2][0]*mtx[0][1]-mtx[0][0]*mtx[2][1]);
1742  m.mtx[0][2]=d*(mtx[0][1]*mtx[1][2]-mtx[1][1]*mtx[0][2]);
1743  m.mtx[1][2]=d*(mtx[1][0]*mtx[0][2]-mtx[0][0]*mtx[1][2]);
1744  m.mtx[2][2]=d*(mtx[0][0]*mtx[1][1]-mtx[1][0]*mtx[0][1]);
1745 
1746  return(m);
1747  }
1748 
1750  static mat3 invert(const mat3 &m)
1751  {return(m.invert());}
1752 
1754  static mat3 scale(double s,double t,double r)
1755  {
1756  return(mat3(vec3(s,0,0),
1757  vec3(0,t,0),
1758  vec3(0,0,r)));
1759  }
1760 
1762  static mat3 scale(const vec3 &c)
1763  {
1764  return(mat3(vec3(c.x,0,0),
1765  vec3(0,c.y,0),
1766  vec3(0,0,c.z)));
1767  }
1768 
1771  static mat3 rotate(double angle,double vx,double vy,double vz)
1772  {
1773  return(rotate(angle,vec3(vx,vy,vz)));
1774  }
1775 
1778  static mat3 rotate(double angle,const vec3 &v)
1779  {
1780  vec3 axis;
1781  double c,s;
1782  double c1;
1783 
1784  double x,y,z;
1785 
1786  angle*=PI/180;
1787 
1788  axis=v.normalize();
1789 
1790  c=cos(angle);
1791  s=sin(angle);
1792 
1793  x=axis.x;
1794  y=axis.y;
1795  z=axis.z;
1796 
1797  c1=1.0-c;
1798 
1799  return(mat3(vec3(x*x*c1+c,x*y*c1-z*s,x*z*c1+y*s),
1800  vec3(y*x*c1+z*s,y*y*c1+c,y*z*c1-x*s),
1801  vec3(z*x*c1-y*s,z*y*c1+x*s,z*z*c1+c)));
1802  }
1803 
1806  static mat3 rotate(const vec3 &from,const vec3 &to)
1807  {
1808  vec3 axis;
1809  double c,s;
1810  double c1;
1811 
1812  double x,y,z;
1813 
1814  vec3 d1=from.normalize();
1815  vec3 d2=to.normalize();
1816  axis=d1.cross(d2);
1817 
1818  double l=axis.length();
1819  c=sqrt(1-l*l); // cos(angle);
1820  s=l; // sin(angle)
1821 
1822  if (l>0) l=1/l;
1823  x=axis.x*l;
1824  y=axis.y*l;
1825  z=axis.z*l;
1826 
1827  c1=1.0-c;
1828 
1829  return(mat3(vec3(x*x*c1+c,x*y*c1-z*s,x*z*c1+y*s),
1830  vec3(y*x*c1+z*s,y*y*c1+c,y*z*c1-x*s),
1831  vec3(z*x*c1-y*s,z*y*c1+x*s,z*z*c1+c)));
1832  }
1833 
1835  mat3& operator += (const mat3 &m);
1836 
1838  mat3& operator *= (const mat3 &m);
1839 
1841  mat3& operator <<= (const mat3 &m);
1842 
1844  mat3& operator >>= (const mat3 &m);
1845 
1847  operator std::string()
1848  {return("(" + std::string(row(0)) + ", " + std::string(row(1)) + ", " + std::string(row(2)) + ")");}
1849 
1850  protected:
1851 
1853  union {
1854  double mtx[3][3];
1855  double pointer[9];
1856  };
1857  };
1858 
1860 inline mat3 operator + (const mat3 &m1,const mat3 &m2)
1861  {
1862  return(mat3(m1[0]+m2[0],
1863  m1[1]+m2[1],
1864  m1[2]+m2[2]));
1865  }
1866 
1868 inline mat3 operator * (const mat3 &m1,const mat3 &m2)
1869  {
1870  return(mat3(vec3(m1.row(0).dot(m2[0]),m1.row(0).dot(m2[1]),m1.row(0).dot(m2[2])),
1871  vec3(m1.row(1).dot(m2[0]),m1.row(1).dot(m2[1]),m1.row(1).dot(m2[2])),
1872  vec3(m1.row(2).dot(m2[0]),m1.row(2).dot(m2[1]),m1.row(2).dot(m2[2]))));
1873  }
1874 
1876 inline mat3& mat3::operator += (const mat3 &m)
1877  {
1878  *this = (*this)+m;
1879  return(*this);
1880  }
1881 
1883 inline mat3& mat3::operator *= (const mat3 &m)
1884  {
1885  *this = (*this)*m;
1886  return(*this);
1887  }
1888 
1890 inline mat3& mat3::operator <<= (const mat3 &m)
1891  {
1892  *this = m*(*this);
1893  return(*this);
1894  }
1895 
1897 inline mat3& mat3::operator >>= (const mat3 &m)
1898  {
1899  *this = (*this)*m;
1900  return(*this);
1901  }
1902 
1904 inline bool operator == (const mat3 &a,const mat3 &b)
1905  {
1906  unsigned int i;
1907 
1908  for (i=0; i<9; i++)
1909  if (((const double *)a)[i]!=((const double *)b)[i]) return(false);
1910 
1911  return(true);
1912  }
1913 
1915 inline bool operator != (const mat3 &a,const mat3 &b)
1916  {
1917  unsigned int i;
1918 
1919  for (i=0; i<9; i++)
1920  if (((const double *)a)[i]!=((const double *)b)[i]) return(true);
1921 
1922  return(false);
1923  }
1924 
1926 inline vec3 operator * (const mat3 &m,const vec3 &v)
1927  {return(vec3(m.row(0).dot(v),m.row(1).dot(v),m.row(2).dot(v)));}
1928 
1930 inline std::ostream& operator << (std::ostream &out,const mat3 &m)
1931  {return(out << "(" << m.row(0) << ", " << m.row(1) << ", " << m.row(2) << ")");}
1932 
1939 class mat3f
1940  {
1941  public:
1942 
1944  mat3f(float diag=1.0f)
1945  {
1946  mtx[0][0]=diag;
1947  mtx[0][1]=0.0f;
1948  mtx[0][2]=0.0f;
1949 
1950  mtx[1][0]=0.0f;
1951  mtx[1][1]=diag;
1952  mtx[1][2]=0.0f;
1953 
1954  mtx[2][0]=0.0f;
1955  mtx[2][1]=0.0f;
1956  mtx[2][2]=diag;
1957  }
1958 
1960  mat3f(const vec3f &r1,
1961  const vec3f &r2,
1962  const vec3f &r3=vec3f(0,0,1))
1963  {
1964  mtx[0][0]=r1.x;
1965  mtx[0][1]=r2.x;
1966  mtx[0][2]=r3.x;
1967 
1968  mtx[1][0]=r1.y;
1969  mtx[1][1]=r2.y;
1970  mtx[1][2]=r3.y;
1971 
1972  mtx[2][0]=r1.z;
1973  mtx[2][1]=r2.z;
1974  mtx[2][2]=r3.z;
1975  }
1976 
1978  mat3f(const mat3 &m)
1979  {
1980  mtx[0][0]=(float)m[0][0];
1981  mtx[0][1]=(float)m[0][1];
1982  mtx[0][2]=(float)m[0][2];
1983 
1984  mtx[1][0]=(float)m[1][0];
1985  mtx[1][1]=(float)m[1][1];
1986  mtx[1][2]=(float)m[1][2];
1987 
1988  mtx[2][0]=(float)m[2][0];
1989  mtx[2][1]=(float)m[2][1];
1990  mtx[2][2]=(float)m[2][2];
1991  }
1992 
1994  static mat3f columns(const vec3f &c1,const vec3f &c2,const vec3f &c3)
1995  {
1996  return(mat3f(vec3f(c1.x,c2.x,c3.x),
1997  vec3f(c1.y,c2.y,c3.y),
1998  vec3f(c1.z,c2.z,c3.z)));
1999  }
2000 
2002  static mat3f columns(float a,float b,float c,
2003  float d,float e,float f,
2004  float g,float h,float i)
2005  {
2006  return(mat3f(vec3f(a,d,g),
2007  vec3f(b,e,h),
2008  vec3f(c,f,i)));
2009  }
2010 
2012  static mat3f rows(const vec3f &r1,const vec3f &r2,const vec3f &r3)
2013  {
2014  return(mat3f(r1,
2015  r2,
2016  r3));
2017  }
2018 
2020  static mat3f rows(float a,float b,float c,
2021  float d,float e,float f,
2022  float g,float h,float i)
2023  {
2024  return(mat3f(vec3f(a,b,c),
2025  vec3f(d,e,f),
2026  vec3f(g,h,i)));
2027  }
2028 
2030  vec3f operator[] (const int i) const
2031  {
2032  assert(i>=0 && i<3);
2033  return(vec3f(mtx[i][0],mtx[i][1],mtx[i][2]));
2034  }
2035 
2037  vec3f row(const int i) const
2038  {
2039  assert(i>=0 && i<3);
2040  return(vec3f(mtx[0][i],mtx[1][i],mtx[2][i]));
2041  }
2042 
2044  vec3f col(const int i) const
2045  {
2046  assert(i>=0 && i<3);
2047  return(vec3f(mtx[i][0],mtx[i][1],mtx[i][2]));
2048  }
2049 
2051  operator mat2f() const
2052  {return(mat2f(row(0).xy(),row(1).xy()));}
2053 
2055  const float *c_ptr() const
2056  {return(pointer);}
2057 
2059  operator const float *() const
2060  {return(pointer);}
2061 
2063  void fromOpenGL(const float m[9])
2064  {
2065  mtx[0][0]=m[0];
2066  mtx[0][1]=m[1];
2067  mtx[0][2]=m[2];
2068 
2069  mtx[1][0]=m[3];
2070  mtx[1][1]=m[4];
2071  mtx[1][2]=m[5];
2072 
2073  mtx[2][0]=m[6];
2074  mtx[2][1]=m[7];
2075  mtx[2][2]=m[8];
2076  }
2077 
2079  operator std::string()
2080  {return("(" + std::string(row(0)) + ", " + std::string(row(1)) + ", " + std::string(row(2)) + ")");}
2081 
2082  protected:
2083 
2085  union {
2086  float mtx[3][3];
2087  float pointer[9];
2088  };
2089  };
2090 
2092 inline std::ostream& operator << (std::ostream &out,const mat3f &m)
2093  {return(out << "(" << m.row(0) << ", " << m.row(1) << ", " << m.row(2) << ")");}
2094 
2096 inline mat3::mat3(const mat3f &m)
2097  {
2098  mtx[0][0]=m[0][0];
2099  mtx[0][1]=m[0][1];
2100  mtx[0][2]=m[0][2];
2101 
2102  mtx[1][0]=m[1][0];
2103  mtx[1][1]=m[1][1];
2104  mtx[1][2]=m[1][2];
2105 
2106  mtx[2][0]=m[2][0];
2107  mtx[2][1]=m[2][1];
2108  mtx[2][2]=m[2][2];
2109  }
2110 
2111 class mat4f;
2112 
2116 class mat4
2117  {
2118  public:
2119 
2121  mat4(double diag=1.0)
2122  {
2123  mtx[0][0]=diag;
2124  mtx[0][1]=0.0;
2125  mtx[0][2]=0.0;
2126  mtx[0][3]=0.0;
2127 
2128  mtx[1][0]=0.0;
2129  mtx[1][1]=diag;
2130  mtx[1][2]=0.0;
2131  mtx[1][3]=0.0;
2132 
2133  mtx[2][0]=0.0;
2134  mtx[2][1]=0.0;
2135  mtx[2][2]=diag;
2136  mtx[2][3]=0.0;
2137 
2138  mtx[3][0]=0.0;
2139  mtx[3][1]=0.0;
2140  mtx[3][2]=0.0;
2141  mtx[3][3]=diag;
2142  }
2143 
2145  mat4(const vec4 &diag)
2146  {
2147  mtx[0][0]=diag.x;
2148  mtx[0][1]=0.0;
2149  mtx[0][2]=0.0;
2150  mtx[0][3]=0.0;
2151 
2152  mtx[1][0]=0.0;
2153  mtx[1][1]=diag.y;
2154  mtx[1][2]=0.0;
2155  mtx[1][3]=0.0;
2156 
2157  mtx[2][0]=0.0;
2158  mtx[2][1]=0.0;
2159  mtx[2][2]=diag.z;
2160  mtx[2][3]=0.0;
2161 
2162  mtx[3][0]=0.0;
2163  mtx[3][1]=0.0;
2164  mtx[3][2]=0.0;
2165  mtx[3][3]=diag.w;
2166  }
2167 
2169  mat4(const vec4 &r1,
2170  const vec4 &r2,
2171  const vec4 &r3,
2172  const vec4 &r4=vec4(0,0,0,1))
2173  {
2174  mtx[0][0]=r1.x;
2175  mtx[0][1]=r2.x;
2176  mtx[0][2]=r3.x;
2177  mtx[0][3]=r4.x;
2178 
2179  mtx[1][0]=r1.y;
2180  mtx[1][1]=r2.y;
2181  mtx[1][2]=r3.y;
2182  mtx[1][3]=r4.y;
2183 
2184  mtx[2][0]=r1.z;
2185  mtx[2][1]=r2.z;
2186  mtx[2][2]=r3.z;
2187  mtx[2][3]=r4.z;
2188 
2189  mtx[3][0]=r1.w;
2190  mtx[3][1]=r2.w;
2191  mtx[3][2]=r3.w;
2192  mtx[3][3]=r4.w;
2193  }
2194 
2196  mat4(const mat3 &m)
2197  {
2198  mtx[0][0]=m[0][0];
2199  mtx[0][1]=m[0][1];
2200  mtx[0][2]=m[0][2];
2201  mtx[0][3]=0.0;
2202 
2203  mtx[1][0]=m[1][0];
2204  mtx[1][1]=m[1][1];
2205  mtx[1][2]=m[1][2];
2206  mtx[1][3]=0.0;
2207 
2208  mtx[2][0]=m[2][0];
2209  mtx[2][1]=m[2][1];
2210  mtx[2][2]=m[2][2];
2211  mtx[2][3]=0.0;
2212 
2213  mtx[3][0]=0.0;
2214  mtx[3][1]=0.0;
2215  mtx[3][2]=0.0;
2216  mtx[3][3]=1.0;
2217  }
2218 
2220  mat4(const mat4f &m);
2221 
2223  static mat4 columns(const vec4 &c1,const vec4 &c2,const vec4 &c3,const vec4 &c4)
2224  {
2225  return(mat4(vec4(c1.x,c2.x,c3.x,c4.x),
2226  vec4(c1.y,c2.y,c3.y,c4.y),
2227  vec4(c1.z,c2.z,c3.z,c4.z),
2228  vec4(c1.w,c2.w,c3.w,c4.w)));
2229  }
2230 
2232  static mat4 columns(double a,double b,double c,double d,
2233  double e,double f,double g,double h,
2234  double i,double j,double k,double l,
2235  double m,double n,double o,double p)
2236  {
2237  return(mat4(vec4(a,e,i,m),
2238  vec4(b,f,j,n),
2239  vec4(c,g,k,o),
2240  vec4(d,h,l,p)));
2241  }
2242 
2244  static mat4 rows(const vec4 &r1,const vec4 &r2,const vec4 &r3,const vec4 &r4)
2245  {
2246  return(mat4(r1,
2247  r2,
2248  r3,
2249  r4));
2250  }
2251 
2253  static mat4 rows(double a,double b,double c,double d,
2254  double e,double f,double g,double h,
2255  double i,double j,double k,double l,
2256  double m,double n,double o,double p)
2257  {
2258  return(mat4(vec4(a,b,c,d),
2259  vec4(e,f,g,h),
2260  vec4(i,j,k,l),
2261  vec4(m,n,o,p)));
2262  }
2263 
2265  vec4 operator[] (const int i) const
2266  {
2267  assert(i>=0 && i<4);
2268  return(vec4(mtx[i][0],mtx[i][1],mtx[i][2],mtx[i][3]));
2269  }
2270 
2272  vec4 row(const int i) const
2273  {
2274  assert(i>=0 && i<4);
2275  return(vec4(mtx[0][i],mtx[1][i],mtx[2][i],mtx[3][i]));
2276  }
2277 
2279  vec4 col(const int i) const
2280  {
2281  assert(i>=0 && i<4);
2282  return(vec4(mtx[i][0],mtx[i][1],mtx[i][2],mtx[i][3]));
2283  }
2284 
2286  operator mat3() const
2287  {return(mat3(row(0).xyz(),row(1).xyz(),row(2).xyz()));}
2288 
2291  {return(mat3(*this));}
2292 
2295  {return(col(3));}
2296 
2298  const double *c_ptr() const
2299  {return(pointer);}
2300 
2302  operator const double *() const
2303  {return(pointer);}
2304 
2306  void fromOpenGL(const double m[16])
2307  {
2308  mtx[0][0]=m[0];
2309  mtx[0][1]=m[1];
2310  mtx[0][2]=m[2];
2311  mtx[0][3]=m[3];
2312 
2313  mtx[1][0]=m[4];
2314  mtx[1][1]=m[5];
2315  mtx[1][2]=m[6];
2316  mtx[1][3]=m[7];
2317 
2318  mtx[2][0]=m[8];
2319  mtx[2][1]=m[9];
2320  mtx[2][2]=m[10];
2321  mtx[2][3]=m[11];
2322 
2323  mtx[3][0]=m[12];
2324  mtx[3][1]=m[13];
2325  mtx[3][2]=m[14];
2326  mtx[3][3]=m[15];
2327  }
2328 
2330  double det() const
2331  {
2332  return(mtx[0][3]*mtx[1][2]*mtx[2][1]*mtx[3][0]-
2333  mtx[0][2]*mtx[1][3]*mtx[2][1]*mtx[3][0]-
2334  mtx[0][3]*mtx[1][1]*mtx[2][2]*mtx[3][0]+
2335  mtx[0][1]*mtx[1][3]*mtx[2][2]*mtx[3][0]+
2336  mtx[0][2]*mtx[1][1]*mtx[2][3]*mtx[3][0]-
2337  mtx[0][1]*mtx[1][2]*mtx[2][3]*mtx[3][0]-
2338  mtx[0][3]*mtx[1][2]*mtx[2][0]*mtx[3][1]+
2339  mtx[0][2]*mtx[1][3]*mtx[2][0]*mtx[3][1]+
2340  mtx[0][3]*mtx[1][0]*mtx[2][2]*mtx[3][1]-
2341  mtx[0][0]*mtx[1][3]*mtx[2][2]*mtx[3][1]-
2342  mtx[0][2]*mtx[1][0]*mtx[2][3]*mtx[3][1]+
2343  mtx[0][0]*mtx[1][2]*mtx[2][3]*mtx[3][1]+
2344  mtx[0][3]*mtx[1][1]*mtx[2][0]*mtx[3][2]-
2345  mtx[0][1]*mtx[1][3]*mtx[2][0]*mtx[3][2]-
2346  mtx[0][3]*mtx[1][0]*mtx[2][1]*mtx[3][2]+
2347  mtx[0][0]*mtx[1][3]*mtx[2][1]*mtx[3][2]+
2348  mtx[0][1]*mtx[1][0]*mtx[2][3]*mtx[3][2]-
2349  mtx[0][0]*mtx[1][1]*mtx[2][3]*mtx[3][2]-
2350  mtx[0][2]*mtx[1][1]*mtx[2][0]*mtx[3][3]+
2351  mtx[0][1]*mtx[1][2]*mtx[2][0]*mtx[3][3]+
2352  mtx[0][2]*mtx[1][0]*mtx[2][1]*mtx[3][3]-
2353  mtx[0][0]*mtx[1][2]*mtx[2][1]*mtx[3][3]-
2354  mtx[0][1]*mtx[1][0]*mtx[2][2]*mtx[3][3]+
2355  mtx[0][0]*mtx[1][1]*mtx[2][2]*mtx[3][3]);
2356  }
2357 
2359  static double det(const mat4 &m)
2360  {return(m.det());}
2361 
2363  mat4 transpose() const
2364  {return(mat4(col(0),col(1),col(2),col(3)));}
2365 
2367  static mat4 transpose(const mat4 &m)
2368  {return(m.transpose());}
2369 
2371  mat4 invert() const
2372  {
2373  mat4 m;
2374  double d;
2375 
2376  // calculate determinant
2377  d=det();
2378 
2379  // check determinant
2380  if (d==0.0) return(mat4(0));
2381 
2382  // calculate inverse
2383  d=1.0/d;
2384  m.mtx[0][0]=d*(mtx[1][2]*mtx[2][3]*mtx[3][1]-mtx[1][3]*mtx[2][2]*mtx[3][1]+mtx[1][3]*mtx[2][1]*mtx[3][2]-mtx[1][1]*mtx[2][3]*mtx[3][2]-mtx[1][2]*mtx[2][1]*mtx[3][3]+mtx[1][1]*mtx[2][2]*mtx[3][3]);
2385  m.mtx[0][1]=d*(mtx[0][3]*mtx[2][2]*mtx[3][1]-mtx[0][2]*mtx[2][3]*mtx[3][1]-mtx[0][3]*mtx[2][1]*mtx[3][2]+mtx[0][1]*mtx[2][3]*mtx[3][2]+mtx[0][2]*mtx[2][1]*mtx[3][3]-mtx[0][1]*mtx[2][2]*mtx[3][3]);
2386  m.mtx[0][2]=d*(mtx[0][2]*mtx[1][3]*mtx[3][1]-mtx[0][3]*mtx[1][2]*mtx[3][1]+mtx[0][3]*mtx[1][1]*mtx[3][2]-mtx[0][1]*mtx[1][3]*mtx[3][2]-mtx[0][2]*mtx[1][1]*mtx[3][3]+mtx[0][1]*mtx[1][2]*mtx[3][3]);
2387  m.mtx[0][3]=d*(mtx[0][3]*mtx[1][2]*mtx[2][1]-mtx[0][2]*mtx[1][3]*mtx[2][1]-mtx[0][3]*mtx[1][1]*mtx[2][2]+mtx[0][1]*mtx[1][3]*mtx[2][2]+mtx[0][2]*mtx[1][1]*mtx[2][3]-mtx[0][1]*mtx[1][2]*mtx[2][3]);
2388  m.mtx[1][0]=d*(mtx[1][3]*mtx[2][2]*mtx[3][0]-mtx[1][2]*mtx[2][3]*mtx[3][0]-mtx[1][3]*mtx[2][0]*mtx[3][2]+mtx[1][0]*mtx[2][3]*mtx[3][2]+mtx[1][2]*mtx[2][0]*mtx[3][3]-mtx[1][0]*mtx[2][2]*mtx[3][3]);
2389  m.mtx[1][1]=d*(mtx[0][2]*mtx[2][3]*mtx[3][0]-mtx[0][3]*mtx[2][2]*mtx[3][0]+mtx[0][3]*mtx[2][0]*mtx[3][2]-mtx[0][0]*mtx[2][3]*mtx[3][2]-mtx[0][2]*mtx[2][0]*mtx[3][3]+mtx[0][0]*mtx[2][2]*mtx[3][3]);
2390  m.mtx[1][2]=d*(mtx[0][3]*mtx[1][2]*mtx[3][0]-mtx[0][2]*mtx[1][3]*mtx[3][0]-mtx[0][3]*mtx[1][0]*mtx[3][2]+mtx[0][0]*mtx[1][3]*mtx[3][2]+mtx[0][2]*mtx[1][0]*mtx[3][3]-mtx[0][0]*mtx[1][2]*mtx[3][3]);
2391  m.mtx[1][3]=d*(mtx[0][2]*mtx[1][3]*mtx[2][0]-mtx[0][3]*mtx[1][2]*mtx[2][0]+mtx[0][3]*mtx[1][0]*mtx[2][2]-mtx[0][0]*mtx[1][3]*mtx[2][2]-mtx[0][2]*mtx[1][0]*mtx[2][3]+mtx[0][0]*mtx[1][2]*mtx[2][3]);
2392  m.mtx[2][0]=d*(mtx[1][1]*mtx[2][3]*mtx[3][0]-mtx[1][3]*mtx[2][1]*mtx[3][0]+mtx[1][3]*mtx[2][0]*mtx[3][1]-mtx[1][0]*mtx[2][3]*mtx[3][1]-mtx[1][1]*mtx[2][0]*mtx[3][3]+mtx[1][0]*mtx[2][1]*mtx[3][3]);
2393  m.mtx[2][1]=d*(mtx[0][3]*mtx[2][1]*mtx[3][0]-mtx[0][1]*mtx[2][3]*mtx[3][0]-mtx[0][3]*mtx[2][0]*mtx[3][1]+mtx[0][0]*mtx[2][3]*mtx[3][1]+mtx[0][1]*mtx[2][0]*mtx[3][3]-mtx[0][0]*mtx[2][1]*mtx[3][3]);
2394  m.mtx[2][2]=d*(mtx[0][1]*mtx[1][3]*mtx[3][0]-mtx[0][3]*mtx[1][1]*mtx[3][0]+mtx[0][3]*mtx[1][0]*mtx[3][1]-mtx[0][0]*mtx[1][3]*mtx[3][1]-mtx[0][1]*mtx[1][0]*mtx[3][3]+mtx[0][0]*mtx[1][1]*mtx[3][3]);
2395  m.mtx[2][3]=d*(mtx[0][3]*mtx[1][1]*mtx[2][0]-mtx[0][1]*mtx[1][3]*mtx[2][0]-mtx[0][3]*mtx[1][0]*mtx[2][1]+mtx[0][0]*mtx[1][3]*mtx[2][1]+mtx[0][1]*mtx[1][0]*mtx[2][3]-mtx[0][0]*mtx[1][1]*mtx[2][3]);
2396  m.mtx[3][0]=d*(mtx[1][2]*mtx[2][1]*mtx[3][0]-mtx[1][1]*mtx[2][2]*mtx[3][0]-mtx[1][2]*mtx[2][0]*mtx[3][1]+mtx[1][0]*mtx[2][2]*mtx[3][1]+mtx[1][1]*mtx[2][0]*mtx[3][2]-mtx[1][0]*mtx[2][1]*mtx[3][2]);
2397  m.mtx[3][1]=d*(mtx[0][1]*mtx[2][2]*mtx[3][0]-mtx[0][2]*mtx[2][1]*mtx[3][0]+mtx[0][2]*mtx[2][0]*mtx[3][1]-mtx[0][0]*mtx[2][2]*mtx[3][1]-mtx[0][1]*mtx[2][0]*mtx[3][2]+mtx[0][0]*mtx[2][1]*mtx[3][2]);
2398  m.mtx[3][2]=d*(mtx[0][2]*mtx[1][1]*mtx[3][0]-mtx[0][1]*mtx[1][2]*mtx[3][0]-mtx[0][2]*mtx[1][0]*mtx[3][1]+mtx[0][0]*mtx[1][2]*mtx[3][1]+mtx[0][1]*mtx[1][0]*mtx[3][2]-mtx[0][0]*mtx[1][1]*mtx[3][2]);
2399  m.mtx[3][3]=d*(mtx[0][1]*mtx[1][2]*mtx[2][0]-mtx[0][2]*mtx[1][1]*mtx[2][0]+mtx[0][2]*mtx[1][0]*mtx[2][1]-mtx[0][0]*mtx[1][2]*mtx[2][1]-mtx[0][1]*mtx[1][0]*mtx[2][2]+mtx[0][0]*mtx[1][1]*mtx[2][2]);
2400 
2401  return(m);
2402  }
2403 
2405  static mat4 invert(const mat4 &m)
2406  {return(m.invert());}
2407 
2409  static mat4 scale(double s,double t,double r,double w=1.0)
2410  {
2411  return(mat4(vec4(s,0,0,0),
2412  vec4(0,t,0,0),
2413  vec4(0,0,r,0),
2414  vec4(0,0,0,w)));
2415  }
2416 
2418  static mat4 scale(const vec4 &c)
2419  {
2420  return(mat4(vec4(c.x,0,0,0),
2421  vec4(0,c.y,0,0),
2422  vec4(0,0,c.z,0),
2423  vec4(0,0,0,c.w)));
2424  }
2425 
2427  static mat4 translate(double x,double y,double z)
2428  {
2429  return(mat4(vec4(1,0,0,x),
2430  vec4(0,1,0,y),
2431  vec4(0,0,1,z),
2432  vec4(0,0,0,1)));
2433  }
2434 
2436  static mat4 translate(const vec4 &v)
2437  {
2438  return(mat4(vec4(1,0,0,v.x),
2439  vec4(0,1,0,v.y),
2440  vec4(0,0,1,v.z),
2441  vec4(0,0,0,v.w)));
2442  }
2443 
2446  static mat4 rotate(double angle,double vx,double vy,double vz)
2447  {return(mat3::rotate(angle,vx,vy,vz));}
2448 
2451  static mat4 rotate(double angle,const vec3 &v)
2452  {return(mat3::rotate(angle,v));}
2453 
2456  static mat4 rotate(const vec3 &from,const vec3 &to)
2457  {return(mat3::rotate(from,to));}
2458 
2463  static mat4 rigid(double a,const vec3 &v,const vec3 &t)
2464  {return(transform(mat3::rotate(a,v),t));}
2465 
2469  static mat4 transform(const mat3 &m,const vec3 &v);
2470 
2474  static mat4 transform(const vec3 &o,const vec3 &x,const vec3 &y,const vec3 &z);
2475 
2480  static mat4 transform(const vec3 &from,const vec3 &to,const vec3 &up=vec3(0,1,0),bool scale=true);
2481 
2483  static mat4 ortho(double l,double r,double b,double t,double n=-1,double f=1);
2484 
2486  static mat4 frustum(double l,double r,double b,double t,double n,double f);
2487 
2489  static mat4 parallel(const vec3 &p,const vec3 &n,const vec3 &d);
2490 
2492  static mat4 perspective(double fovy,double aspect,double znear,double zfar);
2493 
2495  static mat4 lookat(const vec3 &eye,const vec3 &center,const vec3 &up=vec3(0,1,0));
2496 
2498  mat4& operator += (const mat4 &m);
2499 
2501  mat4& operator *= (const mat4 &m);
2502 
2504  mat4& operator <<= (const mat4 &m);
2505 
2507  mat4& operator >>= (const mat4 &m);
2508 
2510  operator std::string()
2511  {return("(" + std::string(row(0)) + ", " + std::string(row(1)) + ", " + std::string(row(2)) + ", " + std::string(row(3)) + ")");}
2512 
2513  protected:
2514 
2516  union {
2517  double mtx[4][4];
2518  double pointer[16];
2519  };
2520  };
2521 
2523 inline mat4 operator + (const mat4 &m1,const mat4 &m2)
2524  {
2525  return(mat4(m1[0]+m2[0],
2526  m1[1]+m2[1],
2527  m1[2]+m2[2],
2528  m1[3]+m2[3]));
2529  }
2530 
2532 inline mat4 operator * (const mat4 &m1,const mat4 &m2)
2533  {
2534  return(mat4(vec4(m1.row(0).dot(m2[0]),m1.row(0).dot(m2[1]),m1.row(0).dot(m2[2]),m1.row(0).dot(m2[3])),
2535  vec4(m1.row(1).dot(m2[0]),m1.row(1).dot(m2[1]),m1.row(1).dot(m2[2]),m1.row(1).dot(m2[3])),
2536  vec4(m1.row(2).dot(m2[0]),m1.row(2).dot(m2[1]),m1.row(2).dot(m2[2]),m1.row(2).dot(m2[3])),
2537  vec4(m1.row(3).dot(m2[0]),m1.row(3).dot(m2[1]),m1.row(3).dot(m2[2]),m1.row(3).dot(m2[3]))));
2538  }
2539 
2541 inline mat4& mat4::operator += (const mat4 &m)
2542  {
2543  *this = (*this)+m;
2544  return(*this);
2545  }
2546 
2548 inline mat4& mat4::operator *= (const mat4 &m)
2549  {
2550  *this = (*this)*m;
2551  return(*this);
2552  }
2553 
2555 inline mat4& mat4::operator <<= (const mat4 &m)
2556  {
2557  *this = m*(*this);
2558  return(*this);
2559  }
2560 
2562 inline mat4& mat4::operator >>= (const mat4 &m)
2563  {
2564  *this = (*this)*m;
2565  return(*this);
2566  }
2567 
2569 inline bool operator == (const mat4 &a,const mat4 &b)
2570  {
2571  unsigned int i;
2572 
2573  for (i=0; i<16; i++)
2574  if (((const double *)a)[i]!=((const double *)b)[i]) return(false);
2575 
2576  return(true);
2577  }
2578 
2580 inline bool operator != (const mat4 &a,const mat4 &b)
2581  {
2582  unsigned int i;
2583 
2584  for (i=0; i<16; i++)
2585  if (((const double *)a)[i]!=((const double *)b)[i]) return(true);
2586 
2587  return(false);
2588  }
2589 
2591 inline mat4 scale(const mat4 &m,const vec4 &c)
2592  {return(m*mat4::scale(c));}
2593 
2595 inline mat4 scale(const mat4 &m,double s,double t,double r,double w=1)
2596  {return(scale(m,vec4(s,t,r,w)));}
2597 
2599 inline mat4 scale(const mat4 &m,double s,double w=1)
2600  {return(scale(m,vec4(s,s,s,w)));}
2601 
2603 inline mat4 translate(const mat4 &m,const vec4 &v)
2604  {return(m*mat4::translate(v));}
2605 
2607 inline mat4 translate(const mat4 &m,double x,double y,double z,double w=1)
2608  {return(translate(m,vec4(x,y,z,w)));}
2609 
2611 inline mat4 rotate(const mat4 &m,double angle,const vec3 &v)
2612  {return(m*mat4::rotate(angle,v));}
2613 
2615 inline mat4 rotate(const mat4 &m,double angle,double vx,double vy,double vz)
2616  {return(rotate(m,angle,vec3(vx,vy,vz)));}
2617 
2619 inline mat4 rotate(const mat4 &m,const vec3 &from,const vec3 &to)
2620  {return(m*mat4::rotate(from,to));}
2621 
2623 inline double determinant(const mat4 &m)
2624  {return(m.det());}
2625 
2627 inline mat4 transpose(const mat4 &m)
2628  {return(m.transpose());}
2629 
2631 inline mat4 inverse(const mat4 &m)
2632  {return(m.invert());}
2633 
2635 inline mat4 inverse_transpose(const mat4 &m)
2636  {return(m.invert().transpose());}
2637 
2639 inline vec4 operator * (const mat4 &m,const vec4 &v)
2640  {return(vec4(m.row(0).dot(v),m.row(1).dot(v),m.row(2).dot(v),m.row(3).dot(v)));}
2641 
2643 inline std::ostream& operator << (std::ostream &out,const mat4 &m)
2644  {return(out << "(" << m.row(0) << ", " << m.row(1) << ", " << m.row(2) << ", " << m.row(3) << ")");}
2645 
2647 inline mat4 mat4::transform(const mat3 &m,const vec3 &v)
2648  {
2649  return(mat4(vec4(m.row(0),v[0]),
2650  vec4(m.row(1),v[1]),
2651  vec4(m.row(2),v[2]),
2652  vec4(0,0,0,1)));
2653  }
2654 
2656 inline mat4 mat4::transform(const vec3 &o,const vec3 &x,const vec3 &y,const vec3 &z)
2657  {
2658  return(mat4(vec4(x,0),
2659  vec4(y,0),
2660  vec4(z,0),
2661  vec4(o,1)).transpose());
2662  }
2663 
2665 inline mat4 mat4::transform(const vec3 &from,const vec3 &to,const vec3 &up,bool scale)
2666  {
2667  vec3 d = (to-from).normalize();
2668  vec3 r = up.cross(d).normalize();
2669  vec3 u = d.cross(r).normalize();
2670 
2671  if (scale) d *= (to-from).length();
2672 
2673  return(mat4::transform(0.5*(from+to),r,u,d));
2674  }
2675 
2677 inline mat4 mat4::ortho(double l,double r,double b,double t,double n,double f)
2678  {
2679  assert(r!=l && t!=b && f!=n);
2680 
2681  return(mat4(vec4(2.0/(r-l),0,0,-(r+l)/(r-l)),
2682  vec4(0,2.0/(t-b),0,-(t+b)/(t-b)),
2683  vec4(0,0,-2.0/(f-n),-(f+n)/(f-n))));
2684  }
2685 
2687 inline mat4 mat4::frustum(double l,double r,double b,double t,double n,double f)
2688  {
2689  assert(r>l && t>b && f>n && n>0 && f>0);
2690 
2691  return(mat4(vec4(2.0*n/(r-l),0,(r+l)/(r-l),0),
2692  vec4(0,2.0*n/(t-b),(t+b)/(t-b),0),
2693  vec4(0,0,-(f+n)/(f-n),-2.0*f*n/(f-n)),
2694  vec4(0,0,-1,0)));
2695  }
2696 
2698 inline mat4 mat4::parallel(const vec3 &p,const vec3 &n,const vec3 &d)
2699  {
2700  double A = n.x;
2701  double B = n.y;
2702  double C = n.z;
2703  double D = -p.dot(n);
2704 
2705  return(mat4(vec4(B*d.y+C*d.z,-B*d.x ,-C*d.x ,-D*d.x),
2706  vec4(-A*d.y ,A*d.x+C*d.z,-C*d.y ,-D*d.y),
2707  vec4(-A*d.z ,-B*d.z ,A*d.x+B*d.y,-D*d.z),
2708  vec4(0 ,0 ,0 ,A*d.x+B*d.y+C*d.z)));
2709  }
2710 
2712 inline mat4 mat4::perspective(double fovy,double aspect,double znear,double zfar)
2713  {
2714  double f;
2715 
2716  fovy*=PI/180;
2717 
2718  assert(fovy>0.0 && fovy<PI);
2719  assert(znear>0.0 && zfar>znear);
2720  assert(aspect>0.0);
2721 
2722  f=1.0/tan(0.5*fovy);
2723 
2724  return(mat4(vec4(f/aspect,0,0,0),
2725  vec4(0,f,0,0),
2726  vec4(0,0,(zfar+znear)/(znear-zfar),(2*zfar*znear)/(znear-zfar)),
2727  vec4(0,0,-1,0)));
2728  }
2729 
2731 inline mat4 mat4::lookat(const vec3 &eye,const vec3 &center,const vec3 &up)
2732  {
2733  vec3 dir,right,top;
2734 
2735  dir=(center-eye).normalize();
2736  top=up.normalize();
2737 
2738  if (dir==vec3(0) || top==vec3(0)) return(mat4(1));
2739 
2740  right=dir.cross(top).normalize();
2741  top=right.cross(dir);
2742 
2743  return(mat4(vec4(right,0),vec4(top,0),vec4(-dir,0))*translate(-eye));
2744  }
2745 
2752 class mat4f
2753  {
2754  public:
2755 
2757  mat4f(float diag=1.0f)
2758  {
2759  mtx[0][0]=diag;
2760  mtx[0][1]=0.0f;
2761  mtx[0][2]=0.0f;
2762  mtx[0][3]=0.0f;
2763 
2764  mtx[1][0]=0.0f;
2765  mtx[1][1]=diag;
2766  mtx[1][2]=0.0f;
2767  mtx[1][3]=0.0f;
2768 
2769  mtx[2][0]=0.0f;
2770  mtx[2][1]=0.0f;
2771  mtx[2][2]=diag;
2772  mtx[2][3]=0.0f;
2773 
2774  mtx[3][0]=0.0f;
2775  mtx[3][1]=0.0f;
2776  mtx[3][2]=0.0f;
2777  mtx[3][3]=diag;
2778  }
2779 
2781  mat4f(const vec4f &r1,
2782  const vec4f &r2,
2783  const vec4f &r3,
2784  const vec4f &r4=vec4f(0,0,0,1))
2785  {
2786  mtx[0][0]=r1.x;
2787  mtx[0][1]=r2.x;
2788  mtx[0][2]=r3.x;
2789  mtx[0][3]=r4.x;
2790 
2791  mtx[1][0]=r1.y;
2792  mtx[1][1]=r2.y;
2793  mtx[1][2]=r3.y;
2794  mtx[1][3]=r4.y;
2795 
2796  mtx[2][0]=r1.z;
2797  mtx[2][1]=r2.z;
2798  mtx[2][2]=r3.z;
2799  mtx[2][3]=r4.z;
2800 
2801  mtx[3][0]=r1.w;
2802  mtx[3][1]=r2.w;
2803  mtx[3][2]=r3.w;
2804  mtx[3][3]=r4.w;
2805  }
2806 
2808  mat4f(const mat4 &m)
2809  {
2810  mtx[0][0]=(float)m[0][0];
2811  mtx[0][1]=(float)m[0][1];
2812  mtx[0][2]=(float)m[0][2];
2813  mtx[0][3]=(float)m[0][3];
2814 
2815  mtx[1][0]=(float)m[1][0];
2816  mtx[1][1]=(float)m[1][1];
2817  mtx[1][2]=(float)m[1][2];
2818  mtx[1][3]=(float)m[1][3];
2819 
2820  mtx[2][0]=(float)m[2][0];
2821  mtx[2][1]=(float)m[2][1];
2822  mtx[2][2]=(float)m[2][2];
2823  mtx[2][3]=(float)m[2][3];
2824 
2825  mtx[3][0]=(float)m[3][0];
2826  mtx[3][1]=(float)m[3][1];
2827  mtx[3][2]=(float)m[3][2];
2828  mtx[3][3]=(float)m[3][3];
2829  }
2830 
2832  static mat4f columns(const vec4f &c1,const vec4f &c2,const vec4f &c3,const vec4f &c4)
2833  {
2834  return(mat4f(vec4f(c1.x,c2.x,c3.x,c4.x),
2835  vec4f(c1.y,c2.y,c3.y,c4.y),
2836  vec4f(c1.z,c2.z,c3.z,c4.z),
2837  vec4f(c1.w,c2.w,c3.w,c4.w)));
2838  }
2839 
2841  static mat4f columns(float a,float b,float c,float d,
2842  float e,float f,float g,float h,
2843  float i,float j,float k,float l,
2844  float m,float n,float o,float p)
2845  {
2846  return(mat4f(vec4f(a,e,i,m),
2847  vec4f(b,f,j,n),
2848  vec4f(c,g,k,o),
2849  vec4f(d,h,l,p)));
2850  }
2851 
2853  static mat4f rows(const vec4f &r1,const vec4f &r2,const vec4f &r3,const vec4f &r4)
2854  {
2855  return(mat4f(r1,
2856  r2,
2857  r3,
2858  r4));
2859  }
2860 
2862  static mat4f rows(float a,float b,float c,float d,
2863  float e,float f,float g,float h,
2864  float i,float j,float k,float l,
2865  float m,float n,float o,float p)
2866  {
2867  return(mat4f(vec4f(a,b,c,d),
2868  vec4f(e,f,g,h),
2869  vec4f(i,j,k,l),
2870  vec4f(m,n,o,p)));
2871  }
2872 
2874  vec4f operator[] (const int i) const
2875  {
2876  assert(i>=0 && i<4);
2877  return(vec4f(mtx[i][0],mtx[i][1],mtx[i][2],mtx[i][3]));
2878  }
2879 
2881  vec4f row(const int i) const
2882  {
2883  assert(i>=0 && i<4);
2884  return(vec4f(mtx[0][i],mtx[1][i],mtx[2][i],mtx[3][i]));
2885  }
2886 
2888  vec4f col(const int i) const
2889  {
2890  assert(i>=0 && i<4);
2891  return(vec4f(mtx[i][0],mtx[i][1],mtx[i][2],mtx[i][3]));
2892  }
2893 
2895  operator mat3f() const
2896  {return(mat3f(row(0).xyz(),row(1).xyz(),row(2).xyz()));}
2897 
2899  const float *c_ptr() const
2900  {return(pointer);}
2901 
2903  operator const float *() const
2904  {return(pointer);}
2905 
2907  void fromOpenGL(const float m[16])
2908  {
2909  mtx[0][0]=m[0];
2910  mtx[0][1]=m[1];
2911  mtx[0][2]=m[2];
2912  mtx[0][3]=m[3];
2913 
2914  mtx[1][0]=m[4];
2915  mtx[1][1]=m[5];
2916  mtx[1][2]=m[6];
2917  mtx[1][3]=m[7];
2918 
2919  mtx[2][0]=m[8];
2920  mtx[2][1]=m[9];
2921  mtx[2][2]=m[10];
2922  mtx[2][3]=m[11];
2923 
2924  mtx[3][0]=m[12];
2925  mtx[3][1]=m[13];
2926  mtx[3][2]=m[14];
2927  mtx[3][3]=m[15];
2928  }
2929 
2931  operator std::string()
2932  {return("(" + std::string(row(0)) + ", " + std::string(row(1)) + ", " + std::string(row(2)) + ", " + std::string(row(3)) + ")");}
2933 
2934  protected:
2935 
2937  union {
2938  float mtx[4][4];
2939  float pointer[16];
2940  };
2941  };
2942 
2944 inline std::ostream& operator << (std::ostream &out,const mat4f &m)
2945  {return(out << "(" << m.row(0) << ", " << m.row(1) << ", " << m.row(2) << ", " << m.row(3) << ")");}
2946 
2948 inline mat4::mat4(const mat4f &m)
2949  {
2950  mtx[0][0]=m[0][0];
2951  mtx[0][1]=m[0][1];
2952  mtx[0][2]=m[0][2];
2953  mtx[0][3]=m[0][3];
2954 
2955  mtx[1][0]=m[1][0];
2956  mtx[1][1]=m[1][1];
2957  mtx[1][2]=m[1][2];
2958  mtx[1][3]=m[1][3];
2959 
2960  mtx[2][0]=m[2][0];
2961  mtx[2][1]=m[2][1];
2962  mtx[2][2]=m[2][2];
2963  mtx[2][3]=m[2][3];
2964 
2965  mtx[3][0]=m[3][0];
2966  mtx[3][1]=m[3][1];
2967  mtx[3][2]=m[3][2];
2968  mtx[3][3]=m[3][3];
2969  }
2970 
2972 class quat
2973  {
2974  public:
2975 
2977  quat(const vec4 &v=vec4(0,0,0,1))
2978  : q(v)
2979  {}
2980 
2982  quat(double x,double y,double z,double w)
2983  : q(vec4(x,y,z,w))
2984  {}
2985 
2987  quat(const vec3 &v,double w)
2988  : q(vec4(v,w))
2989  {}
2990 
2992  double dot(const quat &r) const
2993  {return(q.dot(r.q));}
2994 
2996  double length() const {return(q.length());}
2997 
2999  double norm() const {return(q.norm());}
3000 
3002  quat normalize() const
3003  {return(q.normalize());}
3004 
3006  quat conjugate() const
3007  {return(vec4(-vec3(q.x,q.y,q.z),q.w));}
3008 
3010  quat invert() const
3011  {return(normalize().conjugate());}
3012 
3014  operator vec4() const
3015  {return(q);}
3016 
3018  operator mat3() const
3019  {
3020  double a=q.w;
3021  double b=q.x;
3022  double c=q.y;
3023  double d=q.z;
3024  double a2=a*a;
3025  double b2=b*b;
3026  double c2=c*c;
3027  double d2=d*d;
3028 
3029  return(mat3(vec3(a2+b2-c2-d2,2*(b*c-a*d),2*(b*d+a*c)),
3030  vec3(2*(b*c+a*d),a2-b2+c2-d2,2*(c*d-a*b)),
3031  vec3(2*(b*d-a*c),2*(c*d+a*b),a2-b2-c2+d2)));
3032  }
3033 
3036  static quat rotate(double angle,const vec3 &v)
3037  {
3038  angle*=PI/360;
3039  return(vec4(sin(angle)*v,cos(angle)));
3040  }
3041 
3043  static quat rotate(const vec3 &from,const vec3 &to)
3044  {
3045  vec3 v1=from.normalize();
3046  vec3 v2=to.normalize();
3047  vec3 half=(v1+v2).normalize();
3048  return(quat(v1.cross(half),v1.dot(half)));
3049  }
3050 
3052  quat& operator *= (const quat &q);
3053 
3055  operator std::string()
3056  {return("quat" + std::string(q));}
3057 
3059  std::string to_string(std::string delimiter = ", ",int space=0)
3060  {return("quat" + q.to_string(delimiter,space));}
3061 
3062  friend quat operator + (const quat &a,const quat &b);
3063  friend quat operator - (const quat &a,const quat &b);
3064  friend quat operator * (const quat &a,const quat &b);
3065  friend quat operator * (double a,const quat &b);
3066  friend quat operator * (const quat &a,double b);
3067  friend quat operator - (const quat &r);
3068  friend vec3 operator * (const quat &r,const vec3 &v);
3069 
3070  protected:
3071 
3072  vec4 q;
3073  };
3074 
3076 inline quat operator + (const quat &a,const quat &b)
3077  {return(a.q+b.q);}
3078 
3080 inline quat operator - (const quat &a,const quat &b)
3081  {return(a.q-b.q);}
3082 
3084 inline quat operator * (const double a,const quat &b)
3085  {return(a*b.q);}
3086 
3088 inline quat operator * (const quat &a,const double b)
3089  {return(a.q*b);}
3090 
3092 inline quat operator - (const quat &r)
3093  {return(vec4(-vec3(r.q.x,r.q.y,r.q.z),r.q.w));}
3094 
3096 inline quat operator * (const quat &a,const quat &b)
3097  {
3098  double v=a.q.w,w=b.q.w;
3099  vec3 p(a.q.x,a.q.y,a.q.z),q(b.q.x,b.q.y,b.q.z);
3100 
3101  return(vec4(p*w+q*v-p.cross(q),v*w-p.dot(q)));
3102  }
3103 
3105 inline quat& quat::operator *= (const quat &q)
3106  {
3107  *this = (*this)*q;
3108  return(*this);
3109  }
3110 
3112 inline vec3 operator * (const quat &r,const vec3 &v)
3113  {
3114  quat w=r.normalize();
3115  w=-w*quat(vec4(v,0.0))*w;
3116 
3117  return(vec3(w.q.x,w.q.y,w.q.z));
3118  }
3119 
3121 inline std::ostream& operator << (std::ostream &out,const quat &r)
3122  {return(out << std::setprecision(GLSLMATH_PRECISION) << "(" << vec4(r).x << ", " << vec4(r).y << ", " << vec4(r).z << ", " << vec4(r).w << ")");}
3123 
3124 namespace glslmath {
3125 
3127 inline void print(const char *s = "",std::string prefix = "",std::ostream &out = std::cout)
3128  {
3129  out << prefix << s << std::endl;
3130  }
3131 
3133 inline void print(std::string s,std::string prefix = "",std::ostream &out = std::cout)
3134  {
3135  out << prefix << s << std::endl;
3136  }
3137 
3139 inline void print(char c,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3140  {
3141  if (name.size() > 0) name = name + " = ";
3142  if (isprint(c))
3143  out << name << "'" << c << "'" << std::endl;
3144  else
3145  out << std::hex << name << "0x" << (int)c << std::endl;
3146  }
3147 
3149 inline void print(int v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3150  {
3151  if (name.size() > 0) name = name + " = ";
3152  out << prefix << name << v << std::endl;
3153  }
3154 
3156 inline void print(unsigned int v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3157  {
3158  if (name.size() > 0) name = name + " = ";
3159  out << prefix << name << v << std::endl;
3160  }
3161 
3163 inline void print(double v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3164  {
3165  if (name.size() > 0) name = name + " = ";
3166  out << std::setprecision(GLSLMATH_PRECISION) << prefix << name << v << std::endl;
3167  }
3168 
3170 inline void print(vec2 v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3171  {
3172  if (name.size() > 0) name = name + " = ";
3173  out << prefix << name << std::string(v) << std::endl;
3174  }
3175 
3177 inline void print(vec2f v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3178  {
3179  if (name.size() > 0) name = name + " = ";
3180  out << prefix << name << std::string(v) << std::endl;
3181  }
3182 
3184 inline void print(vec3 v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3185  {
3186  if (name.size() > 0) name = name + " = ";
3187  out << prefix << name << std::string(v) << std::endl;
3188  }
3189 
3191 inline void print(vec3f v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3192  {
3193  if (name.size() > 0) name = name + " = ";
3194  out << prefix << name << std::string(v) << std::endl;
3195  }
3196 
3198 inline void print(vec4 v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3199  {
3200  if (name.size() > 0) name = name + " = ";
3201  out << prefix << name << std::string(v) << std::endl;
3202  }
3203 
3205 inline void print(vec4f v,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3206  {
3207  if (name.size() > 0) name = name + " = ";
3208  out << prefix << name << std::string(v) << std::endl;
3209  }
3210 
3212 inline void print(mat2 m,std::string name = "",std::string prefix = "",int space=13,std::ostream &out = std::cout)
3213  {
3214  if (name.size() > 0) name = name + " = ";
3215  out << prefix << name << "/ " << m.row(0).to_string(" ",space) << " \\" << std::endl;
3216  out << prefix << to_space(name.size()) << "\\ " << m.row(1).to_string(" ",space) << " /" << std::endl;
3217  }
3218 
3220 inline void print(mat2f m,std::string name = "",std::string prefix = "",int space=13,std::ostream &out = std::cout)
3221  {
3222  if (name.size() > 0) name = name + " = ";
3223  out << prefix << "/ " << m.row(0).to_string(" ",space) << " \\" << std::endl;
3224  out << prefix << to_space(name.size()) << "\\ " << m.row(1).to_string(" ",space) << " /" << std::endl;
3225  }
3226 
3228 inline void print(mat3 m,std::string name = "",std::string prefix = "",int space=13,std::ostream &out = std::cout)
3229  {
3230  if (name.size() > 0) name = name + " = ";
3231  out << prefix << to_space(name.size()) << "/ " << m.row(0).to_string(" ",space) << " \\" << std::endl;
3232  out << prefix << name << "| " << m.row(1).to_string(" ",space) << " |" << std::endl;
3233  out << prefix << to_space(name.size()) << "\\ " << m.row(2).to_string(" ",space) << " /" << std::endl;
3234  }
3235 
3237 inline void print(mat3f m,std::string name = "",std::string prefix = "",int space=13,std::ostream &out = std::cout)
3238  {
3239  if (name.size() > 0) name = name + " = ";
3240  out << prefix << to_space(name.size()) << "/ " << m.row(0).to_string(" ",space) << " \\" << std::endl;
3241  out << prefix << name << "| " << m.row(1).to_string(" ",space) << " |" << std::endl;
3242  out << prefix << to_space(name.size()) << "\\ " << m.row(2).to_string(" ",space) << " /" << std::endl;
3243  }
3244 
3246 inline void print(mat4 m,std::string name = "",std::string prefix = "",int space=13,std::ostream &out = std::cout)
3247  {
3248  if (name.size() > 0) name = name + " = ";
3249  out << prefix << to_space(name.size()) << "/ " << m.row(0).to_string(" ",space) << " \\" << std::endl;
3250  out << prefix << name << "| " << m.row(1).to_string(" ",space) << " |" << std::endl;
3251  out << prefix << to_space(name.size()) << "| " << m.row(2).to_string(" ",space) << " |" << std::endl;
3252  out << prefix << to_space(name.size()) << "\\ " << m.row(3).to_string(" ",space) << " /" << std::endl;
3253  }
3254 
3256 inline void print(mat4f m,std::string name = "",std::string prefix = "",int space=13,std::ostream &out = std::cout)
3257  {
3258  if (name.size() > 0) name = name + " = ";
3259  out << prefix << to_space(name.size()) << "/ " << m.row(0).to_string(" ",space) << " \\" << std::endl;
3260  out << prefix << name << "| " << m.row(1).to_string(" ",space) << " |" << std::endl;
3261  out << prefix << to_space(name.size()) << "| " << m.row(2).to_string(" ",space) << " |" << std::endl;
3262  out << prefix << to_space(name.size()) << "\\ " << m.row(3).to_string(" ",space) << " /" << std::endl;
3263  }
3264 
3266 inline void print(quat q,std::string name = "",std::string prefix = "",std::ostream &out = std::cout)
3267  {
3268  if (name.size() > 0) name = name + " = ";
3269  out << prefix << name << std::string(q) << std::endl;
3270  }
3271 
3273 inline vec3 hsv2rgb(double hue,double sat,double val)
3274  {
3275  vec3 rgb;
3276 
3277  double hue6,r,s,t;
3278 
3279  if (hue<0.0) hue=0.0;
3280  if (sat<0.0) sat=0.0;
3281  else if (sat>1.0) sat=1.0;
3282  if (val<0.0) val=0.0;
3283  else if (val>1.0) val=1.0;
3284 
3285  hue/=60.0;
3286  hue=hue-6.0*floor(hue/6.0);
3287  hue6=hue-floor(hue);
3288 
3289  r=val*(1.0-sat);
3290  s=val*(1.0-sat*hue6);
3291  t=val*(1.0-sat*(1.0-hue6));
3292 
3293  switch ((int)floor(hue))
3294  {
3295  default:
3296  case 0: // red -> yellow
3297  rgb=vec3(val,t,r);
3298  break;
3299  case 1: // yellow -> green
3300  rgb=vec3(s,val,r);
3301  break;
3302  case 2: // green -> cyan
3303  rgb=vec3(r,val,t);
3304  break;
3305  case 3: // cyan -> blue
3306  rgb=vec3(r,s,val);
3307  break;
3308  case 4: // blue -> magenta
3309  rgb=vec3(t,r,val);
3310  break;
3311  case 5: // magenta -> red
3312  rgb=vec3(val,r,s);
3313  break;
3314  }
3315 
3316  return(rgb);
3317  }
3318 
3320 inline vec3 rgb2hsv(double r,double g,double b)
3321  {
3322  double h,s,v;
3323  double maxv,minv,diff,rdist,gdist,bdist;
3324 
3325  if (r<0.0) r=0.0;
3326  else if (r>1.0) r=1.0;
3327 
3328  if (g<0.0) g=0.0;
3329  else if (g>1.0) g=1.0;
3330 
3331  if (b<0.0) b=0.0;
3332  else if (b>1.0) b=1.0;
3333 
3334  maxv=r;
3335  if (g>maxv) maxv=g;
3336  if (b>maxv) maxv=b;
3337 
3338  minv=r;
3339  if (g<minv) minv=g;
3340  if (b<minv) minv=b;
3341 
3342  diff=maxv-minv;
3343 
3344  v=maxv;
3345 
3346  if (maxv!=0.0) s=diff/maxv;
3347  else s=0.0;
3348 
3349  if (s==0.0) h=0.0;
3350  else
3351  {
3352  rdist=(maxv-r)/diff;
3353  gdist=(maxv-g)/diff;
3354  bdist=(maxv-b)/diff;
3355 
3356  if (r==maxv) h=bdist-gdist;
3357  else if (g==maxv) h=2.0+rdist-bdist;
3358  else h=4.0+gdist-rdist;
3359 
3360  h*=60.0;
3361  if (h<0.0) h+=360.0;
3362  }
3363 
3364  return(vec3(h,s,v));
3365  }
3366 
3368 inline vec3 hsv2rgb(vec3 hsv)
3369  {return(hsv2rgb(hsv.x,hsv.y,hsv.z));}
3370 
3372 inline vec3 rgb2hsv(vec3 rgb)
3373  {return(rgb2hsv(rgb.x,rgb.y,rgb.z));}
3374 
3375 }
3376 
3377 // matrix stack
3378 template <class T>
3379 class scoped_push
3380  {
3381  public:
3382 
3383  // default constructor
3384  scoped_push(const T &m)
3385  {push_matrix(m);}
3386 
3387  // destructor
3388  ~scoped_push()
3389  {pop_matrix();}
3390 
3391  // load matrix
3392  static void load_matrix(const T &m=T(1))
3393  {
3394  if (stack_.begin()==stack_.end())
3395  stack_.push_back(m);
3396  else
3397  *(--stack_.end())=m;
3398  }
3399 
3400  // push matrix
3401  void push_matrix()
3402  {
3403  if (stack_.begin()==stack_.end())
3404  stack_.push_back(T(1));
3405  else
3406  stack_.push_back(top());
3407  }
3408 
3409  // push matrix
3410  void push_matrix(const T &m)
3411  {
3412  if (stack_.begin()==stack_.end())
3413  stack_.push_back(m);
3414  else
3415  stack_.push_back(top()*m);
3416  }
3417 
3418  // matrix multiplication
3419  static void mult_matrix(const T &m)
3420  {
3421  if (stack_.begin()==stack_.end())
3422  stack_.push_back(m);
3423  else
3424  *(--stack_.end())=top()*m;
3425  }
3426 
3427  // top stack element
3428  static const T top()
3429  {
3430  assert(stack_.begin()!=stack_.end());
3431  return(*(--stack_.end()));
3432  }
3433 
3434  // pop matrix
3435  void pop_matrix()
3436  {
3437  assert(stack_.begin()!=stack_.end());
3438  stack_.pop_back();
3439  }
3440 
3441  protected:
3442 
3443  static std::vector<T> stack_;
3444  };
3445 
3446 // matrix stack convenience macros
3447 #define load_matrix(m) scoped_push<mat4>::load_matrix(m)
3448 #define push_matrix() scoped_push<mat4>::push_matrix()
3449 #define mult_matrix(m) scoped_push<mat4>::mult_matrix(m)
3450 #define mult_matrix_scoped(m) scoped_push<mat4> __scoped_push__(m)
3451 #define top_matrix() scoped_push<mat4>::top()
3452 #define pop_matrix() scoped_push<mat4>::pop_matrix()
3453 
3454 template <class T>
3455 std::vector<T> scoped_push<T>::stack_;
3456 
3457 // scoped opengl matrix stack
3458 class glScopedMatrixStack
3459  {
3460  public:
3461 
3462  glScopedMatrixStack()
3463  {
3464 #ifdef GL_VERSION_1_2
3465  glPushMatrix();
3466 #endif
3467  }
3468 
3469  ~glScopedMatrixStack()
3470  {
3471 #ifdef GL_VERSION_1_2
3472  glPopMatrix();
3473 #endif
3474  }
3475 
3476  };
3477 
3478 // scoped replacement for glPushMatrix/glPopMatrix pairs
3479 #ifndef glPushMatrixScoped
3480 #define glPushMatrixScoped() glScopedMatrixStack __glScopedMatrixStack__
3481 #endif
3482 
3483 namespace glslmath {
3484 
3486 inline unsigned int gcd(unsigned int a,unsigned int b)
3487  {
3488  unsigned int c;
3489 
3490  while (b>0)
3491  {
3492  c=a%b;
3493  a=b;
3494  b=c;
3495  }
3496 
3497  return(a);
3498  }
3499 
3501 inline unsigned int lcm(unsigned int a,unsigned int b)
3502  {return(a*b/gcd(a,b));}
3503 
3505 inline double distance2ray(vec3 p,vec3 o,vec3 d)
3506  {
3507  d=d.normalize();
3508 
3509  double l=(p-o).dot(d);
3510  p-=l*d;
3511 
3512  return((p-o).length());
3513  }
3514 
3516 inline double distance2ray2(vec3 p,vec3 o,vec3 d)
3517  {
3518  d=d.normalize();
3519 
3520  double l=(p-o).dot(d);
3521  p-=l*d;
3522 
3523  return((p-o).norm());
3524  }
3525 
3527 inline double distance2line(vec3 p,vec3 a,vec3 b)
3528  {
3529  vec3 n=b-a;
3530  n=n.normalize();
3531 
3532  double l=(p-a).dot(n);
3533  vec3 h=a+l*n;
3534 
3535  double dh=(p-h).norm();
3536  double da=(p-a).norm();
3537  double db=(p-b).norm();
3538 
3539  if (dh<da && dh<db) return(sqrt(dh));
3540  if (da<db) return(sqrt(da));
3541  else return(sqrt(db));
3542  }
3543 
3545 inline double distance2line2(vec3 p,vec3 a,vec3 b)
3546  {
3547  vec3 n=b-a;
3548  n=n.normalize();
3549 
3550  double l=(p-a).dot(n);
3551  vec3 h=a+l*n;
3552 
3553  double dh=(p-h).norm();
3554  double da=(p-a).norm();
3555  double db=(p-b).norm();
3556 
3557  if (dh<da && dh<db) return(dh);
3558  if (da<db) return(da);
3559  else return(db);
3560  }
3561 
3563 inline void merge_spheres(vec3 &center0,double &radius0,
3564  const vec3 &center1,const double radius1)
3565  {
3566  vec3 d=center1-center0;
3567 
3568  double r=d.length();
3569  d=d.normalize();
3570 
3571  if (radius1>radius0+r)
3572  {
3573  center0=center1;
3574  radius0=radius1;
3575  }
3576  else if (radius1+r>radius0)
3577  {
3578  vec3 a=center1+d*radius1;
3579  vec3 b=center0-d*radius0;
3580 
3581  center0=(a+b)/2.0;
3582  radius0=(a-b).length()/2.0;
3583  }
3584  }
3585 
3588  {
3589  double a,b,c;
3590  double s,r;
3591 
3592  double t1,t2;
3593  double t;
3594 
3595  // compute a, b and c coefficients
3596  a=2*d.dot(d);
3597  b=2*p.dot(d);
3598  c=2*(p.dot(p)-1.0);
3599 
3600  // find discriminant
3601  r=b*b-a*c;
3602 
3603  // if discriminant is negative, ray misses sphere
3604  if (r<0.0) return(DBL_MAX);
3605 
3606  // compute real root
3607  s=sqrt(r);
3608 
3609  // compute two real solutions t1 and t2
3610  t1=(-b+s)/a;
3611  t2=(-b-s)/a;
3612 
3613  // make sure t1 is smaller than t2
3614  if (t1>t2)
3615  {
3616  t=t1;
3617  t1=t2;
3618  t2=t;
3619  }
3620 
3621  // return closest solution
3622  if (t2>-t1) return(t1);
3623  else return(t2);
3624  }
3625 
3628  vec3 o,double r1,double r2,double r3)
3629  {
3630  p-=o;
3631 
3632  p.x/=r1;
3633  p.y/=r2;
3634  p.z/=r3;
3635 
3636  d.x/=r1;
3637  d.y/=r2;
3638  d.z/=r3;
3639 
3640  return(intersect_ray_unitsphere(p,d));
3641  }
3642 
3644 inline double intersect_ray_plane(vec3 p,vec3 d,
3645  vec3 o,vec3 n)
3646  {
3647  double c;
3648 
3649  static const double epsilon=1E-10;
3650 
3651  c=d.dot(n);
3652 
3653  if (fabs(c)<=epsilon) return(DBL_MAX);
3654 
3655  return(n.dot(o-p)/c);
3656  }
3657 
3659 inline int intersect_ray_triangle(const vec3 &o,const vec3 &d,
3660  const vec3 &v0,const vec3 &v1,const vec3 &v2,
3661  vec3 &tuv)
3662  {
3663  static const double epsilon=1E-5;
3664 
3665  double t,u,v;
3666  vec3 edge1,edge2,tvec,pvec,qvec;
3667  double det,inv_det;
3668 
3669  // find vectors for two edges sharing v0
3670  edge1=v1-v0;
3671  edge2=v2-v0;
3672 
3673  // begin calculating determinant - also used to calculate U parameter
3674  pvec=d.cross(edge2);
3675 
3676  // if determinant is near zero, ray lies in plane of triangle
3677  det=edge1.dot(pvec);
3678 
3679  // cull triangles with determinant near zero
3680  if (fabs(det)<epsilon) return(0);
3681 
3682  // calculate inverse determinant
3683  inv_det=1.0/det;
3684 
3685  // calculate distance from v0 to ray origin
3686  tvec=o-v0;
3687 
3688  // calculate U parameter and test bounds
3689  u=tvec.dot(pvec)*inv_det;
3690  if (u<0.0 || u>1.0) return(0);
3691 
3692  // prepare to test V parameter
3693  qvec=tvec.cross(edge1);
3694 
3695  // calculate V parameter and test bounds
3696  v=d.dot(qvec)*inv_det;
3697  if (v<0.0 || u+v>1.0) return(0);
3698 
3699  // calculate t, ray intersects triangle
3700  t=edge2.dot(qvec)*inv_det;
3701 
3702  tuv=vec3(t,u,v);
3703 
3704  return(1);
3705  }
3706 
3708 inline double ray_triangle_dist(const vec3 &o,const vec3 &d,
3709  const vec3 &v1,const vec3 &v2,const vec3 &v3)
3710  {
3711  vec3 tuv(0,0,0);
3712 
3713  if (intersect_ray_triangle(o,d,v1,v2,v3,tuv)==0) return(DBL_MAX);
3714  else return(tuv.x);
3715  }
3716 
3718 inline int itest_point_sphere(const vec3 &p,const vec3 &b,const double r2)
3719  {return((p-b).norm()<=r2);}
3720 
3722 inline int itest_ray_sphere(const vec3 &o,const vec3 &d,
3723  const vec3 &b,const double r2)
3724  {
3725  vec3 dn;
3726 
3727  vec3 bmo;
3728  double bmo2,bmod;
3729 
3730  dn=d.normalize();
3731 
3732  bmo=b-o;
3733  bmo2=bmo.dot(bmo);
3734  if (bmo2<r2) return(1);
3735 
3736  bmod=bmo.dot(dn);
3737  if (bmod<0.0) return(0);
3738  if (r2+bmod*bmod>bmo2) return(1);
3739 
3740  return(0);
3741  }
3742 
3744 inline int itest_cone_sphere(const vec3 &o,const vec3 &d,double cone,
3745  const vec3 &b,const double r)
3746  {
3747  vec3 dn;
3748 
3749  double l0,l;
3750  vec3 p;
3751 
3752  dn=d.normalize();
3753 
3754  l0=dn.dot(b-o);
3755  if (l0<-r) return(0);
3756 
3757  p=o+l0*dn;
3758 
3759  l=(b-p).length()-r*sqrt(1.0+cone*cone);
3760 
3761  return(l<cone*l0);
3762  }
3763 
3765 inline int itest_ray_bbox(const vec3 &o,const vec3 &d,
3766  const vec3 &b,const vec3 &r)
3767  {
3768  double l;
3769  vec3 h;
3770 
3771  if (d.x<0.0 && o.x<b.x-r.x) return(0);
3772  if (d.x>0.0 && o.x>b.x+r.x) return(0);
3773  if (d.y<0.0 && o.y<b.y-r.y) return(0);
3774  if (d.y>0.0 && o.y>b.y+r.y) return(0);
3775  if (d.z<0.0 && o.z<b.z-r.z) return(0);
3776  if (d.z>0.0 && o.z>b.z+r.z) return(0);
3777 
3778  if (d.x!=0.0)
3779  {
3780  if (d.x>0.0) l=(b.x-r.x-o.x)/d.x;
3781  else l=(b.x+r.x-o.x)/d.x;
3782 
3783  if (l>0.0)
3784  {
3785  h=o+d*l;
3786  if (h.y<b.y-r.y && o.y>b.y-r.y) return(0);
3787  if (h.y>b.y+r.y && o.y<b.y+r.y) return(0);
3788  if (h.z<b.z-r.z && o.z>b.z-r.z) return(0);
3789  if (h.z>b.z+r.z && o.z<b.z+r.z) return(0);
3790  }
3791  }
3792 
3793  if (d.y!=0.0)
3794  {
3795  if (d.y>0.0) l=(b.y-r.y-o.y)/d.y;
3796  else l=(b.y+r.y-o.y)/d.y;
3797 
3798  if (l>0.0)
3799  {
3800  h=o+d*l;
3801  if (h.x<b.x-r.x && o.x>b.x-r.x) return(0);
3802  if (h.x>b.x+r.x && o.x<b.x+r.x) return(0);
3803  if (h.z<b.z-r.z && o.z>b.z-r.z) return(0);
3804  if (h.z>b.z+r.z && o.z<b.z+r.z) return(0);
3805  }
3806  }
3807 
3808  if (d.z!=0.0)
3809  {
3810  if (d.z>0.0) l=(b.z-r.z-o.z)/d.z;
3811  else l=(b.z+r.z-o.z)/d.z;
3812 
3813  if (l>0.0)
3814  {
3815  h=o+d*l;
3816  if (h.x<b.x-r.x && o.x>b.x-r.x) return(0);
3817  if (h.x>b.x+r.x && o.x<b.x+r.x) return(0);
3818  if (h.y<b.y-r.y && o.y>b.y-r.y) return(0);
3819  if (h.y>b.y+r.y && o.y<b.y+r.y) return(0);
3820  }
3821  }
3822 
3823  return(1);
3824  }
3825 
3827 inline int itest_plane_sphere(const vec3 &o,const vec3 &n,const double radius,
3828  const vec3 &b,const double r2)
3829  {
3830  vec3 h;
3831  double l;
3832 
3833  h=b-o;
3834  l=h.dot(n);
3835 
3836  if (l*l>r2) return(0); // no intersection
3837  if (h.dot(h)>2.0*(radius*radius+r2)) return(0); // no inclusion (approximate)
3838 
3839  return(1);
3840  }
3841 
3843 inline int vtest_plane_point(const vec3 &o,const vec3 &n,
3844  const vec3 &point)
3845  {
3846  return(dot(point-o,n)>0);
3847  }
3848 
3850 inline int vtest_plane_sphere(const vec3 &o,const vec3 &n,
3851  const vec3 &center,double radius)
3852  {
3853  return(dot(center-o,n)>-radius);
3854  }
3855 
3857 inline int vtest_plane_bbox(const vec3 &o,const vec3 &n,
3858  const vec3 &center,const vec3 &extent)
3859  {
3860  return(dot(center-o,n)>-0.5*dot(extent,vec3(fabs(n.x),fabs(n.y),fabs(n.z))));
3861  }
3862 
3863 }
3864 
3865 namespace glslnoise {
3866 
3869  {
3870  public:
3871 
3873  perlinnoise(int sx=64,int sy=64,int sz=64,
3874  int start=4,float persist=0.5f,
3875  float seed=0.0f)
3876  {
3877  sizex=sx;
3878  sizey=sy;
3879  sizez=sz;
3880 
3881  data=noise(sx,sy,sz,start,persist,seed);
3882  }
3883 
3886  {if (data) delete data;}
3887 
3889  inline float interpolate(float c1,float c2=0.0f,float c3=0.0f)
3890  {
3891  float v;
3892 
3893  if (data) v=interpolate(data,sizex,sizey,sizez,c1,c2,c3);
3894  else v=0.0f;
3895 
3896  if (v<0.0f) v=0.0f;
3897  else if (v>1.0f) v=1.0f;
3898 
3899  return(v);
3900  }
3901 
3902  private:
3903 
3904  int sizex,sizey,sizez;
3905  float *data;
3906 
3907  inline static float get(const float *data,
3908  int sx,int sy,int sz,
3909  int x,int y,int z)
3910  {
3911  assert(x>=0 && x<sx && y>=0 && y<sy && z>=0 && z<sz);
3912  return(data[x+(y+z*sy)*sx]);
3913  }
3914 
3915  inline static void set(float *data,
3916  int sx,int sy,int sz,
3917  int x,int y,int z,
3918  float v)
3919  {
3920  assert(x>=0 && x<sx && y>=0 && y<sy && z>=0 && z<sz);
3921  data[x+(y+z*sy)*sx]=v;
3922  }
3923 
3924  inline static void add(float *data,
3925  int sx,int sy,int sz,
3926  int x,int y,int z,
3927  float v)
3928  {
3929  assert(x>=0 && x<sx && y>=0 && y<sy && z>=0 && z<sz);
3930  data[x+(y+z*sy)*sx]+=v;
3931  }
3932 
3933  inline static float interpolate(float v0,float v1,float v2,float v3,float x)
3934  {
3935  float p,q,r;
3936 
3937  p=v3-v2+v1-v0;
3938  q=v0-v1-p;
3939  r=v2-v0;
3940 
3941  return(((p*x+q)*x+r)*x+v1);
3942  }
3943 
3944  inline static float interpolatex(const float *data,
3945  int sx,int sy,int sz,
3946  int k1,int k2,int k3,
3947  float wx)
3948  {
3949  float v0,v1,v2,v3;
3950 
3951  v1=get(data,sx,sy,sz,k1,k2,k3);
3952  v0=(k1>0)?get(data,sx,sy,sz,k1-1,k2,k3):v1;
3953  v2=(k1<sx-1)?get(data,sx,sy,sz,k1+1,k2,k3):v1;
3954  v3=(k1<sx-2)?get(data,sx,sy,sz,k1+2,k2,k3):v2;
3955 
3956  return(interpolate(v0,v1,v2,v3,wx));
3957  }
3958 
3959  inline static float interpolatey(const float *data,
3960  int sx,int sy,int sz,
3961  int k1,int k2,int k3,
3962  float wx,float wy)
3963  {
3964  float v0,v1,v2,v3;
3965 
3966  v1=interpolatex(data,sx,sy,sz,k1,k2,k3,wx);
3967  v0=(k2>0)?interpolatex(data,sx,sy,sz,k1,k2-1,k3,wx):v1;
3968  v2=(k2<sy-1)?interpolatex(data,sx,sy,sz,k1,k2+1,k3,wx):v1;
3969  v3=(k2<sy-2)?interpolatex(data,sx,sy,sz,k1,k2+2,k3,wx):v2;
3970 
3971  return(interpolate(v0,v1,v2,v3,wy));
3972  }
3973 
3974  inline static float interpolatez(const float *data,
3975  int sx,int sy,int sz,
3976  int k1,int k2,int k3,
3977  float wx,float wy,float wz)
3978  {
3979  float v0,v1,v2,v3;
3980 
3981  v1=interpolatey(data,sx,sy,sz,k1,k2,k3,wx,wy);
3982  v0=(k3>0)?interpolatey(data,sx,sy,sz,k1,k2,k3-1,wx,wy):v1;
3983  v2=(k3<sz-1)?interpolatey(data,sx,sy,sz,k1,k2,k3+1,wx,wy):v1;
3984  v3=(k3<sz-2)?interpolatey(data,sx,sy,sz,k1,k2,k3+2,wx,wy):v2;
3985 
3986  return(interpolate(v0,v1,v2,v3,wz));
3987  }
3988 
3989  inline static float interpolate(const float *data,
3990  int sx,int sy,int sz,
3991  float c1,float c2,float c3)
3992  {
3993  int k1,k2,k3;
3994  float w1,w2,w3;
3995 
3996  c1=c1-(int)floorf(c1);
3997  c2=c2-(int)floorf(c2);
3998  c3=c3-(int)floorf(c3);
3999 
4000  k1=(int)floorf(c1*(sx-1));
4001  w1=c1*(sx-1)-k1;
4002 
4003  k2=(int)floorf(c2*(sy-1));
4004  w2=c2*(sy-1)-k2;
4005 
4006  k3=(int)floorf(c3*(sz-1));
4007  w3=c3*(sz-1)-k3;
4008 
4009  return(interpolatez(data,sx,sy,sz,k1,k2,k3,w1,w2,w3));
4010  }
4011 
4012  inline static void average(float *data,
4013  int sx,int sy,int sz,
4014  int x1,int y1,int z1,
4015  int x2,int y2,int z2,
4016  int dx,int dy,int dz)
4017  {
4018  int x,y,z;
4019 
4020  float v,v1,v2;
4021 
4022  for (x=0; x<dx; x++)
4023  for (y=0; y<dy; y++)
4024  for (z=0; z<dz; z++)
4025  {
4026  v1=get(data,sx,sy,sz,x1+x,y1+y,z1+z);
4027  v2=get(data,sx,sy,sz,x2+x,y2+y,z2+z);
4028  v=(v1+v2)/2.0f;
4029  set(data,sx,sy,sz,x1+x,y1+y,z1+z,v);
4030  set(data,sx,sy,sz,x2+x,y2+y,z2+z,v);
4031  }
4032  }
4033 
4034  public:
4035 
4036  inline static float *noise(int sx=64,int sy=64,int sz=64,
4037  int start=4,float persist=0.5f,
4038  float seed=0.0f)
4039  {
4040  int i;
4041  int x,y,z;
4042 
4043  int size;
4044  int dx,dy,dz;
4045 
4046  float scaling;
4047 
4048  float *noise,*octave;
4049 
4050  float v,minv,maxv;
4051 
4052  if ((sx&(sx-1))!=0 || sx<1) return(NULL);
4053  if ((sy&(sy-1))!=0 || sy<1) return(NULL);
4054  if ((sz&(sz-1))!=0 || sz<1) return(NULL);
4055 
4056  if ((start&(start-1))!=0 || start<1) return(NULL);
4057 
4058  if ((noise=new(std::nothrow)float[sx*sy*sz])==NULL) return(NULL);
4059 
4060  for (x=0; x<sx; x++)
4061  for (y=0; y<sy; y++)
4062  for (z=0; z<sz; z++) set(noise,sx,sy,sz,x,y,z,0.0f);
4063 
4064  if ((octave=new(std::nothrow)float[sx*sy*sz])==NULL)
4065  {
4066  delete noise;
4067  return(NULL);
4068  }
4069 
4070  size=sx;
4071  if (sy>size) size=sy;
4072  if (sz>size) size=sz;
4073 
4074  getrandom(seed);
4075 
4076  scaling=1.0f;
4077 
4078  for (i=start; i<=size; i*=2)
4079  {
4080  dx=i*sx/size;
4081  dy=i*sy/size;
4082  dz=i*sz/size;
4083 
4084  if (dx<1) dx=1;
4085  if (dy<1) dy=1;
4086  if (dz<1) dz=1;
4087 
4088  for (x=0; x<dx; x++)
4089  for (y=0; y<dy; y++)
4090  for (z=0; z<dz; z++)
4091  set(octave,dx,dy,dz,x,y,z,
4092  getrandom()*scaling);
4093 
4094  // seamless noise via octave face averaging
4095  if (dx>1) average(octave,dx,dy,dz,0,0,0,dx-1,0,0,1,dy,dz);
4096  if (dy>1) average(octave,dx,dy,dz,0,0,0,0,dy-1,0,dx,1,dz);
4097  if (dz>1) average(octave,dx,dy,dz,0,0,0,0,0,dz-1,dx,dy,1);
4098 
4099  for (x=0; x<sx; x++)
4100  for (y=0; y<sy; y++)
4101  for (z=0; z<sz; z++)
4102  add(noise,sx,sy,sz,x,y,z,
4103  interpolate(octave,dx,dy,dz,
4104  (sx>1)?(float)x/(sx-1):0.0f,
4105  (sy>1)?(float)y/(sy-1):0.0f,
4106  (sz>1)?(float)z/(sz-1):0.0f));
4107 
4108  scaling*=persist;
4109  }
4110 
4111  delete octave;
4112 
4113  minv=FLT_MAX;
4114  maxv=-FLT_MAX;
4115 
4116  for (x=0; x<sx; x++)
4117  for (y=0; y<sy; y++)
4118  for (z=0; z<sz; z++)
4119  {
4120  v=get(noise,sx,sy,sz,x,y,z);
4121  if (v<minv) minv=v;
4122  if (v>maxv) maxv=v;
4123  }
4124 
4125  if (minv==maxv) maxv++;
4126 
4127  // normalization
4128  for (x=0; x<sx; x++)
4129  for (y=0; y<sy; y++)
4130  for (z=0; z<sz; z++)
4131  set(noise,sx,sy,sz,x,y,z,
4132  (get(noise,sx,sy,sz,x,y,z)-minv)/(maxv-minv));
4133 
4134  return(noise);
4135  }
4136 
4137  inline static float getrandom(float seed=-1.0f)
4138  {
4139  static const long long maxbits=50;
4140  static const long long maxnum=1ull<<maxbits;
4141 
4142  static long long number=0;
4143 
4144  if (seed>=0.0f && seed<=1.0f) number=(long long)(seed*(maxnum-1));
4145 
4146  number=271*(number+331);
4147  number=(number<<(maxbits/3))+(number>>(2*maxbits/3));
4148  number&=maxnum-1;
4149 
4150  return((float)number/(maxnum-1));
4151  }
4152 
4153  };
4154 
4155 inline static double noise(vec3f coord,int size=64,int start=4)
4156  {
4157  static perlinnoise N(size,size,size,start);
4158 
4159  return(N.interpolate(coord.x,coord.y,coord.z));
4160  }
4161 
4162 inline static vec3 noise3D(vec3f coord,int size=64,int start=4)
4163  {
4164  static perlinnoise Nx(size,size,size,start,0.5f,0.25f),
4165  Ny(size,size,size,start,0.5f,0.5f),
4166  Nz(size,size,size,start,0.5f,0.75f);
4167 
4168  return(vec3(Nx.interpolate(coord.x,coord.y,coord.z),
4169  Ny.interpolate(coord.x,coord.y,coord.z),
4170  Nz.interpolate(coord.x,coord.y,coord.z)));
4171  }
4172 
4173 inline static vec4 noise4D(vec3f coord,int size=64,int start=4)
4174  {
4175  static perlinnoise Nx(size,size,size,start,0.5f,0.2f),
4176  Ny(size,size,size,start,0.5f,0.4f),
4177  Nz(size,size,size,start,0.5f,0.6f),
4178  Nw(size,size,size,start,0.5f,0.8f);
4179 
4180  return(vec4(Nx.interpolate(coord.x,coord.y,coord.z),
4181  Ny.interpolate(coord.x,coord.y,coord.z),
4182  Nz.interpolate(coord.x,coord.y,coord.z),
4183  Nw.interpolate(coord.x,coord.y,coord.z)));
4184  }
4185 
4186 }
4187 
4188 namespace glslmath {
4189 
4190 // glslmath test function
4191 inline int test()
4192  {
4193  int errors=0;
4194 
4195  // test vectors
4196  {
4197  vec3 v(0,3,4);
4198  if (!(v.length()==5)) errors++;
4199  vec3 a(-10,0,10),b(10,10,10);
4200  if (!(0.5*(a+b)==vec3(0,5,10))) errors++;
4201  vec4 r=vec4(1,-1,0,0).reflect(vec4(0,1,0,0));
4202  if (!(r==vec4(1,1,0,0))) errors++;
4203  if (vec4(r.zw().yx(),r.xy().yx()).wzyx()!=r) errors++;
4204  vec4 c1(1,0,0),c2(0,0,1,0.25);
4205  if (c1.blend(c2)!=vec4(0.75,0,0.25,1)) errors++;
4206  if (hsv2rgb(60,1,1)!=vec3(1,1,0)) errors++;
4207  if (rgb2hsv(1,1,0)!=vec3(60,1,1)) errors++;
4208  }
4209 
4210  // test matrices
4211  {
4212  mat4 M(vec4(0,1,0,0),
4213  vec4(-1,0,0,0),
4214  vec4(0,0,1,0));
4215 
4216  if (!(M*M.invert()==mat4())) errors++;
4217  }
4218 
4219  // test affine transformation
4220  {
4221  vec3 o=vec3(3,3,3);
4222  vec3 x=vec3(0,1,0);
4223  vec3 y=vec3(0,0,1);
4224  vec3 z=vec3(1,0,0);
4225  mat4 T=mat4::transform(o,x,y,z);
4226  vec4 v(1,0,0);
4227  v=T*v;
4228  if (v!=vec4(3,4,3,1)) errors++;
4229  }
4230 
4231  // test transformations
4232  {
4234  mat4 rotate=mat4::rotate(0,vec3(1,0,0));
4235  mat4 lookat=mat4::lookat(vec3(0,0,0),vec3(0,0,-1),vec3(0,1,0));
4236  if (!(translate==mat4() && rotate==mat4() && lookat==mat4())) errors++;
4237  mat4 fromto=mat4::rotate(vec3(0,1,0),vec3(1,0,0));
4238  if (!(fromto*vec4(0,1,0)==vec4(1,0,0))) errors++;
4239  mat4 perspective=mat4::perspective(90,1,1,2);
4240  if (!(fabs(1-perspective[0].x)<1E-10 && fabs(-3-perspective[2].z)<1E-10)) errors++;
4241  mat4 parallel=mat4::parallel(vec3(1,0,0),vec3(1,1,0),vec3(-1,0,0));
4242  if (vec3(parallel*vec4(1,2,3))!=vec3(-1,2,3)) errors++;
4243  }
4244 
4245  // test combined transformations
4246  {
4247  mat4 T=mat4::translate(0,0,1)*mat4::rotate(90,vec3(0,1,0))*mat4::scale(0.5);
4248  vec4 v(2,0,0);
4249  v=T*v;
4250  if (vec3(v).length()>1E-10) errors++;
4251  }
4252 
4253  // test matrix stack
4254  {
4255  double x1,x2;
4256  {
4257  mult_matrix_scoped(mat4::scale(0.5,1,1));
4258  {
4259  mult_matrix_scoped(mat4::translate(1,1,1));
4260  x1=top_matrix()[3].x;
4261  }
4262  x2=top_matrix()[3].x;
4263  }
4264  if (!(x1==0.5 && x2==0.0)) errors++;
4265  }
4266 
4267  // test quaternions
4268  {
4269  quat q;
4270  vec3 v(0,0,-1);
4271  vec3 w=q*v;
4272  quat a=quat::rotate(10,vec3(0,0,-1));
4273  quat b=quat::rotate(80,vec3(0,0,-1));
4274  quat r=a*b;
4275  vec3 p=r*vec3(1,0,0);
4276  if (!(v.approx(w) && p.approx(vec3(0,-1,0)))) errors++;
4277  quat m=quat::rotate(vec3(0,1,0),vec3(1,0,0));
4278  vec3 n=m*vec3(1,0,0);
4279  if (!n.approx(vec3(0,-1,0))) errors++;
4280  vec3 o=mat3(m)*vec3(1,0,0);
4281  if (!o.approx(vec3(0,-1,0))) errors++;
4282  }
4283 
4284  // test intersection testing
4285  {
4286  vec3 p(0,0,0),d(1,1,1);
4287  vec3 o(1,0,0),n(1,0,0);
4288  double l=glslmath::intersect_ray_plane(p,d.normalize(),o,n);
4289  if (fabs(l-sqrt(3.0))>1E-10) errors++;
4290  }
4291 
4292  // test perlin noise
4293  {
4294  vec3 coord(0.5,0.5,0.5);
4295  double noise_value=glslnoise::noise(coord,32);
4296  vec3 noise_vector=glslnoise::noise3D(coord,32);
4297  if (fabs(noise_value-0.4302484)>1E-5) errors++;
4298  if (!noise_vector.approx(vec3(0.4040824,0.6377566,0.6551602),1E-5)) errors++;
4299  }
4300 
4301  return(errors);
4302  }
4303 
4304 }
4305 
4306 #endif
vec4f::wzyx
vec4f wzyx() const
swizzeling operator
Definition: glslmath.h:1058
inverse
mat4 inverse(const mat4 &m)
inline inverse
Definition: glslmath.h:2631
vec3f
3D float vector
Definition: glslmath.h:584
mat2f::rows
static mat2f rows(const vec2f &r1, const vec2f &r2)
construct matrix from row vectors
Definition: glslmath.h:1459
mat2::transpose
static mat2 transpose(const mat2 &m)
static version of transpose operation
Definition: glslmath.h:1250
vec2f::vec2f
vec2f(const vec2 &v)
copy constructor
Definition: glslmath.h:272
vec2::norm
double norm() const
get squared vector length
Definition: glslmath.h:136
quat::rotate
static quat rotate(const vec3 &from, const vec3 &to)
create rotating quaternion from two vectors
Definition: glslmath.h:3043
mat4::mat4
mat4(const mat3 &m)
copy constructor
Definition: glslmath.h:2196
vec3f::vec3f
vec3f(const vec2 &v, const float vz=0.0f)
copy constructor
Definition: glslmath.h:601
vec2f::operator+=
vec2f & operator+=(const vec2f &v)
inplace addition
Definition: glslmath.h:293
mat3::mat3
mat3(const vec3 &diag)
custom constructor
Definition: glslmath.h:1565
mat4::rotate
static mat4 rotate(double angle, const vec3 &v)
create rotation matrix
Definition: glslmath.h:2451
mat3::row
vec3 row(const int i) const
row getter
Definition: glslmath.h:1661
mat4::operator[]
vec4 operator[](const int i) const
subscript operator (column getter)
Definition: glslmath.h:2265
glslmath::vtest_plane_bbox
int vtest_plane_bbox(const vec3 &o, const vec3 &n, const vec3 &center, const vec3 &extent)
bounding box visibility test
Definition: glslmath.h:3857
mat4::transpose
mat4 transpose() const
transpose 4x4 matrix
Definition: glslmath.h:2363
vec4::vec4
vec4()
default constructor
Definition: glslmath.h:718
vec4::operator-=
vec4 & operator-=(const vec4 &v)
inplace subtraction
Definition: glslmath.h:766
vec3f::vec3f
vec3f(const vec2f &v, const float vz=0.0f)
copy constructor
Definition: glslmath.h:598
mat4::operator*=
mat4 & operator*=(const mat4 &m)
inplace multiplication
Definition: glslmath.h:2548
vec2::vec2
vec2(const double vx, const double vy)
component-wise constructor
Definition: glslmath.h:119
translate
mat4 translate(const mat4 &m, const vec4 &v)
inline translate
Definition: glslmath.h:2603
mat2f::row
vec2f row(const int i) const
row getter
Definition: glslmath.h:1481
glslnoise::perlinnoise::interpolate
float interpolate(float c1, float c2=0.0f, float c3=0.0f)
cubic interpolation of perlin noise
Definition: glslmath.h:3889
quat::normalize
quat normalize() const
normalization
Definition: glslmath.h:3002
mat2f::mat2f
mat2f(const vec2f &r1, const vec2f &r2)
custom constructor
Definition: glslmath.h:1423
vec3::zyx
vec3 zyx() const
swizzeling operator
Definition: glslmath.h:454
vec4f::operator+=
vec4f & operator+=(const vec4f &v)
inplace addition
Definition: glslmath.h:1026
mat3f::c_ptr
const float * c_ptr() const
const pointer to column-major array
Definition: glslmath.h:2055
mat3f::rows
static mat3f rows(float a, float b, float c, float d, float e, float f, float g, float h, float i)
construct matrix from row vectors
Definition: glslmath.h:2020
mat2::scale
static mat2 scale(const vec2 &c)
create scaling matrix
Definition: glslmath.h:1287
mat2f::columns
static mat2f columns(const vec2f &c1, const vec2f &c2)
construct matrix from column vectors
Definition: glslmath.h:1444
glslmath::hsv2rgb
vec3 hsv2rgb(double hue, double sat, double val)
hsv to rgb conversion
Definition: glslmath.h:3273
vec4::wzyx
vec4 wzyx() const
swizzeling operator
Definition: glslmath.h:827
vec4::norm
double norm() const
get squared vector length
Definition: glslmath.h:781
vec3f::vec3f
vec3f(const vec3f &v)
copy constructor
Definition: glslmath.h:592
mat3::scale
static mat3 scale(double s, double t, double r)
create scaling matrix
Definition: glslmath.h:1754
mat2::operator*=
mat2 & operator*=(const mat2 &m)
inplace multiplication
Definition: glslmath.h:1355
mat3::rows
static mat3 rows(const vec3 &r1, const vec3 &r2, const vec3 &r3)
construct matrix from row vectors
Definition: glslmath.h:1636
mat2::invert
mat2 invert() const
invert 2x2 matrix
Definition: glslmath.h:1254
mat3f::columns
static mat3f columns(const vec3f &c1, const vec3f &c2, const vec3f &c3)
construct matrix from column vectors
Definition: glslmath.h:1994
vec4::vec4
vec4(const double vx, const double vy, const double vz, const double vw=1.0)
component-wise constructor
Definition: glslmath.h:733
mat2::det
static double det(const mat2 &m)
static version of determinant operation
Definition: glslmath.h:1242
vec3::blend
vec3 blend(const vec3 &rgb, double alpha) const
blending operator
Definition: glslmath.h:572
mat4f::mat4f
mat4f(const vec4f &r1, const vec4f &r2, const vec4f &r3, const vec4f &r4=vec4f(0, 0, 0, 1))
custom constructor
Definition: glslmath.h:2781
vec2f::vec2f
vec2f(const float v)
single-component constructor
Definition: glslmath.h:278
vec2::yx
vec2 yx() const
swizzeling operator
Definition: glslmath.h:166
mat3::rotate
static mat3 rotate(double angle, const vec3 &v)
create rotation matrix
Definition: glslmath.h:1778
mat4f::mat4f
mat4f(const mat4 &m)
copy constructor
Definition: glslmath.h:2808
vec4::rgb
vec3 rgb() const
swizzeling operator
Definition: glslmath.h:823
vec3::operator-=
vec3 & operator-=(const vec3 &v)
inplace subtraction
Definition: glslmath.h:408
quat::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:3059
quat::quat
quat(const vec4 &v=vec4(0, 0, 0, 1))
default constructor
Definition: glslmath.h:2977
mat4::fromOpenGL
void fromOpenGL(const double m[16])
convert from 16-element column-major OpenGL matrix
Definition: glslmath.h:2306
mat4::perspective
static mat4 perspective(double fovy, double aspect, double znear, double zfar)
create perspective matrix
Definition: glslmath.h:2712
mat2::operator+=
mat2 & operator+=(const mat2 &m)
inplace addition
Definition: glslmath.h:1348
vec3::xy
vec2 xy() const
swizzeling operator
Definition: glslmath.h:450
vec3::dot
double dot(const vec3 &v) const
inner product
Definition: glslmath.h:429
mat3::operator*=
mat3 & operator*=(const mat3 &m)
inplace multiplication
Definition: glslmath.h:1883
quat::operator*=
quat & operator*=(const quat &q)
inplace multiplication
Definition: glslmath.h:3105
vec3::normalize
vec3 normalize() const
normalize vector to unit length
Definition: glslmath.h:528
quat::operator*
friend quat operator*(const quat &a, const quat &b)
multiplication of two quaternions
Definition: glslmath.h:3096
vec3::operator+=
vec3 & operator+=(const vec3 &v)
inplace addition
Definition: glslmath.h:404
mat4::mat4
mat4(double diag=1.0)
default constructor
Definition: glslmath.h:2121
mat4::mat4
mat4(const vec4 &r1, const vec4 &r2, const vec4 &r3, const vec4 &r4=vec4(0, 0, 0, 1))
custom constructor
Definition: glslmath.h:2169
mat2::col
vec2 col(const int i) const
column getter
Definition: glslmath.h:1213
vec2f::operator-=
vec2f & operator-=(const vec2f &v)
inplace subtraction
Definition: glslmath.h:297
vec2
2D double vector
Definition: glslmath.h:108
vec4::normal
static vec4 normal(const vec4 &a, const vec4 &b, const vec4 &c)
calculate triangle normal
Definition: glslmath.h:941
vec3::area
static double area(const vec3 &a, const vec3 &b, const vec3 &c)
calculate triangle area
Definition: glslmath.h:568
quat::norm
double norm() const
get quaternion norm
Definition: glslmath.h:2999
vec3f::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:654
vec4::c_ptr
const double * c_ptr() const
const pointer to linear array
Definition: glslmath.h:754
vec4::normalize
vec4 normalize() const
normalize vector to unit length
Definition: glslmath.h:902
vec2f::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:317
mat2f
2x2 float matrix
Definition: glslmath.h:1408
vec4::operator+=
vec4 & operator+=(const vec4 &v)
inplace addition
Definition: glslmath.h:762
mat2f::columns
static mat2f columns(float a, float b, float c, float d)
construct matrix from column vectors
Definition: glslmath.h:1451
glslmath::distance2ray2
double distance2ray2(vec3 p, vec3 o, vec3 d)
calculate the squared distance of a point p from a ray
Definition: glslmath.h:3516
vec4
4D double vector
Definition: glslmath.h:713
glslmath::itest_ray_sphere
int itest_ray_sphere(const vec3 &o, const vec3 &d, const vec3 &b, const double r2)
geometric ray/sphere intersection test
Definition: glslmath.h:3722
mat4::rotate
static mat4 rotate(double angle, double vx, double vy, double vz)
create rotation matrix
Definition: glslmath.h:2446
vec4f::vec4f
vec4f(const float vx, const float vy, const float vz, const float vw=1.0f)
component-wise constructor
Definition: glslmath.h:993
vec4f::vec4f
vec4f()
default constructor
Definition: glslmath.h:966
vec4f::vec4f
vec4f(const vec4f &v)
copy constructor
Definition: glslmath.h:969
mat3::operator+=
mat3 & operator+=(const mat3 &m)
inplace addition
Definition: glslmath.h:1876
vec4f::vec4f
vec4f(const vec3 &v, const float vw=1.0f)
copy constructor
Definition: glslmath.h:978
vec4f::zw
vec2f zw() const
swizzeling operator
Definition: glslmath.h:1046
mat2::c_ptr
const double * c_ptr() const
const pointer to column-major array
Definition: glslmath.h:1220
glslmath::lcm
unsigned int lcm(unsigned int a, unsigned int b)
smallest common multiple
Definition: glslmath.h:3501
vec2f::c_ptr
const float * c_ptr() const
const pointer to linear array
Definition: glslmath.h:285
vec2::approx
bool approx(const vec2 &v, const double e=1E-10) const
test for approximate equality
Definition: glslmath.h:146
norm
double norm(const vec2 &v)
get squared vector length
Definition: glslmath.h:225
mat4::scale
static mat4 scale(const vec4 &c)
create scaling matrix
Definition: glslmath.h:2418
mat4::columns
static mat4 columns(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l, double m, double n, double o, double p)
construct matrix from column vectors
Definition: glslmath.h:2232
glslmath::gcd
unsigned int gcd(unsigned int a, unsigned int b)
greatest common divisor
Definition: glslmath.h:3486
vec3f::bgr
vec3f bgr() const
swizzeling operator
Definition: glslmath.h:646
glslmath::merge_spheres
void merge_spheres(vec3 &center0, double &radius0, const vec3 &center1, const double radius1)
merge two spheres
Definition: glslmath.h:3563
mat4::row
vec4 row(const int i) const
row getter
Definition: glslmath.h:2272
mat3::det
double det() const
calculate determinant of 3x3 matrix
Definition: glslmath.h:1703
mat2f::mat2f
mat2f(const mat2 &m)
copy constructor
Definition: glslmath.h:1434
vec4f::vec4f
vec4f(const vec2 &xy, const vec2 &zw)
copy constructor
Definition: glslmath.h:990
vec3f::operator+=
vec3f & operator+=(const vec3f &v)
inplace addition
Definition: glslmath.h:622
glslnoise::perlinnoise::perlinnoise
perlinnoise(int sx=64, int sy=64, int sz=64, int start=4, float persist=0.5f, float seed=0.0f)
default constructor
Definition: glslmath.h:3873
vec3f::vec3f
vec3f(const float v)
single-component constructor
Definition: glslmath.h:607
mat2f::rows
static mat2f rows(float a, float b, float c, float d)
construct matrix from row vectors
Definition: glslmath.h:1466
mat4::columns
static mat4 columns(const vec4 &c1, const vec4 &c2, const vec4 &c3, const vec4 &c4)
construct matrix from column vectors
Definition: glslmath.h:2223
vec4f::vec4f
vec4f(const float v, const float vw=1.0f)
single-component constructor
Definition: glslmath.h:996
vec4f::bgra
vec4f bgra() const
swizzeling operator
Definition: glslmath.h:1062
vec4::zw
vec2 zw() const
swizzeling operator
Definition: glslmath.h:815
vec2::operator-=
vec2 & operator-=(const vec2 &v)
inplace subtraction
Definition: glslmath.h:154
mat4f::row
vec4f row(const int i) const
row getter
Definition: glslmath.h:2881
operator*
vec2 operator*(const double a, const vec2 &b)
left-hand side scalar multiplication
Definition: glslmath.h:197
glslmath::itest_point_sphere
int itest_point_sphere(const vec3 &p, const vec3 &b, const double r2)
geometric point/sphere intersection test
Definition: glslmath.h:3718
vec4f::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:1070
vec2f::yx
vec2f yx() const
swizzeling operator
Definition: glslmath.h:309
vec2f::operator*=
vec2f & operator*=(float v)
inplace multiplication
Definition: glslmath.h:301
mat4f
4x4 float matrix
Definition: glslmath.h:2752
glslnoise::perlinnoise::~perlinnoise
~perlinnoise()
destructor
Definition: glslmath.h:3885
vec2::operator+=
vec2 & operator+=(const vec2 &v)
inplace addition
Definition: glslmath.h:150
mat2f::c_ptr
const float * c_ptr() const
const pointer to column-major array
Definition: glslmath.h:1495
mat3f::row
vec3f row(const int i) const
row getter
Definition: glslmath.h:2037
mat3::operator>>=
mat3 & operator>>=(const mat3 &m)
inplace multiplication (right-hand side)
Definition: glslmath.h:1897
lerp
vec2 lerp(double w, const vec2 &a, const vec2 &b)
linear interpolation
Definition: glslmath.h:245
glslmath::rgb2hsv
vec3 rgb2hsv(double r, double g, double b)
rgb to hsv conversion
Definition: glslmath.h:3320
mat3::columns
static mat3 columns(const vec3 &c1, const vec3 &c2, const vec3 &c3)
construct matrix from column vectors
Definition: glslmath.h:1618
glslmath::intersect_ray_plane
double intersect_ray_plane(vec3 p, vec3 d, vec3 o, vec3 n)
ray/plane intersection
Definition: glslmath.h:3644
vec2::c_ptr
const double * c_ptr() const
const pointer to linear array
Definition: glslmath.h:125
vec4::vec4
vec4(const vec4 &v)
copy constructor
Definition: glslmath.h:721
mat4::operator<<=
mat4 & operator<<=(const mat4 &m)
inplace multiplication (left-hand side)
Definition: glslmath.h:2555
mat3::rows
static mat3 rows(double a, double b, double c, double d, double e, double f, double g, double h, double i)
construct matrix from row vectors
Definition: glslmath.h:1644
vec3::vec3
vec3(const double v)
single-component constructor
Definition: glslmath.h:389
length
double length(const vec2 &v)
get vector length
Definition: glslmath.h:221
mat2::row
vec2 row(const int i) const
row getter
Definition: glslmath.h:1206
mat2::operator>>=
mat2 & operator>>=(const mat2 &m)
inplace multiplication (right-hand side)
Definition: glslmath.h:1369
mat3::mat3
mat3(double diag=1.0)
default constructor
Definition: glslmath.h:1549
operator/
vec2 operator/(const vec2 &a, const double b)
right-hand side scalar division
Definition: glslmath.h:205
inverse_transpose
mat4 inverse_transpose(const mat4 &m)
inline inverse transpose
Definition: glslmath.h:2635
vec2::normalize
vec2 normalize() const
normalize vector to unit length
Definition: glslmath.h:229
mat4::frustum
static mat4 frustum(double l, double r, double b, double t, double n, double f)
create frustum matrix
Definition: glslmath.h:2687
mat4::mat4
mat4(const vec4 &diag)
custom constructor
Definition: glslmath.h:2145
mat3::mat3
mat3(const mat2 &m)
copy constructor
Definition: glslmath.h:1599
vec4::xy
vec2 xy() const
swizzeling operator
Definition: glslmath.h:811
vec4::bgra
vec4 bgra() const
swizzeling operator
Definition: glslmath.h:831
mat2::mat2
mat2(double diag=1.0)
default constructor
Definition: glslmath.h:1135
mat2f::fromOpenGL
void fromOpenGL(const float m[4])
convert from 4-element column-major OpenGL matrix
Definition: glslmath.h:1503
vec2::operator*=
vec2 & operator*=(double v)
inplace multiplication
Definition: glslmath.h:158
vec3::norm
double norm() const
get squared vector length
Definition: glslmath.h:423
vec2::vec2
vec2()
default constructor
Definition: glslmath.h:113
vec2f
2D float vector
Definition: glslmath.h:261
mat3f::mat3f
mat3f(const mat3 &m)
copy constructor
Definition: glslmath.h:1978
determinant
double determinant(const mat4 &m)
inline determinant
Definition: glslmath.h:2623
vec4f::vec4f
vec4f(const vec3f &v, const float vw=1.0f)
copy constructor
Definition: glslmath.h:975
mat3f::fromOpenGL
void fromOpenGL(const float m[9])
convert from 9-element column-major OpenGL matrix
Definition: glslmath.h:2063
mat3::mat3
mat3(const vec3 &r1, const vec3 &r2, const vec3 &r3=vec3(0, 0, 1))
custom constructor
Definition: glslmath.h:1581
vec3
3D double vector
Definition: glslmath.h:372
mat2
2x2 double matrix
Definition: glslmath.h:1130
glslmath::itest_ray_bbox
int itest_ray_bbox(const vec3 &o, const vec3 &d, const vec3 &b, const vec3 &r)
geometric ray/bbox intersection test
Definition: glslmath.h:3765
vec2::length
double length() const
get vector length
Definition: glslmath.h:133
glslmath::vtest_plane_sphere
int vtest_plane_sphere(const vec3 &o, const vec3 &n, const vec3 &center, double radius)
bounding sphere visibility test
Definition: glslmath.h:3850
mat3f::col
vec3f col(const int i) const
column getter
Definition: glslmath.h:2044
vec4f::vec4f
vec4f(const vec2f &v, const float vz=0.0f, const float vw=1.0f)
copy constructor
Definition: glslmath.h:981
mat4
4x4 double matrix
Definition: glslmath.h:2116
glslmath::itest_cone_sphere
int itest_cone_sphere(const vec3 &o, const vec3 &d, double cone, const vec3 &b, const double r)
geometric cone/sphere intersection test
Definition: glslmath.h:3744
vec2::vec2
vec2(const vec2 &v)
copy constructor
Definition: glslmath.h:116
vec4::blend
vec4 blend(const vec4 &rgba) const
blending operator
Definition: glslmath.h:949
mat3::scale
static mat3 scale(const vec3 &c)
create scaling matrix
Definition: glslmath.h:1762
mat4::getRotation
mat3 getRotation() const
get 3x3 rotation submatrix (matrix is assumed to be orthonormal)
Definition: glslmath.h:2290
glslmath::ray_triangle_dist
double ray_triangle_dist(const vec3 &o, const vec3 &d, const vec3 &v1, const vec3 &v2, const vec3 &v3)
calculate hit distance on ray to triangle
Definition: glslmath.h:3708
vec3::approx
bool approx(const vec3 &v, const double e=1E-10) const
test for approximate equality
Definition: glslmath.h:446
vec4f
4D float vector
Definition: glslmath.h:961
operator+
vec2 operator+(const vec2 &a, const vec2 &b)
addition of two vectors
Definition: glslmath.h:185
mat3f::mat3f
mat3f(float diag=1.0f)
default constructor
Definition: glslmath.h:1944
reflect
vec3 reflect(const vec3 &v, const vec3 &n)
reflect incident vector at normalized surface normal
Definition: glslmath.h:560
operator==
bool operator==(const vec2 &a, const vec2 &b)
comparison
Definition: glslmath.h:213
vec3::vec3
vec3(const vec2 &v, const double vz=0.0)
copy constructor
Definition: glslmath.h:383
quat::invert
quat invert() const
invert normalized quaternion
Definition: glslmath.h:3010
mat3f::operator[]
vec3f operator[](const int i) const
subscript operator (column getter)
Definition: glslmath.h:2030
vec4::area
static double area(const vec4 &a, const vec4 &b, const vec4 &c)
calculate triangle area
Definition: glslmath.h:945
mat3f::columns
static mat3f columns(float a, float b, float c, float d, float e, float f, float g, float h, float i)
construct matrix from column vectors
Definition: glslmath.h:2002
vec3::vec3
vec3(const vec3 &v)
copy constructor
Definition: glslmath.h:380
mat4f::operator[]
vec4f operator[](const int i) const
subscript operator (column getter)
Definition: glslmath.h:2874
vec3f::operator*=
vec3f & operator*=(float v)
inplace multiplication
Definition: glslmath.h:630
mat4::invert
static mat4 invert(const mat4 &m)
static version of invert operation
Definition: glslmath.h:2405
vec4::approx
bool approx(const vec4 &v, const double e=1E-10) const
test for approximate equality
Definition: glslmath.h:807
mat4f::c_ptr
const float * c_ptr() const
const pointer to column-major array
Definition: glslmath.h:2899
mat4f::rows
static mat4f rows(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p)
construct matrix from row vectors
Definition: glslmath.h:2862
vec3f::vec3f
vec3f(const float vx, const float vy, const float vz)
component-wise constructor
Definition: glslmath.h:604
mat4f::fromOpenGL
void fromOpenGL(const float m[16])
convert from 16-element column-major OpenGL matrix
Definition: glslmath.h:2907
mat2::transpose
mat2 transpose() const
transpose 2x2 matrix
Definition: glslmath.h:1246
vec3::normal
static vec3 normal(const vec3 &a, const vec3 &b, const vec3 &c)
calculate triangle normal
Definition: glslmath.h:564
vec3::cross
vec3 cross(const vec3 &v) const
cross product (0,0,-1)/(-1,0,0)=(0,1,0)
Definition: glslmath.h:433
vec2::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:174
quat::operator+
friend quat operator+(const quat &a, const quat &b)
addition of two quaternions
Definition: glslmath.h:3076
vec3f::c_ptr
const float * c_ptr() const
const pointer to linear array
Definition: glslmath.h:614
rotate
mat4 rotate(const mat4 &m, double angle, const vec3 &v)
inline rotate
Definition: glslmath.h:2611
vec3f::operator-=
vec3f & operator-=(const vec3f &v)
inplace subtraction
Definition: glslmath.h:626
mat4::rows
static mat4 rows(const vec4 &r1, const vec4 &r2, const vec4 &r3, const vec4 &r4)
construct matrix from row vectors
Definition: glslmath.h:2244
vec4f::operator-=
vec4f & operator-=(const vec4f &v)
inplace subtraction
Definition: glslmath.h:1030
mat4::translate
static mat4 translate(const vec4 &v)
create translation matrix
Definition: glslmath.h:2436
mat4::col
vec4 col(const int i) const
column getter
Definition: glslmath.h:2279
glslmath::distance2line
double distance2line(vec3 p, vec3 a, vec3 b)
calculate the distance of a point p from a line segment between vectors a and b
Definition: glslmath.h:3527
mat4f::rows
static mat4f rows(const vec4f &r1, const vec4f &r2, const vec4f &r3, const vec4f &r4)
construct matrix from row vectors
Definition: glslmath.h:2853
vec3f::xy
vec2f xy() const
swizzeling operator
Definition: glslmath.h:638
vec2f::vec2f
vec2f(const vec2f &v)
copy constructor
Definition: glslmath.h:269
glslmath::itest_plane_sphere
int itest_plane_sphere(const vec3 &o, const vec3 &n, const double radius, const vec3 &b, const double r2)
geometric plane/sphere intersection test
Definition: glslmath.h:3827
quat::rotate
static quat rotate(double angle, const vec3 &v)
create rotating quaternion
Definition: glslmath.h:3036
vec4::operator*=
vec4 & operator*=(double v)
inplace multiplication
Definition: glslmath.h:770
mat2::columns
static mat2 columns(const vec2 &c1, const vec2 &c2)
construct matrix from column vectors
Definition: glslmath.h:1169
vec4::vec4
vec4(const vec2 &v, const double vz=0.0, const double vw=1.0)
copy constructor
Definition: glslmath.h:727
mat4::det
double det() const
calculate determinant of 4x4 matrix
Definition: glslmath.h:2330
quat
quaternion
Definition: glslmath.h:2972
mat4::rows
static mat4 rows(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l, double m, double n, double o, double p)
construct matrix from row vectors
Definition: glslmath.h:2253
mat3::det
static double det(const mat3 &m)
static version of determinant operation
Definition: glslmath.h:1711
mat2::scale
static mat2 scale(double s, double t)
create scaling matrix
Definition: glslmath.h:1280
mat4f::columns
static mat4f columns(const vec4f &c1, const vec4f &c2, const vec4f &c3, const vec4f &c4)
construct matrix from column vectors
Definition: glslmath.h:2832
vec4f::xy
vec2f xy() const
swizzeling operator
Definition: glslmath.h:1042
vec3::operator*=
vec3 & operator*=(double v)
inplace multiplication
Definition: glslmath.h:412
vec3f::zyx
vec3f zyx() const
swizzeling operator
Definition: glslmath.h:642
mat2::mat2
mat2(const vec2 &diag)
custom constructor
Definition: glslmath.h:1145
dot
double dot(const vec2 &a, const vec2 &b)
inner product
Definition: glslmath.h:241
vec3::length
double length() const
get vector length
Definition: glslmath.h:420
vec4::vec4
vec4(const vec2 &xy, const vec2 &zw)
copy constructor
Definition: glslmath.h:730
mat4::transpose
static mat4 transpose(const mat4 &m)
static version of transpose operation
Definition: glslmath.h:2367
operator<<
std::ostream & operator<<(std::ostream &out, const vec2 &v)
output operator
Definition: glslmath.h:253
mat2::rows
static mat2 rows(const vec2 &r1, const vec2 &r2)
construct matrix from row vectors
Definition: glslmath.h:1184
mat2::rows
static mat2 rows(double a, double b, double c, double d)
construct matrix from row vectors
Definition: glslmath.h:1191
vec3::reflect
vec3 reflect(const vec3 &n) const
reflect incidental vector at normalized surface normal
Definition: glslmath.h:556
mat4::scale
static mat4 scale(double s, double t, double r, double w=1.0)
create scaling matrix
Definition: glslmath.h:2409
vec4::xyz
vec3 xyz() const
swizzeling operator
Definition: glslmath.h:819
vec4::dot
double dot(const vec4 &v) const
inner product
Definition: glslmath.h:787
mat4f::col
vec4f col(const int i) const
column getter
Definition: glslmath.h:2888
quat::length
double length() const
get quaternion length
Definition: glslmath.h:2996
mat3::invert
static mat3 invert(const mat3 &m)
static version of invert operation
Definition: glslmath.h:1750
vec4::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:842
vec2::dot
double dot(const vec2 &v) const
inner product
Definition: glslmath.h:142
vec3f::vec3f
vec3f(const vec3 &v)
copy constructor
Definition: glslmath.h:595
glslnoise::perlinnoise
perlin noise
Definition: glslmath.h:3868
mat3
3x3 double matrix
Definition: glslmath.h:1544
mat3::transpose
static mat3 transpose(const mat3 &m)
static version of transpose operation
Definition: glslmath.h:1719
glslmath::vtest_plane_point
int vtest_plane_point(const vec3 &o, const vec3 &n, const vec3 &point)
point visibility test
Definition: glslmath.h:3843
cross
vec3 cross(const vec3 &a, const vec3 &b)
cross product
Definition: glslmath.h:544
mat3::c_ptr
const double * c_ptr() const
const pointer to column-major array
Definition: glslmath.h:1679
glslmath::intersect_ray_triangle
int intersect_ray_triangle(const vec3 &o, const vec3 &d, const vec3 &v0, const vec3 &v1, const vec3 &v2, vec3 &tuv)
Moeller-Trumbore ray/triangle intersection.
Definition: glslmath.h:3659
glslmath::distance2ray
double distance2ray(vec3 p, vec3 o, vec3 d)
calculate the distance of a point p from a ray
Definition: glslmath.h:3505
vec3::to_string
std::string to_string(std::string delimiter=", ", int space=0)
conversion to string
Definition: glslmath.h:469
normalize
vec2 normalize(const vec2 &v)
normalization to unit length
Definition: glslmath.h:237
vec3::c_ptr
const double * c_ptr() const
const pointer to linear array
Definition: glslmath.h:396
mat3f::mat3f
mat3f(const vec3f &r1, const vec3f &r2, const vec3f &r3=vec3f(0, 0, 1))
custom constructor
Definition: glslmath.h:1960
vec3::bgr
vec3 bgr() const
swizzeling operator
Definition: glslmath.h:458
vec4::length
double length() const
get vector length
Definition: glslmath.h:778
transpose
mat4 transpose(const mat4 &m)
inline transpose
Definition: glslmath.h:2627
mat2f::mat2f
mat2f(float diag=1.0f)
default constructor
Definition: glslmath.h:1413
quat::dot
double dot(const quat &r) const
inner product
Definition: glslmath.h:2992
vec2f::vec2f
vec2f(const float vx, const float vy)
component-wise constructor
Definition: glslmath.h:275
mat2::invert
static mat2 invert(const mat2 &m)
static version of invert operation
Definition: glslmath.h:1276
quat::conjugate
quat conjugate() const
conjugation
Definition: glslmath.h:3006
scale
mat4 scale(const mat4 &m, const vec4 &c)
inline scale
Definition: glslmath.h:2591
mat3f
3x3 float matrix
Definition: glslmath.h:1939
vec4f::vec4f
vec4f(const vec2 &v, const float vz=0.0f, const float vw=1.0f)
copy constructor
Definition: glslmath.h:984
vec4::reflect
vec4 reflect(const vec4 &n) const
reflect incident vector at normalized surface normal
Definition: glslmath.h:930
mat2::det
double det() const
calculate determinant of 2x2 matrix
Definition: glslmath.h:1238
vec4f::operator*=
vec4f & operator*=(float v)
inplace multiplication
Definition: glslmath.h:1034
mat3f::rows
static mat3f rows(const vec3f &r1, const vec3f &r2, const vec3f &r3)
construct matrix from row vectors
Definition: glslmath.h:2012
vec4::vec4
vec4(const double v, const double vw=1.0)
single-component constructor
Definition: glslmath.h:736
vec4f::vec4f
vec4f(const vec2f &xy, const vec2f &zw)
copy constructor
Definition: glslmath.h:987
mat4f::mat4f
mat4f(float diag=1.0f)
default constructor
Definition: glslmath.h:2757
vec4f::rgb
vec3f rgb() const
swizzeling operator
Definition: glslmath.h:1054
mat4::invert
mat4 invert() const
invert 4x4 matrix
Definition: glslmath.h:2371
mat4::getTranslation
vec3 getTranslation() const
get translation column vector (matrix is assumed to be affine)
Definition: glslmath.h:2294
vec3f::vec3f
vec3f()
default constructor
Definition: glslmath.h:589
mat3::invert
mat3 invert() const
invert 3x3 matrix
Definition: glslmath.h:1723
mat4::lookat
static mat4 lookat(const vec3 &eye, const vec3 &center, const vec3 &up=vec3(0, 1, 0))
create lookat matrix
Definition: glslmath.h:2731
vec4::vec4
vec4(const vec3 &v, const double vw=1.0)
copy constructor
Definition: glslmath.h:724
mat4::translate
static mat4 translate(double x, double y, double z)
create translation matrix
Definition: glslmath.h:2427
mat3::transpose
mat3 transpose() const
transpose 3x3 matrix
Definition: glslmath.h:1715
quat::operator-
friend quat operator-(const quat &a, const quat &b)
subtraction of two quaternions
Definition: glslmath.h:3080
mat2::rotate
static mat2 rotate(double angle)
create rotation matrix
Definition: glslmath.h:1295
operator!=
bool operator!=(const vec2 &a, const vec2 &b)
negated comparison
Definition: glslmath.h:217
glslmath::distance2line2
double distance2line2(vec3 p, vec3 a, vec3 b)
calculate the squared distance of a point p from a line segment between vectors a and b
Definition: glslmath.h:3545
vec2f::vec2f
vec2f()
default constructor
Definition: glslmath.h:266
mat3::rotate
static mat3 rotate(double angle, double vx, double vy, double vz)
create rotation matrix
Definition: glslmath.h:1771
mat4::rigid
static mat4 rigid(double a, const vec3 &v, const vec3 &t)
create rigid-body transformation matrix
Definition: glslmath.h:2463
mat2::fromOpenGL
void fromOpenGL(const double m[4])
convert from 4-element column-major OpenGL matrix
Definition: glslmath.h:1228
mat4f::columns
static mat4f columns(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p)
construct matrix from column vectors
Definition: glslmath.h:2841
vec4::cross
vec4 cross(const vec4 &v) const
cross product (0,0,-1,0)/(-1,0,0,0)=(0,1,0,0)
Definition: glslmath.h:791
glslmath::intersect_ray_ellipsoid
double intersect_ray_ellipsoid(vec3 p, vec3 d, vec3 o, double r1, double r2, double r3)
ray/ellipsoid intersection
Definition: glslmath.h:3627
mat2::mat2
mat2(const vec2 &r1, const vec2 &r2)
custom constructor
Definition: glslmath.h:1155
vec4f::xyz
vec3f xyz() const
swizzeling operator
Definition: glslmath.h:1050
mat3::col
vec3 col(const int i) const
column getter
Definition: glslmath.h:1668
mat4::operator>>=
mat4 & operator>>=(const mat4 &m)
inplace multiplication (right-hand side)
Definition: glslmath.h:2562
vec4f::c_ptr
const float * c_ptr() const
const pointer to linear array
Definition: glslmath.h:1018
mat3::rotate
static mat3 rotate(const vec3 &from, const vec3 &to)
create rotation matrix
Definition: glslmath.h:1806
vec3::vec3
vec3(const double vx, const double vy, const double vz)
component-wise constructor
Definition: glslmath.h:386
glslmath::intersect_ray_unitsphere
double intersect_ray_unitsphere(vec3 p, vec3 d)
ray/unitsphere intersection
Definition: glslmath.h:3587
mat4::parallel
static mat4 parallel(const vec3 &p, const vec3 &n, const vec3 &d)
create parallel projection matrix
Definition: glslmath.h:2698
mat2::operator<<=
mat2 & operator<<=(const mat2 &m)
inplace multiplication (left-hand side)
Definition: glslmath.h:1362
mat2::operator[]
vec2 operator[](const int i) const
subscript operator (column getter)
Definition: glslmath.h:1199
mat3::fromOpenGL
void fromOpenGL(const double m[9])
convert from 9-element column-major OpenGL matrix
Definition: glslmath.h:1687
quat::quat
quat(double x, double y, double z, double w)
custom constructor
Definition: glslmath.h:2982
mat4::det
static double det(const mat4 &m)
static version of determinant operation
Definition: glslmath.h:2359
mat4::operator+=
mat4 & operator+=(const mat4 &m)
inplace addition
Definition: glslmath.h:2541
mat4::transform
static mat4 transform(const mat3 &m, const vec3 &v)
create affine (resp.
Definition: glslmath.h:2647
mat3::columns
static mat3 columns(double a, double b, double c, double d, double e, double f, double g, double h, double i)
construct matrix from column vectors
Definition: glslmath.h:1626
mat2f::col
vec2f col(const int i) const
column getter
Definition: glslmath.h:1488
mat2f::operator[]
vec2f operator[](const int i) const
subscript operator (column getter)
Definition: glslmath.h:1474
operator-
vec2 operator-(const vec2 &a, const vec2 &b)
subtraction of two vectors
Definition: glslmath.h:189
mat3::operator[]
vec3 operator[](const int i) const
subscript operator (column getter)
Definition: glslmath.h:1654
mat2::columns
static mat2 columns(double a, double b, double c, double d)
construct matrix from column vectors
Definition: glslmath.h:1176
mat4::c_ptr
const double * c_ptr() const
const pointer to column-major array
Definition: glslmath.h:2298
mat3::operator<<=
mat3 & operator<<=(const mat3 &m)
inplace multiplication (left-hand side)
Definition: glslmath.h:1890
vec2::vec2
vec2(const double v)
single-component constructor
Definition: glslmath.h:122
vec3::vec3
vec3()
default constructor
Definition: glslmath.h:377
glslmath::print
void print(const char *s="", std::string prefix="", std::ostream &out=std::cout)
pretty print
Definition: glslmath.h:3127
quat::quat
quat(const vec3 &v, double w)
custom constructor
Definition: glslmath.h:2987
vec4f::vec4f
vec4f(const vec4 &v)
copy constructor
Definition: glslmath.h:972
mat4::ortho
static mat4 ortho(double l, double r, double b, double t, double n=-1, double f=1)
create orthographic matrix
Definition: glslmath.h:2677
mat4::rotate
static mat4 rotate(const vec3 &from, const vec3 &to)
create rotation matrix
Definition: glslmath.h:2456
mix
vec2 mix(const vec2 &a, const vec2 &b, double w)
linear interpolation (GLSL-style)
Definition: glslmath.h:249