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