• 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