1/*---------------------------------------------------------------------------*
2  Project:  Horizon
3  File:     math_Matrix34.ipp
4
5  Copyright (C)2009-2010 Nintendo Co., Ltd.  All rights reserved.
6
7  These coded instructions, statements, and computer programs contain
8  proprietary information of Nintendo of America Inc. and/or Nintendo
9  Company Ltd., and are protected by Federal copyright law.  They may
10  not be disclosed to third parties or copied or duplicated in any form,
11  in whole or in part, without the prior written consent of Nintendo.
12
13  $Revision: 47340 $
14 *---------------------------------------------------------------------------*/
15#include <cmath>
16#include <nn/math/math_Vector3.h>
17
18namespace nn {
19namespace math {
20
21
22/* ------------------------------------------------------------------------
23        MTX34
24   ------------------------------------------------------------------------ */
25
26NN_MATH_INLINE MTX34*
27MTX34Identity(MTX34* pOut)
28{
29    NN_NULL_ASSERT( pOut );
30
31    MTX34Copy(pOut, MTX34::Identity());
32
33    return pOut;
34}
35
36NN_MATH_INLINE u32
37MTX34InvTranspose(MTX33* pOut, const MTX34* __restrict p)
38{
39    MTX34 tmp;
40    u32 rval = MTX34InvTranspose(&tmp, p);
41    (void)MTX34ToMTX33(pOut, &tmp);
42    return rval;
43}
44
45NN_MATH_INLINE bool
46MTX34IsIdentity(const MTX34* p)
47{
48    return p->f._00 == 1.f && p->f._01 == 0.f && p->f._02 == 0.f && p->f._03 == 0.f &&
49           p->f._10 == 0.f && p->f._11 == 1.f && p->f._12 == 0.f && p->f._13 == 0.f &&
50           p->f._20 == 0.f && p->f._21 == 0.f && p->f._22 == 1.f && p->f._23 == 0.f;
51}
52
53NN_MATH_INLINE MTX34*
54MTX34MultArray(MTX34* pOut, const MTX34* __restrict p1, const MTX34* __restrict pSrc, s32 count)
55{
56    MTX34* pOutBase = pOut;
57
58    NN_NULL_ASSERT( pOut );
59    NN_NULL_ASSERT( p1 );
60    NN_NULL_ASSERT( pSrc );
61    NN_ASSERT( count > 1 );
62
63    for ( s32 i = 0 ; i < count ; i++ )
64    {
65        MTX34Mult(pOut, p1, pSrc);
66
67        pSrc++;
68        pOut++;
69    }
70
71    return pOutBase;
72}
73
74NN_MATH_INLINE MTX34*
75MTX34RotAxisFIdx(MTX34* pOut, const VEC3* pAxis, f32 fIdx)
76{
77    // Okay for now if it's slow
78    MTX34RotAxisRad_(pOut, pAxis, NN_MATH_FIDX_TO_RAD(fIdx));
79
80    return pOut;
81}
82
83NN_MATH_INLINE MTX34*
84MTX34RotXYZTranslateFIdx(MTX34* pOut, f32 fIdxX, f32 fIdxY, f32 fIdxZ, const VEC3* pT)
85{
86    (void)MTX34RotXYZFIdx(pOut, fIdxX, fIdxY, fIdxZ);
87    pOut->f._03 = pT->x;
88    pOut->f._13 = pT->y;
89    pOut->f._23 = pT->z;
90    return pOut;
91}
92
93NN_MATH_INLINE MTX34*
94MTX34Sub(MTX34* pOut, const MTX34* p1, const MTX34* p2)
95{
96    pOut->f._00 = p1->f._00 - p2->f._00;
97    pOut->f._01 = p1->f._01 - p2->f._01;
98    pOut->f._02 = p1->f._02 - p2->f._02;
99    pOut->f._03 = p1->f._03 - p2->f._03;
100
101    pOut->f._10 = p1->f._10 - p2->f._10;
102    pOut->f._11 = p1->f._11 - p2->f._11;
103    pOut->f._12 = p1->f._12 - p2->f._12;
104    pOut->f._13 = p1->f._13 - p2->f._13;
105
106    pOut->f._20 = p1->f._20 - p2->f._20;
107    pOut->f._21 = p1->f._21 - p2->f._21;
108    pOut->f._22 = p1->f._22 - p2->f._22;
109    pOut->f._23 = p1->f._23 - p2->f._23;
110
111    return pOut;
112}
113
114NN_MATH_INLINE MTX34*
115MTX34TextureProjectionFrustum(MTX34* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 scaleS, f32 scaleT, f32 translateS, f32 translateT)
116{
117    NN_ASSERT(t != b);
118    NN_ASSERT(l != r);
119    NN_NULL_ASSERT(pOut);
120
121    f32 reverseWidth = 1.0f / (r - l);
122
123    f32 (*const mtx)[4] = pOut->m;
124
125    mtx[0][0] = ((2.0f * n) * reverseWidth) * scaleS;
126    mtx[0][1] = 0.0f;
127    mtx[0][2] = (((r + l) * reverseWidth) * scaleS) - translateS;
128    mtx[0][3] = 0.0f;
129
130    f32 reverseHeight = 1.0f / (t - b);
131    mtx[1][0] = 0.0f;
132    mtx[1][1] = ((2.0f * n) * reverseHeight) * scaleT;
133    mtx[1][2] = (((t+ b) * reverseHeight) * scaleT) - translateT;
134    mtx[1][3] = 0.0f;
135
136    mtx[2][0] = 0.0f;
137    mtx[2][1] = 0.0f;
138    mtx[2][2] = -1.0f;
139    mtx[2][3] = 0.0f;
140    return pOut;
141}
142
143NN_MATH_INLINE MTX34*
144MTX34TextureProjectionOrtho(MTX34* pOut, f32 l, f32 r, f32 b, f32 t, f32 scaleS, f32 scaleT, f32 translateS, f32 translateT)
145{
146    NN_ASSERT(t != b);
147    NN_ASSERT(l != r);
148    NN_NULL_ASSERT(pOut);
149
150    f32 reverseWidth = 1.0f / (r - l);
151
152    f32 (*const mtx)[4] = pOut->m;
153
154    mtx[0][0] = 2.0f * reverseWidth * scaleS;
155    mtx[0][1] = 0.0f;
156    mtx[0][2] = 0.0f;
157    mtx[0][3] = ((-(r + l) * reverseWidth) * scaleS) + translateS;
158
159    f32 reverseHeight = 1.0f / (t - b);
160    mtx[1][0] = 0.0f;
161    mtx[1][1] = (2.0f * reverseHeight) * scaleT;
162    mtx[1][2] = 0.0f;
163    mtx[1][3] = ((-(t + b) * reverseHeight) * scaleT) + translateT;
164
165    mtx[2][0] = 0.0f;
166    mtx[2][1] = 0.0f;
167    mtx[2][2] = 0.0f;
168    mtx[2][3] = 1.0f;
169    return pOut;
170}
171
172NN_MATH_INLINE MTX34*
173MTX34TextureProjectionPerspective(MTX34* pOut, f32 fovy, f32 aspect, f32 scaleS, f32 scaleT, f32 translateS, f32 translateT)
174{
175    NN_ASSERT((fovy > 0.0f) && (fovy < math::F_PI));
176    NN_ASSERT(aspect != 0.0f);
177    NN_NULL_ASSERT(pOut);
178
179    f32 angle = fovy * 0.5f;
180    f32 cot = 1.0f / math::TanRad(angle);
181
182    f32 (*const mtx)[4] = pOut->m;
183
184    mtx[0][0] = (cot / aspect) * scaleS;
185    mtx[0][1] = 0.0f;
186    mtx[0][2] = -translateS;
187    mtx[0][3] = 0.0f;
188
189    mtx[1][0] = 0.0f;
190    mtx[1][1] = cot * scaleT;
191    mtx[1][2] = -translateT;
192    mtx[1][3] = 0.0f;
193
194    mtx[2][0] = 0.0f;
195    mtx[2][1] = 0.0f;
196    mtx[2][2] = -1.0f;
197    mtx[2][3] = 0.0f;
198
199    return pOut;
200}
201
202NN_MATH_INLINE MTX34*
203MTX34ShadowProjectionFrustum(MTX34* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f)
204{
205    NN_ASSERT(t != b);
206    NN_ASSERT(l != r);
207    NN_NULL_ASSERT(pOut);
208
209    f32 reverseWidth = 1.0f / (r - l);
210    f32 scale = -1.0f / (f - n);
211
212    f32 (*const mtx)[4] = pOut->m;
213
214    mtx[0][0] = ((-1.0f * n) * reverseWidth) * scale;
215    mtx[0][1] = 0.0f;
216    mtx[0][2] = ((((r + l) * reverseWidth) * -0.5f) + 0.5f) * scale;
217    mtx[0][3] = 0.0f;
218
219    f32 reverseHeight = 1.0f / (t - b);
220    mtx[1][0] = 0.0f;
221    mtx[1][1] = ((-1.0f * n) * reverseHeight) * scale;
222    mtx[1][2] = ((((t+ b) * reverseHeight) * -0.5f) + 0.5f) * scale;
223    mtx[1][3] = 0.0f;
224
225    mtx[2][0] = 0.0f;
226    mtx[2][1] = 0.0f;
227    mtx[2][2] = scale;
228    mtx[2][3] = 0.0f;
229    return pOut;
230}
231
232NN_MATH_INLINE MTX34*
233MTX34ShadowProjectionOrtho(MTX34* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f)
234{
235    NN_ASSERT(t != b);
236    NN_ASSERT(l != r);
237    NN_NULL_ASSERT(pOut);
238
239    f32 reverseWidth = 1.0f / (r - l);
240
241    f32 (*const mtx)[4] = pOut->m;
242
243    mtx[0][0] = reverseWidth;
244    mtx[0][1] = 0.0f;
245    mtx[0][2] = 0.0f;
246    mtx[0][3] = -(r + l) * reverseWidth + 0.5f;
247
248    f32 reverseHeight = 1.0f / (t - b);
249    mtx[1][0] = 0.0f;
250    mtx[1][1] = reverseHeight;
251    mtx[1][2] = 0.0f;
252    mtx[1][3] = -(t + b) * reverseHeight + 0.5f;
253
254    f32 tmp = -1.0f / (f - n);
255    mtx[2][0] = 0.0f;
256    mtx[2][1] = 0.0f;
257    mtx[2][2] = tmp;
258    mtx[2][3] = n * tmp;
259    return pOut;
260}
261
262NN_MATH_INLINE MTX34*
263MTX34ShadowProjectionPerspective(MTX34* pOut, f32 fovy, f32 aspect, f32 n, f32 f)
264{
265    NN_ASSERT((fovy > 0.0f) && (fovy < math::F_PI));
266    NN_ASSERT(aspect != 0.0f);
267    NN_NULL_ASSERT(pOut);
268
269    f32 angle = fovy * 0.5f;
270    f32 cot = -0.5f / math::TanRad(angle);
271    f32 scale = -1.0f / (f - n);
272
273    f32 (*const mtx)[4] = pOut->m;
274
275    mtx[0][0] = (cot / aspect) * scale;
276    mtx[0][1] = 0.0f;
277    mtx[0][2] = 0.5f * scale;
278    mtx[0][3] = 0.0f;
279
280    mtx[1][0] = 0.0f;
281    mtx[1][1] = cot * scale;
282    mtx[1][2] = 0.5f * scale;
283    mtx[1][3] = 0.0f;
284
285    mtx[2][0] = 0.0f;
286    mtx[2][1] = 0.0f;
287    mtx[2][2] = scale;
288    mtx[2][3] = 0.0f;
289
290    return pOut;
291}
292
293NN_MATH_INLINE MTX34*
294MTX34Zero(MTX34* pOut)
295{
296    pOut->f._00 = pOut->f._01 = pOut->f._02 = pOut->f._03 =
297    pOut->f._10 = pOut->f._11 = pOut->f._12 = pOut->f._13 =
298    pOut->f._20 = pOut->f._21 = pOut->f._22 = pOut->f._23 = 0.f;
299
300    return pOut;
301}
302
303}  // namespace math
304}  // namespace nn
305