matrix.h (7681B)
1 /* Copyright 2013 Brian Swetland <swetland@frotz.net> 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef _MATRIX_MATH_H_ 17 #define _MATRIX_MATH_H_ 18 19 #include <math.h> 20 #include <string.h> 21 22 #define D2R(d) (((d) * M_PI) / 180.0) 23 24 /* low level operations */ 25 void __mat4_mul_mat4(float m[16], const float a[16], const float b[16]); 26 void __mat4_mul_vec4(float o[4], const float m[16], const float v[4]); 27 28 void __mat4_set_identity(float m[16]); 29 void __mat4_set_translate(float m[16], float x, float y, float z); 30 void __mat4_set_rotate_x(float m[16], float rad); 31 void __mat4_set_rotate_y(float m[16], float rad); 32 void __mat4_set_rotate_z(float m[16], float rad); 33 void __mat4_set_scale(float m[16], float x, float y, float z); 34 35 void __mat4_set_perspective(float m[16], float fov, float aspect, 36 float znear, float zfar); 37 void __mat4_set_ortho(float m[16], float left, float right, 38 float bottom, float top, float znear, float zfar); 39 40 class mat4; 41 42 struct ivec4 { 43 union { 44 int v[4]; 45 struct { 46 int x, y, z, w; 47 }; 48 }; 49 ivec4(int a, int b, int c, int d) : x(a), y(b), z(c), w(d) {}; 50 ivec4() {}; 51 void set(int a, int b, int c, int d) { 52 x = a; y = b; z = c; w = d; 53 }; 54 }; 55 56 class vec4 { 57 union { 58 float v[4]; 59 struct { 60 float x, y, z, w; 61 }; 62 }; 63 public: 64 vec4() { }; 65 vec4(const vec4 &v) { 66 x = v.x; y = v.y; z = v.z; w = v.z; 67 }; 68 vec4(const float *raw) { 69 memcpy(v, raw, sizeof(float[4])); 70 } 71 vec4(float a, float b, float c, float d) { 72 x = a; y = b; z = c; w = d; 73 }; 74 vec4(float a, float b, float c) { 75 x = a; y = b; z = c; w = 1.0f; 76 }; 77 vec4& set(float a, float b, float c, float d) { 78 x = a; y = b; z = c; w = d; 79 return *this; 80 } 81 vec4& set(float a, float b, float c) { 82 x = a; y = b; z = c; w = 1.0f; 83 return *this; 84 } 85 86 /* raw accessor suitable for glSomething4fv() */ 87 operator const float*() { return v; }; 88 89 vec4& operator*=(float n) { 90 x *= n; y *= n; z *= n; w *= n; 91 return *this; 92 } 93 94 /* linear accessors */ 95 float operator[] (const int n) const { return v[n]; }; 96 float& operator[] (const int n) { return v[n]; }; 97 float operator() (const int n) const { return v[n]; }; 98 float& operator() (const int n) { return v[n]; }; 99 100 friend vec4 operator*(const vec4& a, const float b); 101 friend vec4 operator/(const vec4& a, const float b); 102 friend vec4 operator+(const vec4& a, const vec4& b); 103 friend vec4 operator-(const vec4& a, const vec4& b); 104 105 friend vec4 operator*(const mat4& a, const vec4& b); 106 107 float length(void) { 108 return sqrtf(x*x + y*y + z*z + w*w); 109 } 110 float dot(const vec4& v) { 111 return x*v.x + y*v.y + z*v.z + w*v.w; 112 } 113 vec4& normalize(void) { 114 float n = 1.0f / length(); 115 x *= n; y *= n; z *= n; w *= n; 116 return *this; 117 } 118 }; 119 120 inline vec4 operator*(const vec4& v, const float n) { 121 return vec4(v.x * n, v.y * n, v.z * n, v.w * n); 122 } 123 inline vec4 operator/(const vec4& v, const float n) { 124 return vec4(v.x / n, v.y / n, v.z / n, v.w / n); 125 } 126 inline vec4 operator+(const vec4& a, const vec4& b) { 127 return vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 128 } 129 inline vec4 operator-(const vec4& a, const vec4& b) { 130 return vec4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); 131 } 132 133 class vec3 { 134 union { 135 float v[3]; 136 struct { 137 float x, y, z; 138 }; 139 }; 140 public: 141 vec3() { }; 142 vec3(const vec3 &v) { 143 x = v.x; y = v.y; z = v.z; 144 }; 145 vec3(const float *raw) { 146 memcpy(v, raw, sizeof(float[3])); 147 } 148 vec3(float a, float b, float c) { 149 x = a; y = b; z = c; 150 }; 151 void set(float a, float b, float c) { 152 x = a; y = b; z = c; 153 } 154 155 /* raw accessor suitable for glSomething4fv() */ 156 operator const float*() { return v; }; 157 158 vec3& operator*=(float n) { 159 x *= n; y *= n; z *= n; 160 return *this; 161 } 162 163 /* linear accessors */ 164 float operator[] (const int n) const { return v[n]; }; 165 float& operator[] (const int n) { return v[n]; }; 166 float operator() (const int n) const { return v[n]; }; 167 float& operator() (const int n) { return v[n]; }; 168 169 friend vec3 operator*(const vec3& a, const float b); 170 friend vec3 operator/(const vec3& a, const float b); 171 friend vec3 operator+(const vec3& a, const vec3& b); 172 friend vec3 operator-(const vec3& a, const vec3& b); 173 174 float length(void) { 175 return sqrtf(x*x + y*y + z*z); 176 } 177 float dot(const vec4& v) { 178 return x*v.x + y*v.y + z*v.z; 179 } 180 vec3& normalize(void) { 181 float n = 1.0f / length(); 182 x *= n; y *= n; z *= n; 183 return *this; 184 } 185 }; 186 187 inline vec3 operator*(const vec3& v, const float n) { 188 return vec3(v.x * n, v.y * n, v.z * n); 189 } 190 inline vec3 operator/(const vec3& v, const float n) { 191 return vec3(v.x / n, v.y / n, v.z / n); 192 } 193 inline vec3 operator+(const vec3& a, const vec3& b) { 194 return vec3(a.x + b.x, a.y + b.y, a.z + b.z); 195 } 196 inline vec3 operator-(const vec3& a, const vec3& b) { 197 return vec3(a.x - b.x, a.y - b.y, a.z - b.z); 198 } 199 inline vec3 cross(const vec3& p, const vec3& q) { 200 return vec3(p.y*q.z-p.z*q.y, p.z*q.x-p.x*q.z, p.x*q.y-p.y*q.x); 201 } 202 203 class mat4 { 204 float m[16]; 205 public: 206 mat4() { __mat4_set_identity(m); }; 207 mat4(const float raw[16]) { memcpy(m, raw, sizeof(float[16])); }; 208 209 /* raw column-major matrix, suitable for glSomething4fv() */ 210 operator const float*() { return m; }; 211 const float* data() { return m; }; 212 213 mat4& operator*=(const mat4& b) { 214 __mat4_mul_mat4(m, m, b.m); 215 return *this; 216 } 217 218 friend mat4 operator*(const mat4& a, const mat4& b) { 219 mat4 out; 220 __mat4_mul_mat4(out.m, a.m, b.m); 221 return out; 222 } 223 224 /* linear and grid accessors */ 225 float operator[] (const int n) const { return m[n]; } 226 float& operator[] (const int n) { return m[n]; } 227 float operator() (const int col, const int row) const { return m[col * 4 + row]; }; 228 float& operator() (const int col, const int row) { return m[col * 4 + row]; }; 229 230 mat4& identity(void) { 231 __mat4_set_identity(m); 232 return *this; 233 }; 234 235 mat4& rotateX(float rad) { 236 float r[16]; 237 __mat4_set_rotate_x(r, rad); 238 __mat4_mul_mat4(m, m, r); 239 return *this; 240 }; 241 mat4& rotateY(float rad) { 242 float r[16]; 243 __mat4_set_rotate_y(r, rad); 244 __mat4_mul_mat4(m, m, r); 245 return *this; 246 }; 247 mat4& rotateZ(float rad) { 248 float r[16]; 249 __mat4_set_rotate_z(r, rad); 250 __mat4_mul_mat4(m, m, r); 251 return *this; 252 }; 253 mat4& translate(float x, float y, float z) { 254 float t[16]; 255 __mat4_set_translate(t, x, y, z); 256 __mat4_mul_mat4(m, m, t); 257 return *this; 258 }; 259 mat4& scale(float x, float y, float z) { 260 float t[16]; 261 __mat4_set_scale(t, x, y, z); 262 __mat4_mul_mat4(m, m, t); 263 return *this; 264 } 265 mat4& setOrtho(float left, float right, float bottom, float top, float znear, float zfar) { 266 __mat4_set_ortho(m, left, right, bottom, top, znear, zfar); 267 return *this; 268 }; 269 mat4& setPerspective(float fov, float aspect, float znear, float zfar) { 270 __mat4_set_perspective(m, fov, aspect, znear, zfar); 271 return *this; 272 }; 273 mat4& lookAt(const vec3& eye, const vec3& center, const vec3& up); 274 mat4& camera(const vec3& eye, const vec3& center, const vec3& up) { 275 lookAt(eye, center, up); 276 m[12] = -eye.x; 277 m[13] = -eye.y; 278 m[14] = -eye.z; 279 return *this; 280 } 281 friend vec4 operator*(const mat4& a, const vec4& b); 282 283 mat4& mul(mat4& left, mat4& right) { 284 __mat4_mul_mat4(m, left.m, right.m); 285 return *this; 286 } 287 }; 288 289 inline vec4 operator*(const mat4& a, const vec4& b) { 290 vec4 out; 291 __mat4_mul_vec4(out.v, a.m, b.v); 292 return out; 293 } 294 295 #endif