ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
math3d.c File Reference
#include <tamtypes.h>
#include <graph.h>
#include <math3d.h>
#include <string.h>
#include <math.h>
+ Include dependency graph for math3d.c:

Go to the source code of this file.

Functions

void vector_apply (VECTOR output, VECTOR input0, MATRIX input1)
 
void vector_clamp (VECTOR output, VECTOR input0, float min, float max)
 
void vector_copy (VECTOR output, VECTOR input0)
 
float vector_innerproduct (VECTOR input0, VECTOR input1)
 
void vector_multiply (VECTOR output, VECTOR input0, VECTOR input1)
 
void vector_normalize (VECTOR output, VECTOR input0)
 
void vector_outerproduct (VECTOR output, VECTOR input0, VECTOR input1)
 
void matrix_copy (MATRIX output, MATRIX input0)
 
void matrix_inverse (MATRIX output, MATRIX input0)
 
void matrix_multiply (MATRIX output, MATRIX input0, MATRIX input1)
 
void matrix_rotate (MATRIX output, MATRIX input0, VECTOR input1)
 
void matrix_scale (MATRIX output, MATRIX input0, VECTOR input1)
 
void matrix_translate (MATRIX output, MATRIX input0, VECTOR input1)
 
void matrix_transpose (MATRIX output, MATRIX input0)
 
void matrix_unit (MATRIX output)
 
void create_local_world (MATRIX local_world, VECTOR translation, VECTOR rotation)
 
void create_local_light (MATRIX local_light, VECTOR rotation)
 
void create_world_view (MATRIX world_view, VECTOR translation, VECTOR rotation)
 
void create_view_screen (MATRIX view_screen, float aspect, float left, float right, float bottom, float top, float near, float far)
 
void create_local_screen (MATRIX local_screen, MATRIX local_world, MATRIX world_view, MATRIX view_screen)
 
void calculate_normals (VECTOR *output, int count, VECTOR *normals, MATRIX local_light)
 
void calculate_lights (VECTOR *output, int count, VECTOR *normals, VECTOR *light_direction, VECTOR *light_colour, int *light_type, int light_count)
 
void calculate_colours (VECTOR *output, int count, VECTOR *colours, VECTOR *lights)
 
void calculate_vertices (VECTOR *output, int count, VECTOR *vertices, MATRIX local_screen)
 

Function Documentation

◆ calculate_colours()

void calculate_colours ( VECTOR output,
int  count,
VECTOR colours,
VECTOR lights 
)

Calculate colour values given an array of light intensity values.

Definition at line 539 of file math3d.c.

539  {
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  }
VECTOR colours[24]
Definition: mesh_data.c:58
void vector_clamp(VECTOR output, VECTOR input0, float min, float max)
Definition: math3d.c:50

References colours, and vector_clamp().

Referenced by render_teapot().

◆ calculate_lights()

void calculate_lights ( VECTOR output,
int  count,
VECTOR normals,
VECTOR light_directions,
VECTOR light_colours,
int *  light_types,
int  light_count 
)

Calculate the light intensity for an array of lights given an array of normal values.

Definition at line 492 of file math3d.c.

492  {
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  }
float vector_innerproduct(VECTOR input0, VECTOR input1)
Definition: math3d.c:87
#define LIGHT_DIRECTIONAL
Definition: math3d.h:108
float VECTOR[4]
Definition: math3d.h:21
#define LIGHT_AMBIENT
Definition: math3d.h:106
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

References LIGHT_AMBIENT, light_colour, light_count, light_direction, LIGHT_DIRECTIONAL, light_type, normals, and vector_innerproduct().

Referenced by render_teapot().

◆ calculate_normals()

void calculate_normals ( VECTOR output,
int  count,
VECTOR normals,
MATRIX  local_light 
)

Transform an array of normals by applying the specified local_light matrix.

Definition at line 446 of file math3d.c.

446  {
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  }

References normals.

Referenced by render_teapot().

◆ calculate_vertices()

void calculate_vertices ( VECTOR output,
int  count,
VECTOR vertices,
MATRIX  local_screen 
)

Calculate vertex values by applying the specific local_screen matrix.

Definition at line 557 of file math3d.c.

557  {
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
MATRIX local_screen
Definition: main.c:57

References local_screen, and vertices.

Referenced by render(), and render_teapot().

◆ create_local_light()

void create_local_light ( MATRIX  local_light,
VECTOR  rotation 
)

Create a local_light matrix given a rotation. Commonly used to transform an object's normals for lighting calculations.

Definition at line 386 of file math3d.c.

386  {
387 
388  // Create the local_light matrix.
389  matrix_unit(local_light);
390  matrix_rotate(local_light, local_light, rotation);
391 
392  }
void matrix_rotate(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:285
void matrix_unit(MATRIX output)
Definition: math3d.c:364

References matrix_rotate(), and matrix_unit().

Referenced by render_teapot().

◆ create_local_screen()

void create_local_screen ( MATRIX  local_screen,
MATRIX  local_world,
MATRIX  world_view,
MATRIX  view_screen 
)

Create a local_screen matrix given a local_world, world_view and view_screen matrix. Commonly used with vector_apply() to transform vertices for rendering.

Definition at line 434 of file math3d.c.

434  {
435 
436  // Create the local_screen matrix.
441 
442  }
MATRIX world_view
Definition: main.c:57
MATRIX local_world
Definition: main.c:57
MATRIX view_screen
Definition: main.c:57
void matrix_multiply(MATRIX output, MATRIX input0, MATRIX input1)
Definition: math3d.c:219

References local_screen, local_world, matrix_multiply(), matrix_unit(), view_screen, and world_view.

Referenced by draw_cube(), render(), and render_teapot().

◆ create_local_world()

void create_local_world ( MATRIX  local_world,
VECTOR  translation,
VECTOR  rotation 
)

Create a local_world matrix given a translation and rotation. Commonly used to describe an object's position and orientation.

Definition at line 377 of file math3d.c.

377  {
378 
379  // Create the local_world matrix.
383 
384  }
void matrix_translate(MATRIX output, MATRIX input0, VECTOR input1)
Definition: math3d.c:326

References local_world, matrix_rotate(), matrix_translate(), and matrix_unit().

Referenced by draw_cube(), render(), and render_teapot().

◆ create_view_screen()

void create_view_screen ( MATRIX  view_screen,
float  aspect,
float  left,
float  right,
float  bottom,
float  top,
float  near,
float  far 
)

Create a view_screen matrix given an aspect and clipping plane values. Functionally similar to the opengl function: glFrustum()

Definition at line 416 of file math3d.c.

416  {
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  }

References matrix_unit(), and view_screen.

Referenced by render().

◆ create_world_view()

void create_world_view ( MATRIX  world_view,
VECTOR  translation,
VECTOR  rotation 
)

Create a world_view matrix given a translation and rotation. Commonly used to describe a camera's position and rotation.

Definition at line 394 of file math3d.c.

394  {
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  }

References matrix_rotate(), matrix_translate(), matrix_unit(), and world_view.

Referenced by draw_cube(), render(), and render_teapot().

◆ matrix_copy()

void matrix_copy ( MATRIX  output,
MATRIX  input0 
)

Copy a matrix.

Definition at line 175 of file math3d.c.

175  {
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  }

Referenced by matrix_inverse(), and matrix_transpose().

◆ matrix_inverse()

void matrix_inverse ( MATRIX  output,
MATRIX  input0 
)

Calculate the inverse of a matrix.

Definition at line 201 of file math3d.c.

201  {
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  }
void matrix_copy(MATRIX output, MATRIX input0)
Definition: math3d.c:175
void matrix_transpose(MATRIX output, MATRIX input0)
Definition: math3d.c:338
float MATRIX[16]
Definition: math3d.h:23

References matrix_copy(), and matrix_transpose().

◆ matrix_multiply()

void matrix_multiply ( MATRIX  output,
MATRIX  input0,
MATRIX  input1 
)

Multiply two matrices together.

Definition at line 219 of file math3d.c.

219  {
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  }

Referenced by create_local_screen(), matrix_rotate(), matrix_scale(), and matrix_translate().

◆ matrix_rotate()

void matrix_rotate ( MATRIX  output,
MATRIX  input0,
VECTOR  input1 
)

Create a rotation matrix and apply it to the specified input matrix.

Definition at line 285 of file math3d.c.

285  {
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  }

References matrix_multiply(), and matrix_unit().

Referenced by create_local_light(), create_local_world(), and create_world_view().

◆ matrix_scale()

void matrix_scale ( MATRIX  output,
MATRIX  input0,
VECTOR  input1 
)

Create a scaling matrix and apply it to the specified input matrix.

Definition at line 314 of file math3d.c.

314  {
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  }

References matrix_multiply(), and matrix_unit().

◆ matrix_translate()

void matrix_translate ( MATRIX  output,
MATRIX  input0,
VECTOR  input1 
)

Create a translation matrix and apply it to the specified input matrix.

Definition at line 326 of file math3d.c.

326  {
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  }

References matrix_multiply(), and matrix_unit().

Referenced by create_local_world(), and create_world_view().

◆ matrix_transpose()

void matrix_transpose ( MATRIX  output,
MATRIX  input0 
)

Transpose a matrix.

Definition at line 338 of file math3d.c.

338  {
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  }

References matrix_copy().

Referenced by matrix_inverse().

◆ matrix_unit()

void matrix_unit ( MATRIX  output)

Create a unit matrix.

Definition at line 364 of file math3d.c.

364  {
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  }

Referenced by create_local_light(), create_local_screen(), create_local_world(), create_view_screen(), create_world_view(), matrix_rotate(), matrix_scale(), and matrix_translate().

◆ vector_apply()

void vector_apply ( VECTOR  output,
VECTOR  input0,
MATRIX  input1 
)

Multiply a vector by a matrix, returning a vector.

Definition at line 20 of file math3d.c.

20  {
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  }

◆ vector_clamp()

void vector_clamp ( VECTOR  output,
VECTOR  input0,
float  min,
float  max 
)

Clamp a vector's values by cutting them off at a minimum and maximum value.

Definition at line 50 of file math3d.c.

50  {
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  }
void vector_copy(VECTOR output, VECTOR input0)
Definition: math3d.c:73
#define min(a, b)
Definition: standard.h:54
#define max(a, b)
Definition: standard.h:57

References max, min, and vector_copy().

Referenced by calculate_colours().

◆ vector_copy()

void vector_copy ( VECTOR  output,
VECTOR  input0 
)

Copy a vector.

Definition at line 73 of file math3d.c.

73  {
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  }

Referenced by vector_clamp(), and vector_multiply().

◆ vector_innerproduct()

float vector_innerproduct ( VECTOR  input0,
VECTOR  input1 
)

Calculate the inner product of two vectors. Returns a scalar value.

Definition at line 87 of file math3d.c.

87  {
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  }

Referenced by calculate_lights().

◆ vector_multiply()

void vector_multiply ( VECTOR  output,
VECTOR  input0,
VECTOR  input1 
)

Multiply two vectors together.

Definition at line 107 of file math3d.c.

107  {
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  }

References vector_copy().

◆ vector_normalize()

void vector_normalize ( VECTOR  output,
VECTOR  input0 
)

Normalize a vector by determining its length and dividing its values by this value.

Definition at line 121 of file math3d.c.

121  {
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  }

◆ vector_outerproduct()

void vector_outerproduct ( VECTOR  output,
VECTOR  input0,
VECTOR  input1 
)

Calculate the outer product of two vectors.

Definition at line 151 of file math3d.c.

151  {
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  }