KallistiOS  2.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
matrix.h
Go to the documentation of this file.
1 /* KallistiOS 2.0.0
2 
3  matrix.h
4  (c)2000 Dan Potter
5 
6 */
7 
8 /** \file dc/matrix.h
9  \brief Basic matrix operations.
10 
11  This file contains various basic matrix math functionality for using the
12  SH4's matrix transformation unit. Higher level functionality, like the 3D
13  functionality is built off of these operations.
14 
15  \author Dan Potter
16  \see dc/matrix3d.h
17 */
18 
19 #ifndef __DC_MATRIX_H
20 #define __DC_MATRIX_H
21 
22 #include <sys/cdefs.h>
23 __BEGIN_DECLS
24 
25 #include <kos/vector.h>
26 
27 /** \brief Copy the internal matrix to a memory one.
28 
29  This function stores the current internal matrix to one in memory.
30 
31  \param out A pointer to where to store the matrix (must be at
32  least 8-byte aligned, should be 32-byte aligned).
33 */
34 void mat_store(matrix_t *out);
35 
36 /** \brief Copy a memory matrix into the internal one.
37 
38  This function loads the internal matrix with the values of one in memory.
39 
40  \param out A pointer to where to load the matrix from (must be
41  at least 8-byte aligned, should be 32-byte aligned).
42 */
43 void mat_load(matrix_t *out);
44 
45 /** \brief Clear the internal matrix to identity.
46 
47  This function clears the internal matrix to a standard identity matrix.
48 */
49 void mat_identity();
50 
51 /** \brief Apply a matrix.
52 
53  This function multiplies a matrix in memory onto the internal matrix.
54 
55  \param src A poitner to the matrix to multiply.
56 */
57 void mat_apply(matrix_t *src);
58 
59 /** \brief Transform vectors by the internal matrix.
60 
61  This function transforms zero or more sets of vectors by the current
62  internal matrix. Each vector is 3 single-precision floats long.
63 
64  \param invecs The list of input vectors.
65  \param outvecs The list of output vectors.
66  \param veccnt How many vectors are in the list.
67  \param vecskip Number of empty bytes between vectors.
68 */
69 void mat_transform(vector_t *invecs, vector_t *outvecs, int veccnt, int vecskip);
70 
71 /** \brief Transform vectors by the internal matrix into the store queues.
72 
73  This function transforms one or more sets of vertices using the current
74  internal matrix directly into the store queues. Each vertex is exactly
75  32-bytes long, and the non-xyz data that is with it will be copied over with
76  the transformed coordinates. This is perfect, for instance, for transforming
77  pvr_vertex_t vertices.
78 
79  \param input The list of input vertices.
80  \param output The output pointer.
81  \param veccnt The number of vertices to transform.
82  \note The \ref QACR0 and \ref QACR1 registers must be set
83  appropriately BEFORE calling this function.
84  \author Jim Ursetto
85 */
86 void mat_transform_sq(void * input, void * output, int veccnt);
87 
88 /** \brief Macro to transform a single vertex by the internal matrix.
89 
90  This macro is an inline assembly operation to transform a single vertex. It
91  works most efficiently if the x value is in fr0, y is in fr1, and z is in
92  fr2 before using the macro.
93 
94  \param x The X coordinate to transform.
95  \param y The Y coordinate to transform.
96  \param z The Z coordinate to transform.
97 */
98 #define mat_trans_single(x, y, z) { \
99  register float __x __asm__("fr0") = (x); \
100  register float __y __asm__("fr1") = (y); \
101  register float __z __asm__("fr2") = (z); \
102  __asm__ __volatile__( \
103  "fldi1 fr3\n" \
104  "ftrv xmtrx,fv0\n" \
105  "fldi1 fr2\n" \
106  "fdiv fr3,fr2\n" \
107  "fmul fr2,fr0\n" \
108  "fmul fr2,fr1\n" \
109  : "=f" (__x), "=f" (__y), "=f" (__z) \
110  : "0" (__x), "1" (__y), "2" (__z) \
111  : "fr3" ); \
112  x = __x; y = __y; z = __z; \
113  }
114 
115 /** \brief Macro to transform a single vertex by the internal matrix.
116 
117  This macro is an inline assembly operation to transform a single vertex. It
118  works most efficiently if the x value is in fr0, y is in fr1, z is in
119  fr2, and w is in fr3 before using the macro. This macro is similar to
120  mat_trans_single(), but this one allows an input to and preserves the Z/W
121  value.
122 
123  \param x The X coordinate to transform.
124  \param y The Y coordinate to transform.
125  \param z The Z coordinate to transform.
126  \param w The W coordinate to transform.
127 */
128 #define mat_trans_single4(x, y, z, w) { \
129  register float __x __asm__("fr0") = (x); \
130  register float __y __asm__("fr1") = (y); \
131  register float __z __asm__("fr2") = (z); \
132  register float __w __asm__("fr3") = (w); \
133  __asm__ __volatile__( \
134  "ftrv xmtrx,fv0\n" \
135  "fdiv fr3,fr0\n" \
136  "fdiv fr3,fr1\n" \
137  "fdiv fr3,fr2\n" \
138  "fldi1 fr4\n" \
139  "fdiv fr3,fr4\n" \
140  "fmov fr4,fr3\n" \
141  : "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) \
142  : "0" (__x), "1" (__y), "2" (__z), "3" (__w) \
143  : "fr4" ); \
144  x = __x; y = __y; z = __z; w = __w; \
145  }
146 
147 /** \brief Macro to transform a single vertex by the internal matrix.
148 
149  This macro is an inline assembly operation to transform a single vertex. It
150  works most efficiently if the x value is in fr0, y is in fr1, and z is in
151  fr2 before using the macro. This macro is similar to mat_trans_single(), but
152  this one leaves z/w instead of 1/w for the z component.
153 
154  \param x The X coordinate to transform.
155  \param y The Y coordinate to transform.
156  \param z The Z coordinate to transform.
157 */
158 #define mat_trans_single3(x, y, z) { \
159  register float __x __asm__("fr0") = (x); \
160  register float __y __asm__("fr1") = (y); \
161  register float __z __asm__("fr2") = (z); \
162  __asm__ __volatile__( \
163  "fldi1 fr3\n" \
164  "ftrv xmtrx,fv0\n" \
165  "fdiv fr3,fr0\n" \
166  "fdiv fr3,fr1\n" \
167  "fdiv fr3,fr2\n" \
168  : "=f" (__x), "=f" (__y), "=f" (__z) \
169  : "0" (__x), "1" (__y), "2" (__z) \
170  : "fr3" ); \
171  x = __x; y = __y; z = __z; \
172  }
173 
174 /** \brief Macro to transform a single vertex by the internal matrix with no
175  perspective division.
176 
177  This macro is an inline assembly operation to transform a single vertex. It
178  works most efficiently if the x value is in fr0, y is in fr1, z is in
179  fr2, and w is in fr3 before using the macro. This macro is similar to
180  mat_trans_single(), but this one does not do any perspective division.
181 
182  \param x The X coordinate to transform.
183  \param y The Y coordinate to transform.
184  \param z The Z coordinate to transform.
185  \param w The W coordinate to transform.
186 */
187 #define mat_trans_nodiv(x, y, z, w) { \
188  register float __x __asm__("fr0") = (x); \
189  register float __y __asm__("fr1") = (y); \
190  register float __z __asm__("fr2") = (z); \
191  register float __w __asm__("fr3") = (w); \
192  __asm__ __volatile__( \
193  "ftrv xmtrx,fv0\n" \
194  : "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) \
195  : "0" (__x), "1" (__y), "2" (__z), "3" (__w) ); \
196  x = __x; y = __y; z = __z; w = __w; \
197  }
198 
199 
200 __END_DECLS
201 
202 #endif /* __DC_MATRIX_H */
203