Home | History | Annotate | Download | only in gtx
      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 
     10 namespace glm{
     11 namespace detail{
     12 
     13 GLM_FUNC_QUALIFIER length_t fmat4x4SIMD::length() const
     14 {
     15 	return 4;
     16 }
     17 
     18 //////////////////////////////////////
     19 // Accesses
     20 
     21 GLM_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 
     31 GLM_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 
     44 GLM_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 
     54 GLM_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 
     62 GLM_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 
     76 GLM_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 
     90 GLM_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 
    101 GLM_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 
    115 GLM_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 
    127 GLM_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 
    139 GLM_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 
    152 GLM_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 
    161 GLM_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 
    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_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 
    185 GLM_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 
    198 GLM_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 
    211 GLM_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 
    224 GLM_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 
    233 GLM_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 
    246 GLM_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 
    261 GLM_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 
    276 GLM_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 
    292 GLM_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 
    307 GLM_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 
    322 GLM_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 
    338 GLM_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 
    353 GLM_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 
    368 GLM_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 
    377 GLM_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 
    386 GLM_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 
    400 GLM_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 
    415 GLM_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 
    430 GLM_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 
    437 GLM_FUNC_QUALIFIER fvec4SIMD operator/
    438 (
    439 	const fmat4x4SIMD & m,
    440 	fvec4SIMD const & v
    441 )
    442 {
    443 	return inverse(m) * v;
    444 }
    445 
    446 GLM_FUNC_QUALIFIER fvec4SIMD operator/
    447 (
    448 	fvec4SIMD const & v,
    449 	const fmat4x4SIMD &m
    450 )
    451 {
    452 	return v * inverse(m);
    453 }
    454 
    455 GLM_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
    473 GLM_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 
    487 GLM_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 
    502 GLM_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 
    519 GLM_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 
    532 GLM_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 
    546 GLM_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 
    565 GLM_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 
    572 GLM_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