1 /////////////////////////////////////////////////////////////////////////////////////////////////// 2 // OpenGL Mathematics Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net) 3 /////////////////////////////////////////////////////////////////////////////////////////////////// 4 // Created : 2007-03-14 5 // Updated : 2013-12-25 6 // Licence : This source is under MIT License 7 // File : glm/gtx/bit.inl 8 /////////////////////////////////////////////////////////////////////////////////////////////////// 9 10 #include "../detail/_vectorize.hpp" 11 #include <limits> 12 13 namespace glm 14 { 15 template <typename genIType> 16 GLM_FUNC_QUALIFIER genIType mask 17 ( 18 genIType const & count 19 ) 20 { 21 return ((genIType(1) << (count)) - genIType(1)); 22 } 23 24 VECTORIZE_VEC(mask) 25 26 // highestBitValue 27 template <typename genType> 28 GLM_FUNC_QUALIFIER genType highestBitValue 29 ( 30 genType const & value 31 ) 32 { 33 genType tmp = value; 34 genType result = genType(0); 35 while(tmp) 36 { 37 result = (tmp & (~tmp + 1)); // grab lowest bit 38 tmp &= ~result; // clear lowest bit 39 } 40 return result; 41 } 42 43 template <typename T, precision P> 44 GLM_FUNC_QUALIFIER detail::tvec2<int, P> highestBitValue 45 ( 46 detail::tvec2<T, P> const & value 47 ) 48 { 49 return detail::tvec2<int, P>( 50 highestBitValue(value[0]), 51 highestBitValue(value[1])); 52 } 53 54 template <typename T, precision P> 55 GLM_FUNC_QUALIFIER detail::tvec3<int, P> highestBitValue 56 ( 57 detail::tvec3<T, P> const & value 58 ) 59 { 60 return detail::tvec3<int, P>( 61 highestBitValue(value[0]), 62 highestBitValue(value[1]), 63 highestBitValue(value[2])); 64 } 65 66 template <typename T, precision P> 67 GLM_FUNC_QUALIFIER detail::tvec4<int, P> highestBitValue 68 ( 69 detail::tvec4<T, P> const & value 70 ) 71 { 72 return detail::tvec4<int, P>( 73 highestBitValue(value[0]), 74 highestBitValue(value[1]), 75 highestBitValue(value[2]), 76 highestBitValue(value[3])); 77 } 78 79 // isPowerOfTwo 80 template <typename genType> 81 GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value) 82 { 83 //detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value); 84 //return !(Value & (Value - 1)); 85 86 // For old complier? 87 genType Result = Value; 88 if(std::numeric_limits<genType>::is_signed) 89 Result = abs(Result); 90 return !(Result & (Result - 1)); 91 } 92 93 template <typename T, precision P> 94 GLM_FUNC_QUALIFIER detail::tvec2<bool, P> isPowerOfTwo 95 ( 96 detail::tvec2<T, P> const & value 97 ) 98 { 99 return detail::tvec2<bool, P>( 100 isPowerOfTwo(value[0]), 101 isPowerOfTwo(value[1])); 102 } 103 104 template <typename T, precision P> 105 GLM_FUNC_QUALIFIER detail::tvec3<bool, P> isPowerOfTwo 106 ( 107 detail::tvec3<T, P> const & value 108 ) 109 { 110 return detail::tvec3<bool, P>( 111 isPowerOfTwo(value[0]), 112 isPowerOfTwo(value[1]), 113 isPowerOfTwo(value[2])); 114 } 115 116 template <typename T, precision P> 117 GLM_FUNC_QUALIFIER detail::tvec4<bool, P> isPowerOfTwo 118 ( 119 detail::tvec4<T, P> const & value 120 ) 121 { 122 return detail::tvec4<bool, P>( 123 isPowerOfTwo(value[0]), 124 isPowerOfTwo(value[1]), 125 isPowerOfTwo(value[2]), 126 isPowerOfTwo(value[3])); 127 } 128 129 // powerOfTwoAbove 130 template <typename genType> 131 GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value) 132 { 133 return isPowerOfTwo(value) ? value : highestBitValue(value) << 1; 134 } 135 136 VECTORIZE_VEC(powerOfTwoAbove) 137 138 // powerOfTwoBelow 139 template <typename genType> 140 GLM_FUNC_QUALIFIER genType powerOfTwoBelow 141 ( 142 genType const & value 143 ) 144 { 145 return isPowerOfTwo(value) ? value : highestBitValue(value); 146 } 147 148 VECTORIZE_VEC(powerOfTwoBelow) 149 150 // powerOfTwoNearest 151 template <typename genType> 152 GLM_FUNC_QUALIFIER genType powerOfTwoNearest 153 ( 154 genType const & value 155 ) 156 { 157 if(isPowerOfTwo(value)) 158 return value; 159 160 genType prev = highestBitValue(value); 161 genType next = prev << 1; 162 return (next - value) < (value - prev) ? next : prev; 163 } 164 165 VECTORIZE_VEC(powerOfTwoNearest) 166 167 template <typename genType> 168 GLM_FUNC_QUALIFIER genType bitRevert(genType const & In) 169 { 170 GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values"); 171 172 genType Out = 0; 173 std::size_t BitSize = sizeof(genType) * 8; 174 for(std::size_t i = 0; i < BitSize; ++i) 175 if(In & (genType(1) << i)) 176 Out |= genType(1) << (BitSize - 1 - i); 177 return Out; 178 } 179 180 VECTORIZE_VEC(bitRevert) 181 182 template <typename genType> 183 GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift) 184 { 185 GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values"); 186 187 std::size_t BitSize = sizeof(genType) * 8; 188 return (In << Shift) | (In >> (BitSize - Shift)); 189 } 190 191 template <typename T, precision P> 192 GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateRight 193 ( 194 detail::tvec2<T, P> const & Value, 195 std::size_t Shift 196 ) 197 { 198 return detail::tvec2<T, P>( 199 bitRotateRight(Value[0], Shift), 200 bitRotateRight(Value[1], Shift)); 201 } 202 203 template <typename T, precision P> 204 GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateRight 205 ( 206 detail::tvec3<T, P> const & Value, 207 std::size_t Shift 208 ) 209 { 210 return detail::tvec3<T, P>( 211 bitRotateRight(Value[0], Shift), 212 bitRotateRight(Value[1], Shift), 213 bitRotateRight(Value[2], Shift)); 214 } 215 216 template <typename T, precision P> 217 GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateRight 218 ( 219 detail::tvec4<T, P> const & Value, 220 std::size_t Shift 221 ) 222 { 223 return detail::tvec4<T, P>( 224 bitRotateRight(Value[0], Shift), 225 bitRotateRight(Value[1], Shift), 226 bitRotateRight(Value[2], Shift), 227 bitRotateRight(Value[3], Shift)); 228 } 229 230 template <typename genType> 231 GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift) 232 { 233 GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values"); 234 235 std::size_t BitSize = sizeof(genType) * 8; 236 return (In >> Shift) | (In << (BitSize - Shift)); 237 } 238 239 template <typename T, precision P> 240 GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateLeft 241 ( 242 detail::tvec2<T, P> const & Value, 243 std::size_t Shift 244 ) 245 { 246 return detail::tvec2<T, P>( 247 bitRotateLeft(Value[0], Shift), 248 bitRotateLeft(Value[1], Shift)); 249 } 250 251 template <typename T, precision P> 252 GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateLeft 253 ( 254 detail::tvec3<T, P> const & Value, 255 std::size_t Shift 256 ) 257 { 258 return detail::tvec3<T, P>( 259 bitRotateLeft(Value[0], Shift), 260 bitRotateLeft(Value[1], Shift), 261 bitRotateLeft(Value[2], Shift)); 262 } 263 264 template <typename T, precision P> 265 GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateLeft 266 ( 267 detail::tvec4<T, P> const & Value, 268 std::size_t Shift 269 ) 270 { 271 return detail::tvec4<T, P>( 272 bitRotateLeft(Value[0], Shift), 273 bitRotateLeft(Value[1], Shift), 274 bitRotateLeft(Value[2], Shift), 275 bitRotateLeft(Value[3], Shift)); 276 } 277 278 template <typename genIUType> 279 GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne 280 ( 281 genIUType const & Value, 282 int const & FromBit, 283 int const & ToBit 284 ) 285 { 286 assert(FromBit <= ToBit); 287 assert(ToBit <= sizeof(genIUType) * std::size_t(8)); 288 289 genIUType Result = Value; 290 for(std::size_t i = 0; i <= ToBit; ++i) 291 Result |= (1 << i); 292 return Result; 293 } 294 295 template <typename genIUType> 296 GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero 297 ( 298 genIUType const & Value, 299 int const & FromBit, 300 int const & ToBit 301 ) 302 { 303 assert(FromBit <= ToBit); 304 assert(ToBit <= sizeof(genIUType) * std::size_t(8)); 305 306 genIUType Result = Value; 307 for(std::size_t i = 0; i <= ToBit; ++i) 308 Result &= ~(1 << i); 309 return Result; 310 } 311 312 namespace detail 313 { 314 template <typename PARAM, typename RET> 315 GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y); 316 317 template <typename PARAM, typename RET> 318 GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z); 319 320 template <typename PARAM, typename RET> 321 GLM_FUNC_DECL RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w); 322 323 /* 324 template <typename PARAM, typename RET> 325 inline RET bitfieldInterleave(PARAM x, PARAM y) 326 { 327 RET Result = 0; 328 for (int i = 0; i < sizeof(PARAM) * 8; i++) 329 Result |= (x & 1U << i) << i | (y & 1U << i) << (i + 1); 330 return Result; 331 } 332 333 template <typename PARAM, typename RET> 334 inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z) 335 { 336 RET Result = 0; 337 for (RET i = 0; i < sizeof(PARAM) * 8; i++) 338 { 339 Result |= ((RET(x) & (RET(1) << i)) << ((i << 1) + 0)); 340 Result |= ((RET(y) & (RET(1) << i)) << ((i << 1) + 1)); 341 Result |= ((RET(z) & (RET(1) << i)) << ((i << 1) + 2)); 342 } 343 return Result; 344 } 345 346 template <typename PARAM, typename RET> 347 inline RET bitfieldInterleave(PARAM x, PARAM y, PARAM z, PARAM w) 348 { 349 RET Result = 0; 350 for (int i = 0; i < sizeof(PARAM) * 8; i++) 351 { 352 Result |= ((((RET(x) >> i) & RET(1))) << RET((i << 2) + 0)); 353 Result |= ((((RET(y) >> i) & RET(1))) << RET((i << 2) + 1)); 354 Result |= ((((RET(z) >> i) & RET(1))) << RET((i << 2) + 2)); 355 Result |= ((((RET(w) >> i) & RET(1))) << RET((i << 2) + 3)); 356 } 357 return Result; 358 } 359 */ 360 template <> 361 GLM_FUNC_QUALIFIER glm::uint16 bitfieldInterleave(glm::uint8 x, glm::uint8 y) 362 { 363 glm::uint16 REG1(x); 364 glm::uint16 REG2(y); 365 366 REG1 = ((REG1 << 4) | REG1) & glm::uint16(0x0F0F); 367 REG2 = ((REG2 << 4) | REG2) & glm::uint16(0x0F0F); 368 369 REG1 = ((REG1 << 2) | REG1) & glm::uint16(0x3333); 370 REG2 = ((REG2 << 2) | REG2) & glm::uint16(0x3333); 371 372 REG1 = ((REG1 << 1) | REG1) & glm::uint16(0x5555); 373 REG2 = ((REG2 << 1) | REG2) & glm::uint16(0x5555); 374 375 return REG1 | (REG2 << 1); 376 } 377 378 template <> 379 GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint16 x, glm::uint16 y) 380 { 381 glm::uint32 REG1(x); 382 glm::uint32 REG2(y); 383 384 REG1 = ((REG1 << 8) | REG1) & glm::uint32(0x00FF00FF); 385 REG2 = ((REG2 << 8) | REG2) & glm::uint32(0x00FF00FF); 386 387 REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x0F0F0F0F); 388 REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x0F0F0F0F); 389 390 REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x33333333); 391 REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x33333333); 392 393 REG1 = ((REG1 << 1) | REG1) & glm::uint32(0x55555555); 394 REG2 = ((REG2 << 1) | REG2) & glm::uint32(0x55555555); 395 396 return REG1 | (REG2 << 1); 397 } 398 399 template <> 400 GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y) 401 { 402 glm::uint64 REG1(x); 403 glm::uint64 REG2(y); 404 405 REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x0000FFFF0000FFFF); 406 REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x0000FFFF0000FFFF); 407 408 REG1 = ((REG1 << 8) | REG1) & glm::uint64(0x00FF00FF00FF00FF); 409 REG2 = ((REG2 << 8) | REG2) & glm::uint64(0x00FF00FF00FF00FF); 410 411 REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x0F0F0F0F0F0F0F0F); 412 REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x0F0F0F0F0F0F0F0F); 413 414 REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x3333333333333333); 415 REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x3333333333333333); 416 417 REG1 = ((REG1 << 1) | REG1) & glm::uint64(0x5555555555555555); 418 REG2 = ((REG2 << 1) | REG2) & glm::uint64(0x5555555555555555); 419 420 return REG1 | (REG2 << 1); 421 } 422 423 template <> 424 GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z) 425 { 426 glm::uint32 REG1(x); 427 glm::uint32 REG2(y); 428 glm::uint32 REG3(z); 429 430 REG1 = ((REG1 << 16) | REG1) & glm::uint32(0x00FF0000FF0000FF); 431 REG2 = ((REG2 << 16) | REG2) & glm::uint32(0x00FF0000FF0000FF); 432 REG3 = ((REG3 << 16) | REG3) & glm::uint32(0x00FF0000FF0000FF); 433 434 REG1 = ((REG1 << 8) | REG1) & glm::uint32(0xF00F00F00F00F00F); 435 REG2 = ((REG2 << 8) | REG2) & glm::uint32(0xF00F00F00F00F00F); 436 REG3 = ((REG3 << 8) | REG3) & glm::uint32(0xF00F00F00F00F00F); 437 438 REG1 = ((REG1 << 4) | REG1) & glm::uint32(0x30C30C30C30C30C3); 439 REG2 = ((REG2 << 4) | REG2) & glm::uint32(0x30C30C30C30C30C3); 440 REG3 = ((REG3 << 4) | REG3) & glm::uint32(0x30C30C30C30C30C3); 441 442 REG1 = ((REG1 << 2) | REG1) & glm::uint32(0x9249249249249249); 443 REG2 = ((REG2 << 2) | REG2) & glm::uint32(0x9249249249249249); 444 REG3 = ((REG3 << 2) | REG3) & glm::uint32(0x9249249249249249); 445 446 return REG1 | (REG2 << 1) | (REG3 << 2); 447 } 448 449 template <> 450 GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z) 451 { 452 glm::uint64 REG1(x); 453 glm::uint64 REG2(y); 454 glm::uint64 REG3(z); 455 456 REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); 457 REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); 458 REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); 459 460 REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); 461 REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); 462 REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); 463 464 REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); 465 REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); 466 REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); 467 468 REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); 469 REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); 470 REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); 471 472 REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); 473 REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); 474 REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); 475 476 return REG1 | (REG2 << 1) | (REG3 << 2); 477 } 478 479 template <> 480 GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint32 x, glm::uint32 y, glm::uint32 z) 481 { 482 glm::uint64 REG1(x); 483 glm::uint64 REG2(y); 484 glm::uint64 REG3(z); 485 486 REG1 = ((REG1 << 32) | REG1) & glm::uint64(0xFFFF00000000FFFF); 487 REG2 = ((REG2 << 32) | REG2) & glm::uint64(0xFFFF00000000FFFF); 488 REG3 = ((REG3 << 32) | REG3) & glm::uint64(0xFFFF00000000FFFF); 489 490 REG1 = ((REG1 << 16) | REG1) & glm::uint64(0x00FF0000FF0000FF); 491 REG2 = ((REG2 << 16) | REG2) & glm::uint64(0x00FF0000FF0000FF); 492 REG3 = ((REG3 << 16) | REG3) & glm::uint64(0x00FF0000FF0000FF); 493 494 REG1 = ((REG1 << 8) | REG1) & glm::uint64(0xF00F00F00F00F00F); 495 REG2 = ((REG2 << 8) | REG2) & glm::uint64(0xF00F00F00F00F00F); 496 REG3 = ((REG3 << 8) | REG3) & glm::uint64(0xF00F00F00F00F00F); 497 498 REG1 = ((REG1 << 4) | REG1) & glm::uint64(0x30C30C30C30C30C3); 499 REG2 = ((REG2 << 4) | REG2) & glm::uint64(0x30C30C30C30C30C3); 500 REG3 = ((REG3 << 4) | REG3) & glm::uint64(0x30C30C30C30C30C3); 501 502 REG1 = ((REG1 << 2) | REG1) & glm::uint64(0x9249249249249249); 503 REG2 = ((REG2 << 2) | REG2) & glm::uint64(0x9249249249249249); 504 REG3 = ((REG3 << 2) | REG3) & glm::uint64(0x9249249249249249); 505 506 return REG1 | (REG2 << 1) | (REG3 << 2); 507 } 508 509 template <> 510 GLM_FUNC_QUALIFIER glm::uint32 bitfieldInterleave(glm::uint8 x, glm::uint8 y, glm::uint8 z, glm::uint8 w) 511 { 512 glm::uint32 REG1(x); 513 glm::uint32 REG2(y); 514 glm::uint32 REG3(z); 515 glm::uint32 REG4(w); 516 517 REG1 = ((REG1 << 12) | REG1) & glm::uint32(0x000F000F000F000F); 518 REG2 = ((REG2 << 12) | REG2) & glm::uint32(0x000F000F000F000F); 519 REG3 = ((REG3 << 12) | REG3) & glm::uint32(0x000F000F000F000F); 520 REG4 = ((REG4 << 12) | REG4) & glm::uint32(0x000F000F000F000F); 521 522 REG1 = ((REG1 << 6) | REG1) & glm::uint32(0x0303030303030303); 523 REG2 = ((REG2 << 6) | REG2) & glm::uint32(0x0303030303030303); 524 REG3 = ((REG3 << 6) | REG3) & glm::uint32(0x0303030303030303); 525 REG4 = ((REG4 << 6) | REG4) & glm::uint32(0x0303030303030303); 526 527 REG1 = ((REG1 << 3) | REG1) & glm::uint32(0x1111111111111111); 528 REG2 = ((REG2 << 3) | REG2) & glm::uint32(0x1111111111111111); 529 REG3 = ((REG3 << 3) | REG3) & glm::uint32(0x1111111111111111); 530 REG4 = ((REG4 << 3) | REG4) & glm::uint32(0x1111111111111111); 531 532 return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); 533 } 534 535 template <> 536 GLM_FUNC_QUALIFIER glm::uint64 bitfieldInterleave(glm::uint16 x, glm::uint16 y, glm::uint16 z, glm::uint16 w) 537 { 538 glm::uint64 REG1(x); 539 glm::uint64 REG2(y); 540 glm::uint64 REG3(z); 541 glm::uint64 REG4(w); 542 543 REG1 = ((REG1 << 24) | REG1) & glm::uint64(0x000000FF000000FF); 544 REG2 = ((REG2 << 24) | REG2) & glm::uint64(0x000000FF000000FF); 545 REG3 = ((REG3 << 24) | REG3) & glm::uint64(0x000000FF000000FF); 546 REG4 = ((REG4 << 24) | REG4) & glm::uint64(0x000000FF000000FF); 547 548 REG1 = ((REG1 << 12) | REG1) & glm::uint64(0x000F000F000F000F); 549 REG2 = ((REG2 << 12) | REG2) & glm::uint64(0x000F000F000F000F); 550 REG3 = ((REG3 << 12) | REG3) & glm::uint64(0x000F000F000F000F); 551 REG4 = ((REG4 << 12) | REG4) & glm::uint64(0x000F000F000F000F); 552 553 REG1 = ((REG1 << 6) | REG1) & glm::uint64(0x0303030303030303); 554 REG2 = ((REG2 << 6) | REG2) & glm::uint64(0x0303030303030303); 555 REG3 = ((REG3 << 6) | REG3) & glm::uint64(0x0303030303030303); 556 REG4 = ((REG4 << 6) | REG4) & glm::uint64(0x0303030303030303); 557 558 REG1 = ((REG1 << 3) | REG1) & glm::uint64(0x1111111111111111); 559 REG2 = ((REG2 << 3) | REG2) & glm::uint64(0x1111111111111111); 560 REG3 = ((REG3 << 3) | REG3) & glm::uint64(0x1111111111111111); 561 REG4 = ((REG4 << 3) | REG4) & glm::uint64(0x1111111111111111); 562 563 return REG1 | (REG2 << 1) | (REG3 << 2) | (REG4 << 3); 564 } 565 }//namespace detail 566 567 GLM_FUNC_QUALIFIER int16 bitfieldInterleave(int8 x, int8 y) 568 { 569 union sign8 570 { 571 int8 i; 572 uint8 u; 573 } sign_x, sign_y; 574 575 union sign16 576 { 577 int16 i; 578 uint16 u; 579 } result; 580 581 sign_x.i = x; 582 sign_y.i = y; 583 result.u = bitfieldInterleave(sign_x.u, sign_y.u); 584 585 return result.i; 586 } 587 588 GLM_FUNC_QUALIFIER uint16 bitfieldInterleave(uint8 x, uint8 y) 589 { 590 return detail::bitfieldInterleave<uint8, uint16>(x, y); 591 } 592 593 GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int16 x, int16 y) 594 { 595 union sign16 596 { 597 int16 i; 598 uint16 u; 599 } sign_x, sign_y; 600 601 union sign32 602 { 603 int32 i; 604 uint32 u; 605 } result; 606 607 sign_x.i = x; 608 sign_y.i = y; 609 result.u = bitfieldInterleave(sign_x.u, sign_y.u); 610 611 return result.i; 612 } 613 614 GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint16 x, uint16 y) 615 { 616 return detail::bitfieldInterleave<uint16, uint32>(x, y); 617 } 618 619 GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y) 620 { 621 union sign32 622 { 623 int32 i; 624 uint32 u; 625 } sign_x, sign_y; 626 627 union sign64 628 { 629 int64 i; 630 uint64 u; 631 } result; 632 633 sign_x.i = x; 634 sign_y.i = y; 635 result.u = bitfieldInterleave(sign_x.u, sign_y.u); 636 637 return result.i; 638 } 639 640 GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y) 641 { 642 return detail::bitfieldInterleave<uint32, uint64>(x, y); 643 } 644 645 GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z) 646 { 647 union sign8 648 { 649 int8 i; 650 uint8 u; 651 } sign_x, sign_y, sign_z; 652 653 union sign32 654 { 655 int32 i; 656 uint32 u; 657 } result; 658 659 sign_x.i = x; 660 sign_y.i = y; 661 sign_z.i = z; 662 result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); 663 664 return result.i; 665 } 666 667 GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z) 668 { 669 return detail::bitfieldInterleave<uint8, uint32>(x, y, z); 670 } 671 672 GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z) 673 { 674 union sign16 675 { 676 int16 i; 677 uint16 u; 678 } sign_x, sign_y, sign_z; 679 680 union sign64 681 { 682 int64 i; 683 uint64 u; 684 } result; 685 686 sign_x.i = x; 687 sign_y.i = y; 688 sign_z.i = z; 689 result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); 690 691 return result.i; 692 } 693 694 GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z) 695 { 696 return detail::bitfieldInterleave<uint32, uint64>(x, y, z); 697 } 698 699 GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int32 x, int32 y, int32 z) 700 { 701 union sign16 702 { 703 int32 i; 704 uint32 u; 705 } sign_x, sign_y, sign_z; 706 707 union sign64 708 { 709 int64 i; 710 uint64 u; 711 } result; 712 713 sign_x.i = x; 714 sign_y.i = y; 715 sign_z.i = z; 716 result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u); 717 718 return result.i; 719 } 720 721 GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint32 x, uint32 y, uint32 z) 722 { 723 return detail::bitfieldInterleave<uint32, uint64>(x, y, z); 724 } 725 726 GLM_FUNC_QUALIFIER int32 bitfieldInterleave(int8 x, int8 y, int8 z, int8 w) 727 { 728 union sign8 729 { 730 int8 i; 731 uint8 u; 732 } sign_x, sign_y, sign_z, sign_w; 733 734 union sign32 735 { 736 int32 i; 737 uint32 u; 738 } result; 739 740 sign_x.i = x; 741 sign_y.i = y; 742 sign_z.i = z; 743 sign_w.i = w; 744 result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); 745 746 return result.i; 747 } 748 749 GLM_FUNC_QUALIFIER uint32 bitfieldInterleave(uint8 x, uint8 y, uint8 z, uint8 w) 750 { 751 return detail::bitfieldInterleave<uint8, uint32>(x, y, z, w); 752 } 753 754 GLM_FUNC_QUALIFIER int64 bitfieldInterleave(int16 x, int16 y, int16 z, int16 w) 755 { 756 union sign16 757 { 758 int16 i; 759 uint16 u; 760 } sign_x, sign_y, sign_z, sign_w; 761 762 union sign64 763 { 764 int64 i; 765 uint64 u; 766 } result; 767 768 sign_x.i = x; 769 sign_y.i = y; 770 sign_z.i = z; 771 sign_w.i = w; 772 result.u = bitfieldInterleave(sign_x.u, sign_y.u, sign_z.u, sign_w.u); 773 774 return result.i; 775 } 776 777 GLM_FUNC_QUALIFIER uint64 bitfieldInterleave(uint16 x, uint16 y, uint16 z, uint16 w) 778 { 779 return detail::bitfieldInterleave<uint16, uint64>(x, y, z, w); 780 } 781 782 }//namespace glm 783