• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef VECMATH_H_
18 #define VECMATH_H_
19 
20 #include <math.h>
21 #include "JNIHelper.h"
22 
23 namespace ndk_helper
24 {
25 
26 /******************************************************************
27  * Helper class for vector math operations
28  * Currently all implementations are in pure C++.
29  * Each class is an opaque class so caller does not have a direct access
30  * to each element. This is for an ease of future optimization to use vector operations.
31  *
32  */
33 
34 class Vec2;
35 class Vec3;
36 class Vec4;
37 class Mat4;
38 
39 /******************************************************************
40  * 2 elements vector class
41  *
42  */
43 class Vec2
44 {
45 private:
46     float x_;
47     float y_;
48 
49 public:
50     friend class Vec3;
51     friend class Vec4;
52     friend class Mat4;
53     friend class Quaternion;
54 
Vec2()55     Vec2()
56     {
57         x_ = y_ = 0.f;
58     }
59 
Vec2(const float fX,const float fY)60     Vec2( const float fX, const float fY )
61     {
62         x_ = fX;
63         y_ = fY;
64     }
65 
Vec2(const Vec2 & vec)66     Vec2( const Vec2& vec )
67     {
68         x_ = vec.x_;
69         y_ = vec.y_;
70     }
71 
Vec2(const float * pVec)72     Vec2( const float* pVec )
73     {
74         x_ = (*pVec++);
75         y_ = (*pVec++);
76     }
77 
78     //Operators
79     Vec2 operator*( const Vec2& rhs ) const
80     {
81         Vec2 ret;
82         ret.x_ = x_ * rhs.x_;
83         ret.y_ = y_ * rhs.y_;
84         return ret;
85     }
86 
87     Vec2 operator/( const Vec2& rhs ) const
88     {
89         Vec2 ret;
90         ret.x_ = x_ / rhs.x_;
91         ret.y_ = y_ / rhs.y_;
92         return ret;
93     }
94 
95     Vec2 operator+( const Vec2& rhs ) const
96     {
97         Vec2 ret;
98         ret.x_ = x_ + rhs.x_;
99         ret.y_ = y_ + rhs.y_;
100         return ret;
101     }
102 
103     Vec2 operator-( const Vec2& rhs ) const
104     {
105         Vec2 ret;
106         ret.x_ = x_ - rhs.x_;
107         ret.y_ = y_ - rhs.y_;
108         return ret;
109     }
110 
111     Vec2& operator+=( const Vec2& rhs )
112     {
113         x_ += rhs.x_;
114         y_ += rhs.y_;
115         return *this;
116     }
117 
118     Vec2& operator-=( const Vec2& rhs )
119     {
120         x_ -= rhs.x_;
121         y_ -= rhs.y_;
122         return *this;
123     }
124 
125     Vec2& operator*=( const Vec2& rhs )
126     {
127         x_ *= rhs.x_;
128         y_ *= rhs.y_;
129         return *this;
130     }
131 
132     Vec2& operator/=( const Vec2& rhs )
133     {
134         x_ /= rhs.x_;
135         y_ /= rhs.y_;
136         return *this;
137     }
138 
139     //External operators
140     friend Vec2 operator-( const Vec2& rhs )
141     {
142         return Vec2( rhs ) *= -1;
143     }
144 
145     friend Vec2 operator*( const float lhs, const Vec2& rhs )
146     {
147         Vec2 ret;
148         ret.x_ = lhs * rhs.x_;
149         ret.y_ = lhs * rhs.y_;
150         return ret;
151     }
152 
153     friend Vec2 operator/( const float lhs, const Vec2& rhs )
154     {
155         Vec2 ret;
156         ret.x_ = lhs / rhs.x_;
157         ret.y_ = lhs / rhs.y_;
158         return ret;
159     }
160 
161     //Operators with float
162     Vec2 operator*( const float& rhs ) const
163     {
164         Vec2 ret;
165         ret.x_ = x_ * rhs;
166         ret.y_ = y_ * rhs;
167         return ret;
168     }
169 
170     Vec2& operator*=( const float& rhs )
171     {
172         x_ = x_ * rhs;
173         y_ = y_ * rhs;
174         return *this;
175     }
176 
177     Vec2 operator/( const float& rhs ) const
178     {
179         Vec2 ret;
180         ret.x_ = x_ / rhs;
181         ret.y_ = y_ / rhs;
182         return ret;
183     }
184 
185     Vec2& operator/=( const float& rhs )
186     {
187         x_ = x_ / rhs;
188         y_ = y_ / rhs;
189         return *this;
190     }
191 
192     //Compare
193     bool operator==( const Vec2& rhs ) const
194     {
195         if( x_ != rhs.x_ || y_ != rhs.y_ )
196             return false;
197         return true;
198     }
199 
200     bool operator!=( const Vec2& rhs ) const
201     {
202         if( x_ == rhs.x_ )
203             return false;
204 
205         return true;
206     }
207 
Length()208     float Length() const
209     {
210         return sqrtf( x_ * x_ + y_ * y_ );
211     }
212 
Normalize()213     Vec2 Normalize()
214     {
215         float len = Length();
216         x_ = x_ / len;
217         y_ = y_ / len;
218         return *this;
219     }
220 
Dot(const Vec2 & rhs)221     float Dot( const Vec2& rhs )
222     {
223         return x_ * rhs.x_ + y_ * rhs.y_;
224     }
225 
Validate()226     bool Validate()
227     {
228         if( isnan( x_ ) || isnan( y_ ) )
229             return false;
230         return true;
231     }
232 
Value(float & fX,float & fY)233     void Value( float& fX, float& fY )
234     {
235         fX = x_;
236         fY = y_;
237     }
238 
Dump()239     void Dump()
240     {
241         LOGI( "Vec2 %f %f", x_, y_ );
242     }
243 };
244 
245 /******************************************************************
246  * 3 elements vector class
247  *
248  */
249 class Vec3
250 {
251 private:
252     float x_, y_, z_;
253 
254 public:
255     friend class Vec4;
256     friend class Mat4;
257     friend class Quaternion;
258 
Vec3()259     Vec3()
260     {
261         x_ = y_ = z_ = 0.f;
262     }
263 
Vec3(const float fX,const float fY,const float fZ)264     Vec3( const float fX, const float fY, const float fZ )
265     {
266         x_ = fX;
267         y_ = fY;
268         z_ = fZ;
269     }
270 
Vec3(const Vec3 & vec)271     Vec3( const Vec3& vec )
272     {
273         x_ = vec.x_;
274         y_ = vec.y_;
275         z_ = vec.z_;
276     }
277 
Vec3(const float * pVec)278     Vec3( const float* pVec )
279     {
280         x_ = (*pVec++);
281         y_ = (*pVec++);
282         z_ = *pVec;
283     }
284 
Vec3(const Vec2 & vec,float f)285     Vec3( const Vec2& vec, float f )
286     {
287         x_ = vec.x_;
288         y_ = vec.y_;
289         z_ = f;
290     }
291 
292     Vec3( const Vec4& vec );
293 
294     //Operators
295     Vec3 operator*( const Vec3& rhs ) const
296     {
297         Vec3 ret;
298         ret.x_ = x_ * rhs.x_;
299         ret.y_ = y_ * rhs.y_;
300         ret.z_ = z_ * rhs.z_;
301         return ret;
302     }
303 
304     Vec3 operator/( const Vec3& rhs ) const
305     {
306         Vec3 ret;
307         ret.x_ = x_ / rhs.x_;
308         ret.y_ = y_ / rhs.y_;
309         ret.z_ = z_ / rhs.z_;
310         return ret;
311     }
312 
313     Vec3 operator+( const Vec3& rhs ) const
314     {
315         Vec3 ret;
316         ret.x_ = x_ + rhs.x_;
317         ret.y_ = y_ + rhs.y_;
318         ret.z_ = z_ + rhs.z_;
319         return ret;
320     }
321 
322     Vec3 operator-( const Vec3& rhs ) const
323     {
324         Vec3 ret;
325         ret.x_ = x_ - rhs.x_;
326         ret.y_ = y_ - rhs.y_;
327         ret.z_ = z_ - rhs.z_;
328         return ret;
329     }
330 
331     Vec3& operator+=( const Vec3& rhs )
332     {
333         x_ += rhs.x_;
334         y_ += rhs.y_;
335         z_ += rhs.z_;
336         return *this;
337     }
338 
339     Vec3& operator-=( const Vec3& rhs )
340     {
341         x_ -= rhs.x_;
342         y_ -= rhs.y_;
343         z_ -= rhs.z_;
344         return *this;
345     }
346 
347     Vec3& operator*=( const Vec3& rhs )
348     {
349         x_ *= rhs.x_;
350         y_ *= rhs.y_;
351         z_ *= rhs.z_;
352         return *this;
353     }
354 
355     Vec3& operator/=( const Vec3& rhs )
356     {
357         x_ /= rhs.x_;
358         y_ /= rhs.y_;
359         z_ /= rhs.z_;
360         return *this;
361     }
362 
363     //External operators
364     friend Vec3 operator-( const Vec3& rhs )
365     {
366         return Vec3( rhs ) *= -1;
367     }
368 
369     friend Vec3 operator*( const float lhs, const Vec3& rhs )
370     {
371         Vec3 ret;
372         ret.x_ = lhs * rhs.x_;
373         ret.y_ = lhs * rhs.y_;
374         ret.z_ = lhs * rhs.z_;
375         return ret;
376     }
377 
378     friend Vec3 operator/( const float lhs, const Vec3& rhs )
379     {
380         Vec3 ret;
381         ret.x_ = lhs / rhs.x_;
382         ret.y_ = lhs / rhs.y_;
383         ret.z_ = lhs / rhs.z_;
384         return ret;
385     }
386 
387     //Operators with float
388     Vec3 operator*( const float& rhs ) const
389     {
390         Vec3 ret;
391         ret.x_ = x_ * rhs;
392         ret.y_ = y_ * rhs;
393         ret.z_ = z_ * rhs;
394         return ret;
395     }
396 
397     Vec3& operator*=( const float& rhs )
398     {
399         x_ = x_ * rhs;
400         y_ = y_ * rhs;
401         z_ = z_ * rhs;
402         return *this;
403     }
404 
405     Vec3 operator/( const float& rhs ) const
406     {
407         Vec3 ret;
408         ret.x_ = x_ / rhs;
409         ret.y_ = y_ / rhs;
410         ret.z_ = z_ / rhs;
411         return ret;
412     }
413 
414     Vec3& operator/=( const float& rhs )
415     {
416         x_ = x_ / rhs;
417         y_ = y_ / rhs;
418         z_ = z_ / rhs;
419         return *this;
420     }
421 
422     //Compare
423     bool operator==( const Vec3& rhs ) const
424     {
425         if( x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ )
426             return false;
427         return true;
428     }
429 
430     bool operator!=( const Vec3& rhs ) const
431     {
432         if( x_ == rhs.x_ )
433             return false;
434 
435         return true;
436     }
437 
Length()438     float Length() const
439     {
440         return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ );
441     }
442 
Normalize()443     Vec3 Normalize()
444     {
445         float len = Length();
446         x_ = x_ / len;
447         y_ = y_ / len;
448         z_ = z_ / len;
449         return *this;
450     }
451 
Dot(const Vec3 & rhs)452     float Dot( const Vec3& rhs )
453     {
454         return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
455     }
456 
Cross(const Vec3 & rhs)457     Vec3 Cross( const Vec3& rhs )
458     {
459         Vec3 ret;
460         ret.x_ = y_ * rhs.z_ - z_ * rhs.y_;
461         ret.y_ = z_ * rhs.x_ - x_ * rhs.z_;
462         ret.z_ = x_ * rhs.y_ - y_ * rhs.x_;
463         return ret;
464     }
465 
Validate()466     bool Validate()
467     {
468         if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) )
469             return false;
470         return true;
471     }
472 
Value(float & fX,float & fY,float & fZ)473     void Value( float& fX, float& fY, float& fZ )
474     {
475         fX = x_;
476         fY = y_;
477         fZ = z_;
478     }
479 
Dump()480     void Dump()
481     {
482         LOGI( "Vec3 %f %f %f", x_, y_, z_ );
483     }
484 };
485 
486 /******************************************************************
487  * 4 elements vector class
488  *
489  */
490 class Vec4
491 {
492 private:
493     float x_, y_, z_, w_;
494 
495 public:
496     friend class Vec3;
497     friend class Mat4;
498     friend class Quaternion;
499 
Vec4()500     Vec4()
501     {
502         x_ = y_ = z_ = w_ = 0.f;
503     }
504 
Vec4(const float fX,const float fY,const float fZ,const float fW)505     Vec4( const float fX, const float fY, const float fZ, const float fW )
506     {
507         x_ = fX;
508         y_ = fY;
509         z_ = fZ;
510         w_ = fW;
511     }
512 
Vec4(const Vec4 & vec)513     Vec4( const Vec4& vec )
514     {
515         x_ = vec.x_;
516         y_ = vec.y_;
517         z_ = vec.z_;
518         w_ = vec.w_;
519     }
520 
Vec4(const Vec3 & vec,const float fW)521     Vec4( const Vec3& vec, const float fW )
522     {
523         x_ = vec.x_;
524         y_ = vec.y_;
525         z_ = vec.z_;
526         w_ = fW;
527     }
528 
Vec4(const float * pVec)529     Vec4( const float* pVec )
530     {
531         x_ = (*pVec++);
532         y_ = (*pVec++);
533         z_ = *pVec;
534         w_ = *pVec;
535     }
536 
537     //Operators
538     Vec4 operator*( const Vec4& rhs ) const
539     {
540         Vec4 ret;
541         ret.x_ = x_ * rhs.x_;
542         ret.y_ = y_ * rhs.y_;
543         ret.z_ = z_ * rhs.z_;
544         ret.w_ = z_ * rhs.w_;
545         return ret;
546     }
547 
548     Vec4 operator/( const Vec4& rhs ) const
549     {
550         Vec4 ret;
551         ret.x_ = x_ / rhs.x_;
552         ret.y_ = y_ / rhs.y_;
553         ret.z_ = z_ / rhs.z_;
554         ret.w_ = z_ / rhs.w_;
555         return ret;
556     }
557 
558     Vec4 operator+( const Vec4& rhs ) const
559     {
560         Vec4 ret;
561         ret.x_ = x_ + rhs.x_;
562         ret.y_ = y_ + rhs.y_;
563         ret.z_ = z_ + rhs.z_;
564         ret.w_ = z_ + rhs.w_;
565         return ret;
566     }
567 
568     Vec4 operator-( const Vec4& rhs ) const
569     {
570         Vec4 ret;
571         ret.x_ = x_ - rhs.x_;
572         ret.y_ = y_ - rhs.y_;
573         ret.z_ = z_ - rhs.z_;
574         ret.w_ = z_ - rhs.w_;
575         return ret;
576     }
577 
578     Vec4& operator+=( const Vec4& rhs )
579     {
580         x_ += rhs.x_;
581         y_ += rhs.y_;
582         z_ += rhs.z_;
583         w_ += rhs.w_;
584         return *this;
585     }
586 
587     Vec4& operator-=( const Vec4& rhs )
588     {
589         x_ -= rhs.x_;
590         y_ -= rhs.y_;
591         z_ -= rhs.z_;
592         w_ -= rhs.w_;
593         return *this;
594     }
595 
596     Vec4& operator*=( const Vec4& rhs )
597     {
598         x_ *= rhs.x_;
599         y_ *= rhs.y_;
600         z_ *= rhs.z_;
601         w_ *= rhs.w_;
602         return *this;
603     }
604 
605     Vec4& operator/=( const Vec4& rhs )
606     {
607         x_ /= rhs.x_;
608         y_ /= rhs.y_;
609         z_ /= rhs.z_;
610         w_ /= rhs.w_;
611         return *this;
612     }
613 
614     //External operators
615     friend Vec4 operator-( const Vec4& rhs )
616     {
617         return Vec4( rhs ) *= -1;
618     }
619 
620     friend Vec4 operator*( const float lhs, const Vec4& rhs )
621     {
622         Vec4 ret;
623         ret.x_ = lhs * rhs.x_;
624         ret.y_ = lhs * rhs.y_;
625         ret.z_ = lhs * rhs.z_;
626         ret.w_ = lhs * rhs.w_;
627         return ret;
628     }
629 
630     friend Vec4 operator/( const float lhs, const Vec4& rhs )
631     {
632         Vec4 ret;
633         ret.x_ = lhs / rhs.x_;
634         ret.y_ = lhs / rhs.y_;
635         ret.z_ = lhs / rhs.z_;
636         ret.w_ = lhs / rhs.w_;
637         return ret;
638     }
639 
640     //Operators with float
641     Vec4 operator*( const float& rhs ) const
642     {
643         Vec4 ret;
644         ret.x_ = x_ * rhs;
645         ret.y_ = y_ * rhs;
646         ret.z_ = z_ * rhs;
647         ret.w_ = w_ * rhs;
648         return ret;
649     }
650 
651     Vec4& operator*=( const float& rhs )
652     {
653         x_ = x_ * rhs;
654         y_ = y_ * rhs;
655         z_ = z_ * rhs;
656         w_ = w_ * rhs;
657         return *this;
658     }
659 
660     Vec4 operator/( const float& rhs ) const
661     {
662         Vec4 ret;
663         ret.x_ = x_ / rhs;
664         ret.y_ = y_ / rhs;
665         ret.z_ = z_ / rhs;
666         ret.w_ = w_ / rhs;
667         return ret;
668     }
669 
670     Vec4& operator/=( const float& rhs )
671     {
672         x_ = x_ / rhs;
673         y_ = y_ / rhs;
674         z_ = z_ / rhs;
675         w_ = w_ / rhs;
676         return *this;
677     }
678 
679     //Compare
680     bool operator==( const Vec4& rhs ) const
681     {
682         if( x_ != rhs.x_ || y_ != rhs.y_ || z_ != rhs.z_ || w_ != rhs.w_ )
683             return false;
684         return true;
685     }
686 
687     bool operator!=( const Vec4& rhs ) const
688     {
689         if( x_ == rhs.x_ )
690             return false;
691 
692         return true;
693     }
694 
695     Vec4 operator*( const Mat4& rhs ) const;
696 
Length()697     float Length() const
698     {
699         return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_ );
700     }
701 
Normalize()702     Vec4 Normalize()
703     {
704         float len = Length();
705         x_ = x_ / len;
706         y_ = y_ / len;
707         z_ = z_ / len;
708         w_ = w_ / len;
709         return *this;
710     }
711 
Dot(const Vec3 & rhs)712     float Dot( const Vec3& rhs )
713     {
714         return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
715     }
716 
Cross(const Vec3 & rhs)717     Vec3 Cross( const Vec3& rhs )
718     {
719         Vec3 ret;
720         ret.x_ = y_ * rhs.z_ - z_ * rhs.y_;
721         ret.y_ = z_ * rhs.x_ - x_ * rhs.z_;
722         ret.z_ = x_ * rhs.y_ - y_ * rhs.x_;
723         return ret;
724     }
725 
Validate()726     bool Validate()
727     {
728         if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) || isnan( w_ ) )
729             return false;
730         return true;
731     }
732 
Value(float & fX,float & fY,float & fZ,float & fW)733     void Value( float& fX, float& fY, float& fZ, float& fW )
734     {
735         fX = x_;
736         fY = y_;
737         fZ = z_;
738         fW = w_;
739     }
740 };
741 
742 /******************************************************************
743  * 4x4 matrix
744  *
745  */
746 class Mat4
747 {
748 private:
749     float f_[16];
750 
751 public:
752     friend class Vec3;
753     friend class Vec4;
754     friend class Quaternion;
755 
756     Mat4();
757     Mat4( const float* );
758 
759     Mat4 operator*( const Mat4& rhs ) const;
760     Vec4 operator*( const Vec4& rhs ) const;
761 
762     Mat4 operator+( const Mat4& rhs ) const
763     {
764         Mat4 ret;
765         for( int32_t i = 0; i < 16; ++i )
766         {
767             ret.f_[i] = f_[i] + rhs.f_[i];
768         }
769         return ret;
770     }
771 
772     Mat4 operator-( const Mat4& rhs ) const
773     {
774         Mat4 ret;
775         for( int32_t i = 0; i < 16; ++i )
776         {
777             ret.f_[i] = f_[i] - rhs.f_[i];
778         }
779         return ret;
780     }
781 
782     Mat4& operator+=( const Mat4& rhs )
783     {
784         for( int32_t i = 0; i < 16; ++i )
785         {
786             f_[i] += rhs.f_[i];
787         }
788         return *this;
789     }
790 
791     Mat4& operator-=( const Mat4& rhs )
792     {
793         for( int32_t i = 0; i < 16; ++i )
794         {
795             f_[i] -= rhs.f_[i];
796         }
797         return *this;
798     }
799 
800     Mat4& operator*=( const Mat4& rhs )
801     {
802         Mat4 ret;
803         ret.f_[0] = f_[0] * rhs.f_[0] + f_[4] * rhs.f_[1] + f_[8] * rhs.f_[2]
804                 + f_[12] * rhs.f_[3];
805         ret.f_[1] = f_[1] * rhs.f_[0] + f_[5] * rhs.f_[1] + f_[9] * rhs.f_[2]
806                 + f_[13] * rhs.f_[3];
807         ret.f_[2] = f_[2] * rhs.f_[0] + f_[6] * rhs.f_[1] + f_[10] * rhs.f_[2]
808                 + f_[14] * rhs.f_[3];
809         ret.f_[3] = f_[3] * rhs.f_[0] + f_[7] * rhs.f_[1] + f_[11] * rhs.f_[2]
810                 + f_[15] * rhs.f_[3];
811 
812         ret.f_[4] = f_[0] * rhs.f_[4] + f_[4] * rhs.f_[5] + f_[8] * rhs.f_[6]
813                 + f_[12] * rhs.f_[7];
814         ret.f_[5] = f_[1] * rhs.f_[4] + f_[5] * rhs.f_[5] + f_[9] * rhs.f_[6]
815                 + f_[13] * rhs.f_[7];
816         ret.f_[6] = f_[2] * rhs.f_[4] + f_[6] * rhs.f_[5] + f_[10] * rhs.f_[6]
817                 + f_[14] * rhs.f_[7];
818         ret.f_[7] = f_[3] * rhs.f_[4] + f_[7] * rhs.f_[5] + f_[11] * rhs.f_[6]
819                 + f_[15] * rhs.f_[7];
820 
821         ret.f_[8] = f_[0] * rhs.f_[8] + f_[4] * rhs.f_[9] + f_[8] * rhs.f_[10]
822                 + f_[12] * rhs.f_[11];
823         ret.f_[9] = f_[1] * rhs.f_[8] + f_[5] * rhs.f_[9] + f_[9] * rhs.f_[10]
824                 + f_[13] * rhs.f_[11];
825         ret.f_[10] = f_[2] * rhs.f_[8] + f_[6] * rhs.f_[9] + f_[10] * rhs.f_[10]
826                 + f_[14] * rhs.f_[11];
827         ret.f_[11] = f_[3] * rhs.f_[8] + f_[7] * rhs.f_[9] + f_[11] * rhs.f_[10]
828                 + f_[15] * rhs.f_[11];
829 
830         ret.f_[12] = f_[0] * rhs.f_[12] + f_[4] * rhs.f_[13] + f_[8] * rhs.f_[14]
831                 + f_[12] * rhs.f_[15];
832         ret.f_[13] = f_[1] * rhs.f_[12] + f_[5] * rhs.f_[13] + f_[9] * rhs.f_[14]
833                 + f_[13] * rhs.f_[15];
834         ret.f_[14] = f_[2] * rhs.f_[12] + f_[6] * rhs.f_[13] + f_[10] * rhs.f_[14]
835                 + f_[14] * rhs.f_[15];
836         ret.f_[15] = f_[3] * rhs.f_[12] + f_[7] * rhs.f_[13] + f_[11] * rhs.f_[14]
837                 + f_[15] * rhs.f_[15];
838 
839         *this = ret;
840         return *this;
841     }
842 
843     Mat4 operator*( const float rhs )
844     {
845         Mat4 ret;
846         for( int32_t i = 0; i < 16; ++i )
847         {
848             ret.f_[i] = f_[i] * rhs;
849         }
850         return ret;
851     }
852 
853     Mat4& operator*=( const float rhs )
854     {
855         for( int32_t i = 0; i < 16; ++i )
856         {
857             f_[i] *= rhs;
858         }
859         return *this;
860     }
861 
862     Mat4& operator=( const Mat4& rhs )
863     {
864         for( int32_t i = 0; i < 16; ++i )
865         {
866             f_[i] = rhs.f_[i];
867         }
868         return *this;
869     }
870 
871     Mat4 Inverse();
872 
Transpose()873     Mat4 Transpose()
874     {
875         Mat4 ret;
876         ret.f_[0] = f_[0];
877         ret.f_[1] = f_[4];
878         ret.f_[2] = f_[8];
879         ret.f_[3] = f_[12];
880         ret.f_[4] = f_[1];
881         ret.f_[5] = f_[5];
882         ret.f_[6] = f_[9];
883         ret.f_[7] = f_[13];
884         ret.f_[8] = f_[2];
885         ret.f_[9] = f_[6];
886         ret.f_[10] = f_[10];
887         ret.f_[11] = f_[14];
888         ret.f_[12] = f_[3];
889         ret.f_[13] = f_[7];
890         ret.f_[14] = f_[11];
891         ret.f_[15] = f_[15];
892         *this = ret;
893         return *this;
894     }
895 
PostTranslate(float tx,float ty,float tz)896     Mat4& PostTranslate( float tx, float ty, float tz )
897     {
898         f_[12] += (tx * f_[0]) + (ty * f_[4]) + (tz * f_[8]);
899         f_[13] += (tx * f_[1]) + (ty * f_[5]) + (tz * f_[9]);
900         f_[14] += (tx * f_[2]) + (ty * f_[6]) + (tz * f_[10]);
901         f_[15] += (tx * f_[3]) + (ty * f_[7]) + (tz * f_[11]);
902         return *this;
903     }
904 
Ptr()905     float* Ptr()
906     {
907         return f_;
908     }
909 
910     //--------------------------------------------------------------------------------
911     // Misc
912     //--------------------------------------------------------------------------------
913     static Mat4 Perspective( float width, float height, float nearPlane, float farPlane );
914 
915     static Mat4 LookAt( const Vec3& vEye, const Vec3& vAt, const Vec3& vUp );
916 
917     static Mat4 Translation( const float fX, const float fY, const float fZ );
918     static Mat4 Translation( const Vec3 vec );
919 
920     static Mat4 RotationX( const float angle );
921 
922     static Mat4 RotationY( const float angle );
923 
924     static Mat4 RotationZ( const float angle );
925 
Identity()926     static Mat4 Identity()
927     {
928         Mat4 ret;
929         ret.f_[0] = 1.f;
930         ret.f_[1] = 0;
931         ret.f_[2] = 0;
932         ret.f_[3] = 0;
933         ret.f_[4] = 0;
934         ret.f_[5] = 1.f;
935         ret.f_[6] = 0;
936         ret.f_[7] = 0;
937         ret.f_[8] = 0;
938         ret.f_[9] = 0;
939         ret.f_[10] = 1.f;
940         ret.f_[11] = 0;
941         ret.f_[12] = 0;
942         ret.f_[13] = 0;
943         ret.f_[14] = 0;
944         ret.f_[15] = 1.f;
945         return ret;
946     }
947 
Dump()948     void Dump()
949     {
950         LOGI( "%f %f %f %f", f_[0], f_[1], f_[2], f_[3] );
951         LOGI( "%f %f %f %f", f_[4], f_[5], f_[6], f_[7] );
952         LOGI( "%f %f %f %f", f_[8], f_[9], f_[10], f_[11] );
953         LOGI( "%f %f %f %f", f_[12], f_[13], f_[14], f_[15] );
954     }
955 };
956 
957 /******************************************************************
958  * Quaternion class
959  *
960  */
961 class Quaternion
962 {
963 private:
964     float x_, y_, z_, w_;
965 
966 public:
967     friend class Vec3;
968     friend class Vec4;
969     friend class Mat4;
970 
Quaternion()971     Quaternion()
972     {
973         x_ = 0.f;
974         y_ = 0.f;
975         z_ = 0.f;
976         w_ = 1.f;
977     }
978 
Quaternion(const float fX,const float fY,const float fZ,const float fW)979     Quaternion( const float fX, const float fY, const float fZ, const float fW )
980     {
981         x_ = fX;
982         y_ = fY;
983         z_ = fZ;
984         w_ = fW;
985     }
986 
Quaternion(const Vec3 vec,const float fW)987     Quaternion( const Vec3 vec, const float fW )
988     {
989         x_ = vec.x_;
990         y_ = vec.y_;
991         z_ = vec.z_;
992         w_ = fW;
993     }
994 
Quaternion(const float * p)995     Quaternion( const float* p )
996     {
997         x_ = *p++;
998         y_ = *p++;
999         z_ = *p++;
1000         w_ = *p++;
1001     }
1002 
1003     Quaternion operator*( const Quaternion rhs )
1004     {
1005         Quaternion ret;
1006         ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_;
1007         ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_;
1008         ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_;
1009         ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_;
1010         return ret;
1011     }
1012 
1013     Quaternion& operator*=( const Quaternion rhs )
1014     {
1015         Quaternion ret;
1016         ret.x_ = x_ * rhs.w_ + y_ * rhs.z_ - z_ * rhs.y_ + w_ * rhs.x_;
1017         ret.y_ = -x_ * rhs.z_ + y_ * rhs.w_ + z_ * rhs.x_ + w_ * rhs.y_;
1018         ret.z_ = x_ * rhs.y_ - y_ * rhs.x_ + z_ * rhs.w_ + w_ * rhs.z_;
1019         ret.w_ = -x_ * rhs.x_ - y_ * rhs.y_ - z_ * rhs.z_ + w_ * rhs.w_;
1020         *this = ret;
1021         return *this;
1022     }
1023 
Conjugate()1024     Quaternion Conjugate()
1025     {
1026         x_ = -x_;
1027         y_ = -y_;
1028         z_ = -z_;
1029         return *this;
1030     }
1031 
1032     //Non destuctive version
Conjugated()1033     Quaternion Conjugated()
1034     {
1035         Quaternion ret;
1036         ret.x_ = -x_;
1037         ret.y_ = -y_;
1038         ret.z_ = -z_;
1039         ret.w_ = w_;
1040         return ret;
1041     }
1042 
ToMatrix(Mat4 & mat)1043     void ToMatrix( Mat4& mat )
1044     {
1045         float x2 = x_ * x_ * 2.0f;
1046         float y2 = y_ * y_ * 2.0f;
1047         float z2 = z_ * z_ * 2.0f;
1048         float xy = x_ * y_ * 2.0f;
1049         float yz = y_ * z_ * 2.0f;
1050         float zx = z_ * x_ * 2.0f;
1051         float xw = x_ * w_ * 2.0f;
1052         float yw = y_ * w_ * 2.0f;
1053         float zw = z_ * w_ * 2.0f;
1054 
1055         mat.f_[0] = 1.0f - y2 - z2;
1056         mat.f_[1] = xy + zw;
1057         mat.f_[2] = zx - yw;
1058         mat.f_[4] = xy - zw;
1059         mat.f_[5] = 1.0f - z2 - x2;
1060         mat.f_[6] = yz + xw;
1061         mat.f_[8] = zx + yw;
1062         mat.f_[9] = yz - xw;
1063         mat.f_[10] = 1.0f - x2 - y2;
1064 
1065         mat.f_[3] = mat.f_[7] = mat.f_[11] = mat.f_[12] = mat.f_[13] = mat.f_[14] = 0.0f;
1066         mat.f_[15] = 1.0f;
1067     }
1068 
ToMatrixPreserveTranslate(Mat4 & mat)1069     void ToMatrixPreserveTranslate( Mat4& mat )
1070     {
1071         float x2 = x_ * x_ * 2.0f;
1072         float y2 = y_ * y_ * 2.0f;
1073         float z2 = z_ * z_ * 2.0f;
1074         float xy = x_ * y_ * 2.0f;
1075         float yz = y_ * z_ * 2.0f;
1076         float zx = z_ * x_ * 2.0f;
1077         float xw = x_ * w_ * 2.0f;
1078         float yw = y_ * w_ * 2.0f;
1079         float zw = z_ * w_ * 2.0f;
1080 
1081         mat.f_[0] = 1.0f - y2 - z2;
1082         mat.f_[1] = xy + zw;
1083         mat.f_[2] = zx - yw;
1084         mat.f_[4] = xy - zw;
1085         mat.f_[5] = 1.0f - z2 - x2;
1086         mat.f_[6] = yz + xw;
1087         mat.f_[8] = zx + yw;
1088         mat.f_[9] = yz - xw;
1089         mat.f_[10] = 1.0f - x2 - y2;
1090 
1091         mat.f_[3] = mat.f_[7] = mat.f_[11] = 0.0f;
1092         mat.f_[15] = 1.0f;
1093     }
1094 
RotationAxis(const Vec3 axis,const float angle)1095     static Quaternion RotationAxis( const Vec3 axis, const float angle )
1096     {
1097         Quaternion ret;
1098         float s = sinf( angle / 2 );
1099         ret.x_ = s * axis.x_;
1100         ret.y_ = s * axis.y_;
1101         ret.z_ = s * axis.z_;
1102         ret.w_ = cosf( angle / 2 );
1103         return ret;
1104     }
1105 
Value(float & fX,float & fY,float & fZ,float & fW)1106     void Value( float& fX, float& fY, float& fZ, float& fW )
1107     {
1108         fX = x_;
1109         fY = y_;
1110         fZ = z_;
1111         fW = w_;
1112     }
1113 };
1114 
1115 } //namespace ndk_helper
1116 #endif /* VECMATH_H_ */
1117