• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copy_right 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * y_ou may_ not use this file ex_cept 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 ex_press 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.cpp
19 
20 //--------------------------------------------------------------------------------
21 // vecmath.cpp
22 //--------------------------------------------------------------------------------
23 #include "vecmath.h"
24 
25 namespace android {
26 namespace gamecore {
27 
28 //--------------------------------------------------------------------------------
29 // vec3
30 //--------------------------------------------------------------------------------
Vec3(const Vec4 & vec)31 Vec3::Vec3(const Vec4& vec) {
32   x_ = vec.x_;
33   y_ = vec.y_;
34   z_ = vec.z_;
35 }
36 
37 //--------------------------------------------------------------------------------
38 // vec4
39 //--------------------------------------------------------------------------------
operator *(const Mat4 & rhs) const40 Vec4 Vec4::operator*(const Mat4& rhs) const {
41   Vec4 out;
42   out.x_ = x_ * rhs.f_[0] + y_ * rhs.f_[1] + z_ * rhs.f_[2] + w_ * rhs.f_[3];
43   out.y_ = x_ * rhs.f_[4] + y_ * rhs.f_[5] + z_ * rhs.f_[6] + w_ * rhs.f_[7];
44   out.z_ = x_ * rhs.f_[8] + y_ * rhs.f_[9] + z_ * rhs.f_[10] + w_ * rhs.f_[11];
45   out.w_ =
46       x_ * rhs.f_[12] + y_ * rhs.f_[13] + z_ * rhs.f_[14] + w_ * rhs.f_[15];
47   return out;
48 }
49 
50 //--------------------------------------------------------------------------------
51 // mat4
52 //--------------------------------------------------------------------------------
Mat4()53 Mat4::Mat4() {
54   for (int32_t i = 0; i < 16; ++i) f_[i] = 0.f;
55   // column major identity matrix
56   f_[0] = f_[5] = f_[10] = f_[15] = 1.0f;
57 }
58 
Mat4(const float * mIn)59 Mat4::Mat4(const float* mIn) {
60   for (int32_t i = 0; i < 16; ++i) f_[i] = mIn[i];
61 }
62 
operator *(const Mat4 & rhs) const63 Mat4 Mat4::operator*(const Mat4& rhs) const {
64   Mat4 ret;
65   ret.f_[0] = f_[0] * rhs.f_[0] + f_[4] * rhs.f_[1] + f_[8] * rhs.f_[2] +
66               f_[12] * rhs.f_[3];
67   ret.f_[1] = f_[1] * rhs.f_[0] + f_[5] * rhs.f_[1] + f_[9] * rhs.f_[2] +
68               f_[13] * rhs.f_[3];
69   ret.f_[2] = f_[2] * rhs.f_[0] + f_[6] * rhs.f_[1] + f_[10] * rhs.f_[2] +
70               f_[14] * rhs.f_[3];
71   ret.f_[3] = f_[3] * rhs.f_[0] + f_[7] * rhs.f_[1] + f_[11] * rhs.f_[2] +
72               f_[15] * rhs.f_[3];
73 
74   ret.f_[4] = f_[0] * rhs.f_[4] + f_[4] * rhs.f_[5] + f_[8] * rhs.f_[6] +
75               f_[12] * rhs.f_[7];
76   ret.f_[5] = f_[1] * rhs.f_[4] + f_[5] * rhs.f_[5] + f_[9] * rhs.f_[6] +
77               f_[13] * rhs.f_[7];
78   ret.f_[6] = f_[2] * rhs.f_[4] + f_[6] * rhs.f_[5] + f_[10] * rhs.f_[6] +
79               f_[14] * rhs.f_[7];
80   ret.f_[7] = f_[3] * rhs.f_[4] + f_[7] * rhs.f_[5] + f_[11] * rhs.f_[6] +
81               f_[15] * rhs.f_[7];
82 
83   ret.f_[8] = f_[0] * rhs.f_[8] + f_[4] * rhs.f_[9] + f_[8] * rhs.f_[10] +
84               f_[12] * rhs.f_[11];
85   ret.f_[9] = f_[1] * rhs.f_[8] + f_[5] * rhs.f_[9] + f_[9] * rhs.f_[10] +
86               f_[13] * rhs.f_[11];
87   ret.f_[10] = f_[2] * rhs.f_[8] + f_[6] * rhs.f_[9] + f_[10] * rhs.f_[10] +
88                f_[14] * rhs.f_[11];
89   ret.f_[11] = f_[3] * rhs.f_[8] + f_[7] * rhs.f_[9] + f_[11] * rhs.f_[10] +
90                f_[15] * rhs.f_[11];
91 
92   ret.f_[12] = f_[0] * rhs.f_[12] + f_[4] * rhs.f_[13] + f_[8] * rhs.f_[14] +
93                f_[12] * rhs.f_[15];
94   ret.f_[13] = f_[1] * rhs.f_[12] + f_[5] * rhs.f_[13] + f_[9] * rhs.f_[14] +
95                f_[13] * rhs.f_[15];
96   ret.f_[14] = f_[2] * rhs.f_[12] + f_[6] * rhs.f_[13] + f_[10] * rhs.f_[14] +
97                f_[14] * rhs.f_[15];
98   ret.f_[15] = f_[3] * rhs.f_[12] + f_[7] * rhs.f_[13] + f_[11] * rhs.f_[14] +
99                f_[15] * rhs.f_[15];
100 
101   return ret;
102 }
103 
operator *(const Vec4 & rhs) const104 Vec4 Mat4::operator*(const Vec4& rhs) const {
105   Vec4 ret;
106   ret.x_ = rhs.x_ * f_[0] + rhs.y_ * f_[4] + rhs.z_ * f_[8] + rhs.w_ * f_[12];
107   ret.y_ = rhs.x_ * f_[1] + rhs.y_ * f_[5] + rhs.z_ * f_[9] + rhs.w_ * f_[13];
108   ret.z_ = rhs.x_ * f_[2] + rhs.y_ * f_[6] + rhs.z_ * f_[10] + rhs.w_ * f_[14];
109   ret.w_ = rhs.x_ * f_[3] + rhs.y_ * f_[7] + rhs.z_ * f_[11] + rhs.w_ * f_[15];
110   return ret;
111 }
112 
Inverse()113 Mat4 Mat4::Inverse() {
114   Mat4 ret;
115   float det_1;
116   float pos = 0;
117   float neg = 0;
118   float temp;
119 
120   temp = f_[0] * f_[5] * f_[10];
121   if (temp >= 0)
122     pos += temp;
123   else
124     neg += temp;
125   temp = f_[4] * f_[9] * f_[2];
126   if (temp >= 0)
127     pos += temp;
128   else
129     neg += temp;
130   temp = f_[8] * f_[1] * f_[6];
131   if (temp >= 0)
132     pos += temp;
133   else
134     neg += temp;
135   temp = -f_[8] * f_[5] * f_[2];
136   if (temp >= 0)
137     pos += temp;
138   else
139     neg += temp;
140   temp = -f_[4] * f_[1] * f_[10];
141   if (temp >= 0)
142     pos += temp;
143   else
144     neg += temp;
145   temp = -f_[0] * f_[9] * f_[6];
146   if (temp >= 0)
147     pos += temp;
148   else
149     neg += temp;
150   det_1 = pos + neg;
151 
152   if (det_1 == 0.0) {
153     // Error
154   } else {
155     det_1 = 1.0f / det_1;
156     ret.f_[0] = (f_[5] * f_[10] - f_[9] * f_[6]) * det_1;
157     ret.f_[1] = -(f_[1] * f_[10] - f_[9] * f_[2]) * det_1;
158     ret.f_[2] = (f_[1] * f_[6] - f_[5] * f_[2]) * det_1;
159     ret.f_[4] = -(f_[4] * f_[10] - f_[8] * f_[6]) * det_1;
160     ret.f_[5] = (f_[0] * f_[10] - f_[8] * f_[2]) * det_1;
161     ret.f_[6] = -(f_[0] * f_[6] - f_[4] * f_[2]) * det_1;
162     ret.f_[8] = (f_[4] * f_[9] - f_[8] * f_[5]) * det_1;
163     ret.f_[9] = -(f_[0] * f_[9] - f_[8] * f_[1]) * det_1;
164     ret.f_[10] = (f_[0] * f_[5] - f_[4] * f_[1]) * det_1;
165 
166     /* Calculate -C * inverse(A) */
167     ret.f_[12] =
168         -(f_[12] * ret.f_[0] + f_[13] * ret.f_[4] + f_[14] * ret.f_[8]);
169     ret.f_[13] =
170         -(f_[12] * ret.f_[1] + f_[13] * ret.f_[5] + f_[14] * ret.f_[9]);
171     ret.f_[14] =
172         -(f_[12] * ret.f_[2] + f_[13] * ret.f_[6] + f_[14] * ret.f_[10]);
173 
174     ret.f_[3] = 0.0f;
175     ret.f_[7] = 0.0f;
176     ret.f_[11] = 0.0f;
177     ret.f_[15] = 1.0f;
178   }
179 
180   *this = ret;
181   return *this;
182 }
183 
184 //--------------------------------------------------------------------------------
185 // Misc
186 //--------------------------------------------------------------------------------
RotationX(const float fAngle)187 Mat4 Mat4::RotationX(const float fAngle) {
188   Mat4 ret;
189   float fCosine, fSine;
190 
191   fCosine = cosf(fAngle);
192   fSine = sinf(fAngle);
193 
194   ret.f_[0] = 1.0f;
195   ret.f_[4] = 0.0f;
196   ret.f_[8] = 0.0f;
197   ret.f_[12] = 0.0f;
198   ret.f_[1] = 0.0f;
199   ret.f_[5] = fCosine;
200   ret.f_[9] = fSine;
201   ret.f_[13] = 0.0f;
202   ret.f_[2] = 0.0f;
203   ret.f_[6] = -fSine;
204   ret.f_[10] = fCosine;
205   ret.f_[14] = 0.0f;
206   ret.f_[3] = 0.0f;
207   ret.f_[7] = 0.0f;
208   ret.f_[11] = 0.0f;
209   ret.f_[15] = 1.0f;
210   return ret;
211 }
212 
RotationY(const float fAngle)213 Mat4 Mat4::RotationY(const float fAngle) {
214   Mat4 ret;
215   float fCosine, fSine;
216 
217   fCosine = cosf(fAngle);
218   fSine = sinf(fAngle);
219 
220   ret.f_[0] = fCosine;
221   ret.f_[4] = 0.0f;
222   ret.f_[8] = -fSine;
223   ret.f_[12] = 0.0f;
224   ret.f_[1] = 0.0f;
225   ret.f_[5] = 1.0f;
226   ret.f_[9] = 0.0f;
227   ret.f_[13] = 0.0f;
228   ret.f_[2] = fSine;
229   ret.f_[6] = 0.0f;
230   ret.f_[10] = fCosine;
231   ret.f_[14] = 0.0f;
232   ret.f_[3] = 0.0f;
233   ret.f_[7] = 0.0f;
234   ret.f_[11] = 0.0f;
235   ret.f_[15] = 1.0f;
236   return ret;
237 }
238 
RotationZ(const float fAngle)239 Mat4 Mat4::RotationZ(const float fAngle) {
240   Mat4 ret;
241   float fCosine, fSine;
242 
243   fCosine = cosf(fAngle);
244   fSine = sinf(fAngle);
245 
246   ret.f_[0] = fCosine;
247   ret.f_[4] = fSine;
248   ret.f_[8] = 0.0f;
249   ret.f_[12] = 0.0f;
250   ret.f_[1] = -fSine;
251   ret.f_[5] = fCosine;
252   ret.f_[9] = 0.0f;
253   ret.f_[13] = 0.0f;
254   ret.f_[2] = 0.0f;
255   ret.f_[6] = 0.0f;
256   ret.f_[10] = 1.0f;
257   ret.f_[14] = 0.0f;
258   ret.f_[3] = 0.0f;
259   ret.f_[7] = 0.0f;
260   ret.f_[11] = 0.0f;
261   ret.f_[15] = 1.0f;
262   return ret;
263 }
264 
Scale(const float scaleX,const float scaleY,const float scaleZ)265 Mat4 Mat4::Scale(const float scaleX, const float scaleY, const float scaleZ) {
266   Mat4 ret;
267   ret.f_[0] = scaleX;
268   ret.f_[5] = scaleY;
269   ret.f_[10] = scaleZ;
270   ret.f_[1] = ret.f_[2] = ret.f_[3] = ret.f_[4] = ret.f_[6] = ret.f_[7] =
271       ret.f_[8] = ret.f_[9] = ret.f_[11] = ret.f_[12] = ret.f_[13] =
272           ret.f_[14] = 0.f;
273   ret.f_[15] = 1.0f;
274   return ret;
275 }
276 
Translation(const float fX,const float fY,const float fZ)277 Mat4 Mat4::Translation(const float fX, const float fY, const float fZ) {
278   Mat4 ret;
279   ret.f_[0] = 1.0f;
280   ret.f_[4] = 0.0f;
281   ret.f_[8] = 0.0f;
282   ret.f_[12] = fX;
283   ret.f_[1] = 0.0f;
284   ret.f_[5] = 1.0f;
285   ret.f_[9] = 0.0f;
286   ret.f_[13] = fY;
287   ret.f_[2] = 0.0f;
288   ret.f_[6] = 0.0f;
289   ret.f_[10] = 1.0f;
290   ret.f_[14] = fZ;
291   ret.f_[3] = 0.0f;
292   ret.f_[7] = 0.0f;
293   ret.f_[11] = 0.0f;
294   ret.f_[15] = 1.0f;
295   return ret;
296 }
297 
Translation(const Vec3 vec)298 Mat4 Mat4::Translation(const Vec3 vec) {
299   Mat4 ret;
300   ret.f_[0] = 1.0f;
301   ret.f_[4] = 0.0f;
302   ret.f_[8] = 0.0f;
303   ret.f_[12] = vec.x_;
304   ret.f_[1] = 0.0f;
305   ret.f_[5] = 1.0f;
306   ret.f_[9] = 0.0f;
307   ret.f_[13] = vec.y_;
308   ret.f_[2] = 0.0f;
309   ret.f_[6] = 0.0f;
310   ret.f_[10] = 1.0f;
311   ret.f_[14] = vec.z_;
312   ret.f_[3] = 0.0f;
313   ret.f_[7] = 0.0f;
314   ret.f_[11] = 0.0f;
315   ret.f_[15] = 1.0f;
316   return ret;
317 }
318 
Perspective(float width,float height,float nearPlane,float farPlane)319 Mat4 Mat4::Perspective(float width, float height, float nearPlane,
320                        float farPlane) {
321   float n2 = 2.0f * nearPlane;
322   float rcpnmf = 1.f / (nearPlane - farPlane);
323 
324   Mat4 result;
325   result.f_[0] = n2 / width;
326   result.f_[4] = 0;
327   result.f_[8] = 0;
328   result.f_[12] = 0;
329   result.f_[1] = 0;
330   result.f_[5] = n2 / height;
331   result.f_[9] = 0;
332   result.f_[13] = 0;
333   result.f_[2] = 0;
334   result.f_[6] = 0;
335   result.f_[10] = (farPlane + nearPlane) * rcpnmf;
336   result.f_[14] = farPlane * rcpnmf * n2;
337   result.f_[3] = 0;
338   result.f_[7] = 0;
339   result.f_[11] = -1.0;
340   result.f_[15] = 0;
341 
342   return result;
343 }
344 
Ortho2D(float left,float top,float right,float bottom)345 Mat4 Mat4::Ortho2D(float left, float top, float right, float bottom) {
346   const float zNear = -1.0f;
347   const float zFar = 1.0f;
348   const float inv_z = 1.0f / (zFar - zNear);
349   const float inv_y = 1.0f / (-top + bottom);
350   const float inv_x = 1.0f / (right - left);
351 
352   Mat4 result;
353   result.f_[0] = 2.0f * inv_x;
354   result.f_[1] = 0.0f;
355   result.f_[2] = 0.0f;
356   result.f_[3] = 0.0f;
357 
358   result.f_[4] = 0.0f;
359   result.f_[5] = 2.0 * inv_y;
360   result.f_[6] = 0.0f;
361   result.f_[7] = 0.0f;
362 
363   result.f_[8] = 0.0f;
364   result.f_[9] = 0.0f;
365   result.f_[10] = -2.0f * inv_z;
366   result.f_[11] = 0.0f;
367 
368   result.f_[12] = -(right + left) * inv_x;
369   result.f_[13] = (top + bottom) * inv_y;
370   result.f_[14] = -(zFar + zNear) * inv_z;
371   result.f_[15] = 1.0f;
372   return result;
373 }
374 
LookAt(const Vec3 & vec_eye,const Vec3 & vec_at,const Vec3 & vec_up)375 Mat4 Mat4::LookAt(const Vec3& vec_eye, const Vec3& vec_at, const Vec3& vec_up) {
376   Vec3 vec_forward, vec_up_norm, vec_side;
377   Mat4 result;
378 
379   vec_forward.x_ = vec_eye.x_ - vec_at.x_;
380   vec_forward.y_ = vec_eye.y_ - vec_at.y_;
381   vec_forward.z_ = vec_eye.z_ - vec_at.z_;
382 
383   vec_forward.Normalize();
384   vec_up_norm = vec_up;
385   vec_up_norm.Normalize();
386   vec_side = vec_up_norm.Cross(vec_forward);
387   vec_up_norm = vec_forward.Cross(vec_side);
388 
389   result.f_[0] = vec_side.x_;
390   result.f_[4] = vec_side.y_;
391   result.f_[8] = vec_side.z_;
392   result.f_[12] = 0;
393   result.f_[1] = vec_up_norm.x_;
394   result.f_[5] = vec_up_norm.y_;
395   result.f_[9] = vec_up_norm.z_;
396   result.f_[13] = 0;
397   result.f_[2] = vec_forward.x_;
398   result.f_[6] = vec_forward.y_;
399   result.f_[10] = vec_forward.z_;
400   result.f_[14] = 0;
401   result.f_[3] = 0;
402   result.f_[7] = 0;
403   result.f_[11] = 0;
404   result.f_[15] = 1.0;
405 
406   result.PostTranslate(-vec_eye.x_, -vec_eye.y_, -vec_eye.z_);
407   return result;
408 }
409 
410 }  // namespace gamecore
411 }  // namespace android
412