mathlib.h
上传用户:qccn516
上传日期:2013-05-02
资源大小:3382k
文件大小:30k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. /* mathlib
  2.  *
  3.  * Copyright (C) 2003-2004, Alexander Zaprjagaev <frustum@frustum.org>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License
  16.  * along with this program; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  */
  19. #ifndef __MATHLIB_H__
  20. #define __MATHLIB_H__
  21. #include <math.h>
  22. #define EPSILON 1e-6f
  23. #define PI 3.14159265358979323846f
  24. #define DEG2RAD (PI / 180.0f)
  25. #define RAD2DEG (180.0f / PI)
  26. struct vec2;
  27. struct vec3;
  28. struct vec4;
  29. struct mat3;
  30. struct mat4;
  31. struct quat;
  32. /*****************************************************************************/
  33. /*                                                                           */
  34. /* vec2                                                                      */
  35. /*                                                                           */
  36. /*****************************************************************************/
  37. struct vec2 {
  38. inline vec2() : x(0), y(0) { }
  39. inline vec2(float x,float y) : x(x), y(y) { }
  40. inline vec2(const float *v) : x(v[0]), y(v[1]) { }
  41. inline vec2(const vec2 &v) : x(v.x), y(v.y) { }
  42. inline int operator==(const vec2 &v) { return (fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON); }
  43. inline int operator!=(const vec2 &v) { return !(*this == v); }
  44. inline const vec2 operator*(float f) const { return vec2(x * f,y * f); }
  45. inline const vec2 operator/(float f) const { return vec2(x / f,y / f); }
  46. inline const vec2 operator+(const vec2 &v) const { return vec2(x + v.x,y + v.y); }
  47. inline const vec2 operator-() const { return vec2(-x,-y); }
  48. inline const vec2 operator-(const vec2 &v) const { return vec2(x - v.x,y - v.y); }
  49. inline vec2 &operator*=(float f) { return *this = *this * f; }
  50. inline vec2 &operator/=(float f) { return *this = *this / f; }
  51. inline vec2 &operator+=(const vec2 &v) { return *this = *this + v; }
  52. inline vec2 &operator-=(const vec2 &v) { return *this = *this - v; }
  53. inline float operator*(const vec2 &v) const { return x * v.x + y * v.y; }
  54. inline operator float*() { return (float*)&x; }
  55. inline operator const float*() const { return (float*)&x; }
  56. inline float &operator[](int i) { return ((float*)&x)[i]; }
  57. inline const float operator[](int i) const { return ((float*)&x)[i]; }
  58. inline float length() const { return sqrt(x * x + y * y); }
  59. inline float normalize() {
  60. float inv,length = sqrt(x * x + y * y);
  61. if(length < EPSILON) return 0.0;
  62. inv = 1.0f / length;
  63. x *= inv;
  64. y *= inv;
  65. return length;
  66. }
  67. union {
  68. struct {
  69. float x,y;
  70. };
  71. float v[2];
  72. };
  73. };
  74. /*****************************************************************************/
  75. /*                                                                           */
  76. /* vec3                                                                      */
  77. /*                                                                           */
  78. /*****************************************************************************/
  79. struct vec3 {
  80. inline vec3() : x(0), y(0), z(0) { }
  81. inline vec3(float x,float y,float z) : x(x), y(y), z(z) { }
  82. inline vec3(const float *v) : x(v[0]), y(v[1]), z(v[2]) { }
  83. inline vec3(const vec3 &v) : x(v.x), y(v.y), z(v.z) { }
  84. inline vec3(const vec4 &v);
  85. inline int operator==(const vec3 &v) { return (fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON && fabs(z - v.z) < EPSILON); }
  86. inline int operator!=(const vec3 &v) { return !(*this == v); }
  87. inline const vec3 operator*(float f) const { return vec3(x * f,y * f,z * f); }
  88. inline const vec3 operator/(float f) const { return vec3(x / f,y / f,z / f); }
  89. inline const vec3 operator+(const vec3 &v) const { return vec3(x + v.x,y + v.y,z + v.z); }
  90. inline const vec3 operator-() const { return vec3(-x,-y,-z); }
  91. inline const vec3 operator-(const vec3 &v) const { return vec3(x - v.x,y - v.y,z - v.z); }
  92. inline vec3 &operator*=(float f) { return *this = *this * f; }
  93. inline vec3 &operator/=(float f) { return *this = *this / f; }
  94. inline vec3 &operator+=(const vec3 &v) { return *this = *this + v; }
  95. inline vec3 &operator-=(const vec3 &v) { return *this = *this - v; }
  96. inline float operator*(const vec3 &v) const { return x * v.x + y * v.y + z * v.z; }
  97. inline float operator*(const vec4 &v) const;
  98. inline operator float*() { return (float*)&x; }
  99. inline operator const float*() const { return (float*)&x; }
  100. inline float &operator[](int i) { return ((float*)&x)[i]; }
  101. inline const float operator[](int i) const { return ((float*)&x)[i]; }
  102. inline float length() const { return sqrt(x * x + y * y + z * z); }
  103. inline float normalize() {
  104. float inv,length = sqrt(x * x + y * y + z * z);
  105. if(length < EPSILON) return 0.0;
  106. inv = 1.0f / length;
  107. x *= inv;
  108. y *= inv;
  109. z *= inv;
  110. return length;
  111. }
  112. inline void cross(const vec3 &v1,const vec3 &v2) {
  113. x = v1.y * v2.z - v1.z * v2.y;
  114. y = v1.z * v2.x - v1.x * v2.z;
  115. z = v1.x * v2.y - v1.y * v2.x;
  116. }
  117. union {
  118. struct {
  119. float x,y,z;
  120. };
  121. float v[3];
  122. };
  123. };
  124. inline vec3 cross(const vec3 &v1,const vec3 &v2) {
  125. vec3 ret;
  126. ret.x = v1.y * v2.z - v1.z * v2.y;
  127. ret.y = v1.z * v2.x - v1.x * v2.z;
  128. ret.z = v1.x * v2.y - v1.y * v2.x;
  129. return ret;
  130. }
  131. /*****************************************************************************/
  132. /*                                                                           */
  133. /* vec4                                                                      */
  134. /*                                                                           */
  135. /*****************************************************************************/
  136. struct vec4 {
  137. inline vec4() : x(0), y(0), z(0), w(1) { }
  138. inline vec4(float x,float y,float z,float w) : x(x), y(y), z(z), w(w) { }
  139. inline vec4(const float *v) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) { }
  140. inline vec4(const vec3 &v) : x(v.x), y(v.y), z(v.z), w(1) { }
  141. inline vec4(const vec3 &v,float w) : x(v.x), y(v.y), z(v.z), w(w) { }
  142. inline vec4(const vec4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) { }
  143. inline int operator==(const vec4 &v) { return (fabs(x - v.x) < EPSILON && fabs(y - v.y) < EPSILON && fabs(z - v.z) < EPSILON && fabs(w - v.w) < EPSILON); }
  144. inline int operator!=(const vec4 &v) { return !(*this == v); }
  145. inline const vec4 operator*(float f) const { return vec4(x * f,y * f,z * f,w * f); }
  146. inline const vec4 operator/(float f) const { return vec4(x / f,y / f,z / f,w / f); }
  147. inline const vec4 operator+(const vec4 &v) const { return vec4(x + v.x,y + v.y,z + v.z,w + v.w); }
  148. inline const vec4 operator-() const { return vec4(-x,-y,-z,-w); }
  149. inline const vec4 operator-(const vec4 &v) const { return vec4(x - v.x,y - v.y,z - v.z,z - v.w); }
  150. inline vec4 &operator*=(float f) { return *this = *this * f; }
  151. inline vec4 &operator/=(float f) { return *this = *this / f; }
  152. inline vec4 &operator+=(const vec4 &v) { return *this = *this + v; }
  153. inline vec4 &operator-=(const vec4 &v) { return *this = *this - v; }
  154. inline float operator*(const vec3 &v) const { return x * v.x + y * v.y + z * v.z + w; }
  155. inline float operator*(const vec4 &v) const { return x * v.x + y * v.y + z * v.z + w * v.w; }
  156. inline operator float*() { return (float*)&x; }
  157. inline operator const float*() const { return (float*)&x; }
  158. inline float &operator[](int i) { return ((float*)&x)[i]; }
  159. inline const float operator[](int i) const { return ((float*)&x)[i]; }
  160. union {
  161. struct {
  162. float x,y,z,w;
  163. };
  164. float v[4];
  165. };
  166. };
  167. inline vec3::vec3(const vec4 &v) {
  168. x = v.x;
  169. y = v.y;
  170. z = v.z;
  171. }
  172. inline float vec3::operator*(const vec4 &v) const {
  173. return x * v.x + y * v.y + z * v.z + v.w;
  174. }
  175. /*****************************************************************************/
  176. /*                                                                           */
  177. /* mat3                                                                      */
  178. /*                                                                           */
  179. /*****************************************************************************/
  180. struct mat3 {
  181. mat3() {
  182. mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0;
  183. mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0;
  184. mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0;
  185. }
  186. mat3(const float *m) {
  187. mat[0] = m[0]; mat[3] = m[3]; mat[6] = m[6];
  188. mat[1] = m[1]; mat[4] = m[4]; mat[7] = m[7];
  189. mat[2] = m[2]; mat[5] = m[5]; mat[8] = m[8];
  190. }
  191. mat3(const mat3 &m) {
  192. mat[0] = m[0]; mat[3] = m[3]; mat[6] = m[6];
  193. mat[1] = m[1]; mat[4] = m[4]; mat[7] = m[7];
  194. mat[2] = m[2]; mat[5] = m[5]; mat[8] = m[8];
  195. }
  196. mat3(const mat4 &m);
  197. vec3 operator*(const vec3 &v) const {
  198. vec3 ret;
  199. ret[0] = mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2];
  200. ret[1] = mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2];
  201. ret[2] = mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2];
  202. return ret;
  203. }
  204. vec4 operator*(const vec4 &v) const {
  205. vec4 ret;
  206. ret[0] = mat[0] * v[0] + mat[3] * v[1] + mat[6] * v[2];
  207. ret[1] = mat[1] * v[0] + mat[4] * v[1] + mat[7] * v[2];
  208. ret[2] = mat[2] * v[0] + mat[5] * v[1] + mat[8] * v[2];
  209. ret[3] = v[3];
  210. return ret;
  211. }
  212. mat3 operator*(float f) const {
  213. mat3 ret;
  214. ret[0] = mat[0] * f; ret[3] = mat[3] * f; ret[6] = mat[6] * f;
  215. ret[1] = mat[1] * f; ret[4] = mat[4] * f; ret[7] = mat[7] * f;
  216. ret[2] = mat[2] * f; ret[5] = mat[5] * f; ret[8] = mat[8] * f;
  217. return ret;
  218. }
  219. mat3 operator*(const mat3 &m) const {
  220. mat3 ret;
  221. ret[0] = mat[0] * m[0] + mat[3] * m[1] + mat[6] * m[2];
  222. ret[1] = mat[1] * m[0] + mat[4] * m[1] + mat[7] * m[2];
  223. ret[2] = mat[2] * m[0] + mat[5] * m[1] + mat[8] * m[2];
  224. ret[3] = mat[0] * m[3] + mat[3] * m[4] + mat[6] * m[5];
  225. ret[4] = mat[1] * m[3] + mat[4] * m[4] + mat[7] * m[5];
  226. ret[5] = mat[2] * m[3] + mat[5] * m[4] + mat[8] * m[5];
  227. ret[6] = mat[0] * m[6] + mat[3] * m[7] + mat[6] * m[8];
  228. ret[7] = mat[1] * m[6] + mat[4] * m[7] + mat[7] * m[8];
  229. ret[8] = mat[2] * m[6] + mat[5] * m[7] + mat[8] * m[8];
  230. return ret;
  231. }
  232. mat3 operator+(const mat3 &m) const {
  233. mat3 ret;
  234. ret[0] = mat[0] + m[0]; ret[3] = mat[3] + m[3]; ret[6] = mat[6] + m[6];
  235. ret[1] = mat[1] + m[1]; ret[4] = mat[4] + m[4]; ret[7] = mat[7] + m[7];
  236. ret[2] = mat[2] + m[2]; ret[5] = mat[5] + m[5]; ret[8] = mat[8] + m[8];
  237. return ret;
  238. }
  239. mat3 operator-(const mat3 &m) const {
  240. mat3 ret;
  241. ret[0] = mat[0] - m[0]; ret[3] = mat[3] - m[3]; ret[6] = mat[6] - m[6];
  242. ret[1] = mat[1] - m[1]; ret[4] = mat[4] - m[4]; ret[7] = mat[7] - m[7];
  243. ret[2] = mat[2] - m[2]; ret[5] = mat[5] - m[5]; ret[8] = mat[8] - m[8];
  244. return ret;
  245. }
  246. mat3 &operator*=(float f) { return *this = *this * f; }
  247. mat3 &operator*=(const mat3 &m) { return *this = *this * m; }
  248. mat3 &operator+=(const mat3 &m) { return *this = *this + m; }
  249. mat3 &operator-=(const mat3 &m) { return *this = *this - m; }
  250. operator float*() { return mat; }
  251. operator const float*() const { return mat; }
  252. float &operator[](int i) { return mat[i]; }
  253. const float operator[](int i) const { return mat[i]; }
  254. mat3 transpose() const {
  255. mat3 ret;
  256. ret[0] = mat[0]; ret[3] = mat[1]; ret[6] = mat[2];
  257. ret[1] = mat[3]; ret[4] = mat[4]; ret[7] = mat[5];
  258. ret[2] = mat[6]; ret[5] = mat[7]; ret[8] = mat[8];
  259. return ret;
  260. }
  261. float det() const {
  262. float det;
  263. det = mat[0] * mat[4] * mat[8];
  264. det += mat[3] * mat[7] * mat[2];
  265. det += mat[6] * mat[1] * mat[5];
  266. det -= mat[6] * mat[4] * mat[2];
  267. det -= mat[3] * mat[1] * mat[8];
  268. det -= mat[0] * mat[7] * mat[5];
  269. return det;
  270. }
  271. mat3 inverse() const {
  272. mat3 ret;
  273. float idet = 1.0f / det();
  274. ret[0] =  (mat[4] * mat[8] - mat[7] * mat[5]) * idet;
  275. ret[1] = -(mat[1] * mat[8] - mat[7] * mat[2]) * idet;
  276. ret[2] =  (mat[1] * mat[5] - mat[4] * mat[2]) * idet;
  277. ret[3] = -(mat[3] * mat[8] - mat[6] * mat[5]) * idet;
  278. ret[4] =  (mat[0] * mat[8] - mat[6] * mat[2]) * idet;
  279. ret[5] = -(mat[0] * mat[5] - mat[3] * mat[2]) * idet;
  280. ret[6] =  (mat[3] * mat[7] - mat[6] * mat[4]) * idet;
  281. ret[7] = -(mat[0] * mat[7] - mat[6] * mat[1]) * idet;
  282. ret[8] =  (mat[0] * mat[4] - mat[3] * mat[1]) * idet;
  283. return ret;
  284. }
  285. void zero() {
  286. mat[0] = 0.0; mat[3] = 0.0; mat[6] = 0.0;
  287. mat[1] = 0.0; mat[4] = 0.0; mat[7] = 0.0;
  288. mat[2] = 0.0; mat[5] = 0.0; mat[8] = 0.0;
  289. }
  290. void identity() {
  291. mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0;
  292. mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0;
  293. mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0;
  294. }
  295. void rotate(const vec3 &axis,float angle) {
  296. float rad = angle * DEG2RAD;
  297. float c = cos(rad);
  298. float s = sin(rad);
  299. vec3 v = axis;
  300. v.normalize();
  301. float xx = v.x * v.x;
  302. float yy = v.y * v.y;
  303. float zz = v.z * v.z;
  304. float xy = v.x * v.y;
  305. float yz = v.y * v.z;
  306. float zx = v.z * v.x;
  307. float xs = v.x * s;
  308. float ys = v.y * s;
  309. float zs = v.z * s;
  310. mat[0] = (1.0f - c) * xx + c; mat[3] = (1.0f - c) * xy - zs; mat[6] = (1.0f - c) * zx + ys;
  311. mat[1] = (1.0f - c) * xy + zs; mat[4] = (1.0f - c) * yy + c; mat[7] = (1.0f - c) * yz - xs;
  312. mat[2] = (1.0f - c) * zx - ys; mat[5] = (1.0f - c) * yz + xs; mat[8] = (1.0f - c) * zz + c;
  313. }
  314. void rotate(float x,float y,float z,float angle) {
  315. rotate(vec3(x,y,z),angle);
  316. }
  317. void rotate_x(float angle) {
  318. float rad = angle * DEG2RAD;
  319. float c = cos(rad);
  320. float s = sin(rad);
  321. mat[0] = 1.0; mat[3] = 0.0; mat[6] = 0.0;
  322. mat[1] = 0.0; mat[4] = c; mat[7] = -s;
  323. mat[2] = 0.0; mat[5] = s; mat[8] = c;
  324. }
  325. void rotate_y(float angle) {
  326. float rad = angle * DEG2RAD;
  327. float c = cos(rad);
  328. float s = sin(rad);
  329. mat[0] = c; mat[3] = 0.0; mat[6] = s;
  330. mat[1] = 0.0; mat[4] = 1.0; mat[7] = 0.0;
  331. mat[2] = -s; mat[5] = 0.0; mat[8] = c;
  332. }
  333. void rotate_z(float angle) {
  334. float rad = angle * DEG2RAD;
  335. float c = cos(rad);
  336. float s = sin(rad);
  337. mat[0] = c; mat[3] = -s; mat[6] = 0.0;
  338. mat[1] = s; mat[4] = c; mat[7] = 0.0;
  339. mat[2] = 0.0; mat[5] = 0.0; mat[8] = 1.0;
  340. }
  341. void scale(const vec3 &v) {
  342. mat[0] = v.x; mat[3] = 0.0; mat[6] = 0.0;
  343. mat[1] = 0.0; mat[4] = v.y; mat[7] = 0.0;
  344. mat[2] = 0.0; mat[5] = 0.0; mat[8] = v.z;
  345. }
  346. void scale(float x,float y,float z) {
  347. scale(vec3(x,y,z));
  348. }
  349. void orthonormalize() {
  350. vec3 x(mat[0],mat[1],mat[2]);
  351. vec3 y(mat[3],mat[4],mat[5]);
  352. vec3 z;
  353. x.normalize();
  354. z.cross(x,y);
  355. z.normalize();
  356. y.cross(z,x);
  357. y.normalize();
  358. mat[0] = x.x; mat[3] = y.x; mat[6] = z.x;
  359. mat[1] = x.y; mat[4] = y.y; mat[7] = z.y;
  360. mat[2] = x.z; mat[5] = y.z; mat[8] = z.z;
  361. }
  362. float mat[9];
  363. };
  364. /*****************************************************************************/
  365. /*                                                                           */
  366. /* mat4                                                                      */
  367. /*                                                                           */
  368. /*****************************************************************************/
  369. struct mat4 {
  370. mat4() {
  371. mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;
  372. mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0;
  373. mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0;
  374. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  375. }
  376. mat4(const vec3 &v) {
  377. translate(v);
  378. }
  379. mat4(float x,float y,float z) {
  380. translate(x,y,z);
  381. }
  382. mat4(const vec3 &axis,float angle) {
  383. rotate(axis,angle);
  384. }
  385. mat4(float x,float y,float z,float angle) {
  386. rotate(x,y,z,angle);
  387. }
  388. mat4(const mat3 &m) {
  389. mat[0] = m[0]; mat[4] = m[3]; mat[8] = m[6]; mat[12] = 0.0;
  390. mat[1] = m[1]; mat[5] = m[4]; mat[9] = m[7]; mat[13] = 0.0;
  391. mat[2] = m[2]; mat[6] = m[5]; mat[10] = m[8]; mat[14] = 0.0;
  392. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  393. }
  394. mat4(const float *m) {
  395. mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12];
  396. mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13];
  397. mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14];
  398. mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15];
  399. }
  400. mat4(const mat4 &m) {
  401. mat[0] = m[0]; mat[4] = m[4]; mat[8] = m[8]; mat[12] = m[12];
  402. mat[1] = m[1]; mat[5] = m[5]; mat[9] = m[9]; mat[13] = m[13];
  403. mat[2] = m[2]; mat[6] = m[6]; mat[10] = m[10]; mat[14] = m[14];
  404. mat[3] = m[3]; mat[7] = m[7]; mat[11] = m[11]; mat[15] = m[15];
  405. }
  406. vec3 operator*(const vec3 &v) const {
  407. vec3 ret;
  408. ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12];
  409. ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13];
  410. ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14];
  411. return ret;
  412. }
  413. vec4 operator*(const vec4 &v) const {
  414. vec4 ret;
  415. ret[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * v[3];
  416. ret[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * v[3];
  417. ret[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * v[3];
  418. ret[3] = mat[3] * v[0] + mat[7] * v[1] + mat[11] * v[2] + mat[15] * v[3];
  419. return ret;
  420. }
  421. mat4 operator*(float f) const {
  422. mat4 ret;
  423. ret[0] = mat[0] * f; ret[4] = mat[4] * f; ret[8] = mat[8] * f; ret[12] = mat[12] * f;
  424. ret[1] = mat[1] * f; ret[5] = mat[5] * f; ret[9] = mat[9] * f; ret[13] = mat[13] * f;
  425. ret[2] = mat[2] * f; ret[6] = mat[6] * f; ret[10] = mat[10] * f; ret[14] = mat[14] * f;
  426. ret[3] = mat[3] * f; ret[7] = mat[7] * f; ret[11] = mat[11] * f; ret[15] = mat[15] * f;
  427. return ret;
  428. }
  429. mat4 operator*(const mat4 &m) const {
  430. mat4 ret;
  431. ret[0] = mat[0] * m[0] + mat[4] * m[1] + mat[8] * m[2] + mat[12] * m[3];
  432. ret[1] = mat[1] * m[0] + mat[5] * m[1] + mat[9] * m[2] + mat[13] * m[3];
  433. ret[2] = mat[2] * m[0] + mat[6] * m[1] + mat[10] * m[2] + mat[14] * m[3];
  434. ret[3] = mat[3] * m[0] + mat[7] * m[1] + mat[11] * m[2] + mat[15] * m[3];
  435. ret[4] = mat[0] * m[4] + mat[4] * m[5] + mat[8] * m[6] + mat[12] * m[7];
  436. ret[5] = mat[1] * m[4] + mat[5] * m[5] + mat[9] * m[6] + mat[13] * m[7];
  437. ret[6] = mat[2] * m[4] + mat[6] * m[5] + mat[10] * m[6] + mat[14] * m[7];
  438. ret[7] = mat[3] * m[4] + mat[7] * m[5] + mat[11] * m[6] + mat[15] * m[7];
  439. ret[8] = mat[0] * m[8] + mat[4] * m[9] + mat[8] * m[10] + mat[12] * m[11];
  440. ret[9] = mat[1] * m[8] + mat[5] * m[9] + mat[9] * m[10] + mat[13] * m[11];
  441. ret[10] = mat[2] * m[8] + mat[6] * m[9] + mat[10] * m[10] + mat[14] * m[11];
  442. ret[11] = mat[3] * m[8] + mat[7] * m[9] + mat[11] * m[10] + mat[15] * m[11];
  443. ret[12] = mat[0] * m[12] + mat[4] * m[13] + mat[8] * m[14] + mat[12] * m[15];
  444. ret[13] = mat[1] * m[12] + mat[5] * m[13] + mat[9] * m[14] + mat[13] * m[15];
  445. ret[14] = mat[2] * m[12] + mat[6] * m[13] + mat[10] * m[14] + mat[14] * m[15];
  446. ret[15] = mat[3] * m[12] + mat[7] * m[13] + mat[11] * m[14] + mat[15] * m[15];
  447. return ret;
  448. }
  449. mat4 operator+(const mat4 &m) const {
  450. mat4 ret;
  451. ret[0] = mat[0] + m[0]; ret[4] = mat[4] + m[4]; ret[8] = mat[8] + m[8]; ret[12] = mat[12] + m[12];
  452. ret[1] = mat[1] + m[1]; ret[5] = mat[5] + m[5]; ret[9] = mat[9] + m[9]; ret[13] = mat[13] + m[13];
  453. ret[2] = mat[2] + m[2]; ret[6] = mat[6] + m[6]; ret[10] = mat[10] + m[10]; ret[14] = mat[14] + m[14];
  454. ret[3] = mat[3] + m[3]; ret[7] = mat[7] + m[7]; ret[11] = mat[11] + m[11]; ret[15] = mat[15] + m[15];
  455. return ret;
  456. }
  457. mat4 operator-(const mat4 &m) const {
  458. mat4 ret;
  459. ret[0] = mat[0] - m[0]; ret[4] = mat[4] - m[4]; ret[8] = mat[8] - m[8]; ret[12] = mat[12] - m[12];
  460. ret[1] = mat[1] - m[1]; ret[5] = mat[5] - m[5]; ret[9] = mat[9] - m[9]; ret[13] = mat[13] - m[13];
  461. ret[2] = mat[2] - m[2]; ret[6] = mat[6] - m[6]; ret[10] = mat[10] - m[10]; ret[14] = mat[14] - m[14];
  462. ret[3] = mat[3] - m[3]; ret[7] = mat[7] - m[7]; ret[11] = mat[11] - m[11]; ret[15] = mat[15] - m[15];
  463. return ret;
  464. }
  465. mat4 &operator*=(float f) { return *this = *this * f; }
  466. mat4 &operator*=(const mat4 &m) { return *this = *this * m; }
  467. mat4 &operator+=(const mat4 &m) { return *this = *this + m; }
  468. mat4 &operator-=(const mat4 &m) { return *this = *this - m; }
  469. operator float*() { return mat; }
  470. operator const float*() const { return mat; }
  471. float &operator[](int i) { return mat[i]; }
  472. const float operator[](int i) const { return mat[i]; }
  473. mat4 rotation() const {
  474. mat4 ret;
  475. ret[0] = mat[0]; ret[4] = mat[4]; ret[8] = mat[8]; ret[12] = 0;
  476. ret[1] = mat[1]; ret[5] = mat[5]; ret[9] = mat[9]; ret[13] = 0;
  477. ret[2] = mat[2]; ret[6] = mat[6]; ret[10] = mat[10]; ret[14] = 0;
  478. ret[3] = 0; ret[7] = 0; ret[11] = 0; ret[15] = 1;
  479. return ret;
  480. }
  481. mat4 transpose() const {
  482. mat4 ret;
  483. ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[3];
  484. ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[7];
  485. ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[11];
  486. ret[3] = mat[12]; ret[7] = mat[13]; ret[11] = mat[14]; ret[15] = mat[15];
  487. return ret;
  488. }
  489. mat4 transpose_rotation() const {
  490. mat4 ret;
  491. ret[0] = mat[0]; ret[4] = mat[1]; ret[8] = mat[2]; ret[12] = mat[12];
  492. ret[1] = mat[4]; ret[5] = mat[5]; ret[9] = mat[6]; ret[13] = mat[13];
  493. ret[2] = mat[8]; ret[6] = mat[9]; ret[10] = mat[10]; ret[14] = mat[14];
  494. ret[3] = mat[3]; ret[7] = mat[7]; ret[14] = mat[14]; ret[15] = mat[15];
  495. return ret;
  496. }
  497. float det() const {
  498. float det;
  499. det = mat[0] * mat[5] * mat[10];
  500. det += mat[4] * mat[9] * mat[2];
  501. det += mat[8] * mat[1] * mat[6];
  502. det -= mat[8] * mat[5] * mat[2];
  503. det -= mat[4] * mat[1] * mat[10];
  504. det -= mat[0] * mat[9] * mat[6];
  505. return det;
  506. }
  507. mat4 inverse() const {
  508. mat4 ret;
  509. float idet = 1.0f / det();
  510. ret[0] =  (mat[5] * mat[10] - mat[9] * mat[6]) * idet;
  511. ret[1] = -(mat[1] * mat[10] - mat[9] * mat[2]) * idet;
  512. ret[2] =  (mat[1] * mat[6] - mat[5] * mat[2]) * idet;
  513. ret[3] = 0.0;
  514. ret[4] = -(mat[4] * mat[10] - mat[8] * mat[6]) * idet;
  515. ret[5] =  (mat[0] * mat[10] - mat[8] * mat[2]) * idet;
  516. ret[6] = -(mat[0] * mat[6] - mat[4] * mat[2]) * idet;
  517. ret[7] = 0.0;
  518. ret[8] =  (mat[4] * mat[9] - mat[8] * mat[5]) * idet;
  519. ret[9] = -(mat[0] * mat[9] - mat[8] * mat[1]) * idet;
  520. ret[10] =  (mat[0] * mat[5] - mat[4] * mat[1]) * idet;
  521. ret[11] = 0.0;
  522. ret[12] = -(mat[12] * ret[0] + mat[13] * ret[4] + mat[14] * ret[8]);
  523. ret[13] = -(mat[12] * ret[1] + mat[13] * ret[5] + mat[14] * ret[9]);
  524. ret[14] = -(mat[12] * ret[2] + mat[13] * ret[6] + mat[14] * ret[10]);
  525. ret[15] = 1.0;
  526. return ret;
  527. }
  528. void zero() {
  529. mat[0] = 0.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;
  530. mat[1] = 0.0; mat[5] = 0.0; mat[9] = 0.0; mat[13] = 0.0;
  531. mat[2] = 0.0; mat[6] = 0.0; mat[10] = 0.0; mat[14] = 0.0;
  532. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 0.0;
  533. }
  534. void identity() {
  535. mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;
  536. mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0;
  537. mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0;
  538. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  539. }
  540. void rotate(const vec3 &axis,float angle) {
  541. float rad = angle * DEG2RAD;
  542. float c = cos(rad);
  543. float s = sin(rad);
  544. vec3 v = axis;
  545. v.normalize();
  546. float xx = v.x * v.x;
  547. float yy = v.y * v.y;
  548. float zz = v.z * v.z;
  549. float xy = v.x * v.y;
  550. float yz = v.y * v.z;
  551. float zx = v.z * v.x;
  552. float xs = v.x * s;
  553. float ys = v.y * s;
  554. float zs = v.z * s;
  555. mat[0] = (1.0f - c) * xx + c; mat[4] = (1.0f - c) * xy - zs; mat[8] = (1.0f - c) * zx + ys; mat[12] = 0.0;
  556. mat[1] = (1.0f - c) * xy + zs; mat[5] = (1.0f - c) * yy + c; mat[9] = (1.0f - c) * yz - xs; mat[13] = 0.0;
  557. mat[2] = (1.0f - c) * zx - ys; mat[6] = (1.0f - c) * yz + xs; mat[10] = (1.0f - c) * zz + c; mat[14] = 0.0;
  558. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  559. }
  560. void rotate(float x,float y,float z,float angle) {
  561. rotate(vec3(x,y,z),angle);
  562. }
  563. void rotate_x(float angle) {
  564. float rad = angle * DEG2RAD;
  565. float c = cos(rad);
  566. float s = sin(rad);
  567. mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;
  568. mat[1] = 0.0; mat[5] = c; mat[9] = -s; mat[13] = 0.0;
  569. mat[2] = 0.0; mat[6] = s; mat[10] = c; mat[14] = 0.0;
  570. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  571. }
  572. void rotate_y(float angle) {
  573. float rad = angle * DEG2RAD;
  574. float c = cos(rad);
  575. float s = sin(rad);
  576. mat[0] = c; mat[4] = 0.0; mat[8] = s; mat[12] = 0.0;
  577. mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = 0.0;
  578. mat[2] = -s; mat[6] = 0.0; mat[10] = c; mat[14] = 0.0;
  579. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  580. }
  581. void rotate_z(float angle) {
  582. float rad = angle * DEG2RAD;
  583. float c = cos(rad);
  584. float s = sin(rad);
  585. mat[0] = c; mat[4] = -s; mat[8] = 0.0; mat[12] = 0.0;
  586. mat[1] = s; mat[5] = c; mat[9] = 0.0; mat[13] = 0.0;
  587. mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = 0.0;
  588. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  589. }
  590. void scale(const vec3 &v) {
  591. mat[0] = v.x; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;
  592. mat[1] = 0.0; mat[5] = v.y; mat[9] = 0.0; mat[13] = 0.0;
  593. mat[2] = 0.0; mat[6] = 0.0; mat[10] = v.z; mat[14] = 0.0;
  594. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  595. }
  596. void scale(float x,float y,float z) {
  597. scale(vec3(x,y,z));
  598. }
  599. void translate(const vec3 &v) {
  600. mat[0] = 1.0; mat[4] = 0.0; mat[8] = 0.0; mat[12] = v.x;
  601. mat[1] = 0.0; mat[5] = 1.0; mat[9] = 0.0; mat[13] = v.y;
  602. mat[2] = 0.0; mat[6] = 0.0; mat[10] = 1.0; mat[14] = v.z;
  603. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  604. }
  605. void translate(float x,float y,float z) {
  606. translate(vec3(x,y,z));
  607. }
  608. void reflect(const vec4 &plane) {
  609. float x = plane.x;
  610. float y = plane.y;
  611. float z = plane.z;
  612. float x2 = x * 2.0f;
  613. float y2 = y * 2.0f;
  614. float z2 = z * 2.0f;
  615. mat[0] = 1.0f - x * x2; mat[4] = -y * x2; mat[8] = -z * x2; mat[12] = -plane.w * x2;
  616. mat[1] = -x * y2; mat[5] = 1.0f - y * y2; mat[9] = -z * y2; mat[13] = -plane.w * y2;
  617. mat[2] = -x * z2; mat[6] = -y * z2; mat[10] = 1.0f - z * z2; mat[14] = -plane.w * z2;
  618. mat[3] = 0.0; mat[7] = 0.0; mat[11] = 0.0; mat[15] = 1.0;
  619. }
  620. void reflect(float x,float y,float z,float w) {
  621. reflect(vec4(x,y,z,w));
  622. }
  623. void perspective(float fov,float aspect,float znear,float zfar) {
  624. float y = tan(fov * PI / 360.0f);
  625. float x = y * aspect;
  626. mat[0] = 1.0f / x; mat[4] = 0.0; mat[8] = 0.0; mat[12] = 0.0;
  627. mat[1] = 0.0; mat[5] = 1.0f / y; mat[9] = 0.0; mat[13] = 0.0;
  628. mat[2] = 0.0; mat[6] = 0.0; mat[10] = -(zfar + znear) / (zfar - znear); mat[14] = -(2.0f * zfar * znear) / (zfar - znear);
  629. mat[3] = 0.0; mat[7] = 0.0; mat[11] = -1.0; mat[15] = 0.0;
  630. }
  631. void look_at(const vec3 &eye,const vec3 &dir,const vec3 &up) {
  632. vec3 x,y,z;
  633. mat4 m0,m1;
  634. z = eye - dir;
  635. z.normalize();
  636. x.cross(up,z);
  637. x.normalize();
  638. y.cross(z,x);
  639. y.normalize();
  640. m0[0] = x.x; m0[4] = x.y; m0[8] = x.z; m0[12] = 0.0;
  641. m0[1] = y.x; m0[5] = y.y; m0[9] = y.z; m0[13] = 0.0;
  642. m0[2] = z.x; m0[6] = z.y; m0[10] = z.z; m0[14] = 0.0;
  643. m0[3] = 0.0; m0[7] = 0.0; m0[11] = 0.0; m0[15] = 1.0;
  644. m1.translate(-eye);
  645. *this = m0 * m1;
  646. }
  647. void look_at(const float *eye,const float *dir,const float *up) {
  648. look_at(vec3(eye),vec3(dir),vec3(up));
  649. }
  650. float mat[16];
  651. };
  652. inline mat3::mat3(const mat4 &m) {
  653. mat[0] = m[0]; mat[3] = m[4]; mat[6] = m[8];
  654. mat[1] = m[1]; mat[4] = m[5]; mat[7] = m[9];
  655. mat[2] = m[2]; mat[5] = m[6]; mat[8] = m[10];
  656. }
  657. /*****************************************************************************/
  658. /*                                                                           */
  659. /* quat                                                                      */
  660. /*                                                                           */
  661. /*****************************************************************************/
  662. struct quat {
  663. quat() : x(0), y(0), z(0), w(1) { }
  664. quat(const vec3 &dir,float angle) {
  665. set(dir,angle);
  666. }
  667. quat(float x,float y,float z,float angle) {
  668. set(x,y,z,angle);
  669. }
  670. quat(const mat3 &m) {
  671. float trace = m[0] + m[4] + m[8];
  672. if(trace > 0.0) {
  673. float s = sqrt(trace + 1.0f);
  674. q[3] = 0.5f * s;
  675. s = 0.5f / s;
  676. q[0] = (m[5] - m[7]) * s;
  677. q[1] = (m[6] - m[2]) * s;
  678. q[2] = (m[1] - m[3]) * s;
  679. } else {
  680. static int next[3] = { 1, 2, 0 };
  681. int i = 0;
  682. if(m[4] > m[0]) i = 1;
  683. if(m[8] > m[3 * i + i]) i = 2;
  684. int j = next[i];
  685. int k = next[j];
  686. float s = sqrt(m[3 * i + i] - m[3 * j + j] - m[3 * k + k] + 1.0f);
  687. q[i] = 0.5f * s;
  688. if(s != 0) s = 0.5f / s;
  689. q[3] = (m[3 * j + k] - m[3 * k + j]) * s;
  690. q[j] = (m[3 * i + j] + m[3 * j + i]) * s;
  691. q[k] = (m[3 * i + k] + m[3 * k + i]) * s;
  692. }
  693. }
  694. operator float*() { return (float*)&x; }
  695. operator const float*() const { return (float*)&x; }
  696. float &operator[](int i) { return ((float*)&x)[i]; }
  697. const float operator[](int i) const { return ((float*)&x)[i]; }
  698. quat operator*(const quat &q) const {
  699. quat ret;
  700. ret.x = w * q.x + x * q.x + y * q.z - z * q.y;
  701. ret.y = w * q.y + y * q.w + z * q.x - x * q.z;
  702. ret.z = w * q.z + z * q.w + x * q.y - y * q.x;
  703. ret.w = w * q.w - x * q.x - y * q.y - z * q.z;
  704. return ret;
  705. }
  706. void set(const vec3 &dir,float angle) {
  707. float length = dir.length();
  708. if(length != 0.0) {
  709. length = 1.0f / length;
  710. float sinangle = sin(angle * DEG2RAD / 2.0f);
  711. x = dir[0] * length * sinangle;
  712. y = dir[1] * length * sinangle;
  713. z = dir[2] * length * sinangle;
  714. w = cos(angle * DEG2RAD / 2.0f);
  715. } else {
  716. x = y = z = 0.0;
  717. w = 1.0;
  718. }
  719. }
  720. void set(float x,float y,float z,float angle) {
  721. set(vec3(x,y,z),angle);
  722. }
  723. void slerp(const quat &q0,const quat &q1,float t) {
  724. float k0,k1,cosomega = q0.x * q1.x + q0.y * q1.y + q0.z * q1.z + q0.w * q1.w;
  725. quat q;
  726. if(cosomega < 0.0) {
  727. cosomega = -cosomega;
  728. q.x = -q1.x;
  729. q.y = -q1.y;
  730. q.z = -q1.z;
  731. q.w = -q1.w;
  732. } else {
  733. q.x = q1.x;
  734. q.y = q1.y;
  735. q.z = q1.z;
  736. q.w = q1.w;
  737. }
  738. if(1.0 - cosomega > 1e-6) {
  739. float omega = acos(cosomega);
  740. float sinomega = sin(omega);
  741. k0 = sin((1.0f - t) * omega) / sinomega;
  742. k1 = sin(t * omega) / sinomega;
  743. } else {
  744. k0 = 1.0f - t;
  745. k1 = t;
  746. }
  747. x = q0.x * k0 + q.x * k1;
  748. y = q0.y * k0 + q.y * k1;
  749. z = q0.z * k0 + q.z * k1;
  750. w = q0.w * k0 + q.w * k1;
  751. }
  752. mat3 to_matrix() const {
  753. mat3 ret;
  754. float x2 = x + x;
  755. float y2 = y + y;
  756. float z2 = z + z;
  757. float xx = x * x2;
  758. float yy = y * y2;
  759. float zz = z * z2;
  760. float xy = x * y2;
  761. float yz = y * z2;
  762. float xz = z * x2;
  763. float wx = w * x2;
  764. float wy = w * y2;
  765. float wz = w * z2;
  766. ret[0] = 1.0f - (yy + zz); ret[3] = xy - wz; ret[6] = xz + wy;
  767. ret[1] = xy + wz; ret[4] = 1.0f - (xx + zz); ret[7] = yz - wx;
  768. ret[2] = xz - wy; ret[5] = yz + wx; ret[8] = 1.0f - (xx + yy);
  769. return ret;
  770. }
  771. union {
  772. struct {
  773. float x,y,z,w;
  774. };
  775. float q[4];
  776. };
  777. };
  778. #endif /* __MATHLIB_H__ */