graphics

experiments with opengl3.2/ogles3.3 on linux and win7
git clone http://frotz.net/git/graphics.git
Log | Files | Refs

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