1/*---------------------------------------------------------------------------*
2  Project:  Horizon
3  File:     math_Matrix44.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: 45840 $
14 *---------------------------------------------------------------------------*/
15
16#include <cmath>
17#include <nn/math/math_Vector3.h>
18
19namespace nn {
20namespace math {
21
22/* ------------------------------------------------------------------------
23        MTX44
24   ------------------------------------------------------------------------ */
25
26NN_MATH_INLINE MTX44*
27MTX44FrustumPivot(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot)
28{
29    MTX44Frustum( pOut, l, r, b, t, n, f );
30    MTX44Pivot( pOut, pivot );
31
32    return pOut;
33}
34
35NN_MATH_INLINE MTX44*
36MTX44Identity(MTX44* pOut)
37{
38    NN_NULL_ASSERT( pOut );
39
40    MTX44Copy(pOut, MTX44::Identity());
41
42    return pOut;
43}
44
45NN_MATH_INLINE bool
46MTX44IsIdentity(const MTX44* 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           p->f._30 == 0.f && p->f._31 == 0.f && p->f._32 == 0.f && p->f._33 == 1.f;
52}
53#if 0
54namespace {
55    /*---------------------------------------------------------------------------*
56          Description:  Faces toward the direction of the screen and rotates the projection matrix.
57
58      Arguments:    pOut    Pointer to the matrix to rotate
59                    pivot
60
61      Returns:
62     *---------------------------------------------------------------------------*/
63    inline MTX44*
64    MTX44Pivot( MTX44* pOut, PivotDirection pivot )
65    {
66        // TODO: Process must be optimized.
67
68        const f32 PIVOT_ROTATION_SIN_COS[ PIVOT_NUM ][ 2 ] =
69        {
70        #ifdef NN_PLATFORM_CTR
71            { 0.0f,  1.0f }, // NONE
72            { -1.0f, 0.0f }, // TO_UP
73            { 0.0f, -1.0f }, // TO_RIGHT
74            { 1.0f,  0.0f }, // TO_BOTTOM
75            { 0.0f,  1.0f }, // TO_LEFT
76        #else
77            { 0.0f,  1.0f }, // NONE
78            { 0.0f,  1.0f }, // TO_UP
79            { -1.0f, 0.0f }, // TO_RIGHT
80            { 0.0f, -1.0f }, // TO_BOTTOM
81            { 1.0f,  0.0f }, // TO_LEFT
82        #endif
83        };
84
85        if ( pivot == PIVOT_NONE )
86        {
87            return pOut;
88        }
89
90        f32 sin = PIVOT_ROTATION_SIN_COS[ pivot ][ 0 ];
91        f32 cos = PIVOT_ROTATION_SIN_COS[ pivot ][ 1 ];
92
93        f32 (*const m)[4] = pOut->m;
94
95        if ( sin == 0.0f )
96        {
97            m[0][0] = cos * m[0][0];
98            m[0][1] = cos * m[0][1];
99            m[0][2] = cos * m[0][2];
100            m[0][3] = cos * m[0][3];
101
102            m[1][0] = cos * m[1][0];
103            m[1][1] = cos * m[1][1];
104            m[1][2] = cos * m[1][2];
105            m[1][3] = cos * m[1][3];
106        }
107        else // if ( cos == 0.0f )
108        {
109            f32 tmp = m[0][0];
110            m[0][0] = -sin * m[1][0];
111            m[1][0] = sin * tmp;
112
113            tmp = m[0][1];
114            m[0][1] = -sin * m[1][1];
115            m[1][1] = sin * tmp;
116
117            tmp = m[0][2];
118            m[0][2] = -sin * m[1][2];
119            m[1][2] = sin * tmp;
120
121            tmp = m[0][3];
122            m[0][3] = -sin * m[1][3];
123            m[1][3] = sin * tmp;
124        }
125
126        return pOut;
127    }
128
129} // Namespace
130#endif
131
132NN_MATH_INLINE MTX44*
133MTX44MultArray(MTX44* pOut, const MTX44* __restrict p1, const MTX44* __restrict pSrc, s32 count)
134{
135    MTX44* pOutBase = pOut;
136
137    NN_NULL_ASSERT( pOut );
138    NN_NULL_ASSERT( p1 );
139    NN_NULL_ASSERT( pSrc );
140    NN_ASSERT( count > 1 );
141
142    for ( s32 i = 0 ; i < count ; i++ )
143    {
144        MTX44Mult(pOut, p1, pSrc);
145
146        pSrc++;
147        pOut++;
148    }
149
150    return pOutBase;
151}
152
153namespace {
154    inline void SwapF(f32 &a, f32 &b)
155    {
156        f32 tmp;
157        tmp = a;
158        a = b;
159        b = tmp;
160    }
161} // namespace (unnamed)
162
163NN_MATH_INLINE MTX44*
164MTX44OrthoPivot(MTX44* pOut, f32 l, f32 r, f32 b, f32 t, f32 n, f32 f, PivotDirection pivot)
165{
166    MTX44Ortho( pOut, l, r, b, t, n, f );
167    MTX44Pivot( pOut, pivot );
168
169    return pOut;
170}
171
172NN_MATH_INLINE MTX44*
173MTX44PerspectivePivotRad(MTX44* pOut, f32 fovy, f32 aspect, f32 n, f32 f, PivotDirection pivot)
174{
175    MTX44PerspectiveRad( pOut, fovy, aspect, n, f );
176    MTX44Pivot( pOut, pivot );
177
178    return pOut;
179}
180
181NN_MATH_INLINE MTX44*
182MTX44RotAxisFIdx(MTX44* pOut, const VEC3* pAxis, f32 fIdx)
183{
184    // Okay for now if it's slow
185    MTX44RotAxisRad_(pOut, pAxis, NN_MATH_FIDX_TO_RAD(fIdx));
186
187    return pOut;
188}
189
190NN_MATH_INLINE MTX44*
191MTX44Sub(MTX44* pOut, const MTX44* p1, const MTX44* p2)
192{
193    pOut->f._00 = p1->f._00 - p2->f._00;
194    pOut->f._01 = p1->f._01 - p2->f._01;
195    pOut->f._02 = p1->f._02 - p2->f._02;
196    pOut->f._03 = p1->f._03 - p2->f._03;
197
198    pOut->f._10 = p1->f._10 - p2->f._10;
199    pOut->f._11 = p1->f._11 - p2->f._11;
200    pOut->f._12 = p1->f._12 - p2->f._12;
201    pOut->f._13 = p1->f._13 - p2->f._13;
202
203    pOut->f._20 = p1->f._20 - p2->f._20;
204    pOut->f._21 = p1->f._21 - p2->f._21;
205    pOut->f._22 = p1->f._22 - p2->f._22;
206    pOut->f._23 = p1->f._23 - p2->f._23;
207
208    pOut->f._30 = p1->f._30 - p2->f._30;
209    pOut->f._31 = p1->f._31 - p2->f._31;
210    pOut->f._32 = p1->f._32 - p2->f._32;
211    pOut->f._33 = p1->f._33 - p2->f._33;
212
213    return pOut;
214}
215
216NN_MATH_INLINE MTX44*
217MTX44Zero(MTX44* pOut)
218{
219    pOut->f._00 = pOut->f._01 = pOut->f._02 = pOut->f._03 =
220    pOut->f._10 = pOut->f._11 = pOut->f._12 = pOut->f._13 =
221    pOut->f._20 = pOut->f._21 = pOut->f._22 = pOut->f._23 =
222    pOut->f._30 = pOut->f._31 = pOut->f._32 = pOut->f._33 = 0.f;
223
224    return pOut;
225}
226
227}  // namespace math
228}  // namespace nn
229