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
23namespace 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
34class Vec2;
35class Vec3;
36class Vec4;
37class Mat4;
38
39/******************************************************************
40 * 2 elements vector class
41 *
42 */
43class Vec2
44{
45private:
46    float x_;
47    float y_;
48
49public:
50    friend class Vec3;
51    friend class Vec4;
52    friend class Mat4;
53    friend class Quaternion;
54
55    Vec2()
56    {
57        x_ = y_ = 0.f;
58    }
59
60    Vec2( const float fX, const float fY )
61    {
62        x_ = fX;
63        y_ = fY;
64    }
65
66    Vec2( const Vec2& vec )
67    {
68        x_ = vec.x_;
69        y_ = vec.y_;
70    }
71
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
208    float Length() const
209    {
210        return sqrtf( x_ * x_ + y_ * y_ );
211    }
212
213    Vec2 Normalize()
214    {
215        float len = Length();
216        x_ = x_ / len;
217        y_ = y_ / len;
218        return *this;
219    }
220
221    float Dot( const Vec2& rhs )
222    {
223        return x_ * rhs.x_ + y_ * rhs.y_;
224    }
225
226    bool Validate()
227    {
228        if( isnan( x_ ) || isnan( y_ ) )
229            return false;
230        return true;
231    }
232
233    void Value( float& fX, float& fY )
234    {
235        fX = x_;
236        fY = y_;
237    }
238
239    void Dump()
240    {
241        LOGI( "Vec2 %f %f", x_, y_ );
242    }
243};
244
245/******************************************************************
246 * 3 elements vector class
247 *
248 */
249class Vec3
250{
251private:
252    float x_, y_, z_;
253
254public:
255    friend class Vec4;
256    friend class Mat4;
257    friend class Quaternion;
258
259    Vec3()
260    {
261        x_ = y_ = z_ = 0.f;
262    }
263
264    Vec3( const float fX, const float fY, const float fZ )
265    {
266        x_ = fX;
267        y_ = fY;
268        z_ = fZ;
269    }
270
271    Vec3( const Vec3& vec )
272    {
273        x_ = vec.x_;
274        y_ = vec.y_;
275        z_ = vec.z_;
276    }
277
278    Vec3( const float* pVec )
279    {
280        x_ = (*pVec++);
281        y_ = (*pVec++);
282        z_ = *pVec;
283    }
284
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
438    float Length() const
439    {
440        return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ );
441    }
442
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
452    float Dot( const Vec3& rhs )
453    {
454        return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
455    }
456
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
466    bool Validate()
467    {
468        if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) )
469            return false;
470        return true;
471    }
472
473    void Value( float& fX, float& fY, float& fZ )
474    {
475        fX = x_;
476        fY = y_;
477        fZ = z_;
478    }
479
480    void Dump()
481    {
482        LOGI( "Vec3 %f %f %f", x_, y_, z_ );
483    }
484};
485
486/******************************************************************
487 * 4 elements vector class
488 *
489 */
490class Vec4
491{
492private:
493    float x_, y_, z_, w_;
494
495public:
496    friend class Vec3;
497    friend class Mat4;
498    friend class Quaternion;
499
500    Vec4()
501    {
502        x_ = y_ = z_ = w_ = 0.f;
503    }
504
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
513    Vec4( const Vec4& vec )
514    {
515        x_ = vec.x_;
516        y_ = vec.y_;
517        z_ = vec.z_;
518        w_ = vec.w_;
519    }
520
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
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
697    float Length() const
698    {
699        return sqrtf( x_ * x_ + y_ * y_ + z_ * z_ + w_ * w_ );
700    }
701
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
712    float Dot( const Vec3& rhs )
713    {
714        return x_ * rhs.x_ + y_ * rhs.y_ + z_ * rhs.z_;
715    }
716
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
726    bool Validate()
727    {
728        if( isnan( x_ ) || isnan( y_ ) || isnan( z_ ) || isnan( w_ ) )
729            return false;
730        return true;
731    }
732
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 */
746class Mat4
747{
748private:
749    float f_[16];
750
751public:
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
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
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
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
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
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 */
961class Quaternion
962{
963private:
964    float x_, y_, z_, w_;
965
966public:
967    friend class Vec3;
968    friend class Vec4;
969    friend class Mat4;
970
971    Quaternion()
972    {
973        x_ = 0.f;
974        y_ = 0.f;
975        z_ = 0.f;
976        w_ = 1.f;
977    }
978
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
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
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
1024    Quaternion Conjugate()
1025    {
1026        x_ = -x_;
1027        y_ = -y_;
1028        z_ = -z_;
1029        return *this;
1030    }
1031
1032    //Non destuctive version
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
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
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
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
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