1 //
2 // Copyright (c) 2010-2011 Linaro Limited
3 //
4 // All rights reserved. This program and the accompanying materials
5 // are made available under the terms of the MIT License which accompanies
6 // this distribution, and is available at
7 // http://www.opensource.org/licenses/mit-license.php
8 //
9 // Contributors:
10 //     Jesse Barker - original implementation.
11 //
12 #ifndef VEC_H_
13 #define VEC_H_
14 
15 #include <iostream> // only needed for print() functions...
16 #include <math.h>
17 
18 namespace LibMatrix
19 {
20 // A template class for creating, managing and operating on a 2-element vector
21 // of any type you like (intended for built-in types, but as long as it
22 // supports the basic arithmetic and assignment operators, any type should
23 // work).
24 template<typename T>
25 class tvec2
26 {
27 public:
tvec2()28     tvec2() :
29         x_(0),
30         y_(0) {}
tvec2(const T t)31     tvec2(const T t) :
32         x_(t),
33         y_(t) {}
tvec2(const T x,const T y)34     tvec2(const T x, const T y) :
35         x_(x),
36         y_(y) {}
tvec2(const tvec2 & v)37     tvec2(const tvec2& v) :
38         x_(v.x_),
39         y_(v.y_) {}
~tvec2()40     ~tvec2() {}
41 
42     // Print the elements of the vector to standard out.
43     // Really only useful for debug and test.
print()44     void print() const
45     {
46         std::cout << "| " << x_ << " " << y_ << " |" << std::endl;
47     }
48 
49     // Allow raw data access for API calls and the like.
50     // For example, it is valid to pass a tvec2<float> into a call to
51     // the OpenGL command "glUniform2fv()".
52     operator const T*() const { return &x_;}
53 
54     // Get and set access members for the individual elements.
x()55     const T x() const { return x_; }
y()56     const T y() const { return y_; }
57 
x(const T & val)58     void x(const T& val) { x_ = val; }
y(const T & val)59     void y(const T& val) { y_ = val; }
60 
61     // A direct assignment of 'rhs' to this.  Return a reference to this.
62     tvec2& operator=(const tvec2& rhs)
63     {
64         if (this != &rhs)
65         {
66             x_ = rhs.x_;
67             y_ = rhs.y_;
68         }
69         return *this;
70     }
71 
72     // Divide this by a scalar.  Return a reference to this.
73     tvec2& operator/=(const T& rhs)
74     {
75         x_ /= rhs;
76         y_ /= rhs;
77         return *this;
78     }
79 
80     // Divide a copy of this by a scalar.  Return the copy.
81     const tvec2 operator/(const T& rhs) const
82     {
83         return tvec2(*this) /= rhs;
84     }
85 
86     // Component-wise divide of this by another vector.
87     // Return a reference to this.
88     tvec2& operator/=(const tvec2& rhs)
89     {
90         x_ /= rhs.x_;
91         y_ /= rhs.y_;
92         return *this;
93     }
94 
95     // Component-wise divide of a copy of this by another vector.
96     // Return the copy.
97     const tvec2 operator/(const tvec2& rhs) const
98     {
99         return tvec2(*this) /= rhs;
100     }
101 
102     // Multiply this by a scalar.  Return a reference to this.
103     tvec2& operator*=(const T& rhs)
104     {
105         x_ *= rhs;
106         y_ *= rhs;
107         return *this;
108     }
109 
110     // Multiply a copy of this by a scalar.  Return the copy.
111     const tvec2 operator*(const T& rhs) const
112     {
113         return tvec2(*this) *= rhs;
114     }
115 
116     // Component-wise multiply of this by another vector.
117     // Return a reference to this.
118     tvec2& operator*=(const tvec2& rhs)
119     {
120         x_ *= rhs.x_;
121         y_ *= rhs.y_;
122         return *this;
123     }
124 
125     // Component-wise multiply of a copy of this by another vector.
126     // Return the copy.
127     const tvec2 operator*(const tvec2& rhs) const
128     {
129         return tvec2(*this) *= rhs;
130     }
131 
132     // Add a scalar to this.  Return a reference to this.
133     tvec2& operator+=(const T& rhs)
134     {
135         x_ += rhs;
136         y_ += rhs;
137         return *this;
138     }
139 
140     // Add a scalar to a copy of this.  Return the copy.
141     const tvec2 operator+(const T& rhs) const
142     {
143         return tvec2(*this) += rhs;
144     }
145 
146     // Component-wise addition of another vector to this.
147     // Return a reference to this.
148     tvec2& operator+=(const tvec2& rhs)
149     {
150         x_ += rhs.x_;
151         y_ += rhs.y_;
152         return *this;
153     }
154 
155     // Component-wise addition of another vector to a copy of this.
156     // Return the copy.
157     const tvec2 operator+(const tvec2& rhs) const
158     {
159         return tvec2(*this) += rhs;
160     }
161 
162     // Subtract a scalar from this.  Return a reference to this.
163     tvec2& operator-=(const T& rhs)
164     {
165         x_ -= rhs;
166         y_ -= rhs;
167         return *this;
168     }
169 
170     // Subtract a scalar from a copy of this.  Return the copy.
171     const tvec2 operator-(const T& rhs) const
172     {
173         return tvec2(*this) -= rhs;
174     }
175 
176     // Component-wise subtraction of another vector from this.
177     // Return a reference to this.
178     tvec2& operator-=(const tvec2& rhs)
179     {
180         x_ -= rhs.x_;
181         y_ -= rhs.y_;
182         return *this;
183     }
184 
185     // Component-wise subtraction of another vector from a copy of this.
186     // Return the copy.
187     const tvec2 operator-(const tvec2& rhs) const
188     {
189         return tvec2(*this) -= rhs;
190     }
191 
192     // Compute the length of this and return it.
length()193     float length() const
194     {
195         return sqrt(dot(*this, *this));
196     }
197 
198     // Make this a unit vector.
normalize()199     void normalize()
200     {
201         float l = length();
202         x_ /= l;
203         y_ /= l;
204     }
205 
206     // Compute the dot product of two vectors.
dot(const tvec2 & v1,const tvec2 & v2)207     static T dot(const tvec2& v1, const tvec2& v2)
208     {
209         return (v1.x_ * v2.x_) + (v1.y_ * v2.y_);
210     }
211 
212 private:
213     T x_;
214     T y_;
215 };
216 
217 // A template class for creating, managing and operating on a 3-element vector
218 // of any type you like (intended for built-in types, but as long as it
219 // supports the basic arithmetic and assignment operators, any type should
220 // work).
221 template<typename T>
222 class tvec3
223 {
224 public:
tvec3()225     tvec3() :
226         x_(0),
227         y_(0),
228         z_(0) {}
tvec3(const T t)229     tvec3(const T t) :
230         x_(t),
231         y_(t),
232         z_(t) {}
tvec3(const T x,const T y,const T z)233     tvec3(const T x, const T y, const T z) :
234         x_(x),
235         y_(y),
236         z_(z) {}
tvec3(const tvec3 & v)237     tvec3(const tvec3& v) :
238         x_(v.x_),
239         y_(v.y_),
240         z_(v.z_) {}
~tvec3()241     ~tvec3() {}
242 
243     // Print the elements of the vector to standard out.
244     // Really only useful for debug and test.
print()245     void print() const
246     {
247         std::cout << "| " << x_ << " " << y_ << " " << z_ << " |" << std::endl;
248     }
249 
250     // Allow raw data access for API calls and the like.
251     // For example, it is valid to pass a tvec3<float> into a call to
252     // the OpenGL command "glUniform3fv()".
253     operator const T*() const { return &x_;}
254 
255     // Get and set access members for the individual elements.
x()256     const T x() const { return x_; }
y()257     const T y() const { return y_; }
z()258     const T z() const { return z_; }
259 
x(const T & val)260     void x(const T& val) { x_ = val; }
y(const T & val)261     void y(const T& val) { y_ = val; }
z(const T & val)262     void z(const T& val) { z_ = val; }
263 
264     // A direct assignment of 'rhs' to this.  Return a reference to this.
265     tvec3& operator=(const tvec3& rhs)
266     {
267         if (this != &rhs)
268         {
269             x_ = rhs.x_;
270             y_ = rhs.y_;
271             z_ = rhs.z_;
272         }
273         return *this;
274     }
275 
276     // Divide this by a scalar.  Return a reference to this.
277     tvec3& operator/=(const T& rhs)
278     {
279         x_ /= rhs;
280         y_ /= rhs;
281         z_ /= rhs;
282         return *this;
283     }
284 
285     // Divide a copy of this by a scalar.  Return the copy.
286     const tvec3 operator/(const T& rhs) const
287     {
288         return tvec3(*this) /= rhs;
289     }
290 
291     // Component-wise divide of this by another vector.
292     // Return a reference to this.
293     tvec3& operator/=(const tvec3& rhs)
294     {
295         x_ /= rhs.x_;
296         y_ /= rhs.y_;
297         z_ /= rhs.z_;
298         return *this;
299     }
300 
301     // Component-wise divide of a copy of this by another vector.
302     // Return the copy.
303     const tvec3 operator/(const tvec3& rhs) const
304     {
305         return tvec3(*this) /= rhs;
306     }
307 
308     // Multiply this by a scalar.  Return a reference to this.
309     tvec3& operator*=(const T& rhs)
310     {
311         x_ *= rhs;
312         y_ *= rhs;
313         z_ *= rhs;
314         return *this;
315     }
316 
317     // Multiply a copy of this by a scalar.  Return the copy.
318     const tvec3 operator*(const T& rhs) const
319     {
320         return tvec3(*this) *= rhs;
321     }
322 
323     // Component-wise multiply of this by another vector.
324     // Return a reference to this.
325     tvec3& operator*=(const tvec3& rhs)
326     {
327         x_ *= rhs.x_;
328         y_ *= rhs.y_;
329         z_ *= rhs.z_;
330         return *this;
331     }
332 
333     // Component-wise multiply of a copy of this by another vector.
334     // Return the copy.
335     const tvec3 operator*(const tvec3& rhs) const
336     {
337         return tvec3(*this) *= rhs;
338     }
339 
340     // Add a scalar to this.  Return a reference to this.
341     tvec3& operator+=(const T& rhs)
342     {
343         x_ += rhs;
344         y_ += rhs;
345         z_ += rhs;
346         return *this;
347     }
348 
349     // Add a scalar to a copy of this.  Return the copy.
350     const tvec3 operator+(const T& rhs) const
351     {
352         return tvec3(*this) += rhs;
353     }
354 
355     // Component-wise addition of another vector to this.
356     // Return a reference to this.
357     tvec3& operator+=(const tvec3& rhs)
358     {
359         x_ += rhs.x_;
360         y_ += rhs.y_;
361         z_ += rhs.z_;
362         return *this;
363     }
364 
365     // Component-wise addition of another vector to a copy of this.
366     // Return the copy.
367     const tvec3 operator+(const tvec3& rhs) const
368     {
369         return tvec3(*this) += rhs;
370     }
371 
372     // Subtract a scalar from this.  Return a reference to this.
373     tvec3& operator-=(const T& rhs)
374     {
375         x_ -= rhs;
376         y_ -= rhs;
377         z_ -= rhs;
378         return *this;
379     }
380 
381     // Subtract a scalar from a copy of this.  Return the copy.
382     const tvec3 operator-(const T& rhs) const
383     {
384         return tvec3(*this) -= rhs;
385     }
386 
387     // Component-wise subtraction of another vector from this.
388     // Return a reference to this.
389     tvec3& operator-=(const tvec3& rhs)
390     {
391         x_ -= rhs.x_;
392         y_ -= rhs.y_;
393         z_ -= rhs.z_;
394         return *this;
395     }
396 
397     // Component-wise subtraction of another vector from a copy of this.
398     // Return the copy.
399     const tvec3 operator-(const tvec3& rhs) const
400     {
401         return tvec3(*this) -= rhs;
402     }
403 
404     // Compute the length of this and return it.
length()405     float length() const
406     {
407         return sqrt(dot(*this, *this));
408     }
409 
410     // Make this a unit vector.
normalize()411     void normalize()
412     {
413         float l = length();
414         x_ /= l;
415         y_ /= l;
416         z_ /= l;
417     }
418 
419     // Compute the dot product of two vectors.
dot(const tvec3 & v1,const tvec3 & v2)420     static T dot(const tvec3& v1, const tvec3& v2)
421     {
422         return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_);
423     }
424 
425     // Compute the cross product of two vectors.
cross(const tvec3 & u,const tvec3 & v)426     static tvec3 cross(const tvec3& u, const tvec3& v)
427     {
428         return tvec3((u.y_ * v.z_) - (u.z_ * v.y_),
429                     (u.z_ * v.x_) - (u.x_ * v.z_),
430                     (u.x_ * v.y_) - (u.y_ * v.x_));
431     }
432 
433 private:
434     T x_;
435     T y_;
436     T z_;
437 };
438 
439 // A template class for creating, managing and operating on a 4-element vector
440 // of any type you like (intended for built-in types, but as long as it
441 // supports the basic arithmetic and assignment operators, any type should
442 // work).
443 template<typename T>
444 class tvec4
445 {
446 public:
tvec4()447     tvec4() :
448         x_(0),
449         y_(0),
450         z_(0),
451         w_(0) {}
tvec4(const T t)452     tvec4(const T t) :
453         x_(t),
454         y_(t),
455         z_(t),
456         w_(t) {}
tvec4(const T x,const T y,const T z,const T w)457     tvec4(const T x, const T y, const T z, const T w) :
458         x_(x),
459         y_(y),
460         z_(z),
461         w_(w) {}
tvec4(const tvec4 & v)462     tvec4(const tvec4& v) :
463         x_(v.x_),
464         y_(v.y_),
465         z_(v.z_),
466         w_(v.w_) {}
~tvec4()467     ~tvec4() {}
468 
469     // Print the elements of the vector to standard out.
470     // Really only useful for debug and test.
print()471     void print() const
472     {
473         std::cout << "| " << x_ << " " << y_ << " " << z_ << " " << w_ << " |" << std::endl;
474     }
475 
476     // Allow raw data access for API calls and the like.
477     // For example, it is valid to pass a tvec4<float> into a call to
478     // the OpenGL command "glUniform4fv()".
479     operator const T*() const { return &x_;}
480 
481     // Get and set access members for the individual elements.
x()482     const T x() const { return x_; }
y()483     const T y() const { return y_; }
z()484     const T z() const { return z_; }
w()485     const T w() const { return w_; }
486 
x(const T & val)487     void x(const T& val) { x_ = val; }
y(const T & val)488     void y(const T& val) { y_ = val; }
z(const T & val)489     void z(const T& val) { z_ = val; }
w(const T & val)490     void w(const T& val) { w_ = val; }
491 
492     // A direct assignment of 'rhs' to this.  Return a reference to this.
493     tvec4& operator=(const tvec4& rhs)
494     {
495         if (this != &rhs)
496         {
497             x_ = rhs.x_;
498             y_ = rhs.y_;
499             z_ = rhs.z_;
500             w_ = rhs.w_;
501         }
502         return *this;
503     }
504 
505     // Divide this by a scalar.  Return a reference to this.
506     tvec4& operator/=(const T& rhs)
507     {
508         x_ /= rhs;
509         y_ /= rhs;
510         z_ /= rhs;
511         w_ /= rhs;
512         return *this;
513     }
514 
515     // Divide a copy of this by a scalar.  Return the copy.
516     const tvec4 operator/(const T& rhs) const
517     {
518         return tvec4(*this) /= rhs;
519     }
520 
521     // Component-wise divide of this by another vector.
522     // Return a reference to this.
523     tvec4& operator/=(const tvec4& rhs)
524     {
525         x_ /= rhs.x_;
526         y_ /= rhs.y_;
527         z_ /= rhs.z_;
528         w_ /= rhs.w_;
529         return *this;
530     }
531 
532     // Component-wise divide of a copy of this by another vector.
533     // Return the copy.
534     const tvec4 operator/(const tvec4& rhs) const
535     {
536         return tvec4(*this) /= rhs;
537     }
538 
539     // Multiply this by a scalar.  Return a reference to this.
540     tvec4& operator*=(const T& rhs)
541     {
542         x_ *= rhs;
543         y_ *= rhs;
544         z_ *= rhs;
545         w_ *= rhs;
546         return *this;
547     }
548 
549     // Multiply a copy of this by a scalar.  Return the copy.
550     const tvec4 operator*(const T& rhs) const
551     {
552         return tvec4(*this) *= rhs;
553     }
554 
555     // Component-wise multiply of this by another vector.
556     // Return a reference to this.
557     tvec4& operator*=(const tvec4& rhs)
558     {
559         x_ *= rhs.x_;
560         y_ *= rhs.y_;
561         z_ *= rhs.z_;
562         w_ *= rhs.w_;
563         return *this;
564     }
565 
566     // Component-wise multiply of a copy of this by another vector.
567     // Return the copy.
568     const tvec4 operator*(const tvec4& rhs) const
569     {
570         return tvec4(*this) *= rhs;
571     }
572 
573     // Add a scalar to this.  Return a reference to this.
574     tvec4& operator+=(const T& rhs)
575     {
576         x_ += rhs;
577         y_ += rhs;
578         z_ += rhs;
579         w_ += rhs;
580         return *this;
581     }
582 
583     // Add a scalar to a copy of this.  Return the copy.
584     const tvec4 operator+(const T& rhs) const
585     {
586         return tvec4(*this) += rhs;
587     }
588 
589     // Component-wise addition of another vector to this.
590     // Return a reference to this.
591     tvec4& operator+=(const tvec4& rhs)
592     {
593         x_ += rhs.x_;
594         y_ += rhs.y_;
595         z_ += rhs.z_;
596         w_ += rhs.w_;
597         return *this;
598     }
599 
600     // Component-wise addition of another vector to a copy of this.
601     // Return the copy.
602     const tvec4 operator+(const tvec4& rhs) const
603     {
604         return tvec4(*this) += rhs;
605     }
606 
607     // Subtract a scalar from this.  Return a reference to this.
608     tvec4& operator-=(const T& rhs)
609     {
610         x_ -= rhs;
611         y_ -= rhs;
612         z_ -= rhs;
613         w_ -= rhs;
614         return *this;
615     }
616 
617     // Subtract a scalar from a copy of this.  Return the copy.
618     const tvec4 operator-(const T& rhs) const
619     {
620         return tvec4(*this) -= rhs;
621     }
622 
623     // Component-wise subtraction of another vector from this.
624     // Return a reference to this.
625     tvec4& operator-=(const tvec4& rhs)
626     {
627         x_ -= rhs.x_;
628         y_ -= rhs.y_;
629         z_ -= rhs.z_;
630         w_ -= rhs.w_;
631         return *this;
632     }
633 
634     // Component-wise subtraction of another vector from a copy of this.
635     // Return the copy.
636     const tvec4 operator-(const tvec4& rhs) const
637     {
638         return tvec4(*this) -= rhs;
639     }
640 
641     // Compute the length of this and return it.
length()642     float length() const
643     {
644         return sqrt(dot(*this, *this));
645     }
646 
647     // Make this a unit vector.
normalize()648     void normalize()
649     {
650         float l = length();
651         x_ /= l;
652         y_ /= l;
653         z_ /= l;
654         w_ /= l;
655     }
656 
657     // Compute the dot product of two vectors.
dot(const tvec4 & v1,const tvec4 & v2)658     static T dot(const tvec4& v1, const tvec4& v2)
659     {
660         return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_) + (v1.w_ * v2.w_);
661     }
662 
663 private:
664     T x_;
665     T y_;
666     T z_;
667     T w_;
668 };
669 
670 //
671 // Convenience typedefs.  These are here to present a homogeneous view of these
672 // objects with respect to shader source.
673 //
674 typedef tvec2<float> vec2;
675 typedef tvec3<float> vec3;
676 typedef tvec4<float> vec4;
677 
678 typedef tvec2<double> dvec2;
679 typedef tvec3<double> dvec3;
680 typedef tvec4<double> dvec4;
681 
682 typedef tvec2<int> ivec2;
683 typedef tvec3<int> ivec3;
684 typedef tvec4<int> ivec4;
685 
686 typedef tvec2<unsigned int> uvec2;
687 typedef tvec3<unsigned int> uvec3;
688 typedef tvec4<unsigned int> uvec4;
689 
690 typedef tvec2<bool> bvec2;
691 typedef tvec3<bool> bvec3;
692 typedef tvec4<bool> bvec4;
693 
694 } // namespace LibMatrix
695 
696 // Global operators to allow for things like defining a new vector in terms of
697 // a product of a scalar and a vector
698 template<typename T>
699 const LibMatrix::tvec2<T> operator*(const T t, const LibMatrix::tvec2<T>& v)
700 {
701     return v * t;
702 }
703 
704 template<typename T>
705 const LibMatrix::tvec3<T> operator*(const T t, const LibMatrix::tvec3<T>& v)
706 {
707     return v * t;
708 }
709 
710 template<typename T>
711 const LibMatrix::tvec4<T> operator*(const T t, const LibMatrix::tvec4<T>& v)
712 {
713     return v * t;
714 }
715 
716 #endif // VEC_H_
717