PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
math3d.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# (c) 2005 Naomi Peori <naomi@peori.ca>
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11 #include <tamtypes.h>
12
13 #include <graph.h>
14 #include <math3d.h>
15 #include <string.h>
16 #include <math.h>
17
18 /* VECTOR FUNCTIONS */
19
20 void vector_apply(VECTOR output, VECTOR input0, MATRIX input1) {
21 asm __volatile__ (
22#if __GNUC__ > 3
23 "lqc2 $vf1, 0x00(%2) \n"
24 "lqc2 $vf2, 0x10(%2) \n"
25 "lqc2 $vf3, 0x20(%2) \n"
26 "lqc2 $vf4, 0x30(%2) \n"
27 "lqc2 $vf5, 0x00(%1) \n"
28 "vmulaw $ACC, $vf4, $vf0\n"
29 "vmaddax $ACC, $vf1, $vf5\n"
30 "vmadday $ACC, $vf2, $vf5\n"
31 "vmaddz $vf6, $vf3, $vf5\n"
32 "sqc2 $vf6, 0x00(%0) \n"
33#else
34 "lqc2 vf1, 0x00(%2) \n"
35 "lqc2 vf2, 0x10(%2) \n"
36 "lqc2 vf3, 0x20(%2) \n"
37 "lqc2 vf4, 0x30(%2) \n"
38 "lqc2 vf5, 0x00(%1) \n"
39 "vmulaw ACC, vf4, vf0 \n"
40 "vmaddax ACC, vf1, vf5 \n"
41 "vmadday ACC, vf2, vf5 \n"
42 "vmaddz vf6, vf3, vf5 \n"
43 "sqc2 vf6, 0x00(%0) \n"
44#endif
45 : : "r" (output), "r" (input0), "r" (input1)
46 : "memory"
47 );
48 }
49
50 void vector_clamp(VECTOR output, VECTOR input0, float min, float max) {
51 VECTOR work;
52
53 // Copy the vector.
54 vector_copy(work, input0);
55
56 // Clamp the minimum values.
57 if (work[0] < min) { work[0] = min; }
58 if (work[1] < min) { work[1] = min; }
59 if (work[2] < min) { work[2] = min; }
60 if (work[3] < min) { work[3] = min; }
61
62 // Clamp the maximum values.
63 if (work[0] > max) { work[0] = max; }
64 if (work[1] > max) { work[1] = max; }
65 if (work[2] > max) { work[2] = max; }
66 if (work[3] > max) { work[3] = max; }
67
68 // Output the result.
69 vector_copy(output, work);
70
71 }
72
73 void vector_copy(VECTOR output, VECTOR input0) {
74 asm __volatile__ (
75#if __GNUC__ > 3
76 "lqc2 $vf1, 0x00(%1) \n"
77 "sqc2 $vf1, 0x00(%0) \n"
78#else
79 "lqc2 vf1, 0x00(%1) \n"
80 "sqc2 vf1, 0x00(%0) \n"
81#endif
82 : : "r" (output), "r" (input0)
83 : "memory"
84 );
85 }
86
87 float vector_innerproduct(VECTOR input0, VECTOR input1) {
88 VECTOR work0, work1;
89
90 // Normalize the first vector.
91 work0[0] = (input0[0] / input0[3]);
92 work0[1] = (input0[1] / input0[3]);
93 work0[2] = (input0[2] / input0[3]);
94 work0[3] = 1.00f;
95
96 // Normalize the second vector.
97 work1[0] = (input1[0] / input1[3]);
98 work1[1] = (input1[1] / input1[3]);
99 work1[2] = (input1[2] / input1[3]);
100 work1[3] = 1.00f;
101
102 // Return the inner product.
103 return (work0[0] * work1[0]) + (work0[1] * work1[1]) + (work0[2] * work1[2]);
104
105 }
106
107 void vector_multiply(VECTOR output, VECTOR input0, VECTOR input1) {
108 VECTOR work;
109
110 // Multiply the vectors together.
111 work[0] = input0[0] * input1[0];
112 work[1] = input0[1] * input1[1];
113 work[2] = input0[2] * input1[2];
114 work[3] = input0[3] * input1[3];
115
116 // Output the result.
117 vector_copy(output, work);
118
119 }
120
121 void vector_normalize(VECTOR output, VECTOR input0) {
122 asm __volatile__ (
123#if __GNUC__ > 3
124 "lqc2 $vf1, 0x00(%1) \n"
125 "vmul.xyz $vf2, $vf1, $vf1\n"
126 "vmulax.w $ACC, $vf0, $vf2\n"
127 "vmadday.w $ACC, $vf0, $vf2\n"
128 "vmaddz.w $vf2, $vf0, $vf2\n"
129 "vrsqrt $Q, $vf0w, $vf2w\n"
130 "vsub.w $vf1, $vf0, $vf0\n"
131 "vwaitq \n"
132 "vmulq.xyz $vf1, $vf1, $Q \n"
133 "sqc2 $vf1, 0x00(%0) \n"
134#else
135 "lqc2 vf1, 0x00(%1) \n"
136 "vmul.xyz vf2, vf1, vf1 \n"
137 "vmulax.w ACC, vf0, vf2 \n"
138 "vmadday.w ACC, vf0, vf2 \n"
139 "vmaddz.w vf2, vf0, vf2 \n"
140 "vrsqrt Q, vf0w, vf2w \n"
141 "vsub.w vf1, vf0, vf0 \n"
142 "vwaitq \n"
143 "vmulq.xyz vf1, vf1, Q \n"
144 "sqc2 vf1, 0x00(%0) \n"
145#endif
146 : : "r" (output), "r" (input0)
147 : "memory"
148 );
149 }
150
151 void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1) {
152 asm __volatile__ (
153#if __GNUC__ > 3
154 "lqc2 $vf1, 0x00(%1) \n"
155 "lqc2 $vf2, 0x00(%2) \n"
156 "vopmula.xyz $ACC, $vf1, $vf2\n"
157 "vopmsub.xyz $vf2, $vf2, $vf1\n"
158 "vsub.w $vf2, $vf0, $vf0\n"
159 "sqc2 $vf2, 0x00(%0) \n"
160#else
161 "lqc2 vf1, 0x00(%1) \n"
162 "lqc2 vf2, 0x00(%2) \n"
163 "vopmula.xyz ACC, vf1, vf2 \n"
164 "vopmsub.xyz vf2, vf2, vf1 \n"
165 "vsub.w vf2, vf0, vf0 \n"
166 "sqc2 vf2, 0x00(%0) \n"
167#endif
168 : : "r" (output), "r" (input0), "r" (input1)
169 : "memory"
170 );
171 }
172
173 void vector_add(VECTOR sum, VECTOR addend, VECTOR summand) {
174 VECTOR work;
175 work[0] = addend[0]+summand[0];
176 work[1] = addend[1]+summand[1];
177 work[2] = addend[2]+summand[2];
178 work[3] = addend[3]+summand[3];
179 vector_copy(sum, work);
180}
181
182void vector_cross_product(VECTOR product, VECTOR multiplicand, VECTOR multiplier) {
183 VECTOR work;
184 work[0] = multiplicand[1] * multiplier[2] - multiplicand[2] * multiplier[1];
185 work[1] = multiplicand[2] * multiplier[0] - multiplicand[0] * multiplier[2];
186 work[2] = multiplicand[0] * multiplier[1] - multiplicand[1] * multiplier[0];
187 work[3] = 1.0f;
188 vector_copy(product, work);
189}
190
191void vector_triangle_normal(VECTOR output, VECTOR a, VECTOR b, VECTOR c) {
192 VECTOR ac;
193 VECTOR bc;
194 VECTOR ac_bc;
195 VECTOR triangle_normal;
196
197 vector_add(ac, a, c);
198 vector_add(bc, b, c);
199 vector_cross_product(ac_bc, ac, bc);
200 vector_normalize(triangle_normal, ac_bc);
201
202 vector_copy(output, triangle_normal);
203}
204
205 /* MATRIX FUNCTIONS */
206
207 void matrix_copy(MATRIX output, MATRIX input0) {
208 asm __volatile__ (
209#if __GNUC__ > 3
210 "lqc2 $vf1, 0x00(%1) \n"
211 "lqc2 $vf2, 0x10(%1) \n"
212 "lqc2 $vf3, 0x20(%1) \n"
213 "lqc2 $vf4, 0x30(%1) \n"
214 "sqc2 $vf1, 0x00(%0) \n"
215 "sqc2 $vf2, 0x10(%0) \n"
216 "sqc2 $vf3, 0x20(%0) \n"
217 "sqc2 $vf4, 0x30(%0) \n"
218#else
219 "lqc2 vf1, 0x00(%1) \n"
220 "lqc2 vf2, 0x10(%1) \n"
221 "lqc2 vf3, 0x20(%1) \n"
222 "lqc2 vf4, 0x30(%1) \n"
223 "sqc2 vf1, 0x00(%0) \n"
224 "sqc2 vf2, 0x10(%0) \n"
225 "sqc2 vf3, 0x20(%0) \n"
226 "sqc2 vf4, 0x30(%0) \n"
227#endif
228 : : "r" (output), "r" (input0)
229 : "memory"
230 );
231 }
232
233 void matrix_inverse(MATRIX output, MATRIX input0) {
234 MATRIX work;
235
236 // Calculate the inverse of the matrix.
237 matrix_transpose(work, input0);
238 work[0x03] = 0.00f;
239 work[0x07] = 0.00f;
240 work[0x0B] = 0.00f;
241 work[0x0C] = -(input0[0x0C] * work[0x00] + input0[0x0D] * work[0x04] + input0[0x0E] * work[0x08]);
242 work[0x0D] = -(input0[0x0C] * work[0x01] + input0[0x0D] * work[0x05] + input0[0x0E] * work[0x09]);
243 work[0x0E] = -(input0[0x0C] * work[0x02] + input0[0x0D] * work[0x06] + input0[0x0E] * work[0x0A]);
244 work[0x0F] = 1.00f;
245
246 // Output the result.
247 matrix_copy(output, work);
248
249 }
250
251 void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1) {
252 asm __volatile__ (
253#if __GNUC__ > 3
254 "lqc2 $vf1, 0x00(%1) \n"
255 "lqc2 $vf2, 0x10(%1) \n"
256 "lqc2 $vf3, 0x20(%1) \n"
257 "lqc2 $vf4, 0x30(%1) \n"
258 "lqc2 $vf5, 0x00(%2) \n"
259 "lqc2 $vf6, 0x10(%2) \n"
260 "lqc2 $vf7, 0x20(%2) \n"
261 "lqc2 $vf8, 0x30(%2) \n"
262 "vmulax.xyzw $ACC, $vf5, $vf1\n"
263 "vmadday.xyzw $ACC, $vf6, $vf1\n"
264 "vmaddaz.xyzw $ACC, $vf7, $vf1\n"
265 "vmaddw.xyzw $vf1, $vf8, $vf1\n"
266 "vmulax.xyzw $ACC, $vf5, $vf2\n"
267 "vmadday.xyzw $ACC, $vf6, $vf2\n"
268 "vmaddaz.xyzw $ACC, $vf7, $vf2\n"
269 "vmaddw.xyzw $vf2, $vf8, $vf2\n"
270 "vmulax.xyzw $ACC, $vf5, $vf3\n"
271 "vmadday.xyzw $ACC, $vf6, $vf3\n"
272 "vmaddaz.xyzw $ACC, $vf7, $vf3\n"
273 "vmaddw.xyzw $vf3, $vf8, $vf3\n"
274 "vmulax.xyzw $ACC, $vf5, $vf4\n"
275 "vmadday.xyzw $ACC, $vf6, $vf4\n"
276 "vmaddaz.xyzw $ACC, $vf7, $vf4\n"
277 "vmaddw.xyzw $vf4, $vf8, $vf4\n"
278 "sqc2 $vf1, 0x00(%0) \n"
279 "sqc2 $vf2, 0x10(%0) \n"
280 "sqc2 $vf3, 0x20(%0) \n"
281 "sqc2 $vf4, 0x30(%0) \n"
282#else
283 "lqc2 vf1, 0x00(%1) \n"
284 "lqc2 vf2, 0x10(%1) \n"
285 "lqc2 vf3, 0x20(%1) \n"
286 "lqc2 vf4, 0x30(%1) \n"
287 "lqc2 vf5, 0x00(%2) \n"
288 "lqc2 vf6, 0x10(%2) \n"
289 "lqc2 vf7, 0x20(%2) \n"
290 "lqc2 vf8, 0x30(%2) \n"
291 "vmulax.xyzw ACC, vf5, vf1 \n"
292 "vmadday.xyzw ACC, vf6, vf1 \n"
293 "vmaddaz.xyzw ACC, vf7, vf1 \n"
294 "vmaddw.xyzw vf1, vf8, vf1 \n"
295 "vmulax.xyzw ACC, vf5, vf2 \n"
296 "vmadday.xyzw ACC, vf6, vf2 \n"
297 "vmaddaz.xyzw ACC, vf7, vf2 \n"
298 "vmaddw.xyzw vf2, vf8, vf2 \n"
299 "vmulax.xyzw ACC, vf5, vf3 \n"
300 "vmadday.xyzw ACC, vf6, vf3 \n"
301 "vmaddaz.xyzw ACC, vf7, vf3 \n"
302 "vmaddw.xyzw vf3, vf8, vf3 \n"
303 "vmulax.xyzw ACC, vf5, vf4 \n"
304 "vmadday.xyzw ACC, vf6, vf4 \n"
305 "vmaddaz.xyzw ACC, vf7, vf4 \n"
306 "vmaddw.xyzw vf4, vf8, vf4 \n"
307 "sqc2 vf1, 0x00(%0) \n"
308 "sqc2 vf2, 0x10(%0) \n"
309 "sqc2 vf3, 0x20(%0) \n"
310 "sqc2 vf4, 0x30(%0) \n"
311#endif
312 : : "r" (output), "r" (input0), "r" (input1)
313 : "memory"
314 );
315 }
316
317 void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1) {
318 MATRIX work;
319
320 // Apply the z-axis rotation.
321 matrix_unit(work);
322 work[0x00] = cosf(input1[2]);
323 work[0x01] = sinf(input1[2]);
324 work[0x04] = -sinf(input1[2]);
325 work[0x05] = cosf(input1[2]);
326 matrix_multiply(output, input0, work);
327
328 // Apply the y-axis rotation.
329 matrix_unit(work);
330 work[0x00] = cosf(input1[1]);
331 work[0x02] = -sinf(input1[1]);
332 work[0x08] = sinf(input1[1]);
333 work[0x0A] = cosf(input1[1]);
334 matrix_multiply(output, output, work);
335
336 // Apply the x-axis rotation.
337 matrix_unit(work);
338 work[0x05] = cosf(input1[0]);
339 work[0x06] = sinf(input1[0]);
340 work[0x09] = -sinf(input1[0]);
341 work[0x0A] = cosf(input1[0]);
342 matrix_multiply(output, output, work);
343
344 }
345
346 void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1) {
347 MATRIX work;
348
349 // Apply the scaling.
350 matrix_unit(work);
351 work[0x00] = input1[0];
352 work[0x05] = input1[1];
353 work[0x0A] = input1[2];
354 matrix_multiply(output, input0, work);
355
356 }
357
358 void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1) {
359 MATRIX work;
360
361 // Apply the translation.
362 matrix_unit(work);
363 work[0x0C] = input1[0];
364 work[0x0D] = input1[1];
365 work[0x0E] = input1[2];
366 matrix_multiply(output, input0, work);
367
368 }
369
370 void matrix_transpose(MATRIX output, MATRIX input0) {
371 MATRIX work;
372
373 // Transpose the matrix.
374 work[0x00] = input0[0x00];
375 work[0x01] = input0[0x04];
376 work[0x02] = input0[0x08];
377 work[0x03] = input0[0x0C];
378 work[0x04] = input0[0x01];
379 work[0x05] = input0[0x05];
380 work[0x06] = input0[0x09];
381 work[0x07] = input0[0x0D];
382 work[0x08] = input0[0x02];
383 work[0x09] = input0[0x06];
384 work[0x0A] = input0[0x0A];
385 work[0x0B] = input0[0x0E];
386 work[0x0C] = input0[0x03];
387 work[0x0D] = input0[0x07];
388 work[0x0E] = input0[0x0B];
389 work[0x0F] = input0[0x0F];
390
391 // Output the result.
392 matrix_copy(output, work);
393
394 }
395
396 void matrix_unit(MATRIX output) {
397
398 // Create a unit matrix.
399 memset(output, 0, sizeof(MATRIX));
400 output[0x00] = 1.00f;
401 output[0x05] = 1.00f;
402 output[0x0A] = 1.00f;
403 output[0x0F] = 1.00f;
404
405 }
406
407 /* CREATE FUNCTIONS */
408
409 void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation) {
410
411 // Create the local_world matrix.
412 matrix_unit(local_world);
413 matrix_rotate(local_world, local_world, rotation);
414 matrix_translate(local_world, local_world, translation);
415
416 }
417
418 void create_local_light(MATRIX local_light, VECTOR rotation) {
419
420 // Create the local_light matrix.
421 matrix_unit(local_light);
422 matrix_rotate(local_light, local_light, rotation);
423
424 }
425
426 void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation) {
427 VECTOR work0, work1;
428
429 // Reverse the translation.
430 work0[0] = -translation[0];
431 work0[1] = -translation[1];
432 work0[2] = -translation[2];
433 work0[3] = translation[3];
434
435 // Reverse the rotation.
436 work1[0] = -rotation[0];
437 work1[1] = -rotation[1];
438 work1[2] = -rotation[2];
439 work1[3] = rotation[3];
440
441 // Create the world_view matrix.
442 matrix_unit(world_view);
443 matrix_translate(world_view, world_view, work0);
444 matrix_rotate(world_view, world_view, work1);
445
446 }
447
448 void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far) {
449
450 // Apply the aspect ratio adjustment.
451 left = (left * aspect); right = (right * aspect);
452
453 // Create the view_screen matrix.
454 matrix_unit(view_screen);
455 view_screen[0x00] = (2 * near) / (right - left);
456 view_screen[0x05] = (2 * near) / (top - bottom);
457 view_screen[0x08] = (right + left) / (right - left);
458 view_screen[0x09] = (top + bottom) / (top - bottom);
459 view_screen[0x0A] = (far + near) / (far - near);
460 view_screen[0x0B] = -1.00f;
461 view_screen[0x0E] = (2 * far * near) / (far - near);
462 view_screen[0x0F] = 0.00f;
463
464 }
465
466 void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen) {
467
468 // Create the local_screen matrix.
469 matrix_unit(local_screen);
470 matrix_multiply(local_screen, local_screen, local_world);
471 matrix_multiply(local_screen, local_screen, world_view);
472 matrix_multiply(local_screen, local_screen, view_screen);
473
474 }
475
476 /* CALCULATE FUNCTIONS */
477
478 void calculate_normals(VECTOR *output, int count, VECTOR *normals, MATRIX local_light) {
479 asm __volatile__ (
480#if __GNUC__ > 3
481 "lqc2 $vf1, 0x00(%3) \n"
482 "lqc2 $vf2, 0x10(%3) \n"
483 "lqc2 $vf3, 0x20(%3) \n"
484 "lqc2 $vf4, 0x30(%3) \n"
485 "1: \n"
486 "lqc2 $vf6, 0x00(%2) \n"
487 "vmulaw $ACC, $vf4, $vf0\n"
488 "vmaddax $ACC, $vf1, $vf6\n"
489 "vmadday $ACC, $vf2, $vf6\n"
490 "vmaddz $vf7, $vf3, $vf6\n"
491 "vdiv $Q, $vf0w, $vf7w\n"
492 "vwaitq \n"
493 "vmulq.xyzw $vf7, $vf7, $Q \n"
494 "sqc2 $vf7, 0x00(%0) \n"
495 "addi %0, 0x10 \n"
496 "addi %2, 0x10 \n"
497 "addi %1, -1 \n"
498 "bne $0, %1, 1b \n"
499#else
500 "lqc2 vf1, 0x00(%3) \n"
501 "lqc2 vf2, 0x10(%3) \n"
502 "lqc2 vf3, 0x20(%3) \n"
503 "lqc2 vf4, 0x30(%3) \n"
504 "1: \n"
505 "lqc2 vf6, 0x00(%2) \n"
506 "vmulaw ACC, vf4, vf0 \n"
507 "vmaddax ACC, vf1, vf6 \n"
508 "vmadday ACC, vf2, vf6 \n"
509 "vmaddz vf7, vf3, vf6 \n"
510 "vdiv Q, vf0w, vf7w \n"
511 "vwaitq \n"
512 "vmulq.xyzw vf7, vf7, Q \n"
513 "sqc2 vf7, 0x00(%0) \n"
514 "addi %0, 0x10 \n"
515 "addi %2, 0x10 \n"
516 "addi %1, -1 \n"
517 "bne $0, %1, 1b \n"
518#endif
519 : : "r" (output), "r" (count), "r" (normals), "r" (local_light)
520 : "memory"
521 );
522 }
523
524 void calculate_lights(VECTOR *output, int count, VECTOR *normals, VECTOR *light_direction, VECTOR *light_colour, const int *light_type, int light_count) {
525 int loop0, loop1; float intensity;
526
527 // Clear the output values.
528 memset(output, 0, sizeof(VECTOR) * count);
529
530 // For each normal...
531 for (loop0=0;loop0<count;loop0++) {
532
533 // For each light...
534 for (loop1=0;loop1<light_count;loop1++) {
535
536 // If this is an ambient light...
537 if (light_type[loop1] == LIGHT_AMBIENT) {
538
539 // Set the intensity to full.
540 intensity = 1.00f;
541
542 // Else, if this is a directional light...
543 } else if (light_type[loop1] == LIGHT_DIRECTIONAL) {
544
545 // Get the light intensity.
546 intensity = -vector_innerproduct(normals[loop0], light_direction[loop1]);
547
548 // Clamp the minimum intensity.
549 if (intensity < 0.00f) { intensity = 0.00f; }
550
551 // Else, this is an invalid light type.
552 } else { intensity = 0.00f; }
553
554 // If the light has intensity...
555 if (intensity > 0.00f) {
556
557 // Add the light value.
558 output[loop0][0] += (light_colour[loop1][0] * intensity);
559 output[loop0][1] += (light_colour[loop1][1] * intensity);
560 output[loop0][2] += (light_colour[loop1][2] * intensity);
561 output[loop0][3] = 1.00f;
562
563 }
564
565 }
566
567 }
568
569 }
570
571 void calculate_colours(VECTOR *output, int count, VECTOR *colours, VECTOR *lights) {
572 int loop0;
573
574 // For each colour...
575 for (loop0=0;loop0<count;loop0++) {
576
577 // Apply the light value to the colour.
578 output[loop0][0] = (colours[loop0][0] * lights[loop0][0]);
579 output[loop0][1] = (colours[loop0][1] * lights[loop0][1]);
580 output[loop0][2] = (colours[loop0][2] * lights[loop0][2]);
581
582 // Clamp the colour value.
583 vector_clamp(output[loop0], output[loop0], 0.00f, 1.99f);
584
585 }
586
587 }
588
589 void calculate_vertices(VECTOR *output, int count, VECTOR *vertices, MATRIX local_screen) {
590 asm __volatile__ (
591#if __GNUC__ > 3
592 "lqc2 $vf1, 0x00(%3) \n"
593 "lqc2 $vf2, 0x10(%3) \n"
594 "lqc2 $vf3, 0x20(%3) \n"
595 "lqc2 $vf4, 0x30(%3) \n"
596 "1: \n"
597 "lqc2 $vf6, 0x00(%2) \n"
598 "vmulaw $ACC, $vf4, $vf0\n"
599 "vmaddax $ACC, $vf1, $vf6\n"
600 "vmadday $ACC, $vf2, $vf6\n"
601 "vmaddz $vf7, $vf3, $vf6\n"
602 "vclipw.xyz $vf7, $vf7 \n" // FIXME: Clip detection is still kinda broken.
603 "vnop \n"
604 "vnop \n"
605 "vnop \n"
606 "vnop \n"
607 "cfc2 $10, $18 \n"
608 "beq $10, $0, 3f \n"
609 "2: \n"
610 "sqc2 $0, 0x00(%0) \n"
611 "j 4f \n"
612 "3: \n"
613 "vdiv $Q, $vf0w, $vf7w\n"
614 "vwaitq \n"
615 "vmulq.xyz $vf7, $vf7, $Q \n"
616 "sqc2 $vf7, 0x00(%0) \n"
617#else
618 "lqc2 vf1, 0x00(%3) \n"
619 "lqc2 vf2, 0x10(%3) \n"
620 "lqc2 vf3, 0x20(%3) \n"
621 "lqc2 vf4, 0x30(%3) \n"
622 "1: \n"
623 "lqc2 vf6, 0x00(%2) \n"
624 "vmulaw ACC, vf4, vf0 \n"
625 "vmaddax ACC, vf1, vf6 \n"
626 "vmadday ACC, vf2, vf6 \n"
627 "vmaddz vf7, vf3, vf6 \n"
628 "vclipw.xyz vf7, vf7 \n"
629 "vnop \n"
630 "vnop \n"
631 "vnop \n"
632 "vnop \n" // FIXME: Clip detection is still kinda broken.
633 "cfc2 $10, $18 \n"
634 "beq $10, $0, 3f \n"
635 "2: \n"
636 "sqc2 vi00, 0x00(%0) \n"
637 "j 4f \n"
638 "3: \n"
639 "vdiv Q, vf0w, vf7w \n"
640 "vwaitq \n"
641 "vmulq.xyz vf7, vf7, Q \n"
642 "sqc2 vf7, 0x00(%0) \n"
643#endif
644 "4: \n"
645 "addi %0, 0x10 \n"
646 "addi %2, 0x10 \n"
647 "addi %1, -1 \n"
648 "bne $0, %1, 1b \n"
649 : : "r" (output), "r" (count), "r" (vertices), "r" (local_screen)
650 : "$10", "memory"
651 );
652 }
void vector_normalize(VECTOR output, VECTOR input0)
Definition math3d.c:121
void vector_cross_product(VECTOR product, VECTOR multiplicand, VECTOR multiplier)
Definition math3d.c:182
void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen)
Definition math3d.c:466
void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1)
Definition math3d.c:251
void vector_copy(VECTOR output, VECTOR input0)
Definition math3d.c:73
void vector_multiply(VECTOR output, VECTOR input0, VECTOR input1)
Definition math3d.c:107
void vector_clamp(VECTOR output, VECTOR input0, float min, float max)
Definition math3d.c:50
void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation)
Definition math3d.c:409
void matrix_copy(MATRIX output, MATRIX input0)
Definition math3d.c:207
float vector_innerproduct(VECTOR input0, VECTOR input1)
Definition math3d.c:87
void matrix_inverse(MATRIX output, MATRIX input0)
Definition math3d.c:233
void calculate_lights(VECTOR *output, int count, VECTOR *normals, VECTOR *light_directions, VECTOR *light_colours, const int *light_types, int light_count)
Definition math3d.c:524
void vector_triangle_normal(VECTOR output, VECTOR a, VECTOR b, VECTOR c)
Definition math3d.c:191
void calculate_vertices(VECTOR *output, int count, VECTOR *vertices, MATRIX local_screen)
Definition math3d.c:589
void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1)
Definition math3d.c:346
void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1)
Definition math3d.c:317
void vector_add(VECTOR sum, VECTOR addend, VECTOR summand)
Definition math3d.c:173
void matrix_unit(MATRIX output)
Definition math3d.c:396
#define LIGHT_DIRECTIONAL
Definition math3d.h:117
void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation)
Definition math3d.c:426
void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1)
Definition math3d.c:151
void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far)
Definition math3d.c:448
void calculate_normals(VECTOR *output, int count, VECTOR *normals, MATRIX local_light)
Definition math3d.c:478
#define LIGHT_AMBIENT
Definition math3d.h:115
void vector_apply(VECTOR output, VECTOR input0, MATRIX input1)
Definition math3d.c:20
void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1)
Definition math3d.c:358
void calculate_colours(VECTOR *output, int count, VECTOR *colours, VECTOR *lights)
Definition math3d.c:571
void create_local_light(MATRIX local_light, VECTOR rotation)
Definition math3d.c:418
void matrix_transpose(MATRIX output, MATRIX input0)
Definition math3d.c:370
u32 count
start sector of fragmented bd/file