matrix.h (4981B)
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 <string.h> 20 21 #define D2R(d) (((d) * M_PI) / 180.0) 22 23 #ifdef _WIN32 24 #define M_PI 3.14159265358979323846 25 #endif 26 27 /* low level operations */ 28 void __mat4_mul_mat4(float m[16], const float a[16], const float b[16]); 29 void __mat4_mul_vec4(float o[4], const float m[16], const float v[4]); 30 31 void __mat4_set_identity(float m[16]); 32 void __mat4_set_translate(float m[16], float x, float y, float z); 33 void __mat4_set_rotate_x(float m[16], float rad); 34 void __mat4_set_rotate_y(float m[16], float rad); 35 void __mat4_set_rotate_z(float m[16], float rad); 36 37 void __mat4_set_frustum(float m[16], float left, float right, 38 float bottom, float top, float znear, float zfar); 39 void __mat4_set_perspective(float m[16], float fov, float aspect, 40 float znear, float zfar); 41 void __mat4_set_ortho(float m[16], float left, float right, 42 float bottom, float top, float znear, float zfar); 43 44 class mat4; 45 46 class vec4 { 47 float v[4]; 48 public: 49 vec4() { }; 50 vec4(const vec4 &x) { 51 v[0] = x[0]; v[1] = x[1]; v[2] = x[2]; v[3] = x[3]; 52 }; 53 vec4(const float *raw) { 54 memcpy(v, raw, sizeof(float[4])); 55 } 56 vec4(float a, float b, float c, float d) { 57 v[0] = a; v[1] = b; v[2] = c; v[3] = d; 58 }; 59 vec4(float x, float y, float z) { 60 v[0] = x; v[1] = y; v[2] = z; v[3] = 1.0; 61 }; 62 63 /* raw accessor suitable for glSomething4fv() */ 64 operator const float*() { return v; }; 65 66 vec4& operator*=(float n) { 67 v[0]*=n; v[1]*=n; v[2]*=n; v[3]*=n; 68 return *this; 69 } 70 71 /* linear accessors */ 72 float operator[] (const int n) const { return v[n]; }; 73 float& operator[] (const int n) { return v[n]; }; 74 float operator() (const int n) const { return v[n]; }; 75 float& operator() (const int n) { return v[n]; }; 76 77 friend vec4 operator*(const vec4& a, const float b); 78 friend vec4 operator/(const vec4& a, const float b); 79 friend vec4 operator+(const vec4& a, const vec4& b); 80 friend vec4 operator-(const vec4& a, const vec4& b); 81 82 friend vec4 operator*(const mat4& a, const vec4& b); 83 }; 84 85 inline vec4 operator*(const vec4& a, const float n) { 86 return vec4(a.v[0]*n,a.v[1]*n,a.v[2]*n,a.v[3]*n); 87 } 88 inline vec4 operator/(const vec4& a, const float n) { 89 return vec4(a.v[0]/n,a.v[1]/n,a.v[2]/n,a.v[3]/n); 90 } 91 inline vec4 operator+(const vec4& a, const vec4& b) { 92 return vec4(a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]); 93 } 94 inline vec4 operator-(const vec4& a, const vec4& b) { 95 return vec4(a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]); 96 } 97 98 class mat4 { 99 float m[16]; 100 public: 101 mat4() { __mat4_set_identity(m); }; 102 mat4(const float raw[16]) { memcpy(m, raw, sizeof(float[16])); }; 103 104 /* raw column-major matrix, suitable for glSomething4fv() */ 105 operator const float*() { return m; }; 106 107 mat4& operator*=(const mat4& b) { 108 __mat4_mul_mat4(m, m, b.m); 109 return *this; 110 } 111 112 friend mat4 operator*(const mat4& a, const mat4& b) { 113 mat4 out; 114 __mat4_mul_mat4(out.m, a.m, b.m); 115 return out; 116 } 117 118 /* linear and grid accessors */ 119 float operator[] (const int n) const { return m[n]; } 120 float& operator[] (const int n) { return m[n]; } 121 float operator() (const int col, const int row) const { return m[col * 4 + row]; }; 122 float& operator() (const int col, const int row) { return m[col * 4 + row]; }; 123 124 mat4& identity(void) { 125 __mat4_set_identity(m); 126 return *this; 127 }; 128 129 mat4& rotateX(float rad) { 130 float r[16]; 131 __mat4_set_rotate_x(r, rad); 132 __mat4_mul_mat4(m, m, r); 133 return *this; 134 }; 135 mat4& rotateY(float rad) { 136 float r[16]; 137 __mat4_set_rotate_y(r, rad); 138 __mat4_mul_mat4(m, m, r); 139 return *this; 140 }; 141 mat4& rotateZ(float rad) { 142 float r[16]; 143 __mat4_set_rotate_z(r, rad); 144 __mat4_mul_mat4(m, m, r); 145 return *this; 146 }; 147 mat4& translate(float x, float y, float z) { 148 float t[16]; 149 __mat4_set_translate(t, x, y, z); 150 __mat4_mul_mat4(m, m, t); 151 return *this; 152 }; 153 154 mat4& setOrtho(float left, float right, float bottom, float top, float znear, float zfar) { 155 __mat4_set_ortho(m, left, right, bottom, top, znear, zfar); 156 return *this; 157 }; 158 mat4& setPerspective(float fov, float aspect, float znear, float zfar) { 159 __mat4_set_perspective(m, fov, aspect, znear, zfar); 160 return *this; 161 }; 162 163 friend vec4 operator*(const mat4& a, const vec4& b); 164 165 mat4& mul(mat4& left, mat4& right) { 166 __mat4_mul_mat4(m, left.m, right.m); 167 return *this; 168 } 169 }; 170 171 inline vec4 operator*(const mat4& a, const vec4& b) { 172 vec4 out; 173 __mat4_mul_vec4(out.v, a.m, b.v); 174 return out; 175 } 176 177 #endif