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