-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvecmath.h
2095 lines (1863 loc) · 71.1 KB
/
vecmath.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//
// linear algebra math classes and functions
// Vector classes: Vec3f, Vec3d (float and double)
// Matrix classes: Mtx3f, Mtx3d
// (x)
// vectors on column major form, i.e., v=(y)
// (z)
// Author: Tomas Akenine-Möller
// History: 1991 started (used to be good (on the PC which had some extra C++ features))
// 2000 May, added so that you can write vector[XI]=5.0;
// 2000 May, started to add the Vec4 template class
// 2004 May, added union (again)
#ifndef VECMATH_H
#define VECMATH_H
#include <math.h>
#include <stdio.h>
#include <assert.h>
#include "misc.h"
//#include "types.h"
#define XI 0
#define YI 1
#define ZI 2
#define WI 3
#define UI 0
#define VI 1
#define RI 0
#define GI 1
#define BI 2
#define AI 3 /* alpha */
/* fix this later */
/* #include <limits> */
/* using namespace std; */
template<class CoordType> class Vec2
{
public:
union
{
CoordType vec[2];
struct
{
CoordType x,y;
};
};
// constructors and desctructor
Vec2(); // empty constructor: coords are undefined!!!! =INF if debug
Vec2(CoordType xc, CoordType yc);
Vec2(const Vec2 &v);
~Vec2() { }
void set(const Vec2 &v);
void set(CoordType xc, CoordType yc);
CoordType length(void) const; // length of vector
CoordType length2(void) const; // squared length of vector
// normalize vector (only if length>0.0), returns *this
const Vec2<CoordType>& normalize(void);
CoordType normalizeIf(void); // normalize vector (only if length>0.0)
void operator=(const Vec2 &v); // operator: assignment
Vec2<CoordType> operator*(CoordType t) const; // operator: scaling by scalar
Vec2<CoordType> operator+(const Vec2 &v) const; // operator: addition
Vec2<CoordType> operator-(const Vec2 &v) const; // operator: subtraction
Vec2<CoordType> operator-(void) const; // unary -
Vec2<CoordType> operator^(const Vec2 &v) const; // elementwise multiplication
// elementwise multiplication with functio name instead of operator
Vec2<CoordType> mult(const Vec2 &v) const;
void operator+=(const Vec2 &v); // operator: +=
void operator-=(const Vec2 &v); // operator: -=
void operator*=(CoordType t); // operator: *= (scaling)
CoordType operator*(const Vec2 &v) const; // operator: dot product
// dot product with function name instead of operator
CoordType dot(const Vec2 &v) const;
Vec2<CoordType> lerp(CoordType a,const Vec2 &v) const; // returns a*this+(1-a)*v
bool operator==(const Vec2 &v) const; // equality
bool operator!=(const Vec2 &v) const; // inequality
CoordType& operator[](unsigned short index);
const CoordType& operator[](unsigned short index) const;
void debugprint(void) const;// print coords
};
template<class CoordType>
class Vec3
{
public:
union
{
CoordType vec[3];
struct
{
CoordType x,y,z;
};
};
// constructors and destructor
Vec3(); // empty constructor: coords are undefined!!!! =INF if debug
Vec3(CoordType xc, CoordType yc, CoordType zc);
Vec3(const Vec3 &v);
~Vec3() { }
void set(const Vec3 &v);
void set(CoordType xc, CoordType yc, CoordType zc);
CoordType length(void) const; // length of vector
CoordType length2(void) const; // squared length of vector
// normalize vector (only if length>0.0), returns *this
const Vec3<CoordType>& normalize(void);
CoordType normalizeIf(void); // normalize vector (only if length>0.0)
void operator=(const Vec3 &v); // operator: assignment
Vec3<CoordType> operator*(CoordType t) const; // operator: scaling by scalar
Vec3<CoordType> operator+(const Vec3 &v) const; // operator: addition
Vec3<CoordType> operator-(const Vec3 &v) const; // operator: subtraction
Vec3<CoordType> operator-(void) const; // unary -
Vec3<CoordType> operator^(const Vec3 &v) const; // elementwise multiplication
// elementwise multiplication with functio name instead of operator
Vec3<CoordType> mult(const Vec3 &v) const;
void operator+=(const Vec3 &v); // operator: +=
void operator-=(const Vec3 &v); // operator: -=
void operator*=(CoordType t); // operator: *= (scaling)
CoordType operator*(const Vec3 &v) const; // operator: dot product
// dot product with function name instead of operator
CoordType dot(const Vec3 &v) const;
Vec3<CoordType> operator%(const Vec3 &v) const; // operator: cross product
// cross product with function name instead of operator
Vec3<CoordType> cross(const Vec3 &v) const;
Vec3<CoordType> lerp(CoordType a,const Vec3 &v) const; // returns a*this+(1-a)*v
bool operator==(const Vec3 &v) const; // equality
bool operator!=(const Vec3 &v) const; // inequality
// if index=0 then x, index=1 then y, index=2 then z
CoordType& operator[](unsigned short index);
const CoordType& operator[](unsigned short index) const;
Vec3<CoordType> perpVector(void) const; // create a vector that is perp to this
unsigned int toRGBA(void) const;
void debugprint(void) const; // print coords
};
// not finished yet...
template<class CoordType>
class Vec4
{
public:
union
{
CoordType vec[4];
struct
{
CoordType x,y,z,w;
};
};
// constructors and desctructor
Vec4(); // empty constructor: coords are undefined!!!! =INF if debug
Vec4(CoordType xc, CoordType yc, CoordType zc, CoordType wc);
Vec4(const Vec4 &v);
Vec4(const unsigned int packedCol);
~Vec4() { }
void set(const Vec4 &v);
void set(CoordType xc, CoordType yc, CoordType zc, CoordType wc);
//CoordType length(void) const; // length of vector
//CoordType length2(void) const; // squared length of vector
// normalize vector (only if length>0.0), returns *this
const Vec4<CoordType>& normalize(void);
//CoordType normalizeIf(void); // normalize vector (only if length>0.0)
void operator=(const Vec4 &v); // operator: assignment
Vec4<CoordType> operator*(CoordType t) const; // operator: scaling by scalar
Vec4<CoordType> operator+(const Vec4 &v) const; // operator: addition
Vec4<CoordType> operator-(const Vec4 &v) const; // operator: subtraction
//Vec3<CoordType> operator-(void) const; // unary -
Vec4<CoordType> operator^(const Vec4 &v) const; // elementwise multiplication
// elementwise multiplication with functio name instead of operator
//Vec3<CoordType> mult(const Vec3 &v) const;
//void operator+=(const Vec3 &v); // operator: +=
//void operator-=(const Vec3 &v); // operator: -=
//void operator*=(CoordType t); // operator: *= (scaling)
CoordType operator*(const Vec4 &v) const; // operator: dot product
// dot product with function name instead of operator
//CoordType dot(const Vec3 &v) const;
//Vec3<CoordType> operator%(const Vec3 &v) const; // operator: cross product
// cross product with function name instead of operator
//Vec3<CoordType> cross(const Vec3 &v) const;
Vec4<CoordType> lerp(CoordType a,const Vec4 &v) const; // returns a*this+(1-a)*v
//bool operator==(const Vec3 &v) const; // equality
//bool operator!=(const Vec3 &v) const; // inequality
// if index=0 then x, index=1 then y, index=2 then z
CoordType& operator[](unsigned short index);
const CoordType& operator[](unsigned short index) const;
void debugprint(void) const; // print coords
unsigned int toRGBA(void) const;
};
// Mtx3 -- the 3x3 matrix class
//
// the element order of a matrix (done like this to facilitate OpenGL glLoadMatrix etc,
// this is mostly important for 4x4 matrices
// ( m[0][0] m[1][0] m[2][0] )
// ( m[0][1] m[1][1] m[2][1] )
// ( m[0][2] m[1][2] m[2][2] )
//
// vectors are colum major, i.e. a matrix vector mult is: w=M*v, where w,v are vectors, M matrix
//
template<class CoordType>
class Mtx3
{
public:
union
{
CoordType mtx[3][3];
CoordType array[3*3];
};
// constructors and desctructor
Mtx3(); // empty constructor: matrix is undefined!!!! =INF if debug
Mtx3(CoordType m00, CoordType m10, CoordType m20,
CoordType m01, CoordType m11, CoordType m21,
CoordType m02, CoordType m12, CoordType m22);
Mtx3(const Mtx3 &m);
~Mtx3() { }
void set(const Mtx3 &m);
void set(CoordType m00, CoordType m10, CoordType m20,
CoordType m01, CoordType m11, CoordType m21,
CoordType m02, CoordType m12, CoordType m22);
void set(int x,int y,CoordType m);
void operator=(const Mtx3 &m); // operator: assignment
// if index=0 then col vec 0, index=1 then col vec 1, else col vec 2
Vec3<CoordType> operator[](unsigned short index) const;
Mtx3<CoordType> operator+(const Mtx3 &m) const; // operator: addition
Mtx3<CoordType> operator-(const Mtx3 &m) const; // operator: subtraction
Mtx3<CoordType> operator-(void) const; // unary -
Mtx3<CoordType> operator*(const Mtx3 &m) const; // operator: matrix matrix mult
Vec3<CoordType> operator*(const Vec3<CoordType> &v) const; // operator: matrix vector mult
void operator+=(const Mtx3 &m); // operator: +=
void operator-=(const Mtx3 &m); // operator: -=
void operator*=(const Mtx3 &m); // operator: *=
bool operator==(const Mtx3 &m) const; // equality
bool operator!=(const Mtx3 &m) const; // inequality
void loadIdentity(void);// load matrix with identity matrix
void rotX(CoordType radians);// creates a rotation matrix, "radians" around X-axis
void rotY(CoordType radians);// creates a rotation matrix, "radians" around Y-axis
void rotZ(CoordType radians);// creates a rotation matrix, "radians" around Z-axis
// creates rotation matrix, rotates "radians" around "axis", axis must be normalized
void rotAxis(Vec3<CoordType> &axis,CoordType radians);
// rotation matrix, from from-vector to to-vector (from, to must be normalized)
void vecRotVec(Vec3<CoordType> &from,Vec3<CoordType> &to);
// creates a scaling matrix
void scale(CoordType scaleX,CoordType scaleY,CoordType scaleZ);
void transpose(void);
bool invert(void); // returns true if invertible (and inverts), otherwise no action
void invertOrtho(void);
bool QLAlgorithm(CoordType afDiag[3], CoordType afSubDiag[3]);
void tridiagonal(CoordType afDiag[3], CoordType afSubDiag[3]);
void eigenSolveSymmetric(CoordType afEigenvalue[3],
Vec3<CoordType> akEigenvector[3]) const;
void debugprint(void) const; // print coords
//static const Mtx3<float> identity; // could not get this to work
};
template<class CoordType>
class Mtx4
{
public:
union
{
CoordType mtx[4][4];
CoordType array[4*4];
};
// constructors and desctructor
Mtx4(); // empty constructor: matrix is undefined!!!! =INF if debug
Mtx4(CoordType m00, CoordType m10, CoordType m20, CoordType m30,
CoordType m01, CoordType m11, CoordType m21, CoordType m31,
CoordType m02, CoordType m12, CoordType m22, CoordType m32,
CoordType m03, CoordType m13, CoordType m23, CoordType m33);
Mtx4(const Mtx4 &m);
~Mtx4() { }
void set(const Mtx4 &m);
void set(CoordType m00, CoordType m10, CoordType m20, CoordType m30,
CoordType m01, CoordType m11, CoordType m21, CoordType m31,
CoordType m02, CoordType m12, CoordType m22, CoordType m32,
CoordType m03, CoordType m13, CoordType m23, CoordType m33);
void operator=(const Mtx4 &m); // operator: assignment
Mtx4<CoordType> operator+(const Mtx4 &m) const; // operator: addition
Mtx4<CoordType> operator-(const Mtx4 &m) const; // operator: subtraction
Mtx4<CoordType> operator-(void) const; // unary -
Mtx4<CoordType> operator*(const Mtx4 &m) const; // operator: matrix matrix mult
Vec4<CoordType> operator*(const Vec4<CoordType> &v) const; // operator: matrix vector mult
void operator+=(const Mtx4 &m); // operator: +=
void operator-=(const Mtx4 &m); // operator: -=
void operator*=(const Mtx4 &m); // operator: *=
bool operator==(const Mtx4 &m) const; // equality
bool operator!=(const Mtx4 &m) const; // inequality
Vec3<CoordType> multPnt(const Vec3<CoordType> &v) const; // operator: matrix point mult
Vec3<CoordType> multVec(const Vec3<CoordType> &v) const; // operator: matrix vector mult
Vec3<CoordType> multDivW(const Vec3<CoordType> &v, CoordType vectorW) const; // operator: "matrix point with translation and division of W afterwards" mult
void loadIdentity(void);// load matrix with identity matrix
void rotX(CoordType radians);// creates a rotation matrix, "radians" around X-axis
void rotY(CoordType radians);// creates a rotation matrix, "radians" around Y-axis
void rotZ(CoordType radians);// creates a rotation matrix, "radians" around Z-axis
void rotAxis(Vec3<CoordType> &axis,CoordType radians); // creates rotation matrix, rotates "radians" around "axis", axis must be normalized
void vecRotVec(Vec3<CoordType> &from,Vec3<CoordType> &to); // rotation matrix, from from-vector to to-vector (from, to must be normalized)
void billboardMatrix(Vec3<CoordType> &fromVIew, Vec3<CoordType> &fromUp,Vec3<CoordType> &toVIew,Vec3<CoordType> toUp);
void translate(CoordType tx, CoordType ty, CoordType tz);
void scale(CoordType scaleX,CoordType scaleY,CoordType scaleZ); // creates a scaling matrix
void transpose(void);
bool invert(void);// returns true if invertible (and inverts), otherwise no action
void invertOrtho(void);// simply the transpose of the upper left 3x3 matrix
void invertOrthoTrans(void);// inverse of orthogonal 3x3 plus translation
void debugprint(void) const;// print coords
//static const Mtx4<float> identity; // could not get this to work
};
#define SWAP(A,B) {CoordType c=A; A=B; B=c;}
///////////////////////////////////////////////////////
// Inline functions //
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
// Vec2 functions //
///////////////////////////////////////////////////////
template<class CoordType>
inline Vec2<CoordType>::Vec2()
{
#if _DEBUG
// x=y=numeric_limits<CoordType>::infinity();
#endif
}
template<class CoordType>
inline Vec2<CoordType>::Vec2(CoordType xc, CoordType yc)
{
vec[0]=xc;
vec[1]=yc;
}
template<class CoordType>
inline Vec2<CoordType>::Vec2(const Vec2 &v)
{
vec[0]=v[0];
vec[1]=v[1];
}
template<class CoordType>
inline void Vec2<CoordType>::set(const Vec2 &v)
{
vec[0]=v[0];
vec[1]=v[0];
}
template<class CoordType>
inline void Vec2<CoordType>::set(CoordType xc,CoordType yc)
{
vec[0]=xc;
vec[1]=yc;
}
// length of vector
template<class CoordType>
inline CoordType Vec2<CoordType>::length(void) const
{
return (CoordType)sqrt(vec[0]*vec[0]+vec[1]*vec[1]);
}
// squared length of vector
template<class CoordType>
inline CoordType Vec2<CoordType>::length2(void) const
{
return vec[0]*vec[0]+vec[1]*vec[1];
}
// normalize vector if length>0.0
template<class CoordType>
inline const Vec2<CoordType>& Vec2<CoordType>::normalize(void)
{
CoordType len2=vec[0]*vec[0]+vec[1]*vec[1];
/* assert(len2>numeric_limits<CoordType>::epsilon()); */
/* if(len2>numeric_limits<CoordType>::epsilon()) */
if(len2>0.0000001) /* fix this */
{
CoordType invlen=(CoordType)(1.0/sqrt(len2));
vec[0]*=invlen;
vec[1]*=invlen;
}
return *this;
}
// normalize vector if length>0.0, returns length
template<class CoordType>
inline CoordType Vec2<CoordType>::normalizeIf(void)
{
CoordType len2=vec[0]*vec[0]+vec[1]*vec[1];
/* if(len2>numeric_limits<CoordType>::epsilon()) */
if(len2>0.0000001) /* fix this */
{
CoordType len=(CoordType)sqrt(len2);
CoordType invlen=1.0/len;
vec[0]*=invlen;
vec[1]*=invlen;
return len;
}
else
{
return 0.0;
}
}
// operator: assignment
template<class CoordType>
inline void Vec2<CoordType>::operator=(const Vec2 &v)
{
vec[0]=v[0];
vec[1]=v[1];
}
// operator: scaling by scalar
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::operator*(CoordType t) const
{
return Vec2<CoordType>(t*vec[0], t*vec[1]);
}
// operator: addition
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::operator+(const Vec2 &v) const
{
return Vec2<CoordType>(vec[0]+v[0], vec[1]+v[1]);
}
// operator: subtraction
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::operator-(const Vec2 &v) const
{
return Vec2<CoordType>(vec[0]-v[0], vec[1]-v[1]);
}
// operator: unary -
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::operator-(void) const
{
return Vec2<CoordType>(-vec[0], -vec[1]);
}
// operator: elementwise multiplication
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::operator^(const Vec2 &v) const
{
return Vec2<CoordType>(vec[0]*v[0], vec[1]*v[1]);
}
// elementwise multiplication, same as ^ operator
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::mult(const Vec2 &v) const
{
return Vec2<CoordType>(vec[0]*v[0], vec[1]*v[1]);
}
// operator: +=
template<class CoordType>
inline void Vec2<CoordType>::operator+=(const Vec2 &v)
{
vec[0]+=v[0];
vec[1]+=v[1];
}
// operator: -=
template<class CoordType>
inline void Vec2<CoordType>::operator-=(const Vec2 &v)
{
vec[0]-=v[0];
vec[1]-=v[1];
}
// operator: *=
template<class CoordType>
inline void Vec2<CoordType>::operator*=(CoordType t)
{
vec[0]*=t;
vec[1]*=t;
}
// operator: dot product
template<class CoordType>
inline CoordType Vec2<CoordType>::operator*(const Vec2 &v) const
{
return vec[0]*v[0]+vec[1]*v[1];
}
// dot product (same as operator *)
template<class CoordType>
inline CoordType Vec2<CoordType>::dot(const Vec2 &v) const
{
return vec[0]*v[0]+vec[1]*v[1];
}
// returns a*this+(1-a)*v LERP=Linear intERPolation
template<class CoordType>
inline Vec2<CoordType> Vec2<CoordType>::lerp(CoordType a,const Vec2 &v) const
{
return Vec2<CoordType>(a*vec[0]+(1.0-a)*v[0], a*vec[1]+(1.0-a)*v[1]);
}
// equality
template<class CoordType>
inline bool Vec2<CoordType>::operator==(const Vec2 &v) const
{
return vec[0]==v[0] && vec[1]==v[1];
}
// inequality
template<class CoordType>
inline bool Vec2<CoordType>::operator!=(const Vec2 &v) const
{
return vec[0]!=v[0] || vec[1]!=v[1];
}
// if index=0 then x, index=1 then y
template<class CoordType>
inline CoordType& Vec2<CoordType>::operator[](unsigned short index)
{
assert(index<2);
return vec[index];
}
// if index=0 then x, index=1 then y
template<class CoordType>
inline const CoordType& Vec2<CoordType>::operator[](unsigned short index) const
{
assert(index<2);
return vec[index];
}
// print coords
template<class CoordType>
inline void Vec2<CoordType>::debugprint(void) const
{
fprintf( stderr, "(%2.4f, %2.4f)\n", (float)vec[0], (float)vec[1] );
}
///////////////////////////////////////////////////////
// Vec3 functions //
///////////////////////////////////////////////////////
template<class CoordType>
inline Vec3<CoordType>::Vec3()
{
//#if _DEBUG
/*x=y=z=numeric_limits<CoordType>::infinity(); */
//#endif
}
template<class CoordType>
inline Vec3<CoordType>::Vec3(CoordType xc, CoordType yc, CoordType zc)
{
vec[0]=xc;
vec[1]=yc;
vec[2]=zc;
}
template<class CoordType>
inline Vec3<CoordType>::Vec3(const Vec3 &v)
{
vec[0]=v[0];
vec[1]=v[1];
vec[2]=v[2];
}
template<class CoordType>
inline void Vec3<CoordType>::set(const Vec3 &v)
{
vec[0]=v[0];
vec[1]=v[1];
vec[2]=v[2];
}
template<class CoordType>
inline void Vec3<CoordType>::set(CoordType xc,CoordType yc,CoordType zc)
{
vec[0]=xc;
vec[1]=yc;
vec[2]=zc;
}
template<class CoordType>
inline CoordType Vec3<CoordType>::length(void) const // length of vector
{
return (CoordType)sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
}
template<class CoordType>
inline CoordType Vec3<CoordType>::length2(void) const // squared length of vector
{
return vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2];
}
template<class CoordType>
inline const Vec3<CoordType>& Vec3<CoordType>::normalize(void) // normalize vector if length>0.0
{
CoordType len2=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2];
/*assert(len2>numeric_limits<CoordType>::epsilon()); */
/*if(len2>numeric_limits<CoordType>::epsilon()) */
if(len2>0.00000000000001)
{
CoordType invlen=(CoordType)(1.0/sqrt(len2));
vec[0]*=invlen;
vec[1]*=invlen;
vec[2]*=invlen;
}
return *this;
}
template<class CoordType>
inline CoordType Vec3<CoordType>::normalizeIf(void) // normalize vector if length>0.0, returns length
{
CoordType len2=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2];
/*if(len2>numeric_limits<CoordType>::epsilon()) */
if(len2>0.0000001)
{
CoordType len=(CoordType)sqrt(len2);
CoordType invlen=1.0/len;
vec[0]*=invlen;
vec[1]*=invlen;
vec[2]*=invlen;
return len;
}
else
{
return 0.0;
}
}
template<class CoordType>
inline void Vec3<CoordType>::operator=(const Vec3 &v) // operator: assignment
{
vec[0]=v[0];
vec[1]=v[1];
vec[2]=v[2];
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::operator*(CoordType t) const // operator: scaling by scalar
{
return Vec3<CoordType>(t*vec[0], t*vec[1], t*vec[2]);
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::operator+(const Vec3 &v) const // operator: addition
{
return Vec3<CoordType>(vec[0]+v[0], vec[1]+v[1], vec[2]+v[2]);
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::operator-(const Vec3 &v) const // operator: subtraction
{
return Vec3<CoordType>(vec[0]-v[0], vec[1]-v[1], vec[2]-v[2]);
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::operator-(void) const // operator: unary -
{
return Vec3<CoordType>(-vec[0], -vec[1], -vec[2]);
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::operator^(const Vec3 &v) const // operator: elementwise multiplication
{
return Vec3<CoordType>(vec[0]*v[0], vec[1]*v[1], vec[2]*v[2]);
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::mult(const Vec3 &v) const // elementwise multiplication, same as ^ operator
{
return Vec3<CoordType>(vec[0]*v[0], vec[1]*v[1], vec[2]*v[2]);
}
template<class CoordType>
inline void Vec3<CoordType>::operator+=(const Vec3 &v) // operator: +=
{
vec[0]+=v[0];
vec[1]+=v[1];
vec[2]+=v[2];
}
template<class CoordType>
inline void Vec3<CoordType>::operator-=(const Vec3 &v) // operator: -=
{
vec[0]-=v[0];
vec[1]-=v[1];
vec[2]-=v[2];
}
template<class CoordType>
inline void Vec3<CoordType>::operator*=(CoordType t) // operator: *=
{
vec[0]*=t;
vec[1]*=t;
vec[2]*=t;
}
template<class CoordType>
inline CoordType Vec3<CoordType>::operator*(const Vec3 &v) const // operator: dot product
{
return vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2];
}
template<class CoordType>
inline CoordType Vec3<CoordType>::dot(const Vec3 &v) const // dot product (same as operator *)
{
return vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2];
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::operator%(const Vec3 &v) const // operator: cross product
{
return Vec3(vec[1]*v[2]-vec[2]*v[1], vec[2]*v[0]-vec[0]*v[2], vec[0]*v[1]-vec[1]*v[0]);
}
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::cross(const Vec3 &v) const // cross product (same as operator %)
{
return Vec3(vec[1]*v[2]-vec[2]*v[1], vec[2]*v[0]-vec[0]*v[2], vec[0]*v[1]-vec[1]*v[0]);
}
// returns a*this+(1-a)*v LERP=Linear intERPolation
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::lerp(CoordType a,const Vec3 &v) const
{
return Vec3(a*vec[0]+(1.0-a)*v.vec[0], a*vec[1]+(1.0-a)*v[1], a*vec[2]+(1.0-a)*v[2]);
}
// equality
template<class CoordType>
inline bool Vec3<CoordType>::operator==(const Vec3 &v) const
{
return vec[0]==v[0] && vec[1]==v[1] && vec[2]==v[2];
}
// inequality
template<class CoordType>
inline bool Vec3<CoordType>::operator!=(const Vec3 &v) const
{
return vec[0]!=v[0] || vec[1]!=v[1] || vec[2]!=v[2];
}
// if index=0 then x, index=1 then y, index=2 then z
template<class CoordType>
inline CoordType& Vec3<CoordType>::operator[](unsigned short index)
{
assert(index<3);
return vec[index];
}
// if index=0 then x, index=1 then y, index=2 then z
template<class CoordType>
inline const CoordType& Vec3<CoordType>::operator[](unsigned short index) const
{
assert(index<3);
return vec[index];
}
// create a vector that is perp to this
template<class CoordType>
inline Vec3<CoordType> Vec3<CoordType>::perpVector(void) const
{
// taken from Hughes and Moller JGT paper
Vec3<CoordType> v;
CoordType x,y,z;
x=fabs(vec[XI]);
y=fabs(vec[YI]);
z=fabs(vec[ZI]);
if(x<y)
{
if(x<z) v.set(0.0, -vec[ZI],vec[YI]);
else v.set(-vec[YI],vec[XI],0.0);
}
else
{
if(y<z) v.set(-vec[ZI],0.0,vec[XI]);
else v.set(-vec[YI],vec[XI],0.0);
}
v.normalize();
return v;
}
// convert from three floats to one unsigned int: [RGBA]
template<class CoordType>
inline unsigned int Vec3<CoordType>::toRGBA(void) const
{
unsigned int r,g,b,a;
// clamp color to [0,1] (we do not check for <0.0 because it should not be)
r = (unsigned int) (255.0* max(min(vec[RI],1),0));
g = (unsigned int) (255.0* max(min(vec[GI],1),0));
b = (unsigned int) (255.0* max(min(vec[BI],1),0));
return (r<<0) | (g<<8) | (b<<16); //JON: why rgba lsb->msb?
}
// print coords
template<class CoordType>
inline void Vec3<CoordType>::debugprint(void) const
{
fprintf( stderr, "(%2.4f, %2.4f, %2.4f)\n", (float)vec[0], (float)vec[1], (float)vec[2] );
}
///////////////////////////////////////////////////////
// Vec4 functions //
///////////////////////////////////////////////////////
// not complete
template<class CoordType>
inline Vec4<CoordType>::Vec4()
{
//#if _DEBUG
/*x=y=z=w=numeric_limits<CoordType>::infinity(); */
//#endif
}
template<class CoordType>
inline Vec4<CoordType>::Vec4(CoordType xc, CoordType yc, CoordType zc, CoordType wc)
{
vec[0]=xc;
vec[1]=yc;
vec[2]=zc;
vec[3]=wc;
}
template<class CoordType>
inline Vec4<CoordType>::Vec4(unsigned int packedCol)
{
vec[RI] = ((packedCol >> 0) & 0xFF) / 255.0f;
vec[GI] = ((packedCol >> 8) & 0xFF) / 255.0f;
vec[BI] = ((packedCol >> 16) & 0xFF) / 255.0f;
vec[AI] = ((packedCol >> 24) & 0xFF) / 255.0f;
}
template<class CoordType>
inline Vec4<CoordType>::Vec4(const Vec4 &v)
{
vec[0]=v[0];
vec[1]=v[1];
vec[2]=v[2];
vec[3]=v[3];
}
template<class CoordType>
inline void Vec4<CoordType>::set(const Vec4 &v)
{
vec[0]=v[0];
vec[1]=v[1];
vec[2]=v[2];
vec[3]=v[3];
}
template<class CoordType>
inline void Vec4<CoordType>::set(CoordType xc, CoordType yc, CoordType zc, CoordType wc)
{
vec[0]=xc;
vec[1]=yc;
vec[2]=zc;
vec[3]=wc;
}
template<class CoordType>
inline void Vec4<CoordType>::operator=(const Vec4 &v)
{
vec[0]=v[0];
vec[1]=v[1];
vec[2]=v[2];
vec[3]=v[3];
}
template<class CoordType>
inline Vec4<CoordType> Vec4<CoordType>::operator*(CoordType t) const // operator: scaling by scalar
{
return Vec4<CoordType>(t*vec[0], t*vec[1], t*vec[2], t*vec[3]);
}
template<class CoordType>
inline Vec4<CoordType> Vec4<CoordType>::operator+(const Vec4 &v) const // operator: addition
{
return Vec4<CoordType>(vec[0]+v[0], vec[1]+v[1], vec[2]+v[2], vec[3]+v[3]);
}
template<class CoordType>
inline Vec4<CoordType> Vec4<CoordType>::operator-(const Vec4 &v) const // operator: subtraction
{
return Vec4<CoordType>(vec[0]-v[0], vec[1]-v[1], vec[2]-v[2], vec[3]-v[3]);
}
template<class CoordType>
inline CoordType Vec4<CoordType>::operator*(const Vec4 &v) const // operator: dot product
{
return vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]+vec[3]*v[3];
}
template<class CoordType>
inline Vec4<CoordType> Vec4<CoordType>::operator^(const Vec4 &v) const // operator: elementwise multiplication
{
return Vec4<CoordType>(vec[0]*v[0], vec[1]*v[1], vec[2]*v[2], vec[3]*v[3]);
}
template<class CoordType>
inline CoordType& Vec4<CoordType>::operator[](unsigned short index)
{
assert(index<4);
return vec[index];
}
template<class CoordType>
inline const CoordType& Vec4<CoordType>::operator[](unsigned short index) const
{
assert(index<4);
return vec[index];
}
// normalize vector if length>0.0
template<class CoordType>
inline const Vec4<CoordType>& Vec4<CoordType>::normalize(void)
{
CoordType len2=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]+vec[3]*vec[3];
/* assert(len2>numeric_limits<CoordType>::epsilon()); */
/* if(len2>numeric_limits<CoordType>::epsilon()) */
if(len2>0.0000001) /* fix this */
{
CoordType invlen=(CoordType)(1.0/sqrt(len2));
vec[0]*=invlen;
vec[1]*=invlen;
vec[2]*=invlen;
vec[3]*=invlen;
}
return *this;
}
// returns a*this+(1-a)*v LERP=Linear intERPolation
template<class CoordType>
inline Vec4<CoordType> Vec4<CoordType>::lerp(CoordType a,const Vec4 &v) const
{
return Vec4(a*vec[0]+(1.0-a)*v.vec[0], a*vec[1]+(1.0-a)*v[1], a*vec[2]+(1.0-a)*v[2], a*vec[3] + (1.0-a)*v[3]);
}
template<class CoordType>
inline void Vec4<CoordType>::debugprint(void) const
{
fprintf( stderr, "(%2.4f, %2.4f, %2.4f, %2.4f)\n",
(float)vec[0], (float)vec[1], (float)vec[2],(float)vec[3] );
}
template<class CoordType>
inline unsigned int Vec4<CoordType>::toRGBA(void) const
{
unsigned int r,g,b,a;
// clamp color to [0,1] (we do not check for <0.0 because it should not be)
r = (unsigned int) (255.0 * MAX2(MIN2(vec[RI],1),0));
g = (unsigned int) (255.0 * MAX2(MIN2(vec[GI],1),0));
b = (unsigned int) (255.0 * MAX2(MIN2(vec[BI],1),0));
a = (unsigned int) (255.0 * MAX2(MIN2(vec[AI],1),0));
return (r<<0) | (g<<8) | (b<<16) | (a<<24); //JON: why rgba lsb->msb?
}
///////////////////////////////////////////////////////
// Mtx3 functions //
///////////////////////////////////////////////////////
template<class CoordType>
inline Mtx3<CoordType>::Mtx3() // if debug is on, then set to infinity!
{
#if _DEBUG
/*mtx[0][0]=mtx[1][0]=mtx[2][0]=numeric_limits<CoordType>::infinity(); */
/*mtx[0][1]=mtx[1][1]=mtx[2][1]=numeric_limits<CoordType>::infinity(); */
/*mtx[0][2]=mtx[1][2]=mtx[2][2]=numeric_limits<CoordType>::infinity(); */
#endif
}
template<class CoordType>
inline Mtx3<CoordType>::Mtx3(CoordType m00, CoordType m10, CoordType m20,
CoordType m01, CoordType m11, CoordType m21,
CoordType m02, CoordType m12, CoordType m22)
{
mtx[0][0]=m00; mtx[1][0]=m10; mtx[2][0]=m20;
mtx[0][1]=m01; mtx[1][1]=m11; mtx[2][1]=m21;
mtx[0][2]=m02; mtx[1][2]=m12; mtx[2][2]=m22;
}
template<class CoordType>