You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

590 lines
13 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2009-05-19
  5. // Updated : 2009-05-19
  6. // Licence : This source is under MIT License
  7. // File : glm/gtx/simd_mat4.hpp
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. namespace glm{
  10. namespace detail{
  11. GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::value_size()
  12. {
  13. return sizeof(value_type);
  14. }
  15. GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::col_size()
  16. {
  17. return 4;
  18. }
  19. GLM_FUNC_QUALIFIER fmat4x4SIMD::size_type fmat4x4SIMD::row_size()
  20. {
  21. return 4;
  22. }
  23. GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD()
  24. {
  25. #ifndef GLM_SIMD_ENABLE_DEFAULT_INIT
  26. this->Data[0] = fvec4SIMD(1.0f, 0, 0, 0);
  27. this->Data[1] = fvec4SIMD(0, 1.0f, 0, 0);
  28. this->Data[2] = fvec4SIMD(0, 0, 1.0f, 0);
  29. this->Data[3] = fvec4SIMD(0, 0, 0, 1.0f);
  30. #endif
  31. }
  32. GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD(float const & s)
  33. {
  34. this->Data[0] = fvec4SIMD(s, 0, 0, 0);
  35. this->Data[1] = fvec4SIMD(0, s, 0, 0);
  36. this->Data[2] = fvec4SIMD(0, 0, s, 0);
  37. this->Data[3] = fvec4SIMD(0, 0, 0, s);
  38. }
  39. GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
  40. (
  41. float const & x0, float const & y0, float const & z0, float const & w0,
  42. float const & x1, float const & y1, float const & z1, float const & w1,
  43. float const & x2, float const & y2, float const & z2, float const & w2,
  44. float const & x3, float const & y3, float const & z3, float const & w3
  45. )
  46. {
  47. this->Data[0] = fvec4SIMD(x0, y0, z0, w0);
  48. this->Data[1] = fvec4SIMD(x1, y1, z1, w1);
  49. this->Data[2] = fvec4SIMD(x2, y2, z2, w2);
  50. this->Data[3] = fvec4SIMD(x3, y3, z3, w3);
  51. }
  52. GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
  53. (
  54. fvec4SIMD const & v0,
  55. fvec4SIMD const & v1,
  56. fvec4SIMD const & v2,
  57. fvec4SIMD const & v3
  58. )
  59. {
  60. this->Data[0] = v0;
  61. this->Data[1] = v1;
  62. this->Data[2] = v2;
  63. this->Data[3] = v3;
  64. }
  65. GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
  66. (
  67. tmat4x4<float> const & m
  68. )
  69. {
  70. this->Data[0] = fvec4SIMD(m[0]);
  71. this->Data[1] = fvec4SIMD(m[1]);
  72. this->Data[2] = fvec4SIMD(m[2]);
  73. this->Data[3] = fvec4SIMD(m[3]);
  74. }
  75. GLM_FUNC_QUALIFIER fmat4x4SIMD::fmat4x4SIMD
  76. (
  77. __m128 const in[4]
  78. )
  79. {
  80. this->Data[0] = in[0];
  81. this->Data[1] = in[1];
  82. this->Data[2] = in[2];
  83. this->Data[3] = in[3];
  84. }
  85. //////////////////////////////////////
  86. // Accesses
  87. GLM_FUNC_QUALIFIER fvec4SIMD & fmat4x4SIMD::operator[]
  88. (
  89. fmat4x4SIMD::size_type i
  90. )
  91. {
  92. assert(
  93. //i >= fmat4x4SIMD::size_type(0) &&
  94. i < fmat4x4SIMD::col_size());
  95. return this->Data[i];
  96. }
  97. GLM_FUNC_QUALIFIER fvec4SIMD const & fmat4x4SIMD::operator[]
  98. (
  99. fmat4x4SIMD::size_type i
  100. ) const
  101. {
  102. assert(
  103. //i >= fmat4x4SIMD::size_type(0) &&
  104. i < fmat4x4SIMD::col_size());
  105. return this->Data[i];
  106. }
  107. //////////////////////////////////////////////////////////////
  108. // mat4 operators
  109. GLM_FUNC_QUALIFIER fmat4x4SIMD& fmat4x4SIMD::operator=
  110. (
  111. fmat4x4SIMD const & m
  112. )
  113. {
  114. this->Data[0] = m[0];
  115. this->Data[1] = m[1];
  116. this->Data[2] = m[2];
  117. this->Data[3] = m[3];
  118. return *this;
  119. }
  120. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
  121. (
  122. fmat4x4SIMD const & m
  123. )
  124. {
  125. this->Data[0].Data = _mm_add_ps(this->Data[0].Data, m[0].Data);
  126. this->Data[1].Data = _mm_add_ps(this->Data[1].Data, m[1].Data);
  127. this->Data[2].Data = _mm_add_ps(this->Data[2].Data, m[2].Data);
  128. this->Data[3].Data = _mm_add_ps(this->Data[3].Data, m[3].Data);
  129. return *this;
  130. }
  131. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
  132. (
  133. fmat4x4SIMD const & m
  134. )
  135. {
  136. this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, m[0].Data);
  137. this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, m[1].Data);
  138. this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, m[2].Data);
  139. this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, m[3].Data);
  140. return *this;
  141. }
  142. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
  143. (
  144. fmat4x4SIMD const & m
  145. )
  146. {
  147. sse_mul_ps(&this->Data[0].Data, &m.Data[0].Data, &this->Data[0].Data);
  148. return *this;
  149. }
  150. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
  151. (
  152. fmat4x4SIMD const & m
  153. )
  154. {
  155. __m128 Inv[4];
  156. sse_inverse_ps(&m.Data[0].Data, Inv);
  157. sse_mul_ps(&this->Data[0].Data, Inv, &this->Data[0].Data);
  158. return *this;
  159. }
  160. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator+=
  161. (
  162. float const & s
  163. )
  164. {
  165. __m128 Operand = _mm_set_ps1(s);
  166. this->Data[0].Data = _mm_add_ps(this->Data[0].Data, Operand);
  167. this->Data[1].Data = _mm_add_ps(this->Data[1].Data, Operand);
  168. this->Data[2].Data = _mm_add_ps(this->Data[2].Data, Operand);
  169. this->Data[3].Data = _mm_add_ps(this->Data[3].Data, Operand);
  170. return *this;
  171. }
  172. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-=
  173. (
  174. float const & s
  175. )
  176. {
  177. __m128 Operand = _mm_set_ps1(s);
  178. this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, Operand);
  179. this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, Operand);
  180. this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, Operand);
  181. this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, Operand);
  182. return *this;
  183. }
  184. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator*=
  185. (
  186. float const & s
  187. )
  188. {
  189. __m128 Operand = _mm_set_ps1(s);
  190. this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
  191. this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
  192. this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
  193. this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
  194. return *this;
  195. }
  196. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator/=
  197. (
  198. float const & s
  199. )
  200. {
  201. __m128 Operand = _mm_div_ps(one, _mm_set_ps1(s));
  202. this->Data[0].Data = _mm_mul_ps(this->Data[0].Data, Operand);
  203. this->Data[1].Data = _mm_mul_ps(this->Data[1].Data, Operand);
  204. this->Data[2].Data = _mm_mul_ps(this->Data[2].Data, Operand);
  205. this->Data[3].Data = _mm_mul_ps(this->Data[3].Data, Operand);
  206. return *this;
  207. }
  208. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator++ ()
  209. {
  210. this->Data[0].Data = _mm_add_ps(this->Data[0].Data, one);
  211. this->Data[1].Data = _mm_add_ps(this->Data[1].Data, one);
  212. this->Data[2].Data = _mm_add_ps(this->Data[2].Data, one);
  213. this->Data[3].Data = _mm_add_ps(this->Data[3].Data, one);
  214. return *this;
  215. }
  216. GLM_FUNC_QUALIFIER fmat4x4SIMD & fmat4x4SIMD::operator-- ()
  217. {
  218. this->Data[0].Data = _mm_sub_ps(this->Data[0].Data, one);
  219. this->Data[1].Data = _mm_sub_ps(this->Data[1].Data, one);
  220. this->Data[2].Data = _mm_sub_ps(this->Data[2].Data, one);
  221. this->Data[3].Data = _mm_sub_ps(this->Data[3].Data, one);
  222. return *this;
  223. }
  224. //////////////////////////////////////////////////////////////
  225. // Binary operators
  226. GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
  227. (
  228. const fmat4x4SIMD &m,
  229. float const & s
  230. )
  231. {
  232. return detail::fmat4x4SIMD
  233. (
  234. m[0] + s,
  235. m[1] + s,
  236. m[2] + s,
  237. m[3] + s
  238. );
  239. }
  240. GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
  241. (
  242. float const & s,
  243. const fmat4x4SIMD &m
  244. )
  245. {
  246. return detail::fmat4x4SIMD
  247. (
  248. m[0] + s,
  249. m[1] + s,
  250. m[2] + s,
  251. m[3] + s
  252. );
  253. }
  254. GLM_FUNC_QUALIFIER fmat4x4SIMD operator+
  255. (
  256. const fmat4x4SIMD &m1,
  257. const fmat4x4SIMD &m2
  258. )
  259. {
  260. return detail::fmat4x4SIMD
  261. (
  262. m1[0] + m2[0],
  263. m1[1] + m2[1],
  264. m1[2] + m2[2],
  265. m1[3] + m2[3]
  266. );
  267. }
  268. GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
  269. (
  270. const fmat4x4SIMD &m,
  271. float const & s
  272. )
  273. {
  274. return detail::fmat4x4SIMD
  275. (
  276. m[0] - s,
  277. m[1] - s,
  278. m[2] - s,
  279. m[3] - s
  280. );
  281. }
  282. GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
  283. (
  284. float const & s,
  285. const fmat4x4SIMD &m
  286. )
  287. {
  288. return detail::fmat4x4SIMD
  289. (
  290. s - m[0],
  291. s - m[1],
  292. s - m[2],
  293. s - m[3]
  294. );
  295. }
  296. GLM_FUNC_QUALIFIER fmat4x4SIMD operator-
  297. (
  298. const fmat4x4SIMD &m1,
  299. const fmat4x4SIMD &m2
  300. )
  301. {
  302. return detail::fmat4x4SIMD
  303. (
  304. m1[0] - m2[0],
  305. m1[1] - m2[1],
  306. m1[2] - m2[2],
  307. m1[3] - m2[3]
  308. );
  309. }
  310. GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
  311. (
  312. const fmat4x4SIMD &m,
  313. float const & s
  314. )
  315. {
  316. return detail::fmat4x4SIMD
  317. (
  318. m[0] * s,
  319. m[1] * s,
  320. m[2] * s,
  321. m[3] * s
  322. );
  323. }
  324. GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
  325. (
  326. float const & s,
  327. const fmat4x4SIMD &m
  328. )
  329. {
  330. return detail::fmat4x4SIMD
  331. (
  332. m[0] * s,
  333. m[1] * s,
  334. m[2] * s,
  335. m[3] * s
  336. );
  337. }
  338. GLM_FUNC_QUALIFIER fvec4SIMD operator*
  339. (
  340. const fmat4x4SIMD &m,
  341. fvec4SIMD const & v
  342. )
  343. {
  344. return sse_mul_ps(&m.Data[0].Data, v.Data);
  345. }
  346. GLM_FUNC_QUALIFIER fvec4SIMD operator*
  347. (
  348. fvec4SIMD const & v,
  349. const fmat4x4SIMD &m
  350. )
  351. {
  352. return sse_mul_ps(v.Data, &m.Data[0].Data);
  353. }
  354. GLM_FUNC_QUALIFIER fmat4x4SIMD operator*
  355. (
  356. const fmat4x4SIMD &m1,
  357. const fmat4x4SIMD &m2
  358. )
  359. {
  360. fmat4x4SIMD result;
  361. sse_mul_ps(&m1.Data[0].Data, &m2.Data[0].Data, &result.Data[0].Data);
  362. return result;
  363. }
  364. GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
  365. (
  366. const fmat4x4SIMD &m,
  367. float const & s
  368. )
  369. {
  370. return detail::fmat4x4SIMD
  371. (
  372. m[0] / s,
  373. m[1] / s,
  374. m[2] / s,
  375. m[3] / s
  376. );
  377. }
  378. GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
  379. (
  380. float const & s,
  381. const fmat4x4SIMD &m
  382. )
  383. {
  384. return detail::fmat4x4SIMD
  385. (
  386. s / m[0],
  387. s / m[1],
  388. s / m[2],
  389. s / m[3]
  390. );
  391. }
  392. GLM_FUNC_QUALIFIER fvec4SIMD operator/
  393. (
  394. const fmat4x4SIMD &m,
  395. fvec4SIMD const & v
  396. )
  397. {
  398. return inverse(m) * v;
  399. }
  400. GLM_FUNC_QUALIFIER fvec4SIMD operator/
  401. (
  402. fvec4SIMD const & v,
  403. const fmat4x4SIMD &m
  404. )
  405. {
  406. return v * inverse(m);
  407. }
  408. GLM_FUNC_QUALIFIER fmat4x4SIMD operator/
  409. (
  410. const fmat4x4SIMD &m1,
  411. const fmat4x4SIMD &m2
  412. )
  413. {
  414. __m128 result[4];
  415. __m128 inv[4];
  416. sse_inverse_ps(&m2.Data[0].Data, inv);
  417. sse_mul_ps(&m1.Data[0].Data, inv, result);
  418. return fmat4x4SIMD(result);
  419. }
  420. //////////////////////////////////////////////////////////////
  421. // Unary constant operators
  422. GLM_FUNC_QUALIFIER fmat4x4SIMD const operator-
  423. (
  424. fmat4x4SIMD const & m
  425. )
  426. {
  427. return detail::fmat4x4SIMD
  428. (
  429. -m[0],
  430. -m[1],
  431. -m[2],
  432. -m[3]
  433. );
  434. }
  435. GLM_FUNC_QUALIFIER fmat4x4SIMD const operator--
  436. (
  437. fmat4x4SIMD const & m,
  438. int
  439. )
  440. {
  441. return detail::fmat4x4SIMD
  442. (
  443. m[0] - 1.0f,
  444. m[1] - 1.0f,
  445. m[2] - 1.0f,
  446. m[3] - 1.0f
  447. );
  448. }
  449. GLM_FUNC_QUALIFIER fmat4x4SIMD const operator++
  450. (
  451. fmat4x4SIMD const & m,
  452. int
  453. )
  454. {
  455. return detail::fmat4x4SIMD
  456. (
  457. m[0] + 1.0f,
  458. m[1] + 1.0f,
  459. m[2] + 1.0f,
  460. m[3] + 1.0f
  461. );
  462. }
  463. }//namespace detail
  464. GLM_FUNC_QUALIFIER detail::tmat4x4<float> mat4_cast
  465. (
  466. detail::fmat4x4SIMD const & x
  467. )
  468. {
  469. GLM_ALIGN(16) detail::tmat4x4<float> Result;
  470. _mm_store_ps(&Result[0][0], x.Data[0].Data);
  471. _mm_store_ps(&Result[1][0], x.Data[1].Data);
  472. _mm_store_ps(&Result[2][0], x.Data[2].Data);
  473. _mm_store_ps(&Result[3][0], x.Data[3].Data);
  474. return Result;
  475. }
  476. GLM_FUNC_QUALIFIER detail::fmat4x4SIMD matrixCompMult
  477. (
  478. detail::fmat4x4SIMD const & x,
  479. detail::fmat4x4SIMD const & y
  480. )
  481. {
  482. detail::fmat4x4SIMD result;
  483. result[0] = x[0] * y[0];
  484. result[1] = x[1] * y[1];
  485. result[2] = x[2] * y[2];
  486. result[3] = x[3] * y[3];
  487. return result;
  488. }
  489. GLM_FUNC_QUALIFIER detail::fmat4x4SIMD outerProduct
  490. (
  491. detail::fvec4SIMD const & c,
  492. detail::fvec4SIMD const & r
  493. )
  494. {
  495. __m128 Shu0 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(0, 0, 0, 0));
  496. __m128 Shu1 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(1, 1, 1, 1));
  497. __m128 Shu2 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(2, 2, 2, 2));
  498. __m128 Shu3 = _mm_shuffle_ps(r.Data, r.Data, _MM_SHUFFLE(3, 3, 3, 3));
  499. detail::fmat4x4SIMD result(detail::fmat4x4SIMD::null);
  500. result[0].Data = _mm_mul_ps(c.Data, Shu0);
  501. result[1].Data = _mm_mul_ps(c.Data, Shu1);
  502. result[2].Data = _mm_mul_ps(c.Data, Shu2);
  503. result[3].Data = _mm_mul_ps(c.Data, Shu3);
  504. return result;
  505. }
  506. GLM_FUNC_QUALIFIER detail::fmat4x4SIMD transpose(detail::fmat4x4SIMD const & m)
  507. {
  508. detail::fmat4x4SIMD result;
  509. detail::sse_transpose_ps(&m[0].Data, &result[0].Data);
  510. return result;
  511. }
  512. GLM_FUNC_QUALIFIER float determinant(detail::fmat4x4SIMD const & m)
  513. {
  514. float Result;
  515. _mm_store_ss(&Result, detail::sse_det_ps(&m[0].Data));
  516. return Result;
  517. }
  518. GLM_FUNC_QUALIFIER detail::fmat4x4SIMD inverse(detail::fmat4x4SIMD const & m)
  519. {
  520. detail::fmat4x4SIMD result;
  521. detail::sse_inverse_ps(&m[0].Data, &result[0].Data);
  522. return result;
  523. }
  524. }//namespace glm