Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

331 строка
8.4 KiB

  1. //
  2. // Lol Engine
  3. //
  4. // Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #if defined WIN32 && !defined _XBOX
  14. # define _USE_MATH_DEFINES /* for M_PI */
  15. # define WIN32_LEAN_AND_MEAN
  16. # include <windows.h>
  17. # undef near /* Fuck Microsoft */
  18. # undef far /* Fuck Microsoft again */
  19. #endif
  20. #include <cmath> /* for M_PI */
  21. #include <cstdlib> /* free() */
  22. #include <cstring> /* strdup() */
  23. #include "core.h"
  24. using namespace std;
  25. namespace lol
  26. {
  27. template<> float dot(vec2 v1, vec2 v2)
  28. {
  29. return v1.x * v2.x + v1.y * v2.y;
  30. }
  31. template<> float dot(vec3 v1, vec3 v2)
  32. {
  33. return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
  34. }
  35. template<> float dot(vec4 v1, vec4 v2)
  36. {
  37. return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z + v1.w * v2.w;
  38. }
  39. template<> vec3 cross(vec3 v1, vec3 v2)
  40. {
  41. return vec3(v1.y * v2.z - v1.z * v2.y,
  42. v1.z * v2.x - v1.x * v2.z,
  43. v1.x * v2.y - v1.y * v2.x);
  44. }
  45. static inline float det3(float a, float b, float c,
  46. float d, float e, float f,
  47. float g, float h, float i)
  48. {
  49. return a * (e * i - h * f)
  50. + b * (f * g - i * d)
  51. + c * (d * h - g * e);
  52. }
  53. static inline float cofact3(mat4 const &mat, int i, int j)
  54. {
  55. return det3(mat[(i + 1) & 3][(j + 1) & 3],
  56. mat[(i + 2) & 3][(j + 1) & 3],
  57. mat[(i + 3) & 3][(j + 1) & 3],
  58. mat[(i + 1) & 3][(j + 2) & 3],
  59. mat[(i + 2) & 3][(j + 2) & 3],
  60. mat[(i + 3) & 3][(j + 2) & 3],
  61. mat[(i + 1) & 3][(j + 3) & 3],
  62. mat[(i + 2) & 3][(j + 3) & 3],
  63. mat[(i + 3) & 3][(j + 3) & 3]) * (((i + j) & 1) ? -1.0f : 1.0f);
  64. }
  65. template<> float mat4::det() const
  66. {
  67. float ret = 0;
  68. for (int n = 0; n < 4; n++)
  69. ret += (*this)[n][0] * cofact3(*this, n, 0);
  70. return ret;
  71. }
  72. template<> mat4 mat4::invert() const
  73. {
  74. mat4 ret;
  75. float d = det();
  76. if (d)
  77. {
  78. d = 1.0f / d;
  79. for (int j = 0; j < 4; j++)
  80. for (int i = 0; i < 4; i++)
  81. ret[j][i] = cofact3(*this, i, j) * d;
  82. }
  83. return ret;
  84. }
  85. template<> void vec2::printf() const
  86. {
  87. Log::Debug("[ %6.6f %6.6f ]\n", x, y);
  88. }
  89. template<> void ivec2::printf() const
  90. {
  91. Log::Debug("[ %i %i ]\n", x, y);
  92. }
  93. template<> void vec3::printf() const
  94. {
  95. Log::Debug("[ %6.6f %6.6f %6.6f ]\n", x, y, z);
  96. }
  97. template<> void ivec3::printf() const
  98. {
  99. Log::Debug("[ %i %i %i ]\n", x, y, z);
  100. }
  101. template<> void vec4::printf() const
  102. {
  103. Log::Debug("[ %6.6f %6.6f %6.6f %6.6f ]\n", x, y, z, w);
  104. }
  105. template<> void ivec4::printf() const
  106. {
  107. Log::Debug("[ %i %i %i %i ]\n", x, y, z, w);
  108. }
  109. template<> void quat::printf() const
  110. {
  111. Log::Debug("[ %6.6f %6.6f %6.6f %6.6f ]\n", x, y, z, w);
  112. }
  113. template<> void mat4::printf() const
  114. {
  115. mat4 const &p = *this;
  116. Log::Debug("[ %6.6f %6.6f %6.6f %6.6f\n",
  117. p[0][0], p[1][0], p[2][0], p[3][0]);
  118. Log::Debug(" %6.6f %6.6f %6.6f %6.6f\n",
  119. p[0][1], p[1][1], p[2][1], p[3][1]);
  120. Log::Debug(" %6.6f %6.6f %6.6f %6.6f\n",
  121. p[0][2], p[1][2], p[2][2], p[3][2]);
  122. Log::Debug(" %6.6f %6.6f %6.6f %6.6f ]\n",
  123. p[0][3], p[1][3], p[2][3], p[3][3]);
  124. }
  125. #if !defined __ANDROID__
  126. template<> std::ostream &operator<<(std::ostream &stream, ivec2 const &v)
  127. {
  128. return stream << "(" << v.x << ", " << v.y << ")";
  129. }
  130. template<> std::ostream &operator<<(std::ostream &stream, ivec3 const &v)
  131. {
  132. return stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
  133. }
  134. template<> std::ostream &operator<<(std::ostream &stream, ivec4 const &v)
  135. {
  136. return stream << "(" << v.x << ", " << v.y << ", "
  137. << v.z << ", " << v.w << ")";
  138. }
  139. template<> std::ostream &operator<<(std::ostream &stream, iquat const &v)
  140. {
  141. return stream << "(" << v.x << ", " << v.y << ", "
  142. << v.z << ", " << v.w << ")";
  143. }
  144. template<> std::ostream &operator<<(std::ostream &stream, vec2 const &v)
  145. {
  146. return stream << "(" << v.x << ", " << v.y << ")";
  147. }
  148. template<> std::ostream &operator<<(std::ostream &stream, vec3 const &v)
  149. {
  150. return stream << "(" << v.x << ", " << v.y << ", " << v.z << ")";
  151. }
  152. template<> std::ostream &operator<<(std::ostream &stream, vec4 const &v)
  153. {
  154. return stream << "(" << v.x << ", " << v.y << ", "
  155. << v.z << ", " << v.w << ")";
  156. }
  157. template<> std::ostream &operator<<(std::ostream &stream, quat const &v)
  158. {
  159. return stream << "(" << v.x << ", " << v.y << ", "
  160. << v.z << ", " << v.w << ")";
  161. }
  162. template<> std::ostream &operator<<(std::ostream &stream, mat4 const &m)
  163. {
  164. stream << "((" << m[0][0] << ", " << m[1][0]
  165. << ", " << m[2][0] << ", " << m[3][0] << "), ";
  166. stream << "(" << m[0][1] << ", " << m[1][1]
  167. << ", " << m[2][1] << ", " << m[3][1] << "), ";
  168. stream << "(" << m[0][2] << ", " << m[1][2]
  169. << ", " << m[2][2] << ", " << m[3][2] << "), ";
  170. stream << "(" << m[0][3] << ", " << m[1][3]
  171. << ", " << m[2][3] << ", " << m[3][3] << "))";
  172. return stream;
  173. }
  174. #endif
  175. template<> mat4 mat4::translate(float x, float y, float z)
  176. {
  177. mat4 ret(1.0f);
  178. ret[3][0] = x;
  179. ret[3][1] = y;
  180. ret[3][2] = z;
  181. return ret;
  182. }
  183. template<> mat4 mat4::translate(vec3 v)
  184. {
  185. return translate(v.x, v.y, v.z);
  186. }
  187. template<> mat4 mat4::rotate(float angle, float x, float y, float z)
  188. {
  189. angle *= (M_PI / 180.0f);
  190. float st = sinf(angle);
  191. float ct = cosf(angle);
  192. float len = sqrtf(x * x + y * y + z * z);
  193. float invlen = len ? 1.0f / len : 0.0f;
  194. x *= invlen;
  195. y *= invlen;
  196. z *= invlen;
  197. float mtx = (1.0f - ct) * x;
  198. float mty = (1.0f - ct) * y;
  199. float mtz = (1.0f - ct) * z;
  200. mat4 ret(1.0f);
  201. ret[0][0] = x * mtx + ct;
  202. ret[0][1] = x * mty + st * z;
  203. ret[0][2] = x * mtz - st * y;
  204. ret[1][0] = y * mtx - st * z;
  205. ret[1][1] = y * mty + ct;
  206. ret[1][2] = y * mtz + st * x;
  207. ret[2][0] = z * mtx + st * y;
  208. ret[2][1] = z * mty - st * x;
  209. ret[2][2] = z * mtz + ct;
  210. return ret;
  211. }
  212. template<> mat4 mat4::rotate(float angle, vec3 v)
  213. {
  214. return rotate(angle, v.x, v.y, v.z);
  215. }
  216. template<> mat4 mat4::lookat(vec3 eye, vec3 center, vec3 up)
  217. {
  218. vec3 v3 = normalize(eye - center);
  219. vec3 v2 = normalize(up);
  220. vec3 v1 = normalize(cross(v2, v3));
  221. v2 = cross(v3, v1);
  222. mat4 orient(1.0f);
  223. orient[0][0] = v1.x;
  224. orient[0][1] = v2.x;
  225. orient[0][2] = v3.x;
  226. orient[1][0] = v1.y;
  227. orient[1][1] = v2.y;
  228. orient[1][2] = v3.y;
  229. orient[2][0] = v1.z;
  230. orient[2][1] = v2.z;
  231. orient[2][2] = v3.z;
  232. return orient * mat4::translate(-eye);
  233. }
  234. template<> mat4 mat4::ortho(float left, float right, float bottom,
  235. float top, float near, float far)
  236. {
  237. float invrl = (right != left) ? 1.0f / (right - left) : 0.0f;
  238. float invtb = (top != bottom) ? 1.0f / (top - bottom) : 0.0f;
  239. float invfn = (far != near) ? 1.0f / (far - near) : 0.0f;
  240. mat4 ret(0.0f);
  241. ret[0][0] = 2.0f * invrl;
  242. ret[1][1] = 2.0f * invtb;
  243. ret[2][2] = -2.0f * invfn;
  244. ret[3][0] = - (right + left) * invrl;
  245. ret[3][1] = - (top + bottom) * invtb;
  246. ret[3][2] = - (far + near) * invfn;
  247. ret[3][3] = 1.0f;
  248. return ret;
  249. }
  250. template<> mat4 mat4::frustum(float left, float right, float bottom,
  251. float top, float near, float far)
  252. {
  253. float invrl = (right != left) ? 1.0f / (right - left) : 0.0f;
  254. float invtb = (top != bottom) ? 1.0f / (top - bottom) : 0.0f;
  255. float invfn = (far != near) ? 1.0f / (far - near) : 0.0f;
  256. mat4 ret(0.0f);
  257. ret[0][0] = 2.0f * near * invrl;
  258. ret[1][1] = 2.0f * near * invtb;
  259. ret[2][0] = (right + left) * invrl;
  260. ret[2][1] = (top + bottom) * invtb;
  261. ret[2][2] = - (far + near) * invfn;
  262. ret[2][3] = -1.0f;
  263. ret[3][2] = -2.0f * far * near * invfn;
  264. return ret;
  265. }
  266. template<> mat4 mat4::perspective(float fov_y, float width,
  267. float height, float near, float far)
  268. {
  269. fov_y *= (M_PI / 180.0f);
  270. float t2 = tanf(fov_y * 0.5f);
  271. float t1 = t2 * width / height;
  272. return frustum(-near * t1, near * t1, -near * t2, near * t2, near, far);
  273. }
  274. } /* namespace lol */