1 /* 2 * Copyright (C) 2003 Robert Kooima 3 * 4 * NEVERBALL is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published 6 * by the Free Software Foundation; either version 2 of the License, 7 * or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, but 10 * WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * General Public License for more details. 13 */ 14 15 #ifndef VEC_H 16 #define VEC_H 17 18 #include <math.h> 19 20 #define V_PI 3.1415927f 21 22 #define V_RAD(d) (d * V_PI / 180.f) 23 #define V_DEG(r) (r * 180.f / V_PI) 24 25 #define fsinf(a) ((float) sin((double) (a))) 26 #define fcosf(a) ((float) cos((double) (a))) 27 #define ftanf(a) ((float) tan((double) (a))) 28 #define fabsf(a) ((float) fabs((double) (a))) 29 #define fsqrtf(a) ((float) sqrt((double) (a))) 30 #define fpowf(x,y) ((float) pow((double) (x), (double) (y))) 31 #define fasinf(a) ((float) asin((double) (a))) 32 #define facosf(a) ((float) acos((double) (a))) 33 #define fmodf(x,y) ((float) fmod((double) (x), (double) (y))) 34 #define fatan2f(x, y) ((float) atan2((double) (x), (double) (y))) 35 36 #define flerp(f0, f1, a) ((f0) + ((f1) - (f0)) * (a)) 37 38 /*---------------------------------------------------------------------------*/ 39 40 #define v_dot(u, v) ((u)[0] * (v)[0] + (u)[1] * (v)[1] + (u)[2] * (v)[2]) 41 #define v_len(u) fsqrtf(v_dot(u, u)) 42 43 #define v_cpy(u, v) do { \ 44 (u)[0] = (v)[0]; \ 45 (u)[1] = (v)[1]; \ 46 (u)[2] = (v)[2]; \ 47 } while (0) 48 49 #define v_inv(u, v) do { \ 50 (u)[0] = -(v)[0]; \ 51 (u)[1] = -(v)[1]; \ 52 (u)[2] = -(v)[2]; \ 53 } while (0) 54 55 #define v_scl(u, v, k) do { \ 56 (u)[0] = (v)[0] * (k); \ 57 (u)[1] = (v)[1] * (k); \ 58 (u)[2] = (v)[2] * (k); \ 59 } while (0) 60 61 #define v_add(u, v, w) do { \ 62 (u)[0] = (v)[0] + (w)[0]; \ 63 (u)[1] = (v)[1] + (w)[1]; \ 64 (u)[2] = (v)[2] + (w)[2]; \ 65 } while (0) 66 67 #define v_sub(u, v, w) do { \ 68 (u)[0] = (v)[0] - (w)[0]; \ 69 (u)[1] = (v)[1] - (w)[1]; \ 70 (u)[2] = (v)[2] - (w)[2]; \ 71 } while (0) 72 73 #define v_mid(u, v, w) do { \ 74 (u)[0] = ((v)[0] + (w)[0]) / 2.f; \ 75 (u)[1] = ((v)[1] + (w)[1]) / 2.f; \ 76 (u)[2] = ((v)[2] + (w)[2]) / 2.f; \ 77 } while (0) 78 79 #define v_mad(u, p, v, t) do { \ 80 (u)[0] = (p)[0] + (v)[0] * (t); \ 81 (u)[1] = (p)[1] + (v)[1] * (t); \ 82 (u)[2] = (p)[2] + (v)[2] * (t); \ 83 } while (0) 84 85 #define v_lerp(u, v, w, a) do { \ 86 (u)[0] = flerp(v[0], w[0], a); \ 87 (u)[1] = flerp(v[1], w[1], a); \ 88 (u)[2] = flerp(v[2], w[2], a); \ 89 } while (0) 90 91 #define e_cpy(d, e) do { \ 92 v_cpy((d)[0], (e)[0]); \ 93 v_cpy((d)[1], (e)[1]); \ 94 v_cpy((d)[2], (e)[2]); \ 95 } while (0) 96 97 #define e_orthonrm(e) do { \ 98 v_crs((e)[0], (e)[1], (e)[2]); \ 99 v_crs((e)[2], (e)[0], (e)[1]); \ 100 v_nrm((e)[0], (e)[0]); \ 101 v_nrm((e)[1], (e)[1]); \ 102 v_nrm((e)[2], (e)[2]); \ 103 } while (0) 104 105 #define e_lerp(c, d, e, a) do { \ 106 v_lerp((c)[0], (d)[0], (e)[0], a); \ 107 v_lerp((c)[1], (d)[1], (e)[1], a); \ 108 v_lerp((c)[2], (d)[2], (e)[2], a); \ 109 e_orthonrm(c); \ 110 } while (0) 111 112 /*---------------------------------------------------------------------------*/ 113 114 void v_nrm(float *, const float *); 115 void v_crs(float *, const float *, const float *); 116 117 void m_cpy(float *, const float *); 118 void m_xps(float *, const float *); 119 int m_inv(float *, const float *); 120 121 void m_ident(float *); 122 void m_basis(float *, const float *, 123 const float *, 124 const float *); 125 void m_xlt(float *, const float *); 126 void m_scl(float *, const float *); 127 void m_rot(float *, const float *, float); 128 129 void m_mult(float *, const float *, const float *); 130 void m_pxfm(float *, const float *, const float *); 131 void m_vxfm(float *, const float *, const float *); 132 133 /*---------------------------------------------------------------------------*/ 134 135 #define q_dot(q, r) ((q)[0] * (r)[0] + v_dot((q) + 1, (r) + 1)) 136 #define q_len(q) fsqrtf(q_dot((q), (q))) 137 138 #define q_cpy(q, r) do { \ 139 (q)[0] = (r)[0]; \ 140 (q)[1] = (r)[1]; \ 141 (q)[2] = (r)[2]; \ 142 (q)[3] = (r)[3]; \ 143 } while (0) 144 145 #define q_conj(q, r) do { \ 146 (q)[0] = (r)[0]; \ 147 (q)[1] = -(r)[1]; \ 148 (q)[2] = -(r)[2]; \ 149 (q)[3] = -(r)[3]; \ 150 } while (0) 151 152 void q_as_axisangle(const float q[4], float u[3], float *a); 153 void q_by_axisangle(float q[4], const float u[3], float a); 154 155 void q_nrm(float q[4], const float r[4]); 156 void q_mul(float q[4], const float a[4], const float b[4]); 157 void q_rot(float v[3], const float r[4], const float w[3]); 158 159 void q_euler(float v[3], const float q[4]); 160 void q_slerp(float q[4], const float a[4], const float b[4], float t); 161 162 #endif 163