| 1 |
/* mathlib |
|---|
| 2 |
* |
|---|
| 3 |
* written by Alexander Zaprjagaev |
|---|
| 4 |
* frustum@frustum.tomsk.ru |
|---|
| 5 |
* http://frustum.tomsk.ru |
|---|
| 6 |
*/ |
|---|
| 7 |
|
|---|
| 8 |
#ifndef __MATHLIB_H__ |
|---|
| 9 |
#define __MATHLIB_H__ |
|---|
| 10 |
|
|---|
| 11 |
#include <math.h> |
|---|
| 12 |
|
|---|
| 13 |
#define EPSILON 1e-6 |
|---|
| 14 |
#define PI 3.14159265358979323846f |
|---|
| 15 |
#define DEG2RAD (PI / 180.0f) |
|---|
| 16 |
#define RAD2DEG (180.0 / PI) |
|---|
| 17 |
|
|---|
| 18 |
struct vec2; |
|---|
| 19 |
struct vec3; |
|---|
| 20 |
struct vec4; |
|---|
| 21 |
struct mat3; |
|---|
| 22 |
struct quat; |
|---|
| 23 |
|
|---|
| 24 |
struct vec2 { |
|---|
| 25 |
|
|---|
| 26 |
vec2() : x(0), y(0) { } |
|---|
| 27 |
vec2(float x,float y) : x(x), y(y) { } |
|---|
| 28 |
vec2(const float *v) : x(v[0]), y(v[1]) { } |
|---|
| 29 |
vec2(const vec2 &v) : x(v.x), y(v.y) { } |
|---|
| 30 |
|
|---|
| 31 |
int operator==(const vec2 &v) { return (x == v.x && y == v.y); } |
|---|
| 32 |
int operator!=(const vec2 &v) { return (x != v.x || y != v.y); } |
|---|
| 33 |
|
|---|
| 34 |
const vec2 operator*(float f) const { return vec2(x * f,y * f); } |
|---|
| 35 |
const vec2 operator/(float f) const { return vec2(x / f,y / f); } |
|---|
| 36 |
const vec2 operator+(const vec2 &v) const { return vec2(x + v.x,y + v.y); } |
|---|
| 37 |
const vec2 operator-() const { return vec2(-x,-y); } |
|---|
| 38 |
const vec2 operator-(const vec2 &v) const { return vec2(x - v.x,y - v.y); } |
|---|
| 39 |
|
|---|
| 40 |
vec2 &operator*=(float f) { return *this = *this * f; } |
|---|
| 41 |
vec2 &operator/=(float f) { return *this = *this / f; } |
|---|
| 42 |
vec2 &operator+=(const vec2 &v) { return *this = *this + v; } |
|---|
| 43 |
vec2 &operator-=(const vec2 &v) { return *this = *this - v; } |
|---|
| 44 |
|
|---|
| 45 |
float &operator[](int i) { |
|---|
| 46 |
return ((float*)&x)[i]; |
|---|
| 47 |
} |
|---|
| 48 |
|
|---|
| 49 |
const float operator[](int i) const { |
|---|
| 50 |
return ((float*)&x)[i]; |
|---|
| 51 |
} |
|---|
| 52 |
|
|---|
| 53 |
float length() const { return (float)sqrt(x * x + y * y); } |
|---|
| 54 |
float normalize() { |
|---|
| 55 |
float inv,length = (float)sqrt(x * x + y * y); |
|---|
| 56 |
inv = 1.0f / length; |
|---|
| 57 |
x *= inv; |
|---|
| 58 |
y *= inv; |
|---|
| 59 |
return length; |
|---|
| 60 |
} |
|---|
| 61 |
float dot(const vec2 &v) { return (x * v.x + y * v.y); } |
|---|
| 62 |
|
|---|
| 63 |
union { |
|---|
| 64 |
struct { |
|---|
| 65 |
float x,y; |
|---|
| 66 |
}; |
|---|
| 67 |
float v[2]; |
|---|
| 68 |
}; |
|---|
| 69 |
}; |
|---|
| 70 |
|
|---|
| 71 |
struct vec3 { |
|---|
| 72 |
|
|---|
| 73 |
vec3() : x(0), y(0), z(0) { } |
|---|
| 74 |
vec3(float x,float y,float z) : x(x), y(y), z(z) { } |
|---|
| 75 |
vec3(const float *v) : x(v[0]), y(v[1]), z(v[2]) { } |
|---|
| 76 |
vec3(const vec3 &v) : x(v.x), y(v.y), z(v.z) { } |
|---|
| 77 |
vec3(const vec4 &v); |
|---|
| 78 |
|
|---|
| 79 |
int operator==(const vec3 &v) { return (x == v.x && y == v.y && z == v.z); } |
|---|
| 80 |
int operator!=(const vec3 &v) { return (x != v.x || y != v.y || z != v.z); } |
|---|
| 81 |
|
|---|
| 82 |
const vec3 operator*(float f) const { return vec3(x * f,y * f,z * f); } |
|---|
| 83 |
const vec3 operator/(float f) const { return vec3(x / f,y / f,z / f); } |
|---|
| 84 |
const vec3 operator+(const vec3 &v) const { return vec3(x + v.x,y + v.y,z + v.z); } |
|---|
| 85 |
const vec3 operator-() const { return vec3(-x,-y,-z); } |
|---|
| 86 |
const vec3 operator-(const vec3 &v) const { return vec3(x - v.x,y - v.y,z - v.z); } |
|---|
| 87 |
|
|---|
| 88 |
vec3 &operator*=(float f) { return *this = *this * f; } |
|---|
| 89 |
vec3 &operator/=(float f) { return *this = *this / f; } |
|---|
| 90 |
vec3 &operator+=(const vec3 &v) { return *this = *this + v; } |
|---|
| 91 |
vec3 &operator-=(const vec3 &v) { return *this = *this - v; } |
|---|
| 92 |
|
|---|
| 93 |
float &operator[](int i) { |
|---|
| 94 |
return ((float*)&x)[i]; |
|---|
| 95 |
} |
|---|
| 96 |
|
|---|
| 97 |
const float operator[](int i) const { |
|---|
| 98 |
return ((float*)&x)[i]; |
|---|
| 99 |
} |
|---|
| 100 |
|
|---|
| 101 |
float length() const { return (float)sqrt(x * x + y * y + z * z); } |
|---|
| 102 |
float normalize() { |
|---|
| 103 |
float inv,length = (float)sqrt(x * x + y * y + z * z); |
|---|
| 104 |
inv = 1.0f / length; |
|---|
| 105 |
x *= inv; |
|---|
| 106 |
y *= inv; |
|---|
| 107 |
z *= inv; |
|---|
| 108 |
return length; |
|---|
| 109 |
} |
|---|
| 110 |
float dot(const vec3 &v) { return (x * v.x + y * v.y + z * v.z); } |
|---|
| 111 |
vec3 cross(const vec3 &v1,const vec3 &v2) { |
|---|
| 112 |
x = v1.y * v2.z - v1.z * v2.y; |
|---|
| 113 |
y = v1.z * v2.x - v1.x * v2.z; |
|---|
| 114 |
z = v1.x * v2.y - v1.y * v2.x; |
|---|
| 115 |
return *this; |
|---|
| 116 |
} |
|---|
| 117 |
|
|---|
| 118 |
union { |
|---|
| 119 |
struct { |
|---|
| 120 |
float x,y,z; |
|---|
| 121 |
}; |
|---|
| 122 |
float v[3]; |
|---|
| 123 |
}; |
|---|
| 124 |
}; |
|---|
| 125 |
|
|---|
| 126 |
struct vec4 { |
|---|
| 127 |
|
|---|
| 128 |
vec4() : x(0), y(0), z(0), w(1) { } |
|---|
| 129 |
vec4(float x,float y,float z,float w) : x(x), y(y), z(z), w(w) { } |
|---|
| 130 |
vec4(const float *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) { } |
|---|
| 131 |
vec4(const vec3 &v) : x(v.x), y(v.y), z(v.z), w(1) { } |
|---|
| 132 |
vec4(const vec3 &v,float w) : x(v.x), y(v.y), z(v.z), w(w) { } |
|---|
| 133 |
vec4(const vec4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) { } |
|---|
| 134 |
|
|---|
| 135 |
int operator==(const vec4 &v) { return (x == v.x && y == v.y && z == v.z && w == v.w); } |
|---|
| 136 |
int operator!=(const vec4 &v) { return (x != v.x || y != v.y || z != v.z || w != v.w); } |
|---|
| 137 |
|
|---|
| 138 |
const vec4 operator*(float f) const { return vec4(x * f,y * f,z * f,w * f); } |
|---|
| 139 |
const vec4 operator/(float f) const { return vec4(x / f,y / f,z / f,w / f); } |
|---|
| 140 |
const vec4 operator+(const vec4 &v) const { return vec4(x + v.x,y + v.y,z + v.z, w + v.w); } |
|---|
| 141 |
const vec4 operator-() const { return vec4(-x,-y,-z,-w); } |
|---|
| 142 |
const vec4 operator-(const vec4 &v) const { return vec4(x - v.x,y - v.y,z - v.z, z - v.w); } |
|---|
| 143 |
|
|---|
| 144 |
vec4 &operator*=(float f) { return *this = *this * f; } |
|---|
| 145 |
vec4 &operator/=(float f) { return *this = *this / f; } |
|---|
| 146 |
vec4 &operator+=(const vec4 &v) { return *this = *this + v; } |
|---|
| 147 |
vec4 &operator-=(const vec4 &v) { return *this = *this - v; } |
|---|
| 148 |
|
|---|
| 149 |
float &operator[](int i) { |
|---|
| 150 |
return ((float*)&x)[i]; |
|---|
| 151 |
} |
|---|
| 152 |
|
|---|
| 153 |
const float operator[](int i) const { |
|---|
| 154 |
return ((float*)&x)[i]; |
|---|
| 155 |
} |
|---|
| 156 |
|
|---|
| 157 |
float dot(const vec4 &v) const { return (x * v.x + y * v.y + z * v.z + w * v.w); } |
|---|
| 158 |
|
|---|
| 159 |
union { |
|---|
| 160 |
struct { |
|---|
| 161 |
float x,y,z,w; |
|---|
| 162 |
}; |
|---|
| 163 |
float v[4]; |
|---|
| 164 |
}; |
|---|
| 165 |
}; |
|---|
| 166 |
|
|---|
| 167 |
inline vec3::vec3(const vec4 &v) { |
|---|
| 168 |
x = v.x; |
|---|
| 169 |
y = v.y; |
|---|
| 170 |
z = v.z; |
|---|
| 171 |
} |
|---|
| 172 |
|
|---|
| 173 |
struct mat4 { |
|---|
| 174 |
|
|---|
| 175 |
mat4() { |
|---|
| 176 |
mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; |
|---|
| 177 |
mat[1] = 1.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0; |
|---|
| 178 |
mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0; |
|---|
| 179 |
mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; |
|---|
| 180 |
} |
|---|
| 181 |
mat4(const float *m) { |
|---|
| 182 |
mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12]; |
|---|
| 183 |
mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13]; |
|---|
| 184 |
mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14]; |
|---|
| 185 |
mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15]; |
|---|
| 186 |
} |
|---|
| 187 |
mat4(const mat4 &m) { |
|---|
| 188 |
mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12]; |
|---|
| 189 |
mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13]; |
|---|
| 190 |
mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14]; |
|---|
| 191 |
mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15]; |
|---|
| 192 |
} |
|---|
| 193 |
|
|---|
| 194 |
vec3 operator*(const vec3 &v) { |
|---|
| 195 |
vec3 ret; |
|---|
| 196 |
ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12]; |
|---|
| 197 |
ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13]; |
|---|
| 198 |
ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14]; |
|---|
| 199 |
return ret; |
|---|
| 200 |
} |
|---|
| 201 |
mat4 operator*(const float f) { |
|---|
| 202 |
mat4 ret; |
|---|
| 203 |
ret[0] = mat[0] * f; ret[4] = mat[4] * f; ret[8] = mat[8] * f; ret[12] = mat[12] * f; |
|---|
| 204 |
ret[1] = mat[1] * f; ret[5] = mat[5] * f; ret[9] = mat[9] * f; ret[13] = mat[13] * f; |
|---|
| 205 |
ret[2] = mat[2] * f; ret[6] = mat[6] * f; ret[10] = mat[10] * f; ret[14] = mat[14] * f; |
|---|
| 206 |
ret[3] = mat[3] * f; ret[7] = mat[7] * f; ret[11] = mat[11] * f; ret[15] = mat[15] * f; |
|---|
| 207 |
return ret; |
|---|
| 208 |
} |
|---|
| 209 |
mat4 operator*(const mat4 &m) { |
|---|
| 210 |
mat4 ret; |
|---|
| 211 |
ret[0] = mat[0] * m[0] + mat[4] * m[1] + mat[8] * m[2] + mat[12] * m[3]; |
|---|
| 212 |
ret[1] = mat[1] * m[0] + mat[5] * m[1] + mat[9] * m[2] + mat[13] * m[3]; |
|---|
| 213 |
ret[2] = mat[2] * m[0] + mat[6] * m[1] + mat[10] * m[2] + mat[14] * m[3]; |
|---|
| 214 |
ret[3] = mat[3] * m[0] + mat[7] * m[1] + mat[11] * m[2] + mat[15] * m[3]; |
|---|
| 215 |
ret[4] = mat[0] * m[4] + mat[4] * m[5] + mat[8] * m[6] + mat[12] * m[7]; |
|---|
| 216 |
ret[5] = mat[1] * m[4] + mat[5] * m[5] + mat[9] * m[6] + mat[13] * m[7]; |
|---|
| 217 |
ret[6] = mat[2] * m[4] + mat[6] * m[5] + mat[10] * m[6] + mat[14] * m[7]; |
|---|
| 218 |
ret[7] = mat[3] * m[4] + mat[7] * m[5] + mat[11] * m[6] + mat[15] * m[7]; |
|---|
| 219 |
ret[8] = mat[0] * m[8] + mat[4] * m[9] + mat[8] * m[10] + mat[12] * m[11]; |
|---|
| 220 |
ret[9] = mat[1] * m[8] + mat[5] * m[9] + mat[9] * m[10] + mat[13] * m[11]; |
|---|
| 221 |
ret[10] = mat[2] * m[8] + mat[6] * m[9] + mat[10] * m[10] + mat[14] * m[11]; |
|---|
| 222 |
ret[11] = mat[3] * m[8] + mat[7] * m[9] + mat[11] * m[10] + mat[15] * m[11]; |
|---|
| 223 |
ret[12] = mat[0] * m[12] + mat[4] * m[13] + mat[8] * m[14] + mat[12] * m[15]; |
|---|
| 224 |
ret[13] = mat[1] * m[12] + mat[5] * m[13] + mat[9] * m[14] + mat[13] * m[15]; |
|---|
| 225 |
ret[14] = mat[2] * m[12] + mat[6] * m[13] + mat[10] * m[14] + mat[14] * m[15]; |
|---|
| 226 |
ret[15] = mat[3] * m[12] + mat[7] * m[13] + mat[11] * m[14] + mat[15] * m[15]; |
|---|
| 227 |
return ret; |
|---|
| 228 |
} |
|---|
| 229 |
mat4 operator+(const mat4 &m) { |
|---|
| 230 |
mat4 ret; |
|---|
| 231 |
ret[0] = mat[0] + m[0]; ret[4] = mat[4] + m[4]; ret[8] = mat[8] + m[8]; ret[12] = mat[12] + m[12]; |
|---|
| 232 |
ret[1] = mat[1] + m[1]; ret[5] = mat[5] + m[5]; ret[9] = mat[9] + m[9]; ret[13] = mat[13] + m[13]; |
|---|
| 233 |
ret[2] = mat[2] + m[2]; ret[6] = mat[6] + m[6]; ret[10] = mat[10] + m[10]; ret[14] = mat[14] + m[14]; |
|---|
| 234 |
ret[3] = mat[3] + m[3]; ret[7] = mat[7] + m[7]; ret[11] = mat[11] + m[11]; ret[15] = mat[15] + m[15]; |
|---|
| 235 |
return ret; |
|---|
| 236 |
} |
|---|
| 237 |
mat4 operator-(const mat4 &m) { |
|---|
| 238 |
mat4 ret; |
|---|
| 239 |
ret[0] = mat[0] - m[0]; ret[4] = mat[4] - m[4]; ret[8] = mat[8] - m[8]; ret[12] = mat[12] - m[12]; |
|---|
| 240 |
ret[1] = mat[1] - m[1]; ret[5] = mat[5] - m[5]; ret[9] = mat[9] - m[9]; ret[13] = mat[13] - m[13]; |
|---|
| 241 |
ret[2] = mat[2] - m[2]; ret[6] = mat[6] - m[6]; ret[10] = mat[10] - m[10]; ret[14] = mat[14] - m[14]; |
|---|
| 242 |
ret[3] = mat[3] - m[3]; ret[7] = mat[7] - m[7]; ret[11] = mat[11] - m[11]; ret[15] = mat[15] - m[15]; |
|---|
| 243 |
return ret; |
|---|
| 244 |
} |
|---|
| 245 |
|
|---|
| 246 |
mat4 &operator*=(const float f) { return *this = *this * f; } |
|---|
| 247 |
mat4 &operator*=(const mat4 &m) { return *this = *this * m; } |
|---|
| 248 |
mat4 &operator+=(const mat4 &m) { return *this = *this + m; } |
|---|
| 249 |
mat4 &operator-=(const mat4 &m) { return *this = *this - m; } |
|---|
| 250 |
|
|---|
| 251 |
float &operator[](int i) { |
|---|
| 252 |
return mat[i]; |
|---|
| 253 |
} |
|---|
| 254 |
const float operator[](int i) const { |
|---|
| 255 |
return mat[i]; |
|---|
| 256 |
} |
|---|
| 257 |
|
|---|
| 258 |
mat4 zero() { |
|---|
| 259 |
mat4 ret; |
|---|
| 260 |
ret[0] = 0.0; ret[4] = 0.0; ret[8] = 0.0; ret[12] = 0.0; |
|---|
| 261 |
ret[1] = 0.0; ret[5] = 0.0; ret[9] = 0.0; ret[13] = 0.0; |
|---|
| 262 |
ret[2] = 0.0; ret[6] = 0.0; ret[10] = 0.0; ret[14] = 0.0; |
|---|
| 263 |
ret[3] = 0.0; ret[7] = 0.0; ret[11] = 0.0; ret[15] = 0.0; |
|---|
| 264 |
return ret; |
|---|
| 265 |
} |
|---|
| 266 |
mat4 identity() { |
|---|
| 267 |
mat4 ret; |
|---|
| 268 |
ret[0] = 1.0; ret[4] = 0.0; ret[8] = 0.0; ret[12] = 0.0; |
|---|
| 269 |
ret[1] = 0.0; ret[5] = 1.0; ret[9] = 0.0; ret[13] = 0.0; |
|---|
| 270 |
ret[2] = 0.0; ret[6] = 0.0; ret[10] = 1.0; ret[14] = 0.0; |
|---|
| 271 |
ret[3] = 0.0; ret[7] = 0.0; ret[11] = 0.0; ret[15] = 1.0; |
|---|
| 272 |
return ret; |
|---|
| 273 |
} |
|---|
| 274 |
mat4 rotation() { |
|---|
| 275 |
mat4 ret; |
|---|
| 276 |
ret[0] = mat[0]; ret[4] = mat[4]; ret[8] = mat[8]; ret[12] = 0; |
|---|
| 277 |
ret[1] = mat[1]; ret[5] = mat[5]; ret[9] = mat[9]; ret[13] = 0; |
|---|
| 278 |
ret[2] = mat[2]; ret[6] = mat[6]; ret[10] = mat[10]; ret[14] = 0; |
|---|
| 279 |
ret[3] = 0; ret[7] = 0; ret[11] = 0; ret[15] = 1; |
|---|
| 280 |
return ret; |
|---|
| 281 |
} |
|---|
| 282 |
mat4 transpose() { |
|---|
| 283 |
mat4 ret; |
|---|
| 284 |
ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[3]; |
|---|
| 285 |
ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[7]; |
|---|
| 286 |
ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[11]; |
|---|
| 287 |
ret[3] = mat[12]; ret[7] = mat[13]; ret[11] = mat[14]; ret[15] = mat[15]; |
|---|
| 288 |
return ret; |
|---|
| 289 |
} |
|---|
| 290 |
mat4 inverse() { |
|---|
| 291 |
mat4 ret; |
|---|
| 292 |
float det; |
|---|
| 293 |
det = mat[0] * mat[5] * mat[10]; |
|---|
| 294 |
det += mat[4] * mat[9] * mat[2]; |
|---|
| 295 |
det += mat[8] * mat[1] * mat[6]; |
|---|
| 296 |
det -= mat[8] * mat[5] * mat[2]; |
|---|
| 297 |
det -= mat[4] * mat[1] * mat[10]; |
|---|
| 298 |
det -= mat[0] * mat[9] * mat[6]; |
|---|
| 299 |
det = 1.0f / det; |
|---|
| 300 |
ret[0] = (mat[5] * mat[10] - mat[9] * mat[6]) * det; |
|---|
| 301 |
ret[1] = -(mat[1] * mat[10] - mat[9] * mat[2]) * det; |
|---|
| 302 |
ret[2] = (mat[1] * mat[6] - mat[5] * mat[2]) * det; |
|---|
| 303 |
ret[3] = 0.0; |
|---|
| 304 |
ret[4] = -(mat[4] * mat[10] - mat[8] * mat[6]) * det; |
|---|
| 305 |
ret[5] = (mat[0] * mat[10] - mat[8] * mat[2]) * det; |
|---|
| 306 |
ret[6] = -(mat[0] * mat[6] - mat[4] * mat[2]) * det; |
|---|
| 307 |
ret[7] = 0.0; |
|---|
| 308 |
ret[8] = (mat[4] * mat[9] - mat[8] * mat[5]) * det; |
|---|
| 309 |
ret[9] = -(mat[0] * mat[9] - mat[8] * mat[1]) * det; |
|---|
| 310 |
ret[10] = (mat[0] * mat[5] - mat[4] * mat[1]) * det; |
|---|
| 311 |
ret[11] = 0.0; |
|---|
| 312 |
ret[12] = -(mat[12] * ret[0] + mat[13] * ret[4] + mat[14] * ret[8]); |
|---|
| 313 |
ret[13] = -(mat[12] * ret[1] + mat[13] * ret[5] + mat[14] * ret[9]); |
|---|
| 314 |
ret[14] = -(mat[12] * ret[2] + mat[13] * ret[6] + mat[14] * ret[10]); |
|---|
| 315 |
ret[15] = 1.0; |
|---|
| 316 |
return ret; |
|---|
| 317 |
} |
|---|
| 318 |
|
|---|
| 319 |
void rotation_x(const float angle) { |
|---|
| 320 |
float rad = angle * DEG2RAD; |
|---|
| 321 |
float c = (float)cos(rad); |
|---|
| 322 |
float s = (float)sin(rad); |
|---|
| 323 |
mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; |
|---|
| 324 |
mat[1] = 0.0; mat[5] = c; mat[9] = -s; mat[13] = 0.0; |
|---|
| 325 |
mat[2] = 0.0; mat[6] = s; mat[10] = c; mat[14] = 0.0; |
|---|
| 326 |
mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; |
|---|
| 327 |
} |
|---|
| 328 |
void rotation_y(const float angle) { |
|---|
| 329 |
float rad = angle * DEG2RAD; |
|---|
| 330 |
float c = (float)cos(rad); |
|---|
| 331 |
float s = (float)sin(rad); |
|---|
| 332 |
mat[0] = c; mat[4] = 0.0; mat[8] = s; mat[12] = 0.0; |
|---|
| 333 |
mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0; |
|---|
| 334 |
mat[2] = -s; mat[6] = 0.0; mat[10] = c; mat[14] = 0.0; |
|---|
| 335 |
mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; |
|---|
| 336 |
} |
|---|
| 337 |
void rotation_z(const float angle) { |
|---|
| 338 |
float rad = angle * DEG2RAD; |
|---|
| 339 |
float c = (float)cos(rad); |
|---|
| 340 |
float s = (float)sin(rad); |
|---|
| 341 |
mat[0] = c; mat[4] = -s; mat[8] = 0.0; mat[12] = 0.0; |
|---|
| 342 |
mat[1] = s; mat[5] = c; mat[9] = 0.0; mat[13] = 0.0; |
|---|
| 343 |
mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0; |
|---|
| 344 |
mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; |
|---|
| 345 |
} |
|---|
| 346 |
void translate(const vec3 &v) { |
|---|
| 347 |
mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = v[0]; |
|---|
| 348 |
mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = v[1]; |
|---|
| 349 |
mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = v[2]; |
|---|
| 350 |
mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; |
|---|
| 351 |
} |
|---|
| 352 |
void translate(const float x,const float y,const float z) { |
|---|
| 353 |
translate(vec3(x,y,z)); |
|---|
| 354 |
} |
|---|
| 355 |
void scale(const vec3 &v) { |
|---|
| 356 |
mat[0] = v[0]; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0; |
|---|
| 357 |
mat[1] = 0.0; mat[5] = v[1]; mat[9] = 0.0; mat[13] = 0.0; |
|---|
| 358 |
mat[2] = 0.0; mat[6] = 0.0; mat[10] = v[2]; mat[14] = 0.0; |
|---|
| 359 |
mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0; |
|---|
| 360 |
} |
|---|
| 361 |
void scale(const float x,const float y,const float z) { |
|---|
| 362 |
scale(vec3(x,y,z)); |
|---|
| 363 |
} |
|---|
| 364 |
|
|---|
| 365 |
void lock_at(const vec3 &eye,const vec3 &dir,const vec3 &up) { |
|---|
| 366 |
vec3 x,y,z; |
|---|
| 367 |
mat4 m0,m1; |
|---|
| 368 |
z = eye - dir; |
|---|
| 369 |
z.normalize(); |
|---|
| 370 |
x.cross(up,z); |
|---|
| 371 |
x.normalize(); |
|---|
| 372 |
y.cross(z,x); |
|---|
| 373 |
y.normalize(); |
|---|
| 374 |
m0[0] = x[0]; m0[4] = x[1]; m0[8] = x[2]; m0[12] = 0.0; |
|---|
| 375 |
m0[1] = y[0]; m0[5] = y[1]; m0[9] = y[2]; m0[13] = 0.0; |
|---|
| 376 |
m0[2] = z[0]; m0[6] = z[1]; m0[10] = z[2]; m0[14] = 0.0; |
|---|
| 377 |
m0[3] = 0.0; m0[7] = 0.0; m0[11] = 0.0; m0[15] = 1.0; |
|---|
| 378 |
m1.translate(-eye); |
|---|
| 379 |
*this = m0 * m1; |
|---|
| 380 |
} |
|---|
| 381 |
void look_at(const float *eye,const float *dir,const float *up) { |
|---|
| 382 |
lock_at(vec3(eye),vec3(dir),vec3(up)); |
|---|
| 383 |
} |
|---|
| 384 |
|
|---|
| 385 |
float mat[16]; |
|---|
| 386 |
}; |
|---|
| 387 |
|
|---|
| 388 |
struct quat { |
|---|
| 389 |
|
|---|
| 390 |
quat() : x(0), y(0), z(0), w(1) { } |
|---|
| 391 |
quat(const vec3 &dir,const float angle) { |
|---|
| 392 |
set(dir,angle); |
|---|
| 393 |
} |
|---|
| 394 |
|
|---|
| 395 |
float &operator[](int i) { |
|---|
| 396 |
return ((float*)&x)[i]; |
|---|
| 397 |
} |
|---|
| 398 |
const float operator[](int i) const { |
|---|
| 399 |
return ((float*)&x)[i]; |
|---|
| 400 |
} |
|---|
| 401 |
|
|---|
| 402 |
quat operator*(const quat &q) { |
|---|
| 403 |
quat ret; |
|---|
| 404 |
ret.x = w * q.x + x * q.x + y * q.z - z * q.y; |
|---|
| 405 |
ret.y = w * q.y + y * q.w + z * q.x - x * q.z; |
|---|
| 406 |
ret.z = w * q.z + z * q.w + x * q.y - y * q.x; |
|---|
| 407 |
ret.w = w * q.w - x * q.x - y * q.y - z * q.z; |
|---|
| 408 |
return ret; |
|---|
| 409 |
} |
|---|
| 410 |
|
|---|
| 411 |
void set(const vec3 &dir,const float angle) { |
|---|
| 412 |
float length = dir.length(); |
|---|
| 413 |
if(length != 0.0) { |
|---|
| 414 |
length = 1.0f / length; |
|---|
| 415 |
float sinangle = (float)sin(angle * DEG2RAD / 2.0f); |
|---|
| 416 |
x = dir[0] * length * sinangle; |
|---|
| 417 |
y = dir[1] * length * sinangle; |
|---|
| 418 |
z = dir[2] * length * sinangle; |
|---|
| 419 |
w = (float)cos(angle * DEG2RAD / 2.0); |
|---|
| 420 |
} else { |
|---|
| 421 |
x = y = z = 0.0; |
|---|
| 422 |
w = 1.0; |
|---|
| 423 |
} |
|---|
| 424 |
} |
|---|
| 425 |
void set(const float x,const float y,const float z,const float angle) { |
|---|
| 426 |
set(vec3(x,y,z),angle); |
|---|
| 427 |
} |
|---|
| 428 |
|
|---|
| 429 |
quat slerp(const quat &q0,const quat &q1,const float t) { |
|---|
| 430 |
float k0,k1,cosomega = q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w; |
|---|
| 431 |
quat q,ret; |
|---|
| 432 |
if(cosomega < 0.0) { |
|---|
| 433 |
cosomega = -cosomega; |
|---|
| 434 |
q.x = -q1.x; |
|---|
| 435 |
q.y = -q1.y; |
|---|
| 436 |
q.z = -q1.z; |
|---|
| 437 |
q.w = -q1.w; |
|---|
| 438 |
} else { |
|---|
| 439 |
q.x = q1.x; |
|---|
| 440 |
q.y = q1.y; |
|---|
| 441 |
q.z = q1.z; |
|---|
| 442 |
q.w = q1.w; |
|---|
| 443 |
} |
|---|
| 444 |
if(1.0 - cosomega > 1e-6) { |
|---|
| 445 |
float omega = (float)acos(cosomega); |
|---|
| 446 |
float sinomega = (float)sin(omega); |
|---|
| 447 |
k0 = (float)sin((1.0 - t) * omega) / sinomega; |
|---|
| 448 |
k1 = (float)sin(t * omega) / sinomega; |
|---|
| 449 |
} else { |
|---|
| 450 |
k0 = 1.0f - t; |
|---|
| 451 |
k1 = t; |
|---|
| 452 |
} |
|---|
| 453 |
ret.x = q0.x * k0 + q.x * k1; |
|---|
| 454 |
ret.y = q0.y * k0 + q.y * k1; |
|---|
| 455 |
ret.z = q0.z * k0 + q.z * k1; |
|---|
| 456 |
ret.w = q0.w * k0 + q.w * k1; |
|---|
| 457 |
return ret; |
|---|
| 458 |
} |
|---|
| 459 |
|
|---|
| 460 |
mat4 to_matrix() { |
|---|
| 461 |
mat4 ret; |
|---|
| 462 |
float x2,y2,z2,xx,yy,zz,xy,yz,xz,wx,wy,wz; |
|---|
| 463 |
x2 = x + x; |
|---|
| 464 |
y2 = y + y; |
|---|
| 465 |
z2 = z + z; |
|---|
| 466 |
xx = x * x2; |
|---|
| 467 |
yy = y * y2; |
|---|
| 468 |
zz = z * z2; |
|---|
| 469 |
xy = x * y2; |
|---|
| 470 |
yz = y * z2; |
|---|
| 471 |
xz = z * x2; |
|---|
| 472 |
wx = w * x2; |
|---|
| 473 |
wy = w * y2; |
|---|
| 474 |
wz = w * z2; |
|---|
| 475 |
ret[0] = 1.0f - (yy + zz); ret[4] = xy - wz; ret[8] = xz + wy; ret[12] = 0.0f; |
|---|
| 476 |
ret[1] = xy + wz; ret[5] = 1.0f - (xx + zz); ret[9] = yz - wx; ret[13] = 0.0f; |
|---|
| 477 |
ret[2] = xz - wy; ret[6] = yz + wx; ret[10] = 1.0f - (xx + yy); ret[14] = 0.0f; |
|---|
| 478 |
ret[3] = 0.0f; ret[7] = 0.0f; ret[11] = 0.0f; ret[15] = 1.0f; |
|---|
| 479 |
return ret; |
|---|
| 480 |
} |
|---|
| 481 |
|
|---|
| 482 |
union { |
|---|
| 483 |
struct { |
|---|
| 484 |
float x,y,z,w; |
|---|
| 485 |
}; |
|---|
| 486 |
float q[4]; |
|---|
| 487 |
}; |
|---|
| 488 |
}; |
|---|
| 489 |
|
|---|
| 490 |
#endif /* __MATHLIB_H__ */ |
|---|