KallistiOS  ##version##
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
vec3f.h
Go to the documentation of this file.
1 /* KallistiOS ##version##
2 
3  dc/vec3f.h
4  Copyright (C) 2013, 2014 Josh "PH3NOM" Pearson
5 
6 */
7 
8 /** \file dc/vec3f.h
9  \brief Basic matrix operations.
10 
11  This file contains various basic vector math functionality for using the
12  SH4's vector instructions. Higher level functionality in KGL is built off
13  of these.
14 
15  \author Josh "PH3NOM" Pearson
16  \see dc/matrix.h
17 */
18 
19 #ifndef __DC_VEC3F_H
20 #define __DC_VEC3F_H
21 
22 #include <sys/cdefs.h>
23 __BEGIN_DECLS
24 
25 typedef struct vec3f {
26  float x, y, z;
27 } vec3f_t;
28 
29 #define R_DEG 182.04444443623349541909523793743
30 #define R_RAD 10430.37835
31 
32 /** \brief Macro to return the scalar dot product of two 3d vectors.
33 
34  This macro is an inline assembly operation using the SH4's fast
35  (approximate) math instructions, and returns a single-precision
36  floating-point value.
37 
38  \param x1 The X coordinate of first vector.
39  \param y1 The Y coordinate of first vector.
40  \param z1 The Z coordinate of first vector.
41  \param x2 The X coordinate of second vector.
42  \param y2 The Y coordinate of second vector.
43  \param z2 The Z coordinate of second vector.
44  \param w The result of the calculation.
45 */
46 #define vec3f_dot(x1, y1, z1, x2, y2, z2, w) { \
47  register float __x __asm__("fr0") = (x1); \
48  register float __y __asm__("fr1") = (y1); \
49  register float __z __asm__("fr2") = (z1); \
50  register float __w __asm__("fr3"); \
51  register float __a __asm__("fr4") = (x2); \
52  register float __b __asm__("fr5") = (y2); \
53  register float __c __asm__("fr6") = (z2); \
54  register float __d __asm__("fr7"); \
55  __asm__ __volatile__( \
56  "fldi0 fr3\n" \
57  "fldi0 fr7\n" \
58  "fipr fv4,fv0" \
59  : "+f" (__w) \
60  : "f" (__x), "f" (__y), "f" (__z), "f" (__w), \
61  "f" (__a), "f" (__b), "f" (__c), "f" (__d) \
62  ); \
63  w = __w; \
64  }
65 
66 /** \brief Macro to return scalar Euclidean length of a 3d vector.
67 
68  This macro is an inline assembly operation using the SH4's fast
69  (approximate) math instructions, and returns a single-precision
70  floating-point value.
71 
72  \param x The X coordinate of vector.
73  \param y The Y coordinate of vector.
74  \param z The Z coordinate of vector.
75  \param w The result of the calculation.
76 */
77 #define vec3f_length(x, y, z, w) { \
78  register float __x __asm__("fr0") = (x); \
79  register float __y __asm__("fr1") = (y); \
80  register float __z __asm__("fr2") = (z); \
81  register float __w __asm__("fr3"); \
82  __asm__ __volatile__( \
83  "fldi0 fr3\n" \
84  "fipr fv0,fv0\n" \
85  "fsqrt fr3\n" \
86  : "+f" (__w) \
87  : "f" (__x), "f" (__y), "f" (__z), "f" (__w) \
88  ); \
89  w = __w; \
90  }
91 
92 /** \brief Macro to return the Euclidean distance between two 3d vectors.
93 
94  This macro is an inline assembly operation using the SH4's fast
95  (approximate) math instructions, and returns a single-precision
96  floating-point value.
97 
98  \param x1 The X coordinate of first vector.
99  \param y1 The Y coordinate of first vector.
100  \param z1 The Z coordinate of first vector.
101  \param x2 The X coordinate of second vector.
102  \param y2 The Y coordinate of second vector.
103  \param z2 The Z coordinate of second vector.
104  \param w The result of the calculation.
105 */
106 #define vec3f_distance(x1, y1, z1, x2, y2, z2, w) { \
107  register float __x __asm__("fr0") = (x2-x1); \
108  register float __y __asm__("fr1") = (y2-y1); \
109  register float __z __asm__("fr2") = (z2-z1); \
110  register float __w __asm__("fr3"); \
111  __asm__ __volatile__( \
112  "fldi0 fr3\n" \
113  "fipr fv0,fv0\n" \
114  "fsqrt fr3\n" \
115  : "+f" (__w) \
116  : "f" (__x), "f" (__y), "f" (__z), "f" (__w) \
117  ); \
118  w = __w; \
119  }
120 
121 /** \brief Macro to return the normalized version of a vector.
122 
123  This macro is an inline assembly operation using the SH4's fast
124  (approximate) math instructions to calculate a vector that is in the same
125  direction as the input vector but with a Euclidean length of one. The input
126  vector is modified by the operation as the resulting values.
127 
128  \param x The X coordinate of vector.
129  \param y The Y coordinate of vector.
130  \param z The Z coordinate of vector.
131 */
132 #define vec3f_normalize(x, y, z) { \
133  register float __x __asm__("fr0") = x; \
134  register float __y __asm__("fr1") = y; \
135  register float __z __asm__("fr2") = z; \
136  __asm__ __volatile__( \
137  "fldi0 fr3\n" \
138  "fipr fv0,fv0\n" \
139  "fsrra fr3\n" \
140  "fmul fr3, fr0\n" \
141  "fmul fr3, fr1\n" \
142  "fmul fr3, fr2\n" \
143  : "=f" (__x), "=f" (__y), "=f" (__z) \
144  : "0" (__x), "1" (__y), "2" (__z) \
145  : "fr3" ); \
146  x = __x; y = __y; z = __z; \
147  }
148 
149 /** \brief Macro to return the normalized version of a vector minus another
150  vector.
151 
152  This macro is an inline assembly operation using the SH4's fast
153  (approximate) math instructions. The return vector is stored into the third
154  vertex parameter: x3, y3, and z3.
155 
156  \param x1 The X coordinate of first vector.
157  \param y1 The Y coordinate of first vector.
158  \param z1 The Z coordinate of first vector.
159  \param x2 The X coordinate of second vector.
160  \param y2 The Y coordinate of second vector.
161  \param z2 The Z coordinate of second vector.
162  \param x3 The X coordinate of output vector.
163  \param y3 The Y coordinate of output vector.
164  \param z3 The Z coordinate of output vector.
165 */
166 #define vec3f_sub_normalize(x1, y1, z1, x2, y2, z2, x3, y3, z3) { \
167  register float __x __asm__("fr0") = x1 - x2; \
168  register float __y __asm__("fr1") = y1 - y2; \
169  register float __z __asm__("fr2") = z1 - z2; \
170  __asm__ __volatile__( \
171  "fldi0 fr3\n" \
172  "fipr fv0,fv0\n" \
173  "fsrra fr3\n" \
174  "fmul fr3, fr0\n" \
175  "fmul fr3, fr1\n" \
176  "fmul fr3, fr2\n" \
177  : "=f" (__x), "=f" (__y), "=f" (__z) \
178  : "0" (__x), "1" (__y), "2" (__z) \
179  : "fr3" ); \
180  x3 = __x; y3 = __y; z3 = __z; \
181  }
182 
183 /** \brief Macro to rotate a vector about its origin on the x, y plane.
184 
185  This macro is an inline assembly operation using the SH4's fast
186  (approximate) math instructions. The return vector is stored into the first
187  vertex parameter: x1, y1, and z1.
188 
189  \param px The X coordinate of vector to rotate.
190  \param py The Y coordinate of vector to rotate.
191  \param pz The Z coordinate of vector to rotate.
192  \param cx The X coordinate of origin vector.
193  \param cy The Y coordinate of origin vector.
194  \param cz The Z coordinate of origin vector.
195  \param r The angle (in radians) of rotation.
196 */
197 #define vec3f_rotr_xy(px, py, pz, cx, cy, cz, r) { \
198  register float __px __asm__("fr0") = px; \
199  register float __py __asm__("fr1") = py; \
200  register float __cx __asm__("fr4") = cx; \
201  register float __cy __asm__("fr5") = cy; \
202  register float __r __asm__("fr6") = r; \
203  register float __s __asm__("fr7") = R_RAD; \
204  __asm__ __volatile__( \
205  "fmul fr7, fr6\n" \
206  "ftrc fr6, fpul\n" \
207  "fsca fpul, dr6\n" \
208  "fsub fr4, fr0\n" \
209  "fsub fr5, fr1\n" \
210  "fmov fr0, fr2\n" \
211  "fmov fr1, fr3\n" \
212  "fmul fr7, fr0\n" \
213  "fmul fr6, fr1\n" \
214  "fmul fr6, fr2\n" \
215  "fmul fr7, fr3\n" \
216  "fadd fr0, fr4\n" \
217  "fsub fr1, fr4\n" \
218  "fadd fr2, fr5\n" \
219  "fadd fr3, fr5\n" \
220  : "+f" (__cx), "+f" (__cy) \
221  : "f" (__px), "f" (__py), "f" (__r), "f" (__s) ); \
222  px = __cx; py = __cy; \
223  }
224 
225 /** \brief Macro to rotate a vector about its origin on the x, z plane.
226 
227  This macro is an inline assembly operation using the SH4's fast
228  (approximate) math instructions. The return vector is stored into the first
229  vertex parameter: x1, y1, and z1.
230 
231  \param px The X coordinate of vector to rotate.
232  \param py The Y coordinate of vector to rotate.
233  \param pz The Z coordinate of vector to rotate.
234  \param cx The X coordinate of origin vector.
235  \param cy The Y coordinate of origin vector.
236  \param cz The Z coordinate of origin vector.
237  \param r The angle (in radians) of rotation.
238 */
239 #define vec3f_rotr_xz(px, py, pz, cx, cy, cz, r) { \
240  register float __px __asm__("fr0") = px; \
241  register float __pz __asm__("fr1") = pz; \
242  register float __cx __asm__("fr4") = cx; \
243  register float __cz __asm__("fr5") = cz; \
244  register float __r __asm__("fr6") = r; \
245  register float __s __asm__("fr7") = R_RAD; \
246  __asm__ __volatile__( \
247  "fmul fr7, fr6\n" \
248  "ftrc fr6, fpul\n" \
249  "fsca fpul, dr6\n" \
250  "fsub fr4, fr0\n" \
251  "fsub fr5, fr1\n" \
252  "fmov fr0, fr2\n" \
253  "fmov fr1, fr3\n" \
254  "fmul fr7, fr0\n" \
255  "fmul fr6, fr1\n" \
256  "fmul fr6, fr2\n" \
257  "fmul fr7, fr3\n" \
258  "fadd fr0, fr4\n" \
259  "fsub fr1, fr4\n" \
260  "fadd fr2, fr5\n" \
261  "fadd fr3, fr5\n" \
262  : "+f" (__cx), "+f" (__cz) \
263  : "f" (__px), "f" (__pz), "f" (__r), "f" (__s) ); \
264  px = __cx; pz = __cz; \
265  }
266 
267 /** \brief Macro to rotate a vector about its origin on the y, z plane.
268 
269  This macro is an inline assembly operation using the SH4's fast
270  (approximate) math instructions. The return vector is stored into the first
271  vertex parameter: x1, y1, and z1.
272 
273  \param px The X coordinate of vector to rotate.
274  \param py The Y coordinate of vector to rotate.
275  \param pz The Z coordinate of vector to rotate.
276  \param cx The X coordinate of origin vector.
277  \param cy The Y coordinate of origin vector.
278  \param cz The Z coordinate of origin vector.
279  \param r The angle (in radians) of rotation.
280 */
281 #define vec3f_rotr_yz(px, py, pz, cx, cy, cz, r) { \
282  register float __py __asm__("fr0") = py; \
283  register float __pz __asm__("fr1") = pz; \
284  register float __cy __asm__("fr4") = cy; \
285  register float __cz __asm__("fr5") = cz; \
286  register float __r __asm__("fr6") = r; \
287  register float __s __asm__("fr7") = R_RAD; \
288  __asm__ __volatile__( \
289  "fmul fr7, fr6\n" \
290  "ftrc fr6, fpul\n" \
291  "fsca fpul, dr6\n" \
292  "fsub fr4, fr0\n" \
293  "fsub fr5, fr1\n" \
294  "fmov fr0, fr2\n" \
295  "fmov fr1, fr3\n" \
296  "fmul fr7, fr0\n" \
297  "fmul fr6, fr1\n" \
298  "fmul fr6, fr2\n" \
299  "fmul fr7, fr3\n" \
300  "fadd fr0, fr4\n" \
301  "fsub fr1, fr4\n" \
302  "fadd fr2, fr5\n" \
303  "fadd fr3, fr5\n" \
304  : "+f" (__cy), "+f" (__cz) \
305  : "f" (__py), "f" (__pz), "f" (__r), "f" (__s) ); \
306  py = __cy; pz = __cz; \
307  }
308 
309 /** \brief Macro to rotate a vector about its origin on the x, y plane.
310 
311  This macro is an inline assembly operation using the SH4's fast
312  (approximate) math instructions. The return vector is stored into the first
313  vertex parameter: x1, y1, and z1.
314 
315  \param px The X coordinate of vector to rotate.
316  \param py The Y coordinate of vector to rotate.
317  \param pz The Z coordinate of vector to rotate.
318  \param cx The X coordinate of origin vector.
319  \param cy The Y coordinate of origin vector.
320  \param cz The Z coordinate of origin vector.
321  \param r The angle (in degrees) of rotation.
322 */
323 #define vec3f_rotd_xy(px, py, pz, cx, cy, cz, r) { \
324  register float __px __asm__("fr0") = px; \
325  register float __pz __asm__("fr1") = pz; \
326  register float __cx __asm__("fr4") = cx; \
327  register float __cz __asm__("fr5") = cz; \
328  register float __r __asm__("fr6") = r; \
329  register float __s __asm__("fr7") = R_DEG; \
330  __asm__ __volatile__( \
331  "fmul fr7, fr6\n" \
332  "ftrc fr6, fpul\n" \
333  "fsca fpul, dr6\n" \
334  "fsub fr4, fr0\n" \
335  "fsub fr5, fr1\n" \
336  "fmov fr0, fr2\n" \
337  "fmov fr1, fr3\n" \
338  "fmul fr7, fr0\n" \
339  "fmul fr6, fr1\n" \
340  "fmul fr6, fr2\n" \
341  "fmul fr7, fr3\n" \
342  "fadd fr0, fr4\n" \
343  "fsub fr1, fr4\n" \
344  "fadd fr2, fr5\n" \
345  "fadd fr3, fr5\n" \
346  : "+f" (__cx), "+f" (__cz) \
347  : "f" (__px), "f" (__pz), "f" (__r), "f" (__s) ); \
348  px = __cx; pz = __cz; \
349  }
350 
351 /** \brief Macro to rotate a vector about its origin on the x, z plane.
352 
353  This macro is an inline assembly operation using the SH4's fast
354  (approximate) math instructions. The return vector is stored into the first
355  vertex parameter: x1, y1, and z1.
356 
357  \param px The X coordinate of vector to rotate.
358  \param py The Y coordinate of vector to rotate.
359  \param pz The Z coordinate of vector to rotate.
360  \param cx The X coordinate of origin vector.
361  \param cy The Y coordinate of origin vector.
362  \param cz The Z coordinate of origin vector.
363  \param r The angle (in degrees) of rotation.
364 */
365 #define vec3f_rotd_xz(px, py, pz, cx, cy, cz, r) { \
366  register float __px __asm__("fr0") = px; \
367  register float __pz __asm__("fr1") = pz; \
368  register float __cx __asm__("fr4") = cx; \
369  register float __cz __asm__("fr5") = cz; \
370  register float __r __asm__("fr6") = r; \
371  register float __s __asm__("fr7") = R_DEG; \
372  __asm__ __volatile__( \
373  "fmul fr7, fr6\n" \
374  "ftrc fr6, fpul\n" \
375  "fsca fpul, dr6\n" \
376  "fsub fr4, fr0\n" \
377  "fsub fr5, fr1\n" \
378  "fmov fr0, fr2\n" \
379  "fmov fr1, fr3\n" \
380  "fmul fr7, fr0\n" \
381  "fmul fr6, fr1\n" \
382  "fmul fr6, fr2\n" \
383  "fmul fr7, fr3\n" \
384  "fadd fr0, fr4\n" \
385  "fsub fr1, fr4\n" \
386  "fadd fr2, fr5\n" \
387  "fadd fr3, fr5\n" \
388  : "+f" (__cx), "+f" (__cz) \
389  : "f" (__px), "f" (__pz), "f" (__r), "f" (__s) ); \
390  px = __cx; pz = __cz; \
391  }
392 
393 /** \brief Macro to rotate a vector about its origin on the y, z plane.
394 
395  This macro is an inline assembly operation using the SH4's fast
396  (approximate) math instructions. The return vector is stored into the first
397  vertex parameter: x1, y1, and z1.
398 
399  \param px The X coordinate of vector to rotate.
400  \param py The Y coordinate of vector to rotate.
401  \param pz The Z coordinate of vector to rotate.
402  \param cx The X coordinate of origin vector.
403  \param cy The Y coordinate of origin vector.
404  \param cz The Z coordinate of origin vector.
405  \param r The angle (in degrees) of rotation.
406 */
407 #define vec3f_rotd_yz(px, py, pz, cx, cy, cz, r) { \
408  register float __py __asm__("fr0") = py; \
409  register float __pz __asm__("fr1") = pz; \
410  register float __cy __asm__("fr4") = cy; \
411  register float __cz __asm__("fr5") = cz; \
412  register float __r __asm__("fr6") = r; \
413  register float __s __asm__("fr7") = R_DEG; \
414  __asm__ __volatile__( \
415  "fmul fr7, fr6\n" \
416  "ftrc fr6, fpul\n" \
417  "fsca fpul, dr6\n" \
418  "fsub fr4, fr0\n" \
419  "fsub fr5, fr1\n" \
420  "fmov fr0, fr2\n" \
421  "fmov fr1, fr3\n" \
422  "fmul fr7, fr0\n" \
423  "fmul fr6, fr1\n" \
424  "fmul fr6, fr2\n" \
425  "fmul fr7, fr3\n" \
426  "fadd fr0, fr4\n" \
427  "fsub fr1, fr4\n" \
428  "fadd fr2, fr5\n" \
429  "fadd fr3, fr5\n" \
430  : "+f" (__cy), "+f" (__cz) \
431  : "f" (__py), "f" (__pz), "f" (__r), "f" (__s) ); \
432  py = __cy; pz = __cz; \
433  }
434 
435 __END_DECLS
436 
437 #endif /* !__DC_VEC3F_H */
float z
Definition: vec3f.h:26
struct vec3f vec3f_t
float y
Definition: vec3f.h:26
Definition: vec3f.h:25
float x
Definition: vec3f.h:26