1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - GX -
3 File: fx_mtx44.c
4
5 Copyright 2003-2008 Nintendo. 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 $Date:: 2009-06-19#$
14 $Rev: 10786 $
15 $Author: okajima_manabu $
16 *---------------------------------------------------------------------------*/
17
18 #include <nitro/code32.h> // Always generate ARM binary for efficiency
19
20 #include <nitro/fx/fx_mtx44.h>
21 #include <nitro/fx/fx_vec.h>
22 #include <nitro/fx/fx_cp.h>
23 #include <nitro/mi/memory.h>
24
mul64(fx64 x,fx32 y)25 inline fx32 mul64(fx64 x, fx32 y)
26 {
27 return (fx32)((x * y) >> FX32_SHIFT);
28 }
29
MTX_Identity44_(register MtxFx44 * pDst)30 asm void MTX_Identity44_(register MtxFx44* pDst)
31 {
32 mov r2, #4096 // FX32_ONE
33 mov r3, #0
34 stmia r0!, {r2,r3}
35 mov r1, #0
36 stmia r0!, {r1,r3}
37 stmia r0!, {r1,r2,r3}
38 stmia r0!, {r1,r3}
39 stmia r0!, {r1,r2,r3}
40 stmia r0!, {r1,r3}
41 stmia r0!, {r1,r2}
42
43 bx lr
44 }
45
MTX_Copy44To33_(register const MtxFx44 * pSrc,register MtxFx33 * pDst)46 asm void MTX_Copy44To33_(register const MtxFx44* pSrc, register MtxFx33* pDst)
47 {
48 ldmia r0!, {r2-r3, r12}
49 add r0, r0, #4
50 stmia r1!, {r2-r3, r12}
51
52 ldmia r0!, {r2-r3, r12}
53 add r0, r0, #4
54 stmia r1!, {r2-r3, r12}
55
56 ldmia r0!, {r2-r3, r12}
57 add r0, r0, #4
58 stmia r1!, {r2-r3, r12}
59
60 bx lr
61 }
62
MTX_Copy44To43_(register const MtxFx44 * pSrc,register MtxFx43 * pDst)63 asm void MTX_Copy44To43_(register const MtxFx44* pSrc, register MtxFx43* pDst)
64 {
65 ldmia r0!, {r2-r3, r12}
66 add r0, r0, #4
67 stmia r1!, {r2-r3, r12}
68
69 ldmia r0!, {r2-r3, r12}
70 add r0, r0, #4
71 stmia r1!, {r2-r3, r12}
72
73 ldmia r0!, {r2-r3, r12}
74 add r0, r0, #4
75 stmia r1!, {r2-r3, r12}
76
77 ldmia r0!, {r2-r3, r12}
78 add r0, r0, #4
79 stmia r1!, {r2-r3, r12}
80
81 bx lr
82 }
83
84 /*---------------------------------------------------------------------------*
85 Name: MTX_TransApply44
86
87 Description: Calc T(x, y, z) * pSrc = pDst
88
89 Arguments: pSrc a pointer to a 4x4 matrix
90 pDst a pointer to a 4x4 matrix
91 x x trans factor
92 y y trans factor
93 z z trans factor
94
95 Returns: None.
96 *---------------------------------------------------------------------------*/
MTX_TransApply44(const MtxFx44 * pSrc,MtxFx44 * pDst,fx32 x,fx32 y,fx32 z)97 void MTX_TransApply44(const MtxFx44 *pSrc, MtxFx44 *pDst, fx32 x, fx32 y, fx32 z)
98 {
99 SDK_NULL_ASSERT(pSrc);
100 SDK_NULL_ASSERT(pDst);
101
102 if (pSrc != pDst)
103 {
104 MI_Copy48B(pSrc, pDst);
105 }
106 {
107 fx64 xx = x;
108 fx64 yy = y;
109 fx64 zz = z;
110
111 pDst->_30 =
112 pSrc->_30 + (fx32)((xx * pSrc->_00 + yy * pSrc->_10 + zz * pSrc->_20) >> FX32_SHIFT);
113 pDst->_31 =
114 pSrc->_31 + (fx32)((xx * pSrc->_01 + yy * pSrc->_11 + zz * pSrc->_21) >> FX32_SHIFT);
115 pDst->_32 =
116 pSrc->_32 + (fx32)((xx * pSrc->_02 + yy * pSrc->_12 + zz * pSrc->_22) >> FX32_SHIFT);
117 pDst->_33 =
118 pSrc->_33 + (fx32)((xx * pSrc->_03 + yy * pSrc->_13 + zz * pSrc->_23) >> FX32_SHIFT);
119 }
120 }
121
MTX_Transpose44_(register const MtxFx44 * pSrc,register MtxFx44 * pDst)122 asm void MTX_Transpose44_(register const MtxFx44* pSrc, register MtxFx44* pDst)
123 {
124 stmfd sp!, {r4-r11}
125
126 ldr r12, [r0, #48]
127 ldmia r0!, {r2-r11}
128 stmia r1!, {r2, r6, r10, r12}
129 ldr r12, [r0, #12]
130 stmia r1!, {r3, r7, r11, r12}
131
132 ldmia r0, {r10-r11}
133 ldr r12, [r0, #16]
134 stmia r1!, {r4, r8, r10, r12}
135
136 ldr r12, [r0, #20]
137 stmia r1!, {r5, r9, r11, r12}
138
139 ldmfd sp!, {r4-r11}
140 bx lr
141 }
142
143
144 #include <nitro/code16.h>
MTX_Scale44_(register MtxFx44 * pDst,register fx32 x,register fx32 y,register fx32 z)145 asm void MTX_Scale44_(register MtxFx44 * pDst, register fx32 x, register fx32 y, register fx32 z)
146 {
147 stmia r0!, {r1}
148 mov r1, #0
149 str r2, [r0, #16]
150 mov r2, #0
151 stmia r0!, {r1, r2}
152 stmia r0!, {r1, r2}
153 add r0, r0, #4
154 stmia r0!, {r1, r2}
155 stmia r0!, {r1, r2, r3}
156 stmia r0!, {r1, r2}
157 mov r3, #1
158 lsl r3, r3, #12
159 stmia r0!, {r1, r2}
160 str r3, [r0, #0]
161 bx lr
162 }
163 #include <nitro/code32.h>
164
165
166
167
168 /*---------------------------------------------------------------------------*
169 Name: MTX_ScaleApply44
170
171 Description: This function performs the operation equivalent to
172 MTX_Scale44 + MTX_Concat44.
173
174 Arguments: pSrc a pointer to a 4x4 matrix
175 pDst a pointer to a 4x4 matrix
176 x x scale factor
177 y y scale factor
178 z z scale factor
179
180 Returns: None.
181 *---------------------------------------------------------------------------*/
MTX_ScaleApply44(const MtxFx44 * pSrc,MtxFx44 * pDst,fx32 x,fx32 y,fx32 z)182 void MTX_ScaleApply44(const MtxFx44 *pSrc, MtxFx44 *pDst, fx32 x, fx32 y, fx32 z)
183 {
184 fx64 v;
185
186 SDK_NULL_ASSERT(pSrc);
187 SDK_NULL_ASSERT(pDst);
188
189 v = (fx64)x;
190 pDst->_00 = mul64(v, pSrc->_00);
191 pDst->_01 = mul64(v, pSrc->_01);
192 pDst->_02 = mul64(v, pSrc->_02);
193 pDst->_03 = mul64(v, pSrc->_03);
194
195 v = (fx64)y;
196 pDst->_10 = mul64(v, pSrc->_10);
197 pDst->_11 = mul64(v, pSrc->_11);
198 pDst->_12 = mul64(v, pSrc->_12);
199 pDst->_13 = mul64(v, pSrc->_13);
200
201 v = (fx64)z;
202 pDst->_20 = mul64(v, pSrc->_20);
203 pDst->_21 = mul64(v, pSrc->_21);
204 pDst->_22 = mul64(v, pSrc->_22);
205 pDst->_23 = mul64(v, pSrc->_23);
206
207 if (pSrc != pDst)
208 {
209 register fx32 t1, t2;
210 t1 = pSrc->_30;
211 t2 = pSrc->_31;
212 pDst->_30 = t1;
213 pDst->_31 = t2;
214
215 t1 = pSrc->_32;
216 t2 = pSrc->_33;
217 pDst->_32 = t1;
218 pDst->_33 = t2;
219 }
220 }
221
222 #include <nitro/code16.h>
MTX_RotX44_(register MtxFx44 * pDst,register fx32 sinVal,register fx32 cosVal)223 asm void MTX_RotX44_(register MtxFx44 * pDst, register fx32 sinVal, register fx32 cosVal)
224 {
225
226 str r2, [r0, #20]
227 str r2, [r0, #40]
228 str r1, [r0, #24]
229 neg r1, r1
230 str r1, [r0, #36]
231
232 mov r1, #1
233 mov r2, #0
234 lsl r1, r1, #12
235 mov r3, #0
236
237 stmia r0!, {r1, r2, r3}
238 stmia r0!, {r2, r3}
239 add r0, #8
240 stmia r0!, {r2, r3}
241 add r0, #8
242 stmia r0!, {r2, r3}
243 stmia r0!, {r2, r3}
244 str r1, [r0, #0]
245
246 bx lr
247 }
248 #include <nitro/code32.h>
249
250 #include <nitro/code16.h>
MTX_RotY44_(register MtxFx44 * pDst,register fx32 sinVal,register fx32 cosVal)251 asm void MTX_RotY44_(register MtxFx44 * pDst, register fx32 sinVal, register fx32 cosVal)
252 {
253 str r2, [r0, #0]
254 str r2, [r0, #40]
255 str r1, [r0, #32]
256 neg r1, r1
257 str r1, [r0, #8]
258
259 mov r3, #1
260 mov r1, #0
261 lsl r3, r3, #12
262 mov r2, #0
263
264 str r2, [r0, #4]
265 add r0, #12
266 stmia r0!, {r1, r2, r3}
267 stmia r0!, {r1, r2}
268 str r2, [r0, #4]
269 add r0, #12
270 stmia r0!, {r1, r2}
271 stmia r0!, {r1, r2, r3}
272
273 bx lr
274 }
275 #include <nitro/code32.h>
276
277 #include <nitro/code16.h>
MTX_RotZ44_(register MtxFx44 * pDst,register fx32 sinVal,register fx32 cosVal)278 asm void MTX_RotZ44_(register MtxFx44 * pDst, register fx32 sinVal, register fx32 cosVal)
279 {
280 str r2, [r0, #0]
281 str r2, [r0, #20]
282 str r1, [r0, #4]
283 neg r1, r1
284 str r1, [r0, #16]
285
286 mov r3, #1
287 mov r1, #0
288 lsl r3, r3, #12
289 mov r2, #0
290
291 add r0, #8
292 stmia r0!, {r1, r2}
293 add r0, #8
294 stmia r0!, {r1, r2}
295 stmia r0!, {r1, r2, r3}
296 stmia r0!, {r1, r2}
297 stmia r0!, {r1, r2, r3}
298
299 bx lr
300 }
301 #include <nitro/code32.h>
302
303
304 /*---------------------------------------------------------------------------*
305 Name: MTX_RotAxis44
306
307 Description: Sets a rotation matrix about an arbitrary axis.
308
309 Arguments: pDst a pointer to a 4x4 matrix
310 vec a pointer to a vector containing the x,y,z axis
311 components. *vec must be a unit vector.
312 sinVal sine of an angle of rotation
313 cosVal cosine of an angle of rotation
314
315 Returns: None.
316 *---------------------------------------------------------------------------*/
MTX_RotAxis44(MtxFx44 * pDst,const VecFx32 * vec,fx32 sinVal,fx32 cosVal)317 void MTX_RotAxis44(MtxFx44 *pDst, const VecFx32 *vec, fx32 sinVal, fx32 cosVal)
318 {
319 fx64 t, ss, cc, xx, yy, zz;
320 fx32 t01;
321 fx32 s2;
322 SDK_NULL_ASSERT(pDst);
323 SDK_NULL_ASSERT(vec);
324
325 t = (fx64)(FX32_ONE - cosVal);
326 ss = (fx64)sinVal;
327 cc = (fx64)cosVal;
328 xx = (fx64)vec->x;
329 yy = (fx64)vec->y;
330 zz = (fx64)vec->z;
331
332 t01 = (fx32)((xx * xx * t) >> (FX64_SHIFT + FX64_SHIFT));
333 pDst->_00 = t01 + cosVal;
334
335 t01 = (fx32)((yy * yy * t) >> (FX64_SHIFT + FX64_SHIFT));
336 pDst->_11 = t01 + cosVal;
337
338 t01 = (fx32)((zz * zz * t) >> (FX64_SHIFT + FX64_SHIFT));
339 pDst->_22 = t01 + cosVal;
340
341 t01 = (fx32)((t * xx * yy) >> (FX64_SHIFT + FX64_SHIFT));
342 s2 = (fx32)((ss * zz) >> FX64_SHIFT);
343 pDst->_01 = t01 + s2;
344 pDst->_10 = t01 - s2;
345
346 t01 = (fx32)((t * xx * zz) >> (FX64_SHIFT + FX64_SHIFT));
347 s2 = (fx32)((ss * yy) >> FX64_SHIFT);
348 pDst->_02 = t01 - s2;
349 pDst->_20 = t01 + s2;
350
351 t01 = (fx32)((t * yy * zz) >> (FX64_SHIFT + FX64_SHIFT));
352 s2 = (fx32)((ss * xx) >> FX64_SHIFT);
353 pDst->_12 = t01 + s2;
354 pDst->_21 = t01 - s2;
355
356 pDst->_03 = pDst->_13 = pDst->_23 = pDst->_30 = pDst->_31 = pDst->_32 = 0;
357 pDst->_33 = FX32_ONE;
358 }
359
360
361 /*---------------------------------------------------------------------------*
362 Name: MTX_Concat44
363
364 Description: Concatenates two 4x4 matrices.
365 The order of operation is A x B = AB.
366 OK for any of ab == a == b.
367
368 Arguments: a a pointer to a 4x4 matrix
369 b a pointer to a 4x4 matrix
370 ab a pointer to the resultant matrix
371
372 Returns: None.
373 *---------------------------------------------------------------------------*/
MTX_Concat44(const MtxFx44 * a,const MtxFx44 * b,MtxFx44 * ab)374 void MTX_Concat44(const MtxFx44 *a, const MtxFx44 *b, MtxFx44 *ab)
375 {
376 MtxFx44 tmp;
377 MtxFx44 *p;
378
379 register fx32 x, y, z, w;
380 register fx32 xx, yy, zz, ww;
381
382 SDK_NULL_ASSERT(a);
383 SDK_NULL_ASSERT(b);
384 SDK_NULL_ASSERT(ab);
385
386 if (ab == b)
387 {
388 p = &tmp;
389 }
390 else
391 {
392 p = ab;
393 }
394
395 // compute (a x b) -> p
396
397 // row 0
398 x = a->_00;
399 y = a->_01;
400 z = a->_02;
401 w = a->_03;
402
403 p->_00 =
404 (fx32)(((fx64)x * b->_00 + (fx64)y * b->_10 + (fx64)z * b->_20 +
405 (fx64)w * b->_30) >> FX32_SHIFT);
406 p->_01 =
407 (fx32)(((fx64)x * b->_01 + (fx64)y * b->_11 + (fx64)z * b->_21 +
408 (fx64)w * b->_31) >> FX32_SHIFT);
409 p->_03 =
410 (fx32)(((fx64)x * b->_03 + (fx64)y * b->_13 + (fx64)z * b->_23 +
411 (fx64)w * b->_33) >> FX32_SHIFT);
412
413 xx = b->_02;
414 yy = b->_12;
415 zz = b->_22;
416 ww = b->_32;
417
418 p->_02 = (fx32)(((fx64)x * xx + (fx64)y * yy + (fx64)z * zz + (fx64)w * ww) >> FX32_SHIFT);
419
420 // row 1
421 x = a->_10;
422 y = a->_11;
423 z = a->_12;
424 w = a->_13;
425
426 p->_12 = (fx32)(((fx64)x * xx + (fx64)y * yy + (fx64)z * zz + (fx64)w * ww) >> FX32_SHIFT);
427 p->_11 =
428 (fx32)(((fx64)x * b->_01 + (fx64)y * b->_11 + (fx64)z * b->_21 +
429 (fx64)w * b->_31) >> FX32_SHIFT);
430 p->_13 =
431 (fx32)(((fx64)x * b->_03 + (fx64)y * b->_13 + (fx64)z * b->_23 +
432 (fx64)w * b->_33) >> FX32_SHIFT);
433
434 xx = b->_00;
435 yy = b->_10;
436 zz = b->_20;
437 ww = b->_30;
438
439 p->_10 = (fx32)(((fx64)x * xx + (fx64)y * yy + (fx64)z * zz + (fx64)w * ww) >> FX32_SHIFT);
440
441 // row 2
442 x = a->_20;
443 y = a->_21;
444 z = a->_22;
445 w = a->_23;
446
447 p->_20 = (fx32)(((fx64)x * xx + (fx64)y * yy + (fx64)z * zz + (fx64)w * ww) >> FX32_SHIFT);
448 p->_21 =
449 (fx32)(((fx64)x * b->_01 + (fx64)y * b->_11 + (fx64)z * b->_21 +
450 (fx64)w * b->_31) >> FX32_SHIFT);
451 p->_23 =
452 (fx32)(((fx64)x * b->_03 + (fx64)y * b->_13 + (fx64)z * b->_23 +
453 (fx64)w * b->_33) >> FX32_SHIFT);
454
455 xx = b->_02;
456 yy = b->_12;
457 zz = b->_22;
458 ww = b->_32;
459
460 p->_22 = (fx32)(((fx64)x * xx + (fx64)y * yy + (fx64)z * zz + (fx64)w * ww) >> FX32_SHIFT);
461
462 // row 3
463 x = a->_30;
464 y = a->_31;
465 z = a->_32;
466 w = a->_33;
467
468 p->_32 = (fx32)(((fx64)x * xx + (fx64)y * yy + (fx64)z * zz + (fx64)w * ww) >> FX32_SHIFT);
469 p->_31 =
470 (fx32)(((fx64)x * b->_01 + (fx64)y * b->_11 + (fx64)z * b->_21 +
471 (fx64)w * b->_31) >> FX32_SHIFT);
472 p->_30 =
473 (fx32)(((fx64)x * b->_00 + (fx64)y * b->_10 + (fx64)z * b->_20 +
474 (fx64)w * b->_30) >> FX32_SHIFT);
475 p->_33 =
476 (fx32)(((fx64)x * b->_03 + (fx64)y * b->_13 + (fx64)z * b->_23 +
477 (fx64)w * b->_33) >> FX32_SHIFT);
478
479 if (p == &tmp)
480 {
481 *ab = tmp;
482 }
483 }
484
485 /*---------------------------------------------------------------------------*
486 Name: MTX_FrustumW
487
488 Description: Computes a 4x4 perspective projection matrix from a specified
489 view volume.
490
491 Arguments: t top coordinate of view volume at the near clipping plane
492 b bottom coordinate of view volume at the near clipping plane
493 l left coordinate of view volume at near clipping plane
494 r right coordinate of view volume at near clipping plane
495 n positive distance from camera to near clipping plane
496 f positive distance from camera to far clipping plane
497 mtx 4x4 matrix to be set if not NULL
498
499 Returns: None.
500 *---------------------------------------------------------------------------*/
MTX_FrustumW(fx32 t,fx32 b,fx32 l,fx32 r,fx32 n,fx32 f,fx32 scaleW,MtxFx44 * mtx)501 void MTX_FrustumW(fx32 t, fx32 b, fx32 l, fx32 r, fx32 n, fx32 f, fx32 scaleW, MtxFx44 *mtx)
502 {
503 fx64c inv1, inv2;
504 fx32 dblN;
505
506 SDK_NULL_ASSERT(mtx);
507 SDK_TASSERTMSG(t != b, "MTX_Frustum: 't' and 'b' clipping planes are equal.");
508 SDK_TASSERTMSG(l != r, "MTX_Frustum: 'l' and 'r' clipping planes are equal.");
509 SDK_TASSERTMSG(n != f, "MTX_Frustum: 'n' and 'f' clipping planes are equal.");
510
511 SDK_MINMAX_ASSERT(f, -0x10000 * FX32_ONE, 0x10000 * FX32_ONE - 1);
512 SDK_MINMAX_ASSERT(n, -0x10000 * FX32_ONE, 0x10000 * FX32_ONE - 1);
513
514 /* Initialize matrix in parallel with asynchronous division */
515 {
516 FX_InvAsync(r - l);
517 mtx->_01 = 0;
518 mtx->_02 = 0;
519 mtx->_03 = 0;
520 mtx->_10 = 0;
521 mtx->_12 = 0;
522 mtx->_13 = 0;
523 mtx->_23 = -scaleW;
524 mtx->_30 = 0;
525 mtx->_31 = 0;
526 mtx->_33 = 0;
527 dblN = n << 1;
528 inv1 = FX_GetInvResultFx64c();
529 }
530 {
531 FX_InvAsyncImm(t - b);
532 if (scaleW != FX32_ONE)
533 {
534 inv1 = (inv1 * scaleW) / FX32_ONE;
535 }
536 mtx->_00 = FX_Mul32x64c(dblN, inv1);
537 inv2 = FX_GetInvResultFx64c();
538 }
539 {
540 FX_InvAsyncImm(n - f);
541 if (scaleW != FX32_ONE)
542 {
543 inv2 = (inv2 * scaleW) / FX32_ONE;
544 }
545 mtx->_11 = FX_Mul32x64c(dblN, inv2);
546 mtx->_20 = FX_Mul32x64c(r + l, inv1);
547 mtx->_21 = FX_Mul32x64c(t + b, inv2);
548 inv1 = FX_GetInvResultFx64c();
549 }
550 if (scaleW != FX32_ONE)
551 {
552 inv1 = (inv1 * scaleW) / FX32_ONE;
553 }
554 mtx->_22 = FX_Mul32x64c(f + n, inv1);
555 mtx->_32 = FX_Mul32x64c(FX_Mul(dblN, f), inv1);
556 }
557
558 /*---------------------------------------------------------------------------*
559 Name: MTX_PerspectiveW
560
561 Description: Computes a 4x4 perspective projection matrix from field of
562 view and aspect ratio.
563
564 Arguments: fovySin sine value of fovy
565 fovyCos cosine value of fovy
566 aspect ratio of view window width:height (X / Y)
567 n positive distance from camera to near clipping plane
568 f positive distance from camera to far clipping plane
569 scaleW W scale parameter that adjust precision of view volume.
570 mtx 4x4 matrix to be set if not NULL
571
572 Returns: None.
573 *---------------------------------------------------------------------------*/
MTX_PerspectiveW(fx32 fovySin,fx32 fovyCos,fx32 aspect,fx32 n,fx32 f,fx32 scaleW,MtxFx44 * mtx)574 void MTX_PerspectiveW(fx32 fovySin, fx32 fovyCos, fx32 aspect, fx32 n, fx32 f, fx32 scaleW, MtxFx44 *mtx)
575 {
576 fx32 one_tan;
577 fx64 t;
578
579 SDK_NULL_ASSERT(mtx);
580 SDK_TASSERTMSG(fovySin > 0 && fovySin < FX32_ONE, "G3_Perspective: sine of fovy out of range.");
581 SDK_TASSERTMSG(fovyCos > -FX32_ONE
582 && fovyCos < FX32_ONE, "G3_Perspective: cosine of fovy out of range.");
583 SDK_TASSERTMSG(aspect != 0, "G3_Perspective: aspect is 0.");
584
585 SDK_MINMAX_ASSERT(f, -0x10000 * FX32_ONE, 0x10000 * FX32_ONE - 1);
586 SDK_MINMAX_ASSERT(n, -0x10000 * FX32_ONE, 0x10000 * FX32_ONE - 1);
587
588 one_tan = FX_Div((fx32)fovyCos, (fx32)fovySin);
589 FX_InvAsyncImm(n - f);
590 if (scaleW != FX32_ONE)
591 {
592 one_tan = (one_tan * scaleW) / FX32_ONE;
593 }
594 mtx->_01 = 0;
595 mtx->_02 = 0;
596 mtx->_03 = 0;
597 mtx->_10 = 0;
598 mtx->_11 = one_tan;
599 mtx->_12 = 0;
600 mtx->_13 = 0;
601 mtx->_20 = 0;
602 mtx->_21 = 0;
603 mtx->_23 = -scaleW;
604 mtx->_30 = 0;
605 mtx->_31 = 0;
606 mtx->_33 = 0;
607 t = FX_GetInvResultFx64c();
608 FX_DivAsyncImm(one_tan, aspect);
609 if (scaleW != FX32_ONE)
610 {
611 t = (t * scaleW) / FX32_ONE;
612 }
613 mtx->_22 = FX_Mul32x64c(f + n, t);
614 mtx->_32 = FX_Mul32x64c(FX_Mul(n << 1, f), t);
615 mtx->_00 = FX_GetDivResult();
616 }
617
618 /*---------------------------------------------------------------------------*
619 Name: MTX_OrthoW
620
621 Description: Computes a 4x4 orthographic projection matrix.
622
623 Arguments: t top coordinate of parallel view volume
624 b bottom coordinate of parallel view volume
625 l left coordinate of parallel view volume
626 r right coordinate of parallel view volume
627 n positive distance from camera to near clipping plane
628 f positive distance from camera to far clipping plane
629 scaleW W scale parameter that adjust precision of view volume.
630 mtx 4x4 matrix to be set if not NULL
631
632 Returns: None.
633 *---------------------------------------------------------------------------*/
MTX_OrthoW(fx32 t,fx32 b,fx32 l,fx32 r,fx32 n,fx32 f,fx32 scaleW,MtxFx44 * mtx)634 void MTX_OrthoW(fx32 t, fx32 b, fx32 l, fx32 r, fx32 n, fx32 f, fx32 scaleW, MtxFx44 *mtx)
635 {
636 fx64c inv1, inv2, inv3;
637
638 SDK_NULL_ASSERT(mtx);
639 SDK_TASSERTMSG(t != b, "G3_Ortho: 't' and 'b' clipping planes are equal.");
640 SDK_TASSERTMSG(l != r, "G3_Ortho: 'l' and 'r' clipping planes are equal.");
641 SDK_TASSERTMSG(n != f, "G3_Ortho: 'n' and 'f' clipping planes are equal.");
642
643 SDK_MINMAX_ASSERT(f, -0x10000 * FX32_ONE, 0x10000 * FX32_ONE - 1);
644 SDK_MINMAX_ASSERT(n, -0x10000 * FX32_ONE, 0x10000 * FX32_ONE - 1);
645
646 {
647 FX_InvAsync(r - l);
648 mtx->_01 = 0;
649 mtx->_02 = 0;
650 mtx->_03 = 0;
651 mtx->_10 = 0;
652 mtx->_12 = 0;
653 mtx->_13 = 0;
654 mtx->_20 = 0;
655 mtx->_21 = 0;
656 mtx->_23 = 0;
657 mtx->_33 = scaleW;
658 inv1 = FX_GetInvResultFx64c();
659 }
660 {
661 FX_InvAsyncImm(t - b);
662 if (scaleW != FX32_ONE)
663 {
664 inv1 = (inv1 * scaleW) / FX32_ONE;
665 }
666 mtx->_00 = FX_Mul32x64c(FX32_ONE * 2, inv1);
667 inv2 = FX_GetInvResultFx64c();
668 }
669 {
670 FX_InvAsyncImm(n - f);
671 if (scaleW != FX32_ONE)
672 {
673 inv2 = (inv2 * scaleW) / FX32_ONE;
674 }
675 mtx->_11 = FX_Mul32x64c(FX32_ONE * 2, inv2);
676 inv3 = FX_GetInvResultFx64c();
677 }
678
679 if (scaleW != FX32_ONE)
680 {
681 inv3 = (inv3 * scaleW) / FX32_ONE;
682 }
683 mtx->_22 = FX_Mul32x64c(FX32_ONE * 2, inv3);
684 mtx->_30 = FX_Mul32x64c(-r - l, inv1);
685 mtx->_31 = FX_Mul32x64c(-t - b, inv2);
686 mtx->_32 = FX_Mul32x64c(f + n, inv3);
687 }
688
689 #include <nitro/codereset.h>
690