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