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.

600 lines
14 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////
  2. // OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
  3. ///////////////////////////////////////////////////////////////////////////////////////////////////
  4. // Created : 2007-03-14
  5. // Updated : 2008-11-14
  6. // Licence : This source is under MIT License
  7. // File : glm/gtx/bit.inl
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////
  9. namespace glm
  10. {
  11. template <typename genIType>
  12. GLM_FUNC_QUALIFIER genIType mask
  13. (
  14. genIType const & count
  15. )
  16. {
  17. return ((genIType(1) << (count)) - genIType(1));
  18. }
  19. VECTORIZE_VEC(mask)
  20. // extractField
  21. template <typename genIType>
  22. GLM_FUNC_QUALIFIER genIType extractField
  23. (
  24. half const & value,
  25. genIType const & first,
  26. genIType const & count
  27. )
  28. {
  29. assert(first + count < sizeof(half));
  30. return (value._data() << first) >> ((sizeof(half) << 3) - count);
  31. }
  32. template <typename genIType>
  33. GLM_FUNC_QUALIFIER genIType extractField
  34. (
  35. float const & value,
  36. genIType const & first,
  37. genIType const & count
  38. )
  39. {
  40. assert(first + count < sizeof(float));
  41. return (detail::uif32(value).i << first) >> ((sizeof(float) << 3) - count);
  42. }
  43. template <typename genIType>
  44. GLM_FUNC_QUALIFIER genIType extractField
  45. (
  46. double const & value,
  47. genIType const & first,
  48. genIType const & count
  49. )
  50. {
  51. assert(first + count < sizeof(double));
  52. return (detail::uif64(value).i << first) >> ((sizeof(double) << genIType(3)) - count);
  53. }
  54. template <typename genIUType, typename sizeType>
  55. GLM_FUNC_QUALIFIER genIUType extractField
  56. (
  57. genIUType const & Value,
  58. sizeType const & First,
  59. sizeType const & Count
  60. )
  61. {
  62. sizeType GenSize = sizeof(genIUType) << 3;
  63. assert(First + Count <= GenSize);
  64. genIUType ShiftLeft = Count ? Value << (GenSize - (Count + First)) : 0;
  65. genIUType ShiftBack = ShiftLeft >> genIUType(GenSize - Count);
  66. return ShiftBack;
  67. }
  68. template <typename genIUType, typename sizeType>
  69. GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
  70. (
  71. detail::tvec2<genIUType> const & value,
  72. sizeType const & first,
  73. sizeType const & count
  74. )
  75. {
  76. return detail::tvec2<genIUType>(
  77. extractField(value[0], first, count),
  78. extractField(value[1], first, count));
  79. }
  80. template <typename genIUType, typename sizeType>
  81. GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
  82. (
  83. detail::tvec3<genIUType> const & value,
  84. sizeType const & first,
  85. sizeType const & count
  86. )
  87. {
  88. return detail::tvec3<genIUType>(
  89. extractField(value[0], first, count),
  90. extractField(value[1], first, count),
  91. extractField(value[2], first, count));
  92. }
  93. template <typename genIUType, typename sizeType>
  94. GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
  95. (
  96. detail::tvec4<genIUType> const & value,
  97. sizeType const & first,
  98. sizeType const & count
  99. )
  100. {
  101. return detail::tvec4<genIUType>(
  102. extractField(value[0], first, count),
  103. extractField(value[1], first, count),
  104. extractField(value[2], first, count),
  105. extractField(value[3], first, count));
  106. }
  107. template <typename genIUType, typename sizeType>
  108. GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
  109. (
  110. detail::tvec2<genIUType> const & value,
  111. detail::tvec2<sizeType> const & first,
  112. detail::tvec2<sizeType> const & count
  113. )
  114. {
  115. return detail::tvec2<genIUType>(
  116. extractField(value[0], first[0], count[0]),
  117. extractField(value[1], first[1], count[1]));
  118. }
  119. template <typename genIUType, typename sizeType>
  120. GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
  121. (
  122. detail::tvec3<genIUType> const & value,
  123. detail::tvec3<sizeType> const & first,
  124. detail::tvec3<sizeType> const & count
  125. )
  126. {
  127. return detail::tvec3<genIUType>(
  128. extractField(value[0], first[0], count[0]),
  129. extractField(value[1], first[1], count[1]),
  130. extractField(value[2], first[2], count[2]));
  131. }
  132. template <typename genIUType, typename sizeType>
  133. GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
  134. (
  135. detail::tvec4<genIUType> const & value,
  136. detail::tvec4<sizeType> const & first,
  137. detail::tvec4<sizeType> const & count
  138. )
  139. {
  140. return detail::tvec4<genIUType>(
  141. extractField(value[0], first[0], count[0]),
  142. extractField(value[1], first[1], count[1]),
  143. extractField(value[2], first[2], count[2]),
  144. extractField(value[3], first[3], count[3]));
  145. }
  146. template <typename genIUType, typename sizeType>
  147. GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
  148. (
  149. genIUType const & value,
  150. detail::tvec2<sizeType> const & first,
  151. detail::tvec2<sizeType> const & count
  152. )
  153. {
  154. return detail::tvec2<genIUType>(
  155. extractField(value, first[0], count[0]),
  156. extractField(value, first[1], count[1]));
  157. }
  158. template <typename genIUType, typename sizeType>
  159. GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
  160. (
  161. genIUType const & value,
  162. detail::tvec3<sizeType> const & first,
  163. detail::tvec3<sizeType> const & count
  164. )
  165. {
  166. return detail::tvec3<genIUType>(
  167. extractField(value, first[0], count[0]),
  168. extractField(value, first[1], count[1]),
  169. extractField(value, first[2], count[2]));
  170. }
  171. template <typename genIUType, typename sizeType>
  172. GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
  173. (
  174. genIUType const & value,
  175. detail::tvec4<sizeType> const & first,
  176. detail::tvec4<sizeType> const & count
  177. )
  178. {
  179. return detail::tvec4<genIUType>(
  180. extractField(value, first[0], count[0]),
  181. extractField(value, first[1], count[1]),
  182. extractField(value, first[2], count[2]),
  183. extractField(value, first[3], count[3]));
  184. }
  185. // lowestBit
  186. template <typename genType>
  187. GLM_FUNC_QUALIFIER int lowestBit
  188. (
  189. genType const & Value
  190. )
  191. {
  192. assert(Value != genType(0)); // not valid call
  193. genType Bit;
  194. for(Bit = genType(0); !(Value & (1 << Bit)); ++Bit){}
  195. return Bit;
  196. }
  197. template <typename valType>
  198. GLM_FUNC_QUALIFIER detail::tvec2<int> lowestBit
  199. (
  200. detail::tvec2<valType> const & value
  201. )
  202. {
  203. return detail::tvec2<int>(
  204. lowestBit(value[0]),
  205. lowestBit(value[1]));
  206. }
  207. template <typename valType>
  208. GLM_FUNC_QUALIFIER detail::tvec3<int> lowestBit
  209. (
  210. detail::tvec3<valType> const & value
  211. )
  212. {
  213. return detail::tvec3<int>(
  214. lowestBit(value[0]),
  215. lowestBit(value[1]),
  216. lowestBit(value[2]));
  217. }
  218. template <typename valType>
  219. GLM_FUNC_QUALIFIER detail::tvec4<int> lowestBit
  220. (
  221. detail::tvec4<valType> const & value
  222. )
  223. {
  224. return detail::tvec4<int>(
  225. lowestBit(value[0]),
  226. lowestBit(value[1]),
  227. lowestBit(value[2]),
  228. lowestBit(value[3]));
  229. }
  230. // highestBit
  231. template <typename genType>
  232. GLM_FUNC_QUALIFIER int highestBit
  233. (
  234. genType const & value
  235. )
  236. {
  237. assert(value != genType(0)); // not valid call
  238. genType bit = genType(-1);
  239. for(genType tmp = value; tmp; tmp >>= 1, ++bit){}
  240. return bit;
  241. }
  242. //template <>
  243. //GLM_FUNC_QUALIFIER int highestBit<int>
  244. //(
  245. // int value
  246. //)
  247. //{
  248. // int bit = -1;
  249. // for(int tmp = value; tmp; tmp >>= 1, ++bit);
  250. // return bit;
  251. //}
  252. template <typename valType>
  253. GLM_FUNC_QUALIFIER detail::tvec2<int> highestBit
  254. (
  255. detail::tvec2<valType> const & value
  256. )
  257. {
  258. return detail::tvec2<int>(
  259. highestBit(value[0]),
  260. highestBit(value[1]));
  261. }
  262. template <typename valType>
  263. GLM_FUNC_QUALIFIER detail::tvec3<int> highestBit
  264. (
  265. detail::tvec3<valType> const & value
  266. )
  267. {
  268. return detail::tvec3<int>(
  269. highestBit(value[0]),
  270. highestBit(value[1]),
  271. highestBit(value[2]));
  272. }
  273. template <typename valType>
  274. GLM_FUNC_QUALIFIER detail::tvec4<int> highestBit
  275. (
  276. detail::tvec4<valType> const & value
  277. )
  278. {
  279. return detail::tvec4<int>(
  280. highestBit(value[0]),
  281. highestBit(value[1]),
  282. highestBit(value[2]),
  283. highestBit(value[3]));
  284. }
  285. // highestBitValue
  286. template <typename genType>
  287. GLM_FUNC_QUALIFIER genType highestBitValue
  288. (
  289. genType const & value
  290. )
  291. {
  292. genType tmp = value;
  293. genType result = genType(0);
  294. while(tmp)
  295. {
  296. result = (tmp & (~tmp + 1)); // grab lowest bit
  297. tmp &= ~result; // clear lowest bit
  298. }
  299. return result;
  300. }
  301. template <typename valType>
  302. GLM_FUNC_QUALIFIER detail::tvec2<int> highestBitValue
  303. (
  304. detail::tvec2<valType> const & value
  305. )
  306. {
  307. return detail::tvec2<int>(
  308. highestBitValue(value[0]),
  309. highestBitValue(value[1]));
  310. }
  311. template <typename valType>
  312. GLM_FUNC_QUALIFIER detail::tvec3<int> highestBitValue
  313. (
  314. detail::tvec3<valType> const & value
  315. )
  316. {
  317. return detail::tvec3<int>(
  318. highestBitValue(value[0]),
  319. highestBitValue(value[1]),
  320. highestBitValue(value[2]));
  321. }
  322. template <typename valType>
  323. GLM_FUNC_QUALIFIER detail::tvec4<int> highestBitValue
  324. (
  325. detail::tvec4<valType> const & value
  326. )
  327. {
  328. return detail::tvec4<int>(
  329. highestBitValue(value[0]),
  330. highestBitValue(value[1]),
  331. highestBitValue(value[2]),
  332. highestBitValue(value[3]));
  333. }
  334. // isPowerOfTwo
  335. template <typename genType>
  336. GLM_FUNC_QUALIFIER bool isPowerOfTwo(genType const & Value)
  337. {
  338. //detail::If<std::numeric_limits<genType>::is_signed>::apply(abs, Value);
  339. //return !(Value & (Value - 1));
  340. // For old complier?
  341. genType Result = Value;
  342. if(std::numeric_limits<genType>::is_signed)
  343. Result = abs(Result);
  344. return !(Result & (Result - 1));
  345. }
  346. template <typename valType>
  347. GLM_FUNC_QUALIFIER detail::tvec2<bool> isPowerOfTwo
  348. (
  349. detail::tvec2<valType> const & value
  350. )
  351. {
  352. return detail::tvec2<bool>(
  353. isPowerOfTwo(value[0]),
  354. isPowerOfTwo(value[1]));
  355. }
  356. template <typename valType>
  357. GLM_FUNC_QUALIFIER detail::tvec3<bool> isPowerOfTwo
  358. (
  359. detail::tvec3<valType> const & value
  360. )
  361. {
  362. return detail::tvec3<bool>(
  363. isPowerOfTwo(value[0]),
  364. isPowerOfTwo(value[1]),
  365. isPowerOfTwo(value[2]));
  366. }
  367. template <typename valType>
  368. GLM_FUNC_QUALIFIER detail::tvec4<bool> isPowerOfTwo
  369. (
  370. detail::tvec4<valType> const & value
  371. )
  372. {
  373. return detail::tvec4<bool>(
  374. isPowerOfTwo(value[0]),
  375. isPowerOfTwo(value[1]),
  376. isPowerOfTwo(value[2]),
  377. isPowerOfTwo(value[3]));
  378. }
  379. // powerOfTwoAbove
  380. template <typename genType>
  381. GLM_FUNC_QUALIFIER genType powerOfTwoAbove(genType const & value)
  382. {
  383. return isPowerOfTwo(value) ? value : highestBitValue(value) << 1;
  384. }
  385. VECTORIZE_VEC(powerOfTwoAbove)
  386. // powerOfTwoBelow
  387. template <typename genType>
  388. GLM_FUNC_QUALIFIER genType powerOfTwoBelow
  389. (
  390. genType const & value
  391. )
  392. {
  393. return isPowerOfTwo(value) ? value : highestBitValue(value);
  394. }
  395. VECTORIZE_VEC(powerOfTwoBelow)
  396. // powerOfTwoNearest
  397. template <typename genType>
  398. GLM_FUNC_QUALIFIER genType powerOfTwoNearest
  399. (
  400. genType const & value
  401. )
  402. {
  403. if(isPowerOfTwo(value))
  404. return value;
  405. genType prev = highestBitValue(value);
  406. genType next = prev << 1;
  407. return (next - value) < (value - prev) ? next : prev;
  408. }
  409. VECTORIZE_VEC(powerOfTwoNearest)
  410. template <typename genType>
  411. GLM_FUNC_QUALIFIER genType bitRevert(genType const & In)
  412. {
  413. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRevert' only accept integer values");
  414. genType Out = 0;
  415. std::size_t BitSize = sizeof(genType) * 8;
  416. for(std::size_t i = 0; i < BitSize; ++i)
  417. if(In & (genType(1) << i))
  418. Out |= genType(1) << (BitSize - 1 - i);
  419. return Out;
  420. }
  421. VECTORIZE_VEC(bitRevert)
  422. template <typename genType>
  423. GLM_FUNC_QUALIFIER genType bitRotateRight(genType const & In, std::size_t Shift)
  424. {
  425. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateRight' only accept integer values");
  426. std::size_t BitSize = sizeof(genType) * 8;
  427. return (In << Shift) | (In >> (BitSize - Shift));
  428. }
  429. template <typename valType>
  430. GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateRight
  431. (
  432. detail::tvec2<valType> const & Value,
  433. std::size_t Shift
  434. )
  435. {
  436. return detail::tvec2<valType>(
  437. bitRotateRight(Value[0], Shift),
  438. bitRotateRight(Value[1], Shift));
  439. }
  440. template <typename valType>
  441. GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateRight
  442. (
  443. detail::tvec3<valType> const & Value,
  444. std::size_t Shift
  445. )
  446. {
  447. return detail::tvec3<valType>(
  448. bitRotateRight(Value[0], Shift),
  449. bitRotateRight(Value[1], Shift),
  450. bitRotateRight(Value[2], Shift));
  451. }
  452. template <typename valType>
  453. GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateRight
  454. (
  455. detail::tvec4<valType> const & Value,
  456. std::size_t Shift
  457. )
  458. {
  459. return detail::tvec4<valType>(
  460. bitRotateRight(Value[0], Shift),
  461. bitRotateRight(Value[1], Shift),
  462. bitRotateRight(Value[2], Shift),
  463. bitRotateRight(Value[3], Shift));
  464. }
  465. template <typename genType>
  466. GLM_FUNC_QUALIFIER genType bitRotateLeft(genType const & In, std::size_t Shift)
  467. {
  468. GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_integer, "'bitRotateLeft' only accept integer values");
  469. std::size_t BitSize = sizeof(genType) * 8;
  470. return (In >> Shift) | (In << (BitSize - Shift));
  471. }
  472. template <typename valType>
  473. GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateLeft
  474. (
  475. detail::tvec2<valType> const & Value,
  476. std::size_t Shift
  477. )
  478. {
  479. return detail::tvec2<valType>(
  480. bitRotateLeft(Value[0], Shift),
  481. bitRotateLeft(Value[1], Shift));
  482. }
  483. template <typename valType>
  484. GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateLeft
  485. (
  486. detail::tvec3<valType> const & Value,
  487. std::size_t Shift
  488. )
  489. {
  490. return detail::tvec3<valType>(
  491. bitRotateLeft(Value[0], Shift),
  492. bitRotateLeft(Value[1], Shift),
  493. bitRotateLeft(Value[2], Shift));
  494. }
  495. template <typename valType>
  496. GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateLeft
  497. (
  498. detail::tvec4<valType> const & Value,
  499. std::size_t Shift
  500. )
  501. {
  502. return detail::tvec4<valType>(
  503. bitRotateLeft(Value[0], Shift),
  504. bitRotateLeft(Value[1], Shift),
  505. bitRotateLeft(Value[2], Shift),
  506. bitRotateLeft(Value[3], Shift));
  507. }
  508. template <typename genIUType>
  509. GLM_FUNC_QUALIFIER genIUType fillBitfieldWithOne
  510. (
  511. genIUType const & Value,
  512. int const & FromBit,
  513. int const & ToBit
  514. )
  515. {
  516. assert(FromBit <= ToBit);
  517. assert(ToBit <= sizeof(genIUType) * std::size_t(8));
  518. genIUType Result = Value;
  519. for(std::size_t i = 0; i <= ToBit; ++i)
  520. Result |= (1 << i);
  521. return Result;
  522. }
  523. template <typename genIUType>
  524. GLM_FUNC_QUALIFIER genIUType fillBitfieldWithZero
  525. (
  526. genIUType const & Value,
  527. int const & FromBit,
  528. int const & ToBit
  529. )
  530. {
  531. assert(FromBit <= ToBit);
  532. assert(ToBit <= sizeof(genIUType) * std::size_t(8));
  533. genIUType Result = Value;
  534. for(std::size_t i = 0; i <= ToBit; ++i)
  535. Result &= ~(1 << i);
  536. return Result;
  537. }
  538. }//namespace glm