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