Counter Strike : Global Offensive Source Code
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.

1141 lines
30 KiB

  1. //--------------------------------------------------------------------------------------------------
  2. // qhMath.inl
  3. //
  4. // Copyright(C) 2011 by D. Gregorius. All rights reserved.
  5. //--------------------------------------------------------------------------------------------------
  6. //--------------------------------------------------------------------------------------------------
  7. // qhMath
  8. //--------------------------------------------------------------------------------------------------
  9. inline qhReal qhSin( qhReal Rad )
  10. {
  11. return sin( Rad );
  12. }
  13. //--------------------------------------------------------------------------------------------------
  14. inline qhReal qhCos( qhReal Rad )
  15. {
  16. return cos( Rad );
  17. }
  18. //--------------------------------------------------------------------------------------------------
  19. inline qhReal qhTan( qhReal Rad )
  20. {
  21. return tan( Rad );
  22. }
  23. //--------------------------------------------------------------------------------------------------
  24. inline qhReal qhArcSin( qhReal X )
  25. {
  26. return asin( X );
  27. }
  28. //--------------------------------------------------------------------------------------------------
  29. inline qhReal qhArcCos( qhReal X )
  30. {
  31. return acos( X );
  32. }
  33. //--------------------------------------------------------------------------------------------------
  34. inline qhReal qhArcTan( qhReal X )
  35. {
  36. return atan( X );
  37. }
  38. //--------------------------------------------------------------------------------------------------
  39. inline qhReal qhArcTan2( qhReal Y, qhReal X )
  40. {
  41. return atan2( Y, X );
  42. }
  43. //--------------------------------------------------------------------------------------------------
  44. inline qhReal qhAbs( qhReal X )
  45. {
  46. return X >= 0 ? X : -X;
  47. }
  48. //--------------------------------------------------------------------------------------------------
  49. inline qhReal qhSqrt( qhReal X )
  50. {
  51. return sqrt( X );
  52. }
  53. //--------------------------------------------------------------------------------------------------
  54. template< typename T > inline T qhMin( T X, T Y )
  55. {
  56. return X < Y ? X : Y;
  57. }
  58. //--------------------------------------------------------------------------------------------------
  59. template< typename T > inline T qhMax( T X, T Y )
  60. {
  61. return X > Y ? X : Y;
  62. }
  63. //--------------------------------------------------------------------------------------------------
  64. template< typename T > inline T qhClamp( T X, T Min, T Max )
  65. {
  66. return qhMax( Min, qhMin( X, Max ) );
  67. }
  68. //--------------------------------------------------------------------------------------------------
  69. // qhVector
  70. //--------------------------------------------------------------------------------------------------
  71. inline qhVector3::qhVector3( void )
  72. {
  73. }
  74. //--------------------------------------------------------------------------------------------------
  75. inline qhVector3::qhVector3( qhReal _X, qhReal _Y, qhReal _Z )
  76. : X( _X )
  77. , Y( _Y )
  78. , Z( _Z )
  79. {
  80. }
  81. //--------------------------------------------------------------------------------------------------
  82. inline qhVector3::qhVector3( const qhReal* _V )
  83. : X( _V[ 0 ] )
  84. , Y( _V[ 1 ] )
  85. , Z( _V[ 2 ] )
  86. {
  87. }
  88. //--------------------------------------------------------------------------------------------------
  89. inline qhVector3::operator qhReal*( void )
  90. {
  91. return &X;
  92. }
  93. //--------------------------------------------------------------------------------------------------
  94. inline qhVector3::operator const qhReal*( void ) const
  95. {
  96. return &X;
  97. }
  98. //--------------------------------------------------------------------------------------------------
  99. inline qhVector3& qhVector3::operator*=( const qhVector3& V )
  100. {
  101. X *= V.X;
  102. Y *= V.Y;
  103. Z *= V.Z;
  104. return *this;
  105. }
  106. //--------------------------------------------------------------------------------------------------
  107. inline qhVector3& qhVector3::operator+=( const qhVector3& V )
  108. {
  109. X += V.X;
  110. Y += V.Y;
  111. Z += V.Z;
  112. return *this;
  113. }
  114. //--------------------------------------------------------------------------------------------------
  115. inline qhVector3& qhVector3::operator-=( const qhVector3& V )
  116. {
  117. X -= V.X;
  118. Y -= V.Y;
  119. Z -= V.Z;
  120. return *this;
  121. }
  122. //--------------------------------------------------------------------------------------------------
  123. inline qhVector3& qhVector3::operator*=( qhReal S )
  124. {
  125. X *= S;
  126. Y *= S;
  127. Z *= S;
  128. return *this;
  129. }
  130. //--------------------------------------------------------------------------------------------------
  131. inline qhVector3& qhVector3::operator/=( qhReal S )
  132. {
  133. X /= S;
  134. Y /= S;
  135. Z /= S;
  136. return *this;
  137. }
  138. //--------------------------------------------------------------------------------------------------
  139. inline qhVector3 qhVector3::operator+( void ) const
  140. {
  141. return *this;
  142. }
  143. //--------------------------------------------------------------------------------------------------
  144. inline qhVector3 qhVector3::operator-( void ) const
  145. {
  146. return qhVector3( -X, -Y, -Z );
  147. }
  148. //--------------------------------------------------------------------------------------------------
  149. inline qhVector3 operator*( const qhMatrix3& M, const qhVector3& V )
  150. {
  151. return M.C1 * V.X + M.C2 * V.Y + M.C3 * V.Z;
  152. }
  153. //--------------------------------------------------------------------------------------------------
  154. inline qhVector3 operator*( const qhQuaternion& Q, const qhVector3& V )
  155. {
  156. QH_ASSERT( qhAbs( 1.0f - qhLength( Q ) ) < 100.0f * FLT_EPSILON );
  157. return V + 2 * qhCross( Q.V(), qhCross( Q.V(), V ) + Q.S() * V );
  158. }
  159. //--------------------------------------------------------------------------------------------------
  160. inline qhVector3 operator*( const qhTransform& T, const qhVector3& V )
  161. {
  162. return T.Rotation * V + T.Translation;
  163. }
  164. //--------------------------------------------------------------------------------------------------
  165. inline qhVector3 operator*( const qhVector3& V1, const qhVector3& V2 )
  166. {
  167. return qhVector3( V1.X * V2.X, V1.Y * V2.Y, V1.Z * V2.Z );
  168. }
  169. //--------------------------------------------------------------------------------------------------
  170. inline qhVector3 operator+( const qhVector3& V1, const qhVector3& V2 )
  171. {
  172. return qhVector3( V1.X + V2.X, V1.Y + V2.Y, V1.Z + V2.Z );
  173. }
  174. //--------------------------------------------------------------------------------------------------
  175. inline qhVector3 operator-( const qhVector3& V1, const qhVector3& V2 )
  176. {
  177. return qhVector3( V1.X - V2.X, V1.Y - V2.Y, V1.Z - V2.Z );
  178. }
  179. //--------------------------------------------------------------------------------------------------
  180. inline qhVector3 operator*( qhReal S, const qhVector3& V )
  181. {
  182. return qhVector3( S * V.X, S * V.Y, S * V.Z );
  183. }
  184. //--------------------------------------------------------------------------------------------------
  185. inline qhVector3 operator*( const qhVector3& V, qhReal S )
  186. {
  187. return qhVector3( V.X * S, V.Y * S, V.Z * S );
  188. }
  189. //--------------------------------------------------------------------------------------------------
  190. inline qhVector3 operator/( const qhVector3& V, qhReal S )
  191. {
  192. return qhVector3( V.X / S, V.Y / S, V.Z / S );
  193. }
  194. //--------------------------------------------------------------------------------------------------
  195. inline bool operator==( const qhVector3& V1, const qhVector3& V2 )
  196. {
  197. return V1.X == V2.X && V1.Y == V2.Y && V1.Z == V2.Z;
  198. }
  199. //--------------------------------------------------------------------------------------------------
  200. inline bool operator!=( const qhVector3& V1, const qhVector3& V2 )
  201. {
  202. return V1.X != V2.X || V1.Y != V2.Y || V1.Z != V2.Z;
  203. }
  204. //--------------------------------------------------------------------------------------------------
  205. inline void qhStore( qhReal Dst[ 3 ], const qhVector3& V )
  206. {
  207. Dst[ 0 ] = V.X;
  208. Dst[ 1 ] = V.Y;
  209. Dst[ 2 ] = V.Z;
  210. }
  211. //--------------------------------------------------------------------------------------------------
  212. inline qhVector3 qhMul( const qhMatrix3& M, const qhVector3& V )
  213. {
  214. return M.C1 * V.X + M.C2 * V.Y + M.C3 * V.Z;
  215. }
  216. //--------------------------------------------------------------------------------------------------
  217. inline qhVector3 qhTMul( const qhMatrix3& M, const qhVector3& V )
  218. {
  219. qhVector3 Out;
  220. Out.X = qhDot( M.C1, V );
  221. Out.Y = qhDot( M.C2, V );
  222. Out.Z = qhDot( M.C3, V );
  223. return Out;
  224. }
  225. //--------------------------------------------------------------------------------------------------
  226. inline qhVector3 qhMul( const qhQuaternion& Q, const qhVector3& V )
  227. {
  228. QH_ASSERT( qhAbs( qhReal( 1 ) - qhLength( Q ) ) < qhReal( 100 ) * QH_REAL_EPSILON );
  229. return V + 2.0f * qhCross( Q.V(), qhCross( Q.V(), V ) + Q.S() * V );
  230. }
  231. //--------------------------------------------------------------------------------------------------
  232. inline qhVector3 qhTMul( const qhQuaternion& Q, const qhVector3& V )
  233. {
  234. QH_ASSERT( qhAbs( qhReal( 1 ) - qhLength( Q ) ) < qhReal( 100 ) * QH_REAL_EPSILON );
  235. return V - 2.0f * qhCross( Q.V(), Q.S() * V - qhCross( Q.V(), V ) );
  236. }
  237. //--------------------------------------------------------------------------------------------------
  238. inline qhVector3 qhMul( const qhTransform& T, const qhVector3& V )
  239. {
  240. return qhMul( T.Rotation, V ) + T.Translation;
  241. }
  242. //--------------------------------------------------------------------------------------------------
  243. inline qhVector3 qhTMul( const qhTransform& T, const qhVector3& V )
  244. {
  245. return qhTMul( T.Rotation, V - T.Translation );
  246. }
  247. //--------------------------------------------------------------------------------------------------
  248. inline qhVector3 qhMul( const qhVector3& V1, const qhVector3& V2 )
  249. {
  250. return qhVector3( V1.X * V2.X, V1.Y * V2.Y, V1.Z * V2.Z );
  251. }
  252. //--------------------------------------------------------------------------------------------------
  253. inline qhVector3 qhAdd( const qhVector3& V1, const qhVector3& V2 )
  254. {
  255. return qhVector3( V1.X + V2.X, V1.Y + V2.Y, V1.Z + V2.Z );
  256. }
  257. //--------------------------------------------------------------------------------------------------
  258. inline qhVector3 qhSub( const qhVector3& V1, const qhVector3& V2 )
  259. {
  260. return qhVector3( V1.X - V2.X, V1.Y - V2.Y, V1.Z - V2.Z );
  261. }
  262. //--------------------------------------------------------------------------------------------------
  263. inline qhVector3 qhCross( const qhVector3& V1, const qhVector3& V2 )
  264. {
  265. qhReal X = V1.Y * V2.Z - V1.Z * V2.Y;
  266. qhReal Y = V1.Z * V2.X - V1.X * V2.Z;
  267. qhReal Z = V1.X * V2.Y - V1.Y * V2.X;
  268. return qhVector3( X, Y, Z );
  269. }
  270. //--------------------------------------------------------------------------------------------------
  271. inline qhVector3 qhScale( const qhVector3& V, qhReal S )
  272. {
  273. return qhVector3( V.X * S, V.Y * S, V.Z * S );
  274. }
  275. //--------------------------------------------------------------------------------------------------
  276. inline qhVector3 qhNormalize( const qhVector3& V )
  277. {
  278. qhReal Length = qhLength( V );
  279. return qhVector3( V.X / Length, V.Y / Length, V.Z / Length );
  280. }
  281. //--------------------------------------------------------------------------------------------------
  282. inline qhVector3 qhNegate( const qhVector3& V )
  283. {
  284. return qhVector3( -V.X, -V.Y, -V.Z );
  285. }
  286. //--------------------------------------------------------------------------------------------------
  287. inline qhVector3 qhAbs( const qhVector3& V )
  288. {
  289. qhVector3 Out;
  290. Out.X = qhAbs( V.X );
  291. Out.Y = qhAbs( V.Y );
  292. Out.Z = qhAbs( V.Z );
  293. return Out;
  294. }
  295. //--------------------------------------------------------------------------------------------------
  296. inline qhVector3 qhMin( const qhVector3& V1, const qhVector3& V2 )
  297. {
  298. qhVector3 Out;
  299. Out.X = qhMin( V1.X, V2.X );
  300. Out.Y = qhMin( V1.Y, V2.Y );
  301. Out.Z = qhMin( V1.Z, V2.Z );
  302. return Out;
  303. }
  304. //--------------------------------------------------------------------------------------------------
  305. inline qhVector3 qhMax( const qhVector3& V1, const qhVector3& V2 )
  306. {
  307. qhVector3 Out;
  308. Out.X = qhMax( V1.X, V2.X );
  309. Out.Y = qhMax( V1.Y, V2.Y );
  310. Out.Z = qhMax( V1.Z, V2.Z );
  311. return Out;
  312. }
  313. //--------------------------------------------------------------------------------------------------
  314. inline qhVector3 qhClamp( const qhVector3& V, const qhVector3& Min, const qhVector3& Max )
  315. {
  316. qhVector3 Out;
  317. Out.X = qhClamp( V.X, Min.X, Max.X );
  318. Out.Y = qhClamp( V.Y, Min.Y, Max.Y );
  319. Out.Z = qhClamp( V.Z, Min.Z, Max.Z );
  320. return Out;
  321. }
  322. //--------------------------------------------------------------------------------------------------
  323. inline qhReal qhDot( const qhVector3& V1, const qhVector3& V2 )
  324. {
  325. return V1.X * V2.X + V1.Y * V2.Y + V1.Z * V2.Z;
  326. }
  327. //--------------------------------------------------------------------------------------------------
  328. inline qhReal qhLength( const qhVector3& V )
  329. {
  330. return sqrt( qhDot( V, V ) );
  331. }
  332. //--------------------------------------------------------------------------------------------------
  333. inline qhReal qhLengthSq( const qhVector3& V )
  334. {
  335. return qhDot( V, V );
  336. }
  337. //--------------------------------------------------------------------------------------------------
  338. inline qhReal qhDistance( const qhVector3& V1, const qhVector3& V2 )
  339. {
  340. return qhLength( V1 - V2 );
  341. }
  342. //--------------------------------------------------------------------------------------------------
  343. inline qhReal qhDistanceSq( const qhVector3& V1, const qhVector3& V2 )
  344. {
  345. return qhLengthSq( V1 - V2 );
  346. }
  347. //--------------------------------------------------------------------------------------------------
  348. inline qhReal qhDet( const qhVector3& V1, const qhVector3& V2, const qhVector3& V3 )
  349. {
  350. return qhDot( V1, qhCross( V2, V3 ) );
  351. }
  352. //--------------------------------------------------------------------------------------------------
  353. inline int qhMinElement( const qhVector3& V )
  354. {
  355. return V.X < V.Y ? ( V.X < V.Z ? 0 : 2 ) : ( V.Y < V.Z ? 1 : 2 );
  356. }
  357. //--------------------------------------------------------------------------------------------------
  358. inline int qhMaxElement( const qhVector3& V )
  359. {
  360. return V.X < V.Y ? ( V.Y < V.Z ? 2 : 1 ) : ( V.X < V.Z ? 2 : 0 );
  361. }
  362. //--------------------------------------------------------------------------------------------------
  363. // qhMatrix3
  364. //--------------------------------------------------------------------------------------------------
  365. inline qhMatrix3::qhMatrix3( void )
  366. {
  367. }
  368. //--------------------------------------------------------------------------------------------------
  369. inline qhMatrix3::qhMatrix3( qhReal A11, qhReal A22, qhReal A33 )
  370. : C1( A11, 0.0f, 0.0f )
  371. , C2( 0.0f, A22, 0.0f )
  372. , C3( 0.0f, 0.0f, A33 )
  373. {
  374. }
  375. //--------------------------------------------------------------------------------------------------
  376. inline qhMatrix3::qhMatrix3( const qhVector3& C1, const qhVector3& C2, const qhVector3& C3 )
  377. : C1( C1 )
  378. , C2( C2 )
  379. , C3( C3 )
  380. {
  381. }
  382. //--------------------------------------------------------------------------------------------------
  383. inline qhMatrix3& qhMatrix3::operator*=( const qhMatrix3& M )
  384. {
  385. *this = qhMul( *this, M );
  386. return *this;
  387. }
  388. //--------------------------------------------------------------------------------------------------
  389. inline qhMatrix3& qhMatrix3::operator+=( const qhMatrix3& M )
  390. {
  391. C1 += M.C1;
  392. C2 += M.C2;
  393. C3 += M.C3;
  394. return *this;
  395. }
  396. //--------------------------------------------------------------------------------------------------
  397. inline qhMatrix3& qhMatrix3::operator-=( const qhMatrix3& M )
  398. {
  399. C1 -= M.C1;
  400. C2 -= M.C2;
  401. C3 -= M.C3;
  402. return *this;
  403. }
  404. //--------------------------------------------------------------------------------------------------
  405. inline qhMatrix3& qhMatrix3::operator*=( qhReal F )
  406. {
  407. C1 *= F;
  408. C2 *= F;
  409. C3 *= F;
  410. return *this;
  411. }
  412. //--------------------------------------------------------------------------------------------------
  413. inline qhMatrix3& qhMatrix3::operator/=( qhReal F )
  414. {
  415. C1 /= F;
  416. C2 /= F;
  417. C3 /= F;
  418. return *this;
  419. }
  420. //--------------------------------------------------------------------------------------------------
  421. inline qhMatrix3 qhMatrix3::operator+( void ) const
  422. {
  423. return *this;
  424. }
  425. //--------------------------------------------------------------------------------------------------
  426. inline qhMatrix3 qhMatrix3::operator-( void ) const
  427. {
  428. qhMatrix3 Out;
  429. Out.C1 = -C1;
  430. Out.C2 = -C2;
  431. Out.C3 = -C3;
  432. return Out;
  433. }
  434. //--------------------------------------------------------------------------------------------------
  435. inline qhMatrix3 operator*( const qhMatrix3& M1, const qhMatrix3& M2 )
  436. {
  437. qhMatrix3 Out;
  438. Out.C1 = M1 * M2.C1;
  439. Out.C2 = M1 * M2.C2;
  440. Out.C3 = M1 * M2.C3;
  441. return Out;
  442. }
  443. //--------------------------------------------------------------------------------------------------
  444. inline qhMatrix3 operator+( const qhMatrix3& M1, const qhMatrix3& M2 )
  445. {
  446. qhMatrix3 Out;
  447. Out.C1 = M1.C1 + M2.C1;
  448. Out.C2 = M1.C2 + M2.C2;
  449. Out.C3 = M1.C3 + M2.C3;
  450. return Out;
  451. }
  452. //--------------------------------------------------------------------------------------------------
  453. inline qhMatrix3 operator-( const qhMatrix3& M1, const qhMatrix3& M2 )
  454. {
  455. qhMatrix3 Out;
  456. Out.C1 = M1.C1 - M2.C1;
  457. Out.C2 = M1.C2 - M2.C2;
  458. Out.C3 = M1.C3 - M2.C3;
  459. return Out;
  460. }
  461. //--------------------------------------------------------------------------------------------------
  462. inline qhMatrix3 operator*( qhReal F, const qhMatrix3& M )
  463. {
  464. qhMatrix3 Out;
  465. Out.C1 = F * M.C1;
  466. Out.C2 = F * M.C2;
  467. Out.C3 = F * M.C3;
  468. return Out;
  469. }
  470. //--------------------------------------------------------------------------------------------------
  471. inline qhMatrix3 operator*( const qhMatrix3& M, qhReal F )
  472. {
  473. qhMatrix3 Out;
  474. Out.C1 = M.C1 * F;
  475. Out.C2 = M.C2 * F;
  476. Out.C3 = M.C3 * F;
  477. return Out;
  478. }
  479. //--------------------------------------------------------------------------------------------------
  480. inline qhMatrix3 operator/( const qhMatrix3& M, qhReal F )
  481. {
  482. qhMatrix3 Out;
  483. Out.C1 = M.C1 / F;
  484. Out.C2 = M.C2 / F;
  485. Out.C3 = M.C3 / F;
  486. return Out;
  487. }
  488. //--------------------------------------------------------------------------------------------------
  489. inline bool operator==( const qhMatrix3& M1, const qhMatrix3& M2 )
  490. {
  491. return M1.C1 == M2.C1 && M1.C2 == M2.C2 && M1.C3 == M2.C3;
  492. }
  493. //--------------------------------------------------------------------------------------------------
  494. inline bool operator!=( const qhMatrix3& M1, const qhMatrix3& M2 )
  495. {
  496. return M1.C1 != M2.C1 || M1.C2 != M2.C2 || M1.C3 != M2.C3;
  497. }
  498. //--------------------------------------------------------------------------------------------------
  499. inline qhMatrix3 qhMul( const qhMatrix3& M1, const qhMatrix3& M2 )
  500. {
  501. qhMatrix3 Out;
  502. Out.C1 = M1 * M2.C1;
  503. Out.C2 = M1 * M2.C2;
  504. Out.C3 = M1 * M2.C3;
  505. return Out;
  506. }
  507. //--------------------------------------------------------------------------------------------------
  508. inline qhMatrix3 qhTMul( const qhMatrix3& M1, const qhMatrix3& M2 )
  509. {
  510. QH_ASSERT( 0 );
  511. return qhMatrix3();
  512. }
  513. //--------------------------------------------------------------------------------------------------
  514. inline qhMatrix3 qhTranspose( const qhMatrix3& M )
  515. {
  516. qhMatrix3 Out;
  517. Out.C1 = qhVector3( M.C1.X, M.C2.X, M.C3.X );
  518. Out.C2 = qhVector3( M.C1.Y, M.C2.Y, M.C3.Y );
  519. Out.C3 = qhVector3( M.C1.Z, M.C2.Z, M.C3.Z );
  520. return Out;
  521. }
  522. //--------------------------------------------------------------------------------------------------
  523. inline qhMatrix3 qhInvert( const qhMatrix3& M )
  524. {
  525. qhReal Det = qhDet( M );
  526. if ( Det > 1000.0f * FLT_MIN )
  527. {
  528. qhMatrix3 Out;
  529. Out.C1 = qhCross( M.C2, M.C3 ) / Det;
  530. Out.C2 = qhCross( M.C3, M.C1 ) / Det;
  531. Out.C3 = qhCross( M.C1, M.C2 ) / Det;
  532. return qhTranspose( Out );
  533. }
  534. return QH_MAT3_ZERO;
  535. }
  536. //--------------------------------------------------------------------------------------------------
  537. inline qhMatrix3 qhInvertT( const qhMatrix3& M )
  538. {
  539. qhReal Det = qhDet( M );
  540. if ( Det > 1000.0f * FLT_MIN )
  541. {
  542. qhMatrix3 Out;
  543. Out.C1 = qhCross( M.C2, M.C3 ) / Det;
  544. Out.C2 = qhCross( M.C3, M.C1 ) / Det;
  545. Out.C3 = qhCross( M.C1, M.C2 ) / Det;
  546. return Out;
  547. }
  548. return QH_MAT3_ZERO;
  549. }
  550. //--------------------------------------------------------------------------------------------------
  551. inline qhMatrix3 qhConvert( const qhQuaternion& Q )
  552. {
  553. qhReal XX = Q.X * Q.X;
  554. qhReal YY = Q.Y * Q.Y;
  555. qhReal ZZ = Q.Z * Q.Z;
  556. qhReal XY = Q.X * Q.Y;
  557. qhReal XZ = Q.X * Q.Z;
  558. qhReal XW = Q.X * Q.W;
  559. qhReal YZ = Q.Y * Q.Z;
  560. qhReal YW = Q.Y * Q.W;
  561. qhReal ZW = Q.Z * Q.W;
  562. qhMatrix3 Out;
  563. Out.C1 = qhVector3( 1.0f - 2.0f * ( YY + ZZ ), 2.0f * ( XY + ZW ), 2.0f * ( XZ - YW ) );
  564. Out.C2 = qhVector3( 2.0f * ( XY - ZW ), 1.0f - 2.0f * ( XX + ZZ ), 2.0f * ( YZ + XW ) );
  565. Out.C3 = qhVector3( 2.0f * ( XZ + YW ), 2.0f * ( YZ - XW ), 1.0f - 2.0f * ( XX + YY ) );
  566. return Out;
  567. }
  568. //--------------------------------------------------------------------------------------------------
  569. inline qhMatrix3 qhSkew( const qhVector3& V )
  570. {
  571. qhMatrix3 Out;
  572. Out.C1 = qhVector3( 0, V.Z, -V.Y );
  573. Out.C2 = qhVector3( -V.Z, 0, V.X );
  574. Out.C3 = qhVector3( V.Y, -V.X, 0 );
  575. return Out;
  576. }
  577. //--------------------------------------------------------------------------------------------------
  578. inline qhReal qhTrace( const qhMatrix3& M )
  579. {
  580. return M.C1.X + M.C2.Y + M.C3.Z;
  581. }
  582. //--------------------------------------------------------------------------------------------------
  583. inline qhReal qhDet( const qhMatrix3& M )
  584. {
  585. return qhDot( M.C1, qhCross( M.C2, M.C3 ) );
  586. }
  587. //--------------------------------------------------------------------------------------------------
  588. // qhQuaternion
  589. //--------------------------------------------------------------------------------------------------
  590. inline qhQuaternion::qhQuaternion( void )
  591. {
  592. }
  593. //--------------------------------------------------------------------------------------------------
  594. inline qhQuaternion::qhQuaternion( qhReal _X, qhReal _Y, qhReal _Z, qhReal _W )
  595. : X( _X )
  596. , Y( _Y )
  597. , Z( _Z )
  598. , W( _W )
  599. {
  600. }
  601. //--------------------------------------------------------------------------------------------------
  602. inline qhQuaternion::qhQuaternion( const qhVector3& V, qhReal S )
  603. : X( V.X )
  604. , Y( V.Y )
  605. , Z( V.Z )
  606. , W( S )
  607. {
  608. }
  609. //--------------------------------------------------------------------------------------------------
  610. inline qhQuaternion::qhQuaternion( const qhReal* Q )
  611. : X( Q[ 0 ] )
  612. , Y( Q[ 1 ] )
  613. , Z( Q[ 2 ] )
  614. , W( Q[ 3 ] )
  615. {
  616. }
  617. //--------------------------------------------------------------------------------------------------
  618. inline qhQuaternion operator*( const qhQuaternion& Q1, const qhQuaternion& Q2 )
  619. {
  620. qhVector3 V = qhCross( Q1.V(), Q2.V() ) + Q2.V() * Q1.S() + Q1.V() * Q2.S();
  621. qhReal S = Q1.S() * Q2.S() - qhDot( Q1.V(), Q2.V() );
  622. return qhQuaternion( V, S );
  623. }
  624. //--------------------------------------------------------------------------------------------------
  625. inline qhQuaternion qhRotation( const qhVector3& V1, const qhVector3& V2 )
  626. {
  627. qhQuaternion Out;
  628. qhVector3 M = 0.5f * ( V1 + V2 );
  629. if ( qhLengthSq( M ) > FLT_EPSILON * FLT_EPSILON )
  630. {
  631. qhVector3 V = qhCross( V1, M );
  632. qhReal S = qhDot( V1, M );
  633. Out = qhQuaternion( V, S );
  634. }
  635. else
  636. {
  637. // Anti-parallel: Use a perpendicular vector
  638. if ( qhAbs( V1.X ) > 0.5f )
  639. {
  640. Out.X = V1.Y;
  641. Out.Y = -V1.X;
  642. Out.Z = 0.0f;
  643. }
  644. else
  645. {
  646. Out.X = 0.0f;
  647. Out.Y = V1.Z;
  648. Out.Z = -V1.Y;
  649. }
  650. Out.W = 0.0f;
  651. }
  652. // The algorithm is simplified and made more accurate by normalizing at the end
  653. return qhNormalize( Out );
  654. }
  655. //--------------------------------------------------------------------------------------------------
  656. inline qhQuaternion qhRotationX( float Rad )
  657. {
  658. qhReal Sin = qhSin( qhReal( 0.5 ) * Rad );
  659. qhReal Cos = qhCos( qhReal( 0.5 ) * Rad );
  660. qhVector3 V = qhVector3( Sin, 0.0f, 0.0f );
  661. qhReal S = Cos;
  662. return qhQuaternion( V, S );
  663. }
  664. //--------------------------------------------------------------------------------------------------
  665. inline qhQuaternion qhRotationY( float Rad )
  666. {
  667. qhReal Sin = qhSin( qhReal( 0.5 ) * Rad );
  668. qhReal Cos = qhCos( qhReal( 0.5 ) * Rad );
  669. qhVector3 V = qhVector3( 0.0f, Sin, 0.0f );
  670. qhReal S = Cos;
  671. return qhQuaternion( V, S );
  672. }
  673. //--------------------------------------------------------------------------------------------------
  674. inline qhQuaternion qhRotationZ( float Rad )
  675. {
  676. qhReal Sin = qhSin( qhReal( 0.5 ) * Rad );
  677. qhReal Cos = qhCos( qhReal( 0.5 ) * Rad );
  678. qhVector3 V = qhVector3( 0.0f, 0.0f, Sin );
  679. qhReal S = Cos;
  680. return qhQuaternion( V, S );
  681. }
  682. //--------------------------------------------------------------------------------------------------
  683. inline qhQuaternion qhConjugate( const qhQuaternion& Q )
  684. {
  685. qhVector3 V = -Q.V();
  686. qhReal S = Q.S();
  687. return qhQuaternion( V, S );
  688. }
  689. //--------------------------------------------------------------------------------------------------
  690. inline qhQuaternion qhNormalize( const qhQuaternion& Q )
  691. {
  692. qhReal Length = qhLength( Q );
  693. if ( Length > qhReal( 1000.0 ) * FLT_MIN )
  694. {
  695. qhQuaternion Out;
  696. Out.X = Q.X / Length;
  697. Out.Y = Q.Y / Length;
  698. Out.Z = Q.Z / Length;
  699. Out.W = Q.W / Length;
  700. return Out;
  701. }
  702. return QH_QUAT_ZERO;
  703. }
  704. //--------------------------------------------------------------------------------------------------
  705. inline qhReal qhDot( const qhQuaternion& Q1, const qhQuaternion& Q2 )
  706. {
  707. return Q1.X * Q2.X + Q1.Y * Q2.Y + Q1.Z * Q2.Z + Q1.W * Q2.W;
  708. }
  709. //--------------------------------------------------------------------------------------------------
  710. inline qhReal qhLength( const qhQuaternion& Q )
  711. {
  712. return qhSqrt( Q.X * Q.X + Q.Y * Q.Y + Q.Z * Q.Z + Q.W * Q.W );
  713. }
  714. //--------------------------------------------------------------------------------------------------
  715. inline qhReal qhLengthSq( const qhQuaternion& Q )
  716. {
  717. return Q.X * Q.X + Q.Y * Q.Y + Q.Z * Q.Z + Q.W * Q.W;
  718. }
  719. //--------------------------------------------------------------------------------------------------
  720. // qhPlane
  721. //--------------------------------------------------------------------------------------------------
  722. inline qhPlane::qhPlane( void )
  723. {
  724. }
  725. //--------------------------------------------------------------------------------------------------
  726. inline qhPlane::qhPlane( const qhVector3& _Normal, qhReal _Offset )
  727. : Normal( _Normal )
  728. , Offset( _Offset )
  729. {
  730. }
  731. //--------------------------------------------------------------------------------------------------
  732. inline qhPlane::qhPlane( const qhVector3& _Normal, const qhVector3& _Point )
  733. : Normal( _Normal )
  734. , Offset( qhDot( _Normal, _Point ) )
  735. {
  736. }
  737. //--------------------------------------------------------------------------------------------------
  738. inline qhPlane::qhPlane( const qhVector3& Point1, const qhVector3& Point2, const qhVector3& Point3 )
  739. {
  740. qhVector3 Edge1 = Point2 - Point1;
  741. qhVector3 Edge2 = Point3 - Point1;
  742. Normal = qhCross( Edge1, Edge2 );
  743. Offset = qhDot( Normal , Point1 );
  744. }
  745. //--------------------------------------------------------------------------------------------------
  746. inline void qhPlane::Negate( void )
  747. {
  748. Normal = -Normal;
  749. Offset = -Offset;
  750. }
  751. //--------------------------------------------------------------------------------------------------
  752. inline void qhPlane::Normalize( void )
  753. {
  754. qhReal Length = qhLength( Normal );
  755. Normal /= Length;
  756. Offset /= Length;
  757. }
  758. //--------------------------------------------------------------------------------------------------
  759. inline void qhPlane::Translate( const qhVector3& Translation )
  760. {
  761. Offset += qhDot( Normal, Translation );
  762. }
  763. //--------------------------------------------------------------------------------------------------
  764. inline qhReal qhPlane::Distance( const qhVector3& Point ) const
  765. {
  766. return qhDot( Normal, Point ) - Offset;
  767. }
  768. //--------------------------------------------------------------------------------------------------
  769. inline void qhStore( qhReal Dst[ 4 ], const qhPlane& Plane )
  770. {
  771. Dst[ 0 ] = Plane.Normal.X;
  772. Dst[ 1 ] = Plane.Normal.Y;
  773. Dst[ 2 ] = Plane.Normal.Z;
  774. Dst[ 3 ] = Plane.Offset;
  775. }
  776. //--------------------------------------------------------------------------------------------------
  777. // qhBounds3
  778. //--------------------------------------------------------------------------------------------------
  779. inline qhBounds3::qhBounds3( void )
  780. {
  781. }
  782. //--------------------------------------------------------------------------------------------------
  783. inline qhBounds3::qhBounds3( const qhVector3& Min, const qhVector3& Max )
  784. : Min( Min )
  785. , Max( Max )
  786. {
  787. }
  788. //--------------------------------------------------------------------------------------------------
  789. inline qhBounds3& qhBounds3::operator+=( const qhVector3& Point )
  790. {
  791. Min = qhMin( Min, Point );
  792. Max = qhMax( Max, Point );
  793. return *this;
  794. }
  795. //--------------------------------------------------------------------------------------------------
  796. inline qhBounds3& qhBounds3::operator+=( const qhBounds3& Bounds )
  797. {
  798. Min = qhMin( Min, Bounds.Min );
  799. Max = qhMax( Max, Bounds.Max );
  800. return *this;
  801. }
  802. //--------------------------------------------------------------------------------------------------
  803. inline qhVector3 qhBounds3::GetCenter( void ) const
  804. {
  805. return 0.5f * ( Max + Min );
  806. }
  807. //--------------------------------------------------------------------------------------------------
  808. inline qhVector3 qhBounds3::GetExtent( void ) const
  809. {
  810. return 0.5f * ( Max - Min );
  811. }
  812. //--------------------------------------------------------------------------------------------------
  813. inline qhReal qhBounds3::GetVolume( void ) const
  814. {
  815. qhVector3 Diagonal = Max - Min;
  816. return Diagonal.X * Diagonal.Y * Diagonal.Z;
  817. }
  818. //--------------------------------------------------------------------------------------------------
  819. inline qhBounds3 operator+( const qhBounds3& Bounds1, const qhBounds3& Bounds2 )
  820. {
  821. qhBounds3 Out;
  822. Out.Min = qhMin( Bounds1.Min, Bounds2.Min );
  823. Out.Max = qhMax( Bounds1.Max, Bounds2.Max );
  824. return Out;
  825. }
  826. //--------------------------------------------------------------------------------------------------
  827. inline bool operator==( const qhBounds3& Bounds1, const qhBounds3& Bounds2 )
  828. {
  829. return Bounds1.Min == Bounds2.Min && Bounds1.Max == Bounds2.Max;
  830. }
  831. //--------------------------------------------------------------------------------------------------
  832. inline bool operator!=( const qhBounds3& Bounds1, const qhBounds3& Bounds2 )
  833. {
  834. return Bounds1.Min != Bounds2.Min || Bounds1.Max != Bounds2.Max;
  835. }