ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
math3d.c
Go to the documentation of this file.
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  /* MATRIX FUNCTIONS */
174 
175  void matrix_copy(MATRIX output, MATRIX input0) {
176  asm __volatile__ (
177 #if __GNUC__ > 3
178  "lqc2 $vf1, 0x00(%1) \n"
179  "lqc2 $vf2, 0x10(%1) \n"
180  "lqc2 $vf3, 0x20(%1) \n"
181  "lqc2 $vf4, 0x30(%1) \n"
182  "sqc2 $vf1, 0x00(%0) \n"
183  "sqc2 $vf2, 0x10(%0) \n"
184  "sqc2 $vf3, 0x20(%0) \n"
185  "sqc2 $vf4, 0x30(%0) \n"
186 #else
187  "lqc2 vf1, 0x00(%1) \n"
188  "lqc2 vf2, 0x10(%1) \n"
189  "lqc2 vf3, 0x20(%1) \n"
190  "lqc2 vf4, 0x30(%1) \n"
191  "sqc2 vf1, 0x00(%0) \n"
192  "sqc2 vf2, 0x10(%0) \n"
193  "sqc2 vf3, 0x20(%0) \n"
194  "sqc2 vf4, 0x30(%0) \n"
195 #endif
196  : : "r" (output), "r" (input0)
197  : "memory"
198  );
199  }
200 
201  void matrix_inverse(MATRIX output, MATRIX input0) {
202  MATRIX work;
203 
204  // Calculate the inverse of the matrix.
205  matrix_transpose(work, input0);
206  work[0x03] = 0.00f;
207  work[0x07] = 0.00f;
208  work[0x0B] = 0.00f;
209  work[0x0C] = -(input0[0x0C] * work[0x00] + input0[0x0D] * work[0x04] + input0[0x0E] * work[0x08]);
210  work[0x0D] = -(input0[0x0C] * work[0x01] + input0[0x0D] * work[0x05] + input0[0x0E] * work[0x09]);
211  work[0x0E] = -(input0[0x0C] * work[0x02] + input0[0x0D] * work[0x06] + input0[0x0E] * work[0x0A]);
212  work[0x0F] = 1.00f;
213 
214  // Output the result.
215  matrix_copy(output, work);
216 
217  }
218 
219  void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1) {
220  asm __volatile__ (
221 #if __GNUC__ > 3
222  "lqc2 $vf1, 0x00(%1) \n"
223  "lqc2 $vf2, 0x10(%1) \n"
224  "lqc2 $vf3, 0x20(%1) \n"
225  "lqc2 $vf4, 0x30(%1) \n"
226  "lqc2 $vf5, 0x00(%2) \n"
227  "lqc2 $vf6, 0x10(%2) \n"
228  "lqc2 $vf7, 0x20(%2) \n"
229  "lqc2 $vf8, 0x30(%2) \n"
230  "vmulax.xyzw $ACC, $vf5, $vf1\n"
231  "vmadday.xyzw $ACC, $vf6, $vf1\n"
232  "vmaddaz.xyzw $ACC, $vf7, $vf1\n"
233  "vmaddw.xyzw $vf1, $vf8, $vf1\n"
234  "vmulax.xyzw $ACC, $vf5, $vf2\n"
235  "vmadday.xyzw $ACC, $vf6, $vf2\n"
236  "vmaddaz.xyzw $ACC, $vf7, $vf2\n"
237  "vmaddw.xyzw $vf2, $vf8, $vf2\n"
238  "vmulax.xyzw $ACC, $vf5, $vf3\n"
239  "vmadday.xyzw $ACC, $vf6, $vf3\n"
240  "vmaddaz.xyzw $ACC, $vf7, $vf3\n"
241  "vmaddw.xyzw $vf3, $vf8, $vf3\n"
242  "vmulax.xyzw $ACC, $vf5, $vf4\n"
243  "vmadday.xyzw $ACC, $vf6, $vf4\n"
244  "vmaddaz.xyzw $ACC, $vf7, $vf4\n"
245  "vmaddw.xyzw $vf4, $vf8, $vf4\n"
246  "sqc2 $vf1, 0x00(%0) \n"
247  "sqc2 $vf2, 0x10(%0) \n"
248  "sqc2 $vf3, 0x20(%0) \n"
249  "sqc2 $vf4, 0x30(%0) \n"
250 #else
251  "lqc2 vf1, 0x00(%1) \n"
252  "lqc2 vf2, 0x10(%1) \n"
253  "lqc2 vf3, 0x20(%1) \n"
254  "lqc2 vf4, 0x30(%1) \n"
255  "lqc2 vf5, 0x00(%2) \n"
256  "lqc2 vf6, 0x10(%2) \n"
257  "lqc2 vf7, 0x20(%2) \n"
258  "lqc2 vf8, 0x30(%2) \n"
259  "vmulax.xyzw ACC, vf5, vf1 \n"
260  "vmadday.xyzw ACC, vf6, vf1 \n"
261  "vmaddaz.xyzw ACC, vf7, vf1 \n"
262  "vmaddw.xyzw vf1, vf8, vf1 \n"
263  "vmulax.xyzw ACC, vf5, vf2 \n"
264  "vmadday.xyzw ACC, vf6, vf2 \n"
265  "vmaddaz.xyzw ACC, vf7, vf2 \n"
266  "vmaddw.xyzw vf2, vf8, vf2 \n"
267  "vmulax.xyzw ACC, vf5, vf3 \n"
268  "vmadday.xyzw ACC, vf6, vf3 \n"
269  "vmaddaz.xyzw ACC, vf7, vf3 \n"
270  "vmaddw.xyzw vf3, vf8, vf3 \n"
271  "vmulax.xyzw ACC, vf5, vf4 \n"
272  "vmadday.xyzw ACC, vf6, vf4 \n"
273  "vmaddaz.xyzw ACC, vf7, vf4 \n"
274  "vmaddw.xyzw vf4, vf8, vf4 \n"
275  "sqc2 vf1, 0x00(%0) \n"
276  "sqc2 vf2, 0x10(%0) \n"
277  "sqc2 vf3, 0x20(%0) \n"
278  "sqc2 vf4, 0x30(%0) \n"
279 #endif
280  : : "r" (output), "r" (input0), "r" (input1)
281  : "memory"
282  );
283  }
284 
285  void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1) {
286  MATRIX work;
287 
288  // Apply the z-axis rotation.
289  matrix_unit(work);
290  work[0x00] = cosf(input1[2]);
291  work[0x01] = sinf(input1[2]);
292  work[0x04] = -sinf(input1[2]);
293  work[0x05] = cosf(input1[2]);
294  matrix_multiply(output, input0, work);
295 
296  // Apply the y-axis rotation.
297  matrix_unit(work);
298  work[0x00] = cosf(input1[1]);
299  work[0x02] = -sinf(input1[1]);
300  work[0x08] = sinf(input1[1]);
301  work[0x0A] = cosf(input1[1]);
302  matrix_multiply(output, output, work);
303 
304  // Apply the x-axis rotation.
305  matrix_unit(work);
306  work[0x05] = cosf(input1[0]);
307  work[0x06] = sinf(input1[0]);
308  work[0x09] = -sinf(input1[0]);
309  work[0x0A] = cosf(input1[0]);
310  matrix_multiply(output, output, work);
311 
312  }
313 
314  void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1) {
315  MATRIX work;
316 
317  // Apply the scaling.
318  matrix_unit(work);
319  work[0x00] = input1[0];
320  work[0x05] = input1[1];
321  work[0x0A] = input1[2];
322  matrix_multiply(output, input0, work);
323 
324  }
325 
326  void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1) {
327  MATRIX work;
328 
329  // Apply the translation.
330  matrix_unit(work);
331  work[0x0C] = input1[0];
332  work[0x0D] = input1[1];
333  work[0x0E] = input1[2];
334  matrix_multiply(output, input0, work);
335 
336  }
337 
338  void matrix_transpose(MATRIX output, MATRIX input0) {
339  MATRIX work;
340 
341  // Transpose the matrix.
342  work[0x00] = input0[0x00];
343  work[0x01] = input0[0x04];
344  work[0x02] = input0[0x08];
345  work[0x03] = input0[0x0C];
346  work[0x04] = input0[0x01];
347  work[0x05] = input0[0x05];
348  work[0x06] = input0[0x09];
349  work[0x07] = input0[0x0D];
350  work[0x08] = input0[0x02];
351  work[0x09] = input0[0x06];
352  work[0x0A] = input0[0x0A];
353  work[0x0B] = input0[0x0E];
354  work[0x0C] = input0[0x03];
355  work[0x0D] = input0[0x07];
356  work[0x0E] = input0[0x0B];
357  work[0x0F] = input0[0x0F];
358 
359  // Output the result.
360  matrix_copy(output, work);
361 
362  }
363 
364  void matrix_unit(MATRIX output) {
365 
366  // Create a unit matrix.
367  memset(output, 0, sizeof(MATRIX));
368  output[0x00] = 1.00f;
369  output[0x05] = 1.00f;
370  output[0x0A] = 1.00f;
371  output[0x0F] = 1.00f;
372 
373  }
374 
375  /* CREATE FUNCTIONS */
376 
377  void create_local_world(MATRIX local_world, VECTOR translation, VECTOR rotation) {
378 
379  // Create the local_world matrix.
383 
384  }
385 
386  void create_local_light(MATRIX local_light, VECTOR rotation) {
387 
388  // Create the local_light matrix.
389  matrix_unit(local_light);
390  matrix_rotate(local_light, local_light, rotation);
391 
392  }
393 
394  void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation) {
395  VECTOR work0, work1;
396 
397  // Reverse the translation.
398  work0[0] = -translation[0];
399  work0[1] = -translation[1];
400  work0[2] = -translation[2];
401  work0[3] = translation[3];
402 
403  // Reverse the rotation.
404  work1[0] = -rotation[0];
405  work1[1] = -rotation[1];
406  work1[2] = -rotation[2];
407  work1[3] = rotation[3];
408 
409  // Create the world_view matrix.
413 
414  }
415 
416  void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far) {
417 
418  // Apply the aspect ratio adjustment.
419  left = (left * aspect); right = (right * aspect);
420 
421  // Create the view_screen matrix.
423  view_screen[0x00] = (2 * near) / (right - left);
424  view_screen[0x05] = (2 * near) / (top - bottom);
425  view_screen[0x08] = (right + left) / (right - left);
426  view_screen[0x09] = (top + bottom) / (top - bottom);
427  view_screen[0x0A] = (far + near) / (far - near);
428  view_screen[0x0B] = -1.00f;
429  view_screen[0x0E] = (2 * far * near) / (far - near);
430  view_screen[0x0F] = 0.00f;
431 
432  }
433 
435 
436  // Create the local_screen matrix.
441 
442  }
443 
444  /* CALCULATE FUNCTIONS */
445 
446  void calculate_normals(VECTOR *output, int count, VECTOR *normals, MATRIX local_light) {
447  asm __volatile__ (
448 #if __GNUC__ > 3
449  "lqc2 $vf1, 0x00(%3) \n"
450  "lqc2 $vf2, 0x10(%3) \n"
451  "lqc2 $vf3, 0x20(%3) \n"
452  "lqc2 $vf4, 0x30(%3) \n"
453  "1: \n"
454  "lqc2 $vf6, 0x00(%2) \n"
455  "vmulaw $ACC, $vf4, $vf0\n"
456  "vmaddax $ACC, $vf1, $vf6\n"
457  "vmadday $ACC, $vf2, $vf6\n"
458  "vmaddz $vf7, $vf3, $vf6\n"
459  "vdiv $Q, $vf0w, $vf7w\n"
460  "vwaitq \n"
461  "vmulq.xyzw $vf7, $vf7, $Q \n"
462  "sqc2 $vf7, 0x00(%0) \n"
463  "addi %0, 0x10 \n"
464  "addi %2, 0x10 \n"
465  "addi %1, -1 \n"
466  "bne $0, %1, 1b \n"
467 #else
468  "lqc2 vf1, 0x00(%3) \n"
469  "lqc2 vf2, 0x10(%3) \n"
470  "lqc2 vf3, 0x20(%3) \n"
471  "lqc2 vf4, 0x30(%3) \n"
472  "1: \n"
473  "lqc2 vf6, 0x00(%2) \n"
474  "vmulaw ACC, vf4, vf0 \n"
475  "vmaddax ACC, vf1, vf6 \n"
476  "vmadday ACC, vf2, vf6 \n"
477  "vmaddz vf7, vf3, vf6 \n"
478  "vdiv Q, vf0w, vf7w \n"
479  "vwaitq \n"
480  "vmulq.xyzw vf7, vf7, Q \n"
481  "sqc2 vf7, 0x00(%0) \n"
482  "addi %0, 0x10 \n"
483  "addi %2, 0x10 \n"
484  "addi %1, -1 \n"
485  "bne $0, %1, 1b \n"
486 #endif
487  : : "r" (output), "r" (count), "r" (normals), "r" (local_light)
488  : "memory"
489  );
490  }
491 
493  int loop0, loop1; float intensity = 0.00f;
494 
495  // Clear the output values.
496  memset(output, 0, sizeof(VECTOR) * count);
497 
498  // For each normal...
499  for (loop0=0;loop0<count;loop0++) {
500 
501  // For each light...
502  for (loop1=0;loop1<light_count;loop1++) {
503 
504  // If this is an ambient light...
505  if (light_type[loop1] == LIGHT_AMBIENT) {
506 
507  // Set the intensity to full.
508  intensity = 1.00f;
509 
510  // Else, if this is a directional light...
511  } else if (light_type[loop1] == LIGHT_DIRECTIONAL) {
512 
513  // Get the light intensity.
514  intensity = -vector_innerproduct(normals[loop0], light_direction[loop1]);
515 
516  // Clamp the minimum intensity.
517  if (intensity < 0.00f) { intensity = 0.00f; }
518 
519  // Else, this is an invalid light type.
520  } else { intensity = 0.00f; }
521 
522  // If the light has intensity...
523  if (intensity > 0.00f) {
524 
525  // Add the light value.
526  output[loop0][0] += (light_colour[loop1][0] * intensity);
527  output[loop0][1] += (light_colour[loop1][1] * intensity);
528  output[loop0][2] += (light_colour[loop1][2] * intensity);
529  output[loop0][3] = 1.00f;
530 
531  }
532 
533  }
534 
535  }
536 
537  }
538 
539  void calculate_colours(VECTOR *output, int count, VECTOR *colours, VECTOR *lights) {
540  int loop0;
541 
542  // For each colour...
543  for (loop0=0;loop0<count;loop0++) {
544 
545  // Apply the light value to the colour.
546  output[loop0][0] = (colours[loop0][0] * lights[loop0][0]);
547  output[loop0][1] = (colours[loop0][1] * lights[loop0][1]);
548  output[loop0][2] = (colours[loop0][2] * lights[loop0][2]);
549 
550  // Clamp the colour value.
551  vector_clamp(output[loop0], output[loop0], 0.00f, 1.99f);
552 
553  }
554 
555  }
556 
558  asm __volatile__ (
559 #if __GNUC__ > 3
560  "lqc2 $vf1, 0x00(%3) \n"
561  "lqc2 $vf2, 0x10(%3) \n"
562  "lqc2 $vf3, 0x20(%3) \n"
563  "lqc2 $vf4, 0x30(%3) \n"
564  "1: \n"
565  "lqc2 $vf6, 0x00(%2) \n"
566  "vmulaw $ACC, $vf4, $vf0\n"
567  "vmaddax $ACC, $vf1, $vf6\n"
568  "vmadday $ACC, $vf2, $vf6\n"
569  "vmaddz $vf7, $vf3, $vf6\n"
570  "vclipw.xyz $vf7, $vf7 \n" // FIXME: Clip detection is still kinda broken.
571  "cfc2 $10, $18 \n"
572  "beq $10, $0, 3f \n"
573  "2: \n"
574  "sqc2 $0, 0x00(%0) \n"
575  "j 4f \n"
576  "3: \n"
577  "vdiv $Q, $vf0w, $vf7w\n"
578  "vwaitq \n"
579  "vmulq.xyz $vf7, $vf7, $Q \n"
580  "sqc2 $vf7, 0x00(%0) \n"
581 #else
582  "lqc2 vf1, 0x00(%3) \n"
583  "lqc2 vf2, 0x10(%3) \n"
584  "lqc2 vf3, 0x20(%3) \n"
585  "lqc2 vf4, 0x30(%3) \n"
586  "1: \n"
587  "lqc2 vf6, 0x00(%2) \n"
588  "vmulaw ACC, vf4, vf0 \n"
589  "vmaddax ACC, vf1, vf6 \n"
590  "vmadday ACC, vf2, vf6 \n"
591  "vmaddz vf7, vf3, vf6 \n"
592  "vclipw.xyz vf7, vf7 \n" // FIXME: Clip detection is still kinda broken.
593  "cfc2 $10, $18 \n"
594  "beq $10, $0, 3f \n"
595  "2: \n"
596  "sqc2 vi00, 0x00(%0) \n"
597  "j 4f \n"
598  "3: \n"
599  "vdiv Q, vf0w, vf7w \n"
600  "vwaitq \n"
601  "vmulq.xyz vf7, vf7, Q \n"
602  "sqc2 vf7, 0x00(%0) \n"
603 #endif
604  "4: \n"
605  "addi %0, 0x10 \n"
606  "addi %2, 0x10 \n"
607  "addi %1, -1 \n"
608  "bne $0, %1, 1b \n"
609  : : "r" (output), "r" (count), "r" (vertices), "r" (local_screen)
610  : "$10", "memory"
611  );
612  }
VECTOR vertices[24]
Definition: mesh_data.c:31
VECTOR colours[24]
Definition: mesh_data.c:58
MATRIX world_view
Definition: main.c:57
MATRIX local_screen
Definition: main.c:57
MATRIX local_world
Definition: main.c:57
MATRIX view_screen
Definition: main.c:57
void vector_normalize(VECTOR output, VECTOR input0)
Definition: math3d.c:121
void create_local_screen(MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen)
Definition: math3d.c:434
void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1)
Definition: math3d.c:219
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:377
void matrix_copy(MATRIX output, MATRIX input0)
Definition: math3d.c:175
float vector_innerproduct(VECTOR input0, VECTOR input1)
Definition: math3d.c:87
void matrix_inverse(MATRIX output, MATRIX input0)
Definition: math3d.c:201
void calculate_vertices(VECTOR *output, int count, VECTOR *vertices, MATRIX local_screen)
Definition: math3d.c:557
void matrix_scale(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:314
void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:285
void matrix_unit(MATRIX output)
Definition: math3d.c:364
void create_world_view(MATRIX world_view, VECTOR translation, VECTOR rotation)
Definition: math3d.c:394
void vector_outerproduct(VECTOR output, VECTOR input0, VECTOR input1)
Definition: math3d.c:151
void calculate_lights(VECTOR *output, int count, VECTOR *normals, VECTOR *light_direction, VECTOR *light_colour, int *light_type, int light_count)
Definition: math3d.c:492
void create_view_screen(MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far)
Definition: math3d.c:416
void calculate_normals(VECTOR *output, int count, VECTOR *normals, MATRIX local_light)
Definition: math3d.c:446
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:326
void calculate_colours(VECTOR *output, int count, VECTOR *colours, VECTOR *lights)
Definition: math3d.c:539
void create_local_light(MATRIX local_light, VECTOR rotation)
Definition: math3d.c:386
void matrix_transpose(MATRIX output, MATRIX input0)
Definition: math3d.c:338
float MATRIX[16]
Definition: math3d.h:23
#define LIGHT_DIRECTIONAL
Definition: math3d.h:108
float VECTOR[4]
Definition: math3d.h:21
#define LIGHT_AMBIENT
Definition: math3d.h:106
#define min(a, b)
Definition: standard.h:54
#define max(a, b)
Definition: standard.h:57
VECTOR normals[1598]
Definition: mesh_data.c:4756
VECTOR light_direction[4]
Definition: teapot.c:45
int light_count
Definition: teapot.c:43
int light_type[4]
Definition: teapot.c:59
VECTOR light_colour[4]
Definition: teapot.c:52