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