Leaked source code of windows server 2003
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.

2664 lines
66 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 1998 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: d3dxmath.cpp
  6. // Content:
  7. //
  8. //////////////////////////////////////////////////////////////////////////////
  9. #include "pchmath.h"
  10. #define EPSILON 0.00001f
  11. //
  12. // WithinEpsilon - Are two values within EPSILON of each other?
  13. //
  14. static inline BOOL
  15. WithinEpsilon(float a, float b)
  16. {
  17. float f = a - b;
  18. return -EPSILON <= f && f <= EPSILON;
  19. }
  20. //
  21. // sincosf - Compute the sin and cos of an angle at the same time
  22. //
  23. static inline void
  24. sincosf(float angle, float *psin, float *pcos)
  25. {
  26. #ifdef _X86_
  27. #define fsincos __asm _emit 0xd9 __asm _emit 0xfb
  28. __asm {
  29. mov eax, psin
  30. mov edx, pcos
  31. fld angle
  32. fsincos
  33. fstp DWORD ptr [edx]
  34. fstp DWORD ptr [eax]
  35. }
  36. #undef fsincos
  37. #else //!_X86_
  38. *psin = sinf(angle);
  39. *pcos = cosf(angle);
  40. #endif //!_X86_
  41. }
  42. //--------------------------
  43. // 2D Vector
  44. //--------------------------
  45. D3DXVECTOR2* WINAPI VB_D3DXVec2Normalize
  46. ( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV )
  47. {
  48. #if DBG
  49. if(!pOut || !pV)
  50. return NULL;
  51. #endif
  52. float f = VB_D3DXVec2LengthSq(pV);
  53. if(WithinEpsilon(f, 1.0f))
  54. {
  55. if(pOut != pV)
  56. *pOut = *pV;
  57. }
  58. else if(f > EPSILON * EPSILON)
  59. {
  60. *pOut = *pV / sqrtf(f);
  61. }
  62. else
  63. {
  64. pOut->x = 0.0f;
  65. pOut->y = 0.0f;
  66. }
  67. return pOut;
  68. }
  69. D3DXVECTOR2* WINAPI VB_D3DXVec2Hermite
  70. ( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV1, const D3DXVECTOR2 *pT1,
  71. const D3DXVECTOR2 *pV2, const D3DXVECTOR2 *pT2, float s )
  72. {
  73. #if DBG
  74. if(!pOut || !pV1 || !pT1 || !pV2 || !pT2)
  75. return NULL;
  76. #endif
  77. float s2 = s * s;
  78. float s3 = s * s2;
  79. float sV1 = 2.0f * s3 - 3.0f * s2 + 1.0f;
  80. float sT1 = s3 - 2.0f * s2 + s;
  81. float sV2 = -2.0f * s3 + 3.0f * s2;
  82. float sT2 = s3 - s2;
  83. pOut->x = sV1 * pV1->x + sT1 * pT1->x + sV2 * pV2->x + sT2 * pT2->x;
  84. pOut->y = sV1 * pV1->y + sT1 * pT1->y + sV2 * pV2->y + sT2 * pT2->y;
  85. return pOut;
  86. }
  87. D3DXVECTOR2* WINAPI VB_D3DXVec2BaryCentric
  88. ( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV1, const D3DXVECTOR2 *pV2,
  89. D3DXVECTOR2 *pV3, float f, float g)
  90. {
  91. #if DBG
  92. if(!pOut || !pV1 || !pV2 || !pV3)
  93. return NULL;
  94. #endif
  95. pOut->x = pV1->x + f * (pV2->x - pV1->x) + g * (pV3->x - pV1->x);
  96. pOut->y = pV1->y + f * (pV2->y - pV1->y) + g * (pV3->y - pV1->y);
  97. return pOut;
  98. }
  99. D3DXVECTOR4* WINAPI VB_D3DXVec2Transform
  100. ( D3DXVECTOR4 *pOut, const D3DXVECTOR2 *pV, const D3DXMATRIX *pM )
  101. {
  102. #if DBG
  103. if(!pOut || !pV || !pM)
  104. return NULL;
  105. #endif
  106. #ifdef _X86_
  107. __asm {
  108. mov eax, DWORD PTR [pV]
  109. mov edx, DWORD PTR [pM]
  110. mov ecx, DWORD PTR [pOut]
  111. fld DWORD PTR [eax+0*4] ; X
  112. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  113. fld DWORD PTR [eax+0*4] ; X
  114. fmul DWORD PTR [edx+(0*4+2)*4] ; M02
  115. fld DWORD PTR [eax+0*4] ; X
  116. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  117. fld DWORD PTR [eax+0*4] ; X
  118. fmul DWORD PTR [edx+(0*4+3)*4] ; M03
  119. fxch st(3)
  120. fld DWORD PTR [eax+1*4] ; Y
  121. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  122. fld DWORD PTR [eax+1*4] ; Y
  123. fmul DWORD PTR [edx+(1*4+2)*4] ; M12
  124. fld DWORD PTR [eax+1*4] ; Y
  125. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  126. fld DWORD PTR [eax+1*4] ; Y
  127. fmul DWORD PTR [edx+(1*4+3)*4] ; M13
  128. fxch st(3)
  129. faddp st(4), st
  130. faddp st(4), st
  131. faddp st(4), st
  132. faddp st(4), st
  133. fld DWORD PTR [edx+(3*4+0)*4] ; M30
  134. faddp st(1), st
  135. fld DWORD PTR [edx+(3*4+1)*4] ; M31
  136. faddp st(2), st
  137. fld DWORD PTR [edx+(3*4+2)*4] ; M32
  138. faddp st(3), st
  139. fld DWORD PTR [edx+(3*4+3)*4] ; M33
  140. faddp st(4), st
  141. fstp DWORD PTR [ecx+0*4]
  142. fstp DWORD PTR [ecx+1*4]
  143. fstp DWORD PTR [ecx+2*4]
  144. fstp DWORD PTR [ecx+3*4]
  145. }
  146. return pOut;
  147. #else // !_X86_
  148. D3DXVECTOR4 v;
  149. v.x = pV->x * pM->m00 + pV->y * pM->m10 + pM->m30;
  150. v.y = pV->x * pM->m01 + pV->y * pM->m11 + pM->m31;
  151. v.z = pV->x * pM->m02 + pV->y * pM->m12 + pM->m32;
  152. v.w = pV->x * pM->m03 + pV->y * pM->m13 + pM->m33;
  153. *pOut = v;
  154. return pOut;
  155. #endif // !_X86_
  156. }
  157. D3DXVECTOR2* WINAPI VB_D3DXVec2TransformCoord
  158. ( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV, const D3DXMATRIX *pM )
  159. {
  160. #if DBG
  161. if(!pOut || !pV || !pM)
  162. return NULL;
  163. #endif
  164. float w;
  165. #ifdef _X86_
  166. __asm {
  167. mov eax, DWORD PTR [pV]
  168. mov edx, DWORD PTR [pM]
  169. mov ecx, DWORD PTR [pOut]
  170. fld DWORD PTR [eax+0*4] ; X
  171. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  172. fld DWORD PTR [eax+0*4] ; X
  173. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  174. fld DWORD PTR [eax+0*4] ; X
  175. fmul DWORD PTR [edx+(0*4+3)*4] ; M03
  176. fxch st(2)
  177. fld DWORD PTR [eax+1*4] ; Y
  178. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  179. fld DWORD PTR [eax+1*4] ; Y
  180. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  181. fld DWORD PTR [eax+1*4] ; Y
  182. fmul DWORD PTR [edx+(1*4+3)*4] ; M13
  183. fxch st(2)
  184. faddp st(3), st
  185. faddp st(3), st
  186. faddp st(3), st
  187. fld DWORD PTR [eax+2*4] ; Z
  188. fmul DWORD PTR [edx+(2*4+0)*4] ; M20
  189. fld DWORD PTR [eax+2*4] ; Z
  190. fmul DWORD PTR [edx+(2*4+1)*4] ; M21
  191. fld DWORD PTR [eax+2*4] ; Z
  192. fmul DWORD PTR [edx+(2*4+3)*4] ; M23
  193. fxch st(2)
  194. faddp st(3), st
  195. faddp st(3), st
  196. faddp st(3), st
  197. fld DWORD PTR [edx+(3*4+0)*4] ; M30
  198. faddp st(1), st
  199. fld DWORD PTR [edx+(3*4+1)*4] ; M31
  200. faddp st(2), st
  201. fld DWORD PTR [edx+(3*4+3)*4] ; M33
  202. faddp st(3), st
  203. fstp DWORD PTR [ecx+0*4]
  204. fstp DWORD PTR [ecx+1*4]
  205. fstp DWORD PTR [w]
  206. }
  207. #else // !_X86_
  208. D3DXVECTOR4 v;
  209. v.x = pV->x * pM->m00 + pV->y * pM->m10 + pM->m30;
  210. v.y = pV->x * pM->m01 + pV->y * pM->m11 + pM->m31;
  211. w = pV->x * pM->m03 + pV->y * pM->m13 + pM->m33;
  212. *pOut = *((D3DXVECTOR2 *) &v);
  213. #endif // !_X86_
  214. if(!WithinEpsilon(w, 1.0f))
  215. *pOut /= w;
  216. return pOut;
  217. }
  218. D3DXVECTOR2* WINAPI VB_D3DXVec2TransformNormal
  219. ( D3DXVECTOR2 *pOut, const D3DXVECTOR2 *pV, const D3DXMATRIX *pM )
  220. {
  221. #if DBG
  222. if(!pOut || !pV || !pM)
  223. return NULL;
  224. #endif
  225. #ifdef _X86_
  226. __asm {
  227. mov eax, DWORD PTR [pV]
  228. mov edx, DWORD PTR [pM]
  229. mov ecx, DWORD PTR [pOut]
  230. fld DWORD PTR [eax+0*4] ; X
  231. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  232. fld DWORD PTR [eax+0*4] ; X
  233. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  234. fxch st(1)
  235. fld DWORD PTR [eax+1*4] ; Y
  236. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  237. fld DWORD PTR [eax+1*4] ; Y
  238. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  239. fxch st(1)
  240. faddp st(2), st
  241. faddp st(2), st
  242. fstp DWORD PTR [ecx+0*4]
  243. fstp DWORD PTR [ecx+1*4]
  244. }
  245. return pOut;
  246. #else // !_X86_
  247. D3DXVECTOR2 v;
  248. v.x = pV->x * pM->m00 + pV->y * pM->m10;
  249. v.y = pV->x * pM->m01 + pV->y * pM->m11;
  250. *pOut = v;
  251. return pOut;
  252. #endif // !_X86_
  253. }
  254. //--------------------------
  255. // 3D Vector
  256. //--------------------------
  257. D3DXVECTOR3* WINAPI VB_D3DXVec3Normalize
  258. ( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV )
  259. {
  260. #if DBG
  261. if(!pOut || !pV)
  262. return NULL;
  263. #endif
  264. float f = VB_D3DXVec3LengthSq(pV);
  265. if(WithinEpsilon(f, 1.0f))
  266. {
  267. if(pOut != pV)
  268. *pOut = *pV;
  269. }
  270. else if(f > EPSILON * EPSILON)
  271. {
  272. *pOut = *pV / sqrtf(f);
  273. }
  274. else
  275. {
  276. pOut->x = 0.0f;
  277. pOut->y = 0.0f;
  278. pOut->z = 0.0f;
  279. }
  280. return pOut;
  281. }
  282. D3DXVECTOR3* WINAPI VB_D3DXVec3Hermite
  283. ( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pT1,
  284. const D3DXVECTOR3 *pV2, const D3DXVECTOR3 *pT2, float s )
  285. {
  286. #if DBG
  287. if(!pOut || !pV1 || !pT1 || !pV2 || !pT2)
  288. return NULL;
  289. #endif
  290. float s2 = s * s;
  291. float s3 = s * s2;
  292. float sV1 = 2.0f * s3 - 3.0f * s2 + 1.0f;
  293. float sT1 = s3 - 2.0f * s2 + s;
  294. float sV2 = -2.0f * s3 + 3.0f * s2;
  295. float sT2 = s3 - s2;
  296. pOut->x = sV1 * pV1->x + sT1 * pT1->x + sV2 * pV2->x + sT2 * pT2->x;
  297. pOut->y = sV1 * pV1->y + sT1 * pT1->y + sV2 * pV2->y + sT2 * pT2->y;
  298. pOut->z = sV1 * pV1->z + sT1 * pT1->z + sV2 * pV2->z + sT2 * pT2->z;
  299. return pOut;
  300. }
  301. D3DXVECTOR3* WINAPI VB_D3DXVec3BaryCentric
  302. ( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pV2,
  303. const D3DXVECTOR3 *pV3, float f, float g)
  304. {
  305. #if DBG
  306. if(!pOut || !pV1 || !pV2 || !pV3)
  307. return NULL;
  308. #endif
  309. pOut->x = pV1->x + f * (pV2->x - pV1->x) + g * (pV3->x - pV1->x);
  310. pOut->y = pV1->y + f * (pV2->y - pV1->y) + g * (pV3->y - pV1->y);
  311. pOut->z = pV1->z + f * (pV2->z - pV1->z) + g * (pV3->z - pV1->z);
  312. return pOut;
  313. }
  314. D3DXVECTOR4* WINAPI VB_D3DXVec3Transform
  315. ( D3DXVECTOR4 *pOut, const D3DXVECTOR3 *pV, const D3DXMATRIX *pM )
  316. {
  317. #if DBG
  318. if(!pOut || !pV || !pM)
  319. return NULL;
  320. #endif
  321. #ifdef _X86_
  322. __asm {
  323. mov eax, DWORD PTR [pV]
  324. mov edx, DWORD PTR [pM]
  325. mov ecx, DWORD PTR [pOut]
  326. fld DWORD PTR [eax+0*4] ; X
  327. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  328. fld DWORD PTR [eax+0*4] ; X
  329. fmul DWORD PTR [edx+(0*4+2)*4] ; M02
  330. fld DWORD PTR [eax+0*4] ; X
  331. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  332. fld DWORD PTR [eax+0*4] ; X
  333. fmul DWORD PTR [edx+(0*4+3)*4] ; M03
  334. fxch st(3)
  335. fld DWORD PTR [eax+1*4] ; Y
  336. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  337. fld DWORD PTR [eax+1*4] ; Y
  338. fmul DWORD PTR [edx+(1*4+2)*4] ; M12
  339. fld DWORD PTR [eax+1*4] ; Y
  340. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  341. fld DWORD PTR [eax+1*4] ; Y
  342. fmul DWORD PTR [edx+(1*4+3)*4] ; M13
  343. fxch st(3)
  344. faddp st(4), st
  345. faddp st(4), st
  346. faddp st(4), st
  347. faddp st(4), st
  348. fld DWORD PTR [eax+2*4] ; Z
  349. fmul DWORD PTR [edx+(2*4+0)*4] ; M20
  350. fld DWORD PTR [eax+2*4] ; Z
  351. fmul DWORD PTR [edx+(2*4+2)*4] ; M22
  352. fld DWORD PTR [eax+2*4] ; Z
  353. fmul DWORD PTR [edx+(2*4+1)*4] ; M21
  354. fld DWORD PTR [eax+2*4] ; Z
  355. fmul DWORD PTR [edx+(2*4+3)*4] ; M23
  356. fxch st(3)
  357. faddp st(4), st
  358. faddp st(4), st
  359. faddp st(4), st
  360. faddp st(4), st
  361. fld DWORD PTR [edx+(3*4+0)*4] ; M30
  362. faddp st(1), st
  363. fld DWORD PTR [edx+(3*4+1)*4] ; M31
  364. faddp st(2), st
  365. fld DWORD PTR [edx+(3*4+2)*4] ; M32
  366. faddp st(3), st
  367. fld DWORD PTR [edx+(3*4+3)*4] ; M33
  368. faddp st(4), st
  369. fstp DWORD PTR [ecx+0*4]
  370. fstp DWORD PTR [ecx+1*4]
  371. fstp DWORD PTR [ecx+2*4]
  372. fstp DWORD PTR [ecx+3*4]
  373. }
  374. return pOut;
  375. #else // !_X86_
  376. D3DXVECTOR4 v;
  377. v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20 + pM->m30;
  378. v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21 + pM->m31;
  379. v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22 + pM->m32;
  380. v.w = pV->x * pM->m03 + pV->y * pM->m13 + pV->z * pM->m23 + pM->m33;
  381. *pOut = v;
  382. return pOut;
  383. #endif // !_X86_
  384. }
  385. D3DXVECTOR3* WINAPI VB_D3DXVec3TransformCoord
  386. ( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV, const D3DXMATRIX *pM )
  387. {
  388. #if DBG
  389. if(!pOut || !pV || !pM)
  390. return NULL;
  391. #endif
  392. float w;
  393. #ifdef _X86_
  394. __asm {
  395. mov eax, DWORD PTR [pV]
  396. mov edx, DWORD PTR [pM]
  397. mov ecx, DWORD PTR [pOut]
  398. fld DWORD PTR [eax+0*4] ; X
  399. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  400. fld DWORD PTR [eax+0*4] ; X
  401. fmul DWORD PTR [edx+(0*4+2)*4] ; M02
  402. fld DWORD PTR [eax+0*4] ; X
  403. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  404. fld DWORD PTR [eax+0*4] ; X
  405. fmul DWORD PTR [edx+(0*4+3)*4] ; M03
  406. fxch st(3)
  407. fld DWORD PTR [eax+1*4] ; Y
  408. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  409. fld DWORD PTR [eax+1*4] ; Y
  410. fmul DWORD PTR [edx+(1*4+2)*4] ; M12
  411. fld DWORD PTR [eax+1*4] ; Y
  412. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  413. fld DWORD PTR [eax+1*4] ; Y
  414. fmul DWORD PTR [edx+(1*4+3)*4] ; M13
  415. fxch st(3)
  416. faddp st(4), st
  417. faddp st(4), st
  418. faddp st(4), st
  419. faddp st(4), st
  420. fld DWORD PTR [eax+2*4] ; Z
  421. fmul DWORD PTR [edx+(2*4+0)*4] ; M20
  422. fld DWORD PTR [eax+2*4] ; Z
  423. fmul DWORD PTR [edx+(2*4+2)*4] ; M22
  424. fld DWORD PTR [eax+2*4] ; Z
  425. fmul DWORD PTR [edx+(2*4+1)*4] ; M21
  426. fld DWORD PTR [eax+2*4] ; Z
  427. fmul DWORD PTR [edx+(2*4+3)*4] ; M23
  428. fxch st(3)
  429. faddp st(4), st
  430. faddp st(4), st
  431. faddp st(4), st
  432. faddp st(4), st
  433. fld DWORD PTR [edx+(3*4+0)*4] ; M30
  434. faddp st(1), st
  435. fld DWORD PTR [edx+(3*4+1)*4] ; M31
  436. faddp st(2), st
  437. fld DWORD PTR [edx+(3*4+2)*4] ; M32
  438. faddp st(3), st
  439. fld DWORD PTR [edx+(3*4+3)*4] ; M33
  440. faddp st(4), st
  441. fstp DWORD PTR [ecx+0*4]
  442. fstp DWORD PTR [ecx+1*4]
  443. fstp DWORD PTR [ecx+2*4]
  444. fstp DWORD PTR [w]
  445. }
  446. #else // !_X86_
  447. D3DXVECTOR3 v;
  448. v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20 + pM->m30;
  449. v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21 + pM->m31;
  450. v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22 + pM->m32;
  451. w = pV->x * pM->m03 + pV->y * pM->m13 + pV->z * pM->m23 + pM->m33;
  452. *pOut = v;
  453. #endif // !_X86_
  454. if(!WithinEpsilon(w, 1.0f))
  455. *pOut /= w;
  456. return pOut;
  457. }
  458. D3DXVECTOR3* WINAPI VB_D3DXVec3TransformNormal
  459. ( D3DXVECTOR3 *pOut, const D3DXVECTOR3 *pV, const D3DXMATRIX *pM )
  460. {
  461. #if DBG
  462. if(!pOut || !pV || !pM)
  463. return NULL;
  464. #endif
  465. #ifdef _X86_
  466. __asm {
  467. mov eax, DWORD PTR [pV]
  468. mov edx, DWORD PTR [pM]
  469. mov ecx, DWORD PTR [pOut]
  470. fld DWORD PTR [eax+0*4] ; X
  471. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  472. fld DWORD PTR [eax+0*4] ; X
  473. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  474. fld DWORD PTR [eax+0*4] ; X
  475. fmul DWORD PTR [edx+(0*4+2)*4] ; M02
  476. fxch st(2)
  477. fld DWORD PTR [eax+1*4] ; Y
  478. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  479. fld DWORD PTR [eax+1*4] ; Y
  480. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  481. fld DWORD PTR [eax+1*4] ; Y
  482. fmul DWORD PTR [edx+(1*4+2)*4] ; M12
  483. fxch st(2)
  484. faddp st(3), st
  485. faddp st(3), st
  486. faddp st(3), st
  487. fld DWORD PTR [eax+2*4] ; Z
  488. fmul DWORD PTR [edx+(2*4+0)*4] ; M20
  489. fld DWORD PTR [eax+2*4] ; Z
  490. fmul DWORD PTR [edx+(2*4+1)*4] ; M21
  491. fld DWORD PTR [eax+2*4] ; Z
  492. fmul DWORD PTR [edx+(2*4+2)*4] ; M22
  493. fxch st(2)
  494. faddp st(3), st
  495. faddp st(3), st
  496. faddp st(3), st
  497. fstp DWORD PTR [ecx+0*4]
  498. fstp DWORD PTR [ecx+1*4]
  499. fstp DWORD PTR [ecx+2*4]
  500. }
  501. return pOut;
  502. #else // !_X86_
  503. D3DXVECTOR3 v;
  504. v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20;
  505. v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21;
  506. v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22;
  507. *pOut = v;
  508. return pOut;
  509. #endif // !_X86_
  510. }
  511. //--------------------------
  512. // 4D Vector
  513. //--------------------------
  514. D3DXVECTOR4* WINAPI VB_D3DXVec4Cross
  515. ( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV1, const D3DXVECTOR4 *pV2,
  516. const D3DXVECTOR4 *pV3)
  517. {
  518. #if DBG
  519. if(!pOut || !pV1 || !pV2 || !pV3)
  520. return NULL;
  521. #endif
  522. D3DXVECTOR4 v;
  523. v.x = pV1->y * (pV2->z * pV3->w - pV3->z * pV2->w) -
  524. pV1->z * (pV2->y * pV3->w - pV3->y * pV2->w) +
  525. pV1->w * (pV2->y * pV3->z - pV3->y * pV2->z);
  526. v.y = pV1->x * (pV3->z * pV2->w - pV2->z * pV3->w) -
  527. pV1->z * (pV3->x * pV2->w - pV2->x * pV3->w) +
  528. pV1->w * (pV3->x * pV2->z - pV2->x * pV3->z);
  529. v.z = pV1->x * (pV2->y * pV3->w - pV3->y * pV2->w) -
  530. pV1->y * (pV2->x * pV3->w - pV3->x * pV2->w) +
  531. pV1->w * (pV2->x * pV3->y - pV3->x * pV2->y);
  532. v.w = pV1->x * (pV3->y * pV2->z - pV2->y * pV3->z) -
  533. pV1->y * (pV3->x * pV2->z - pV2->x * pV3->z) +
  534. pV1->z * (pV3->x * pV2->y - pV2->x * pV3->y);
  535. *pOut = v;
  536. return pOut;
  537. }
  538. D3DXVECTOR4* WINAPI VB_D3DXVec4Normalize
  539. ( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV )
  540. {
  541. #if DBG
  542. if(!pOut || !pV)
  543. return NULL;
  544. #endif
  545. float f = D3DXVec4LengthSq(pV);
  546. if(WithinEpsilon(f, 1.0f))
  547. {
  548. if(pOut != pV)
  549. *pOut = *pV;
  550. }
  551. else if(f > EPSILON * EPSILON)
  552. {
  553. *pOut = *pV / sqrtf(f);
  554. }
  555. else
  556. {
  557. pOut->x = 0.0f;
  558. pOut->y = 0.0f;
  559. pOut->z = 0.0f;
  560. pOut->w = 0.0f;
  561. }
  562. return pOut;
  563. }
  564. D3DXVECTOR4* WINAPI VB_D3DXVec4Hermite
  565. ( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV1, const D3DXVECTOR4 *pT1,
  566. const D3DXVECTOR4 *pV2, const D3DXVECTOR4 *pT2, float s )
  567. {
  568. #if DBG
  569. if(!pOut || !pV1 || !pT1 || !pV2 || !pT2)
  570. return NULL;
  571. #endif
  572. float s2 = s * s;
  573. float s3 = s * s2;
  574. float sV1 = 2.0f * s3 - 3.0f * s2 + 1.0f;
  575. float sT1 = s3 - 2.0f * s2 + s;
  576. float sV2 = -2.0f * s3 + 3.0f * s2;
  577. float sT2 = s3 - s2;
  578. pOut->x = sV1 * pV1->x + sT1 * pT1->x + sV2 * pV2->x + sT2 * pT2->x;
  579. pOut->y = sV1 * pV1->y + sT1 * pT1->y + sV2 * pV2->y + sT2 * pT2->y;
  580. pOut->z = sV1 * pV1->z + sT1 * pT1->z + sV2 * pV2->z + sT2 * pT2->z;
  581. pOut->w = sV1 * pV1->w + sT1 * pT1->w + sV2 * pV2->w + sT2 * pT2->w;
  582. return pOut;
  583. }
  584. D3DXVECTOR4* WINAPI VB_D3DXVec4BaryCentric
  585. ( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV1, const D3DXVECTOR4 *pV2,
  586. const D3DXVECTOR4 *pV3, float f, float g)
  587. {
  588. #if DBG
  589. if(!pOut || !pV1 || !pV2 || !pV3)
  590. return NULL;
  591. #endif
  592. pOut->x = pV1->x + f * (pV2->x - pV1->x) + g * (pV3->x - pV1->x);
  593. pOut->y = pV1->y + f * (pV2->y - pV1->y) + g * (pV3->y - pV1->y);
  594. pOut->z = pV1->z + f * (pV2->z - pV1->z) + g * (pV3->z - pV1->z);
  595. pOut->w = pV1->w + f * (pV2->w - pV1->w) + g * (pV3->w - pV1->w);
  596. return pOut;
  597. }
  598. D3DXVECTOR4* WINAPI VB_D3DXVec4Transform
  599. ( D3DXVECTOR4 *pOut, const D3DXVECTOR4 *pV, const D3DXMATRIX *pM )
  600. {
  601. #if DBG
  602. if(!pOut || !pV || !pM)
  603. return NULL;
  604. #endif
  605. #ifdef _X86_
  606. __asm {
  607. mov eax, DWORD PTR [pV]
  608. mov edx, DWORD PTR [pM]
  609. mov ecx, DWORD PTR [pOut]
  610. fld DWORD PTR [eax+0*4] ; X
  611. fmul DWORD PTR [edx+(0*4+0)*4] ; M00
  612. fld DWORD PTR [eax+0*4] ; X
  613. fmul DWORD PTR [edx+(0*4+2)*4] ; M02
  614. fld DWORD PTR [eax+0*4] ; X
  615. fmul DWORD PTR [edx+(0*4+1)*4] ; M01
  616. fld DWORD PTR [eax+0*4] ; X
  617. fmul DWORD PTR [edx+(0*4+3)*4] ; M03
  618. fxch st(3)
  619. fld DWORD PTR [eax+1*4] ; Y
  620. fmul DWORD PTR [edx+(1*4+0)*4] ; M10
  621. fld DWORD PTR [eax+1*4] ; Y
  622. fmul DWORD PTR [edx+(1*4+2)*4] ; M12
  623. fld DWORD PTR [eax+1*4] ; Y
  624. fmul DWORD PTR [edx+(1*4+1)*4] ; M11
  625. fld DWORD PTR [eax+1*4] ; Y
  626. fmul DWORD PTR [edx+(1*4+3)*4] ; M13
  627. fxch st(3)
  628. faddp st(4), st
  629. faddp st(4), st
  630. faddp st(4), st
  631. faddp st(4), st
  632. fld DWORD PTR [eax+2*4] ; Z
  633. fmul DWORD PTR [edx+(2*4+0)*4] ; M20
  634. fld DWORD PTR [eax+2*4] ; Z
  635. fmul DWORD PTR [edx+(2*4+2)*4] ; M22
  636. fld DWORD PTR [eax+2*4] ; Z
  637. fmul DWORD PTR [edx+(2*4+1)*4] ; M21
  638. fld DWORD PTR [eax+2*4] ; Z
  639. fmul DWORD PTR [edx+(2*4+3)*4] ; M23
  640. fxch st(3)
  641. faddp st(4), st
  642. faddp st(4), st
  643. faddp st(4), st
  644. faddp st(4), st
  645. fld DWORD PTR [eax+3*4] ; W
  646. fmul DWORD PTR [edx+(3*4+0)*4] ; M30
  647. fld DWORD PTR [eax+3*4] ; W
  648. fmul DWORD PTR [edx+(3*4+2)*4] ; M32
  649. fld DWORD PTR [eax+3*4] ; W
  650. fmul DWORD PTR [edx+(3*4+1)*4] ; M31
  651. fld DWORD PTR [eax+3*4] ; W
  652. fmul DWORD PTR [edx+(3*4+3)*4] ; M33
  653. fxch st(3)
  654. faddp st(4), st
  655. faddp st(4), st
  656. faddp st(4), st
  657. faddp st(4), st
  658. fstp DWORD PTR [ecx+0*4]
  659. fstp DWORD PTR [ecx+1*4]
  660. fstp DWORD PTR [ecx+2*4]
  661. fstp DWORD PTR [ecx+3*4]
  662. }
  663. return pOut;
  664. #else // !_X86_
  665. D3DXVECTOR4 v;
  666. v.x = pV->x * pM->m00 + pV->y * pM->m10 + pV->z * pM->m20 + pV->w * pM->m30;
  667. v.y = pV->x * pM->m01 + pV->y * pM->m11 + pV->z * pM->m21 + pV->w * pM->m31;
  668. v.z = pV->x * pM->m02 + pV->y * pM->m12 + pV->z * pM->m22 + pV->w * pM->m32;
  669. v.w = pV->x * pM->m03 + pV->y * pM->m13 + pV->z * pM->m23 + pV->w * pM->m33;
  670. *pOut = v;
  671. return pOut;
  672. #endif // !_X86_
  673. }
  674. //--------------------------
  675. // 4D Matrix
  676. //--------------------------
  677. float WINAPI VB_D3DXMatrixfDeterminant
  678. ( const D3DXMATRIX *pM )
  679. {
  680. #if DBG
  681. if(!pM)
  682. return 0.0f;
  683. #endif
  684. return (pM->m00 * (pM->m11 * (pM->m22 * pM->m33 - pM->m32 * pM->m23) -
  685. pM->m12 * (pM->m21 * pM->m33 - pM->m31 * pM->m23) +
  686. pM->m13 * (pM->m21 * pM->m32 - pM->m31 * pM->m22)))
  687. - (pM->m01 * (pM->m10 * (pM->m22 * pM->m33 - pM->m32 * pM->m23) -
  688. pM->m12 * (pM->m20 * pM->m33 - pM->m30 * pM->m23) +
  689. pM->m13 * (pM->m20 * pM->m32 - pM->m30 * pM->m22)))
  690. + (pM->m02 * (pM->m10 * (pM->m21 * pM->m33 - pM->m31 * pM->m23) -
  691. pM->m11 * (pM->m20 * pM->m33 - pM->m30 * pM->m23) +
  692. pM->m13 * (pM->m20 * pM->m31 - pM->m30 * pM->m21)))
  693. - (pM->m03 * (pM->m10 * (pM->m21 * pM->m32 - pM->m31 * pM->m22) -
  694. pM->m11 * (pM->m20 * pM->m32 - pM->m30 * pM->m22) +
  695. pM->m12 * (pM->m20 * pM->m31 - pM->m30 * pM->m21)));
  696. }
  697. D3DXMATRIX* WINAPI VB_D3DXMatrixMultiply
  698. ( D3DXMATRIX *pOut, const D3DXMATRIX *pM1, const D3DXMATRIX *pM2 )
  699. {
  700. #if DBG
  701. if(!pOut || !pM1 || !pM2)
  702. return NULL;
  703. #endif
  704. #ifdef _X86_
  705. #define MAT(m,a,b) DWORD PTR [(m)+(a)*4+(b)*4]
  706. D3DXMATRIX Out;
  707. if(pM2 != pOut)
  708. goto LRowByColumn;
  709. if(pM1 != pOut)
  710. goto LColumnByRow;
  711. Out = *pM2;
  712. pM2 = &Out;
  713. goto LRowByColumn;
  714. LRowByColumn:
  715. __asm {
  716. mov ebx, DWORD PTR[pOut] // result
  717. mov ecx, DWORD PTR[pM1] // a
  718. mov edx, DWORD PTR[pM2] // b
  719. mov edi, -4
  720. LLoopRow:
  721. mov esi, -4
  722. fld MAT(ecx, 0, 0) // a0
  723. fld MAT(ecx, 0, 1) // a1
  724. fld MAT(ecx, 0, 2) // a2
  725. fld MAT(ecx, 0, 3) // a3
  726. LLoopColumn:
  727. fld st(3) // a0
  728. fmul MAT(edx, esi, 1*4) // a0*b0
  729. fld st(3) // a1
  730. fmul MAT(edx, esi, 2*4) // a1*b1
  731. fld st(3) // a2
  732. fmul MAT(edx, esi, 3*4) // a2*b2
  733. fld st(3) // a3
  734. fmul MAT(edx, esi, 4*4) // a3*b3
  735. fxch st(3)
  736. faddp st(1), st // a2*b2+a0*b0
  737. fxch st(2)
  738. faddp st(1), st // a3*b3+a1*b1
  739. faddp st(1), st // a3*b3+a1*b1+a2*b2+a0*b0
  740. fstp MAT(ebx, esi, 4)
  741. inc esi
  742. jnz LLoopColumn
  743. ffree st(3)
  744. ffree st(2)
  745. ffree st(1)
  746. ffree st(0)
  747. lea ecx, MAT(ecx, 0, 4)
  748. lea ebx, MAT(ebx, 0, 4)
  749. inc edi
  750. jnz LLoopRow
  751. }
  752. return pOut;
  753. LColumnByRow:
  754. __asm {
  755. mov ebx, DWORD PTR[pOut] // result
  756. mov ecx, DWORD PTR[pM1] // a
  757. mov edx, DWORD PTR[pM2] // b
  758. mov edi, -4
  759. LLoopColumn2:
  760. mov esi, -16
  761. fld MAT(edx, edi, 1*4); // b0
  762. fld MAT(edx, edi, 2*4); // b1
  763. fld MAT(edx, edi, 3*4); // b2
  764. fld MAT(edx, edi, 4*4); // b3
  765. LLoopRow2:
  766. fld st(3) // b0
  767. fmul MAT(ecx, esi, 0+16) // a0*b0
  768. fld st(3) // b1
  769. fmul MAT(ecx, esi, 1+16) // a1*b1
  770. fld st(3) // b2
  771. fmul MAT(ecx, esi, 2+16) // a2*b2
  772. fld st(3) // b3
  773. fmul MAT(ecx, esi, 3+16) // a3*b3
  774. fxch st(3)
  775. faddp st(1), st // a2*b2+a0*b0
  776. fxch st(2)
  777. faddp st(1), st // a3*b3+a1*b1
  778. faddp st(1), st // a3*b3+a1*b1+a2*b2+a0*b0
  779. fstp MAT(ebx, esi, 0+16)
  780. add esi, 4
  781. jnz LLoopRow2
  782. ffree st(3)
  783. ffree st(2)
  784. ffree st(1)
  785. ffree st(0)
  786. lea ebx, MAT(ebx, 0, 1)
  787. inc edi
  788. jnz LLoopColumn2
  789. }
  790. return pOut;
  791. #undef MAT
  792. #else //!_X86_
  793. D3DXMATRIX Out;
  794. D3DXMATRIX *pM = (pOut == pM1 || pOut == pM2) ? &Out : pOut;
  795. pM->m00 = pM1->m00 * pM2->m00 + pM1->m01 * pM2->m10 + pM1->m02 * pM2->m20 + pM1->m03 * pM2->m30;
  796. pM->m01 = pM1->m00 * pM2->m01 + pM1->m01 * pM2->m11 + pM1->m02 * pM2->m21 + pM1->m03 * pM2->m31;
  797. pM->m02 = pM1->m00 * pM2->m02 + pM1->m01 * pM2->m12 + pM1->m02 * pM2->m22 + pM1->m03 * pM2->m32;
  798. pM->m03 = pM1->m00 * pM2->m03 + pM1->m01 * pM2->m13 + pM1->m02 * pM2->m23 + pM1->m03 * pM2->m33;
  799. pM->m10 = pM1->m10 * pM2->m00 + pM1->m11 * pM2->m10 + pM1->m12 * pM2->m20 + pM1->m13 * pM2->m30;
  800. pM->m11 = pM1->m10 * pM2->m01 + pM1->m11 * pM2->m11 + pM1->m12 * pM2->m21 + pM1->m13 * pM2->m31;
  801. pM->m12 = pM1->m10 * pM2->m02 + pM1->m11 * pM2->m12 + pM1->m12 * pM2->m22 + pM1->m13 * pM2->m32;
  802. pM->m13 = pM1->m10 * pM2->m03 + pM1->m11 * pM2->m13 + pM1->m12 * pM2->m23 + pM1->m13 * pM2->m33;
  803. pM->m20 = pM1->m20 * pM2->m00 + pM1->m21 * pM2->m10 + pM1->m22 * pM2->m20 + pM1->m23 * pM2->m30;
  804. pM->m21 = pM1->m20 * pM2->m01 + pM1->m21 * pM2->m11 + pM1->m22 * pM2->m21 + pM1->m23 * pM2->m31;
  805. pM->m22 = pM1->m20 * pM2->m02 + pM1->m21 * pM2->m12 + pM1->m22 * pM2->m22 + pM1->m23 * pM2->m32;
  806. pM->m23 = pM1->m20 * pM2->m03 + pM1->m21 * pM2->m13 + pM1->m22 * pM2->m23 + pM1->m23 * pM2->m33;
  807. pM->m30 = pM1->m30 * pM2->m00 + pM1->m31 * pM2->m10 + pM1->m32 * pM2->m20 + pM1->m33 * pM2->m30;
  808. pM->m31 = pM1->m30 * pM2->m01 + pM1->m31 * pM2->m11 + pM1->m32 * pM2->m21 + pM1->m33 * pM2->m31;
  809. pM->m32 = pM1->m30 * pM2->m02 + pM1->m31 * pM2->m12 + pM1->m32 * pM2->m22 + pM1->m33 * pM2->m32;
  810. pM->m33 = pM1->m30 * pM2->m03 + pM1->m31 * pM2->m13 + pM1->m32 * pM2->m23 + pM1->m33 * pM2->m33;
  811. if(pM != pOut)
  812. *pOut = *pM;
  813. return pOut;
  814. #endif //!_X86_
  815. }
  816. D3DXMATRIX* WINAPI VB_D3DXMatrixTranspose
  817. ( D3DXMATRIX *pOut, const D3DXMATRIX *pM )
  818. {
  819. #if DBG
  820. if(!pOut || !pM)
  821. return NULL;
  822. #endif
  823. float f;
  824. f = pM->m01; pOut->m01 = pM->m10; pOut->m10 = f;
  825. f = pM->m02; pOut->m02 = pM->m20; pOut->m20 = f;
  826. f = pM->m03; pOut->m03 = pM->m30; pOut->m30 = f;
  827. f = pM->m12; pOut->m12 = pM->m21; pOut->m21 = f;
  828. f = pM->m13; pOut->m13 = pM->m31; pOut->m31 = f;
  829. f = pM->m23; pOut->m23 = pM->m32; pOut->m32 = f;
  830. if(pOut != pM)
  831. {
  832. pOut->m00 = pM->m00;
  833. pOut->m11 = pM->m11;
  834. pOut->m22 = pM->m22;
  835. pOut->m33 = pM->m33;
  836. }
  837. return pOut;
  838. }
  839. D3DXMATRIX* WINAPI VB_D3DXMatrixInverse
  840. ( D3DXMATRIX *pOut, float *pfDeterminant, const D3DXMATRIX *pM )
  841. {
  842. #if DBG
  843. if(!pOut || !pM)
  844. return NULL;
  845. #endif
  846. // XXXlorenmcq - The code was designed to work on a processor with more
  847. // than 4 general-purpose registers. Is there a more optimal way of
  848. // doing this on X86?
  849. float fX00, fX01, fX02;
  850. float fX10, fX11, fX12;
  851. float fX20, fX21, fX22;
  852. float fX30, fX31, fX32;
  853. float fY01, fY02, fY03, fY12, fY13, fY23;
  854. float fZ02, fZ03, fZ12, fZ13, fZ22, fZ23, fZ32, fZ33;
  855. #define fX03 fX01
  856. #define fX13 fX11
  857. #define fX23 fX21
  858. #define fX33 fX31
  859. #define fZ00 fX02
  860. #define fZ10 fX12
  861. #define fZ20 fX22
  862. #define fZ30 fX32
  863. #define fZ01 fX03
  864. #define fZ11 fX13
  865. #define fZ21 fX23
  866. #define fZ31 fX33
  867. #define fDet fY01
  868. #define fRcp fY02
  869. // read 1st two columns of matrix
  870. fX00 = pM->m00;
  871. fX01 = pM->m01;
  872. fX10 = pM->m10;
  873. fX11 = pM->m11;
  874. fX20 = pM->m20;
  875. fX21 = pM->m21;
  876. fX30 = pM->m30;
  877. fX31 = pM->m31;
  878. // compute all six 2x2 determinants of 1st two columns
  879. fY01 = fX00 * fX11 - fX10 * fX01;
  880. fY02 = fX00 * fX21 - fX20 * fX01;
  881. fY03 = fX00 * fX31 - fX30 * fX01;
  882. fY12 = fX10 * fX21 - fX20 * fX11;
  883. fY13 = fX10 * fX31 - fX30 * fX11;
  884. fY23 = fX20 * fX31 - fX30 * fX21;
  885. // read 2nd two columns of matrix
  886. fX02 = pM->m02;
  887. fX03 = pM->m03;
  888. fX12 = pM->m12;
  889. fX13 = pM->m13;
  890. fX22 = pM->m22;
  891. fX23 = pM->m23;
  892. fX32 = pM->m32;
  893. fX33 = pM->m33;
  894. // compute all 3x3 cofactors for 2nd two columns
  895. fZ33 = fX02 * fY12 - fX12 * fY02 + fX22 * fY01;
  896. fZ23 = fX12 * fY03 - fX32 * fY01 - fX02 * fY13;
  897. fZ13 = fX02 * fY23 - fX22 * fY03 + fX32 * fY02;
  898. fZ03 = fX22 * fY13 - fX32 * fY12 - fX12 * fY23;
  899. fZ32 = fX13 * fY02 - fX23 * fY01 - fX03 * fY12;
  900. fZ22 = fX03 * fY13 - fX13 * fY03 + fX33 * fY01;
  901. fZ12 = fX23 * fY03 - fX33 * fY02 - fX03 * fY23;
  902. fZ02 = fX13 * fY23 - fX23 * fY13 + fX33 * fY12;
  903. // compute all six 2x2 determinants of 2nd two columns
  904. fY01 = fX02 * fX13 - fX12 * fX03;
  905. fY02 = fX02 * fX23 - fX22 * fX03;
  906. fY03 = fX02 * fX33 - fX32 * fX03;
  907. fY12 = fX12 * fX23 - fX22 * fX13;
  908. fY13 = fX12 * fX33 - fX32 * fX13;
  909. fY23 = fX22 * fX33 - fX32 * fX23;
  910. // read 1st two columns of matrix
  911. fX00 = pM->m00;
  912. fX01 = pM->m01;
  913. fX10 = pM->m10;
  914. fX11 = pM->m11;
  915. fX20 = pM->m20;
  916. fX21 = pM->m21;
  917. fX30 = pM->m30;
  918. fX31 = pM->m31;
  919. // compute all 3x3 cofactors for 1st two columns
  920. fZ30 = fX11 * fY02 - fX21 * fY01 - fX01 * fY12;
  921. fZ20 = fX01 * fY13 - fX11 * fY03 + fX31 * fY01;
  922. fZ10 = fX21 * fY03 - fX31 * fY02 - fX01 * fY23;
  923. fZ00 = fX11 * fY23 - fX21 * fY13 + fX31 * fY12;
  924. fZ31 = fX00 * fY12 - fX10 * fY02 + fX20 * fY01;
  925. fZ21 = fX10 * fY03 - fX30 * fY01 - fX00 * fY13;
  926. fZ11 = fX00 * fY23 - fX20 * fY03 + fX30 * fY02;
  927. fZ01 = fX20 * fY13 - fX30 * fY12 - fX10 * fY23;
  928. // compute 4x4 determinant & its reciprocal
  929. fDet = fX30 * fZ30 + fX20 * fZ20 + fX10 * fZ10 + fX00 * fZ00;
  930. if(pfDeterminant)
  931. *pfDeterminant = fDet;
  932. fRcp = 1.0f / fDet;
  933. if(!_finite(fRcp))
  934. return NULL;
  935. // multiply all 3x3 cofactors by reciprocal & transpose
  936. pOut->m00 = fZ00 * fRcp;
  937. pOut->m01 = fZ10 * fRcp;
  938. pOut->m02 = fZ20 * fRcp;
  939. pOut->m03 = fZ30 * fRcp;
  940. pOut->m10 = fZ01 * fRcp;
  941. pOut->m11 = fZ11 * fRcp;
  942. pOut->m12 = fZ21 * fRcp;
  943. pOut->m13 = fZ31 * fRcp;
  944. pOut->m20 = fZ02 * fRcp;
  945. pOut->m21 = fZ12 * fRcp;
  946. pOut->m22 = fZ22 * fRcp;
  947. pOut->m23 = fZ32 * fRcp;
  948. pOut->m30 = fZ03 * fRcp;
  949. pOut->m31 = fZ13 * fRcp;
  950. pOut->m32 = fZ23 * fRcp;
  951. pOut->m33 = fZ33 * fRcp;
  952. return pOut;
  953. }
  954. D3DXMATRIX* WINAPI VB_D3DXMatrixScaling
  955. ( D3DXMATRIX *pOut, float sx, float sy, float sz )
  956. {
  957. #if DBG
  958. if(!pOut)
  959. return NULL;
  960. #endif
  961. pOut->m01 = pOut->m02 = pOut->m03 =
  962. pOut->m10 = pOut->m12 = pOut->m13 =
  963. pOut->m20 = pOut->m21 = pOut->m23 =
  964. pOut->m30 = pOut->m31 = pOut->m32 = 0.0f;
  965. pOut->m00 = sx;
  966. pOut->m11 = sy;
  967. pOut->m22 = sz;
  968. pOut->m33 = 1.0f;
  969. return pOut;
  970. }
  971. D3DXMATRIX* WINAPI VB_D3DXMatrixTranslation
  972. ( D3DXMATRIX *pOut, float x, float y, float z )
  973. {
  974. #if DBG
  975. if(!pOut)
  976. return NULL;
  977. #endif
  978. pOut->m01 = pOut->m02 = pOut->m03 =
  979. pOut->m10 = pOut->m12 = pOut->m13 =
  980. pOut->m20 = pOut->m21 = pOut->m23 = 0.0f;
  981. pOut->m00 = pOut->m11 = pOut->m22 = pOut->m33 = 1.0f;
  982. pOut->m30 = x;
  983. pOut->m31 = y;
  984. pOut->m32 = z;
  985. return pOut;
  986. }
  987. D3DXMATRIX* WINAPI VB_D3DXMatrixRotationX
  988. ( D3DXMATRIX *pOut, float angle )
  989. {
  990. #if DBG
  991. if(!pOut)
  992. return NULL;
  993. #endif
  994. float s, c;
  995. sincosf(angle, &s, &c);
  996. pOut->m00 = 1.0f; pOut->m01 = 0.0f; pOut->m02 = 0.0f; pOut->m03 = 0.0f;
  997. pOut->m10 = 0.0f; pOut->m11 = c; pOut->m12 = s; pOut->m13 = 0.0f;
  998. pOut->m20 = 0.0f; pOut->m21 = -s; pOut->m22 = c; pOut->m23 = 0.0f;
  999. pOut->m30 = 0.0f; pOut->m31 = 0.0f; pOut->m32 = 0.0f; pOut->m33 = 1.0f;
  1000. return pOut;
  1001. }
  1002. D3DXMATRIX* WINAPI VB_D3DXMatrixRotationY
  1003. ( D3DXMATRIX *pOut, float angle )
  1004. {
  1005. #if DBG
  1006. if(!pOut)
  1007. return NULL;
  1008. #endif
  1009. float s, c;
  1010. sincosf(angle, &s, &c);
  1011. pOut->m00 = c; pOut->m01 = 0.0f; pOut->m02 = -s; pOut->m03 = 0.0f;
  1012. pOut->m10 = 0.0f; pOut->m11 = 1.0f; pOut->m12 = 0.0f; pOut->m13 = 0.0f;
  1013. pOut->m20 = s; pOut->m21 = 0.0f; pOut->m22 = c; pOut->m23 = 0.0f;
  1014. pOut->m30 = 0.0f; pOut->m31 = 0.0f; pOut->m32 = 0.0f; pOut->m33 = 1.0f;
  1015. return pOut;
  1016. }
  1017. D3DXMATRIX* WINAPI VB_D3DXMatrixRotationZ
  1018. ( D3DXMATRIX *pOut, float angle )
  1019. {
  1020. #if DBG
  1021. if(!pOut)
  1022. return NULL;
  1023. #endif
  1024. float s, c;
  1025. sincosf(angle, &s, &c);
  1026. pOut->m00 = c; pOut->m01 = s; pOut->m02 = 0.0f; pOut->m03 = 0.0f;
  1027. pOut->m10 = -s; pOut->m11 = c; pOut->m12 = 0.0f; pOut->m13 = 0.0f;
  1028. pOut->m20 = 0.0f; pOut->m21 = 0.0f; pOut->m22 = 1.0f; pOut->m23 = 0.0f;
  1029. pOut->m30 = 0.0f; pOut->m31 = 0.0f; pOut->m32 = 0.0f; pOut->m33 = 1.0f;
  1030. return pOut;
  1031. }
  1032. D3DXMATRIX* WINAPI VB_D3DXMatrixRotationAxis
  1033. ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pV, float angle )
  1034. {
  1035. #if DBG
  1036. if(!pOut || !pV)
  1037. return NULL;
  1038. #endif
  1039. float s, c;
  1040. sincosf(angle, &s, &c);
  1041. float c1 = 1 - c;
  1042. D3DXVECTOR3 v = *pV;
  1043. VB_D3DXVec3Normalize(&v, &v);
  1044. float xyc1 = v.x * v.y * c1;
  1045. float yzc1 = v.y * v.z * c1;
  1046. float zxc1 = v.z * v.x * c1;
  1047. pOut->m00 = v.x * v.x * c1 + c;
  1048. pOut->m01 = xyc1 + v.z * s;
  1049. pOut->m02 = zxc1 - v.y * s;
  1050. pOut->m03 = 0.0f;
  1051. pOut->m10 = xyc1 - v.z * s;
  1052. pOut->m11 = v.y * v.y * c1 + c;
  1053. pOut->m12 = yzc1 + v.x * s;
  1054. pOut->m13 = 0.0f;
  1055. pOut->m20 = zxc1 + v.y * s;
  1056. pOut->m21 = yzc1 - v.x * s;
  1057. pOut->m22 = v.z * v.z * c1 + c;
  1058. pOut->m23 = 0.0f;
  1059. pOut->m30 = 0.0f;
  1060. pOut->m31 = 0.0f;
  1061. pOut->m32 = 0.0f;
  1062. pOut->m33 = 1.0f;
  1063. return pOut;
  1064. }
  1065. D3DXMATRIX* WINAPI VB_D3DXMatrixRotationQuaternion
  1066. ( D3DXMATRIX *pOut, const D3DXQUATERNION *pQ)
  1067. {
  1068. #if DBG
  1069. if(!pOut || !pQ)
  1070. return NULL;
  1071. #endif
  1072. float x2 = pQ->x + pQ->x;
  1073. float y2 = pQ->y + pQ->y;
  1074. float z2 = pQ->z + pQ->z;
  1075. float wx2 = pQ->w * x2;
  1076. float wy2 = pQ->w * y2;
  1077. float wz2 = pQ->w * z2;
  1078. float xx2 = pQ->x * x2;
  1079. float xy2 = pQ->x * y2;
  1080. float xz2 = pQ->x * z2;
  1081. float yy2 = pQ->y * y2;
  1082. float yz2 = pQ->y * z2;
  1083. float zz2 = pQ->z * z2;
  1084. pOut->m00 = 1.0f - yy2 - zz2;
  1085. pOut->m01 = xy2 + wz2;
  1086. pOut->m02 = xz2 - wy2;
  1087. pOut->m03 = 0.0f;
  1088. pOut->m10 = xy2 - wz2;
  1089. pOut->m11 = 1.0f - xx2 - zz2;
  1090. pOut->m12 = yz2 + wx2;
  1091. pOut->m13 = 0.0f;
  1092. pOut->m20 = xz2 + wy2;
  1093. pOut->m21 = yz2 - wx2;
  1094. pOut->m22 = 1.0f - xx2 - yy2;
  1095. pOut->m23 = 0.0f;
  1096. pOut->m30 = 0.0f;
  1097. pOut->m31 = 0.0f;
  1098. pOut->m32 = 0.0f;
  1099. pOut->m33 = 1.0f;
  1100. return pOut;
  1101. }
  1102. D3DXMATRIX* WINAPI VB_D3DXMatrixRotationYawPitchRoll
  1103. ( D3DXMATRIX *pOut, float yaw, float pitch, float roll )
  1104. {
  1105. #if DBG
  1106. if(!pOut)
  1107. return NULL;
  1108. #endif
  1109. D3DXQUATERNION q;
  1110. VB_D3DXQuaternionRotationYawPitchRoll(&q, yaw, pitch, roll);
  1111. D3DXMatrixRotationQuaternion(pOut, &q);
  1112. return pOut;
  1113. }
  1114. D3DXMATRIX* WINAPI VB_D3DXMatrixTransformation
  1115. ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pScalingCenter,
  1116. const D3DXQUATERNION *pScalingRotation, const D3DXVECTOR3 *pScaling,
  1117. const D3DXVECTOR3 *pRotationCenter, const D3DXQUATERNION *pRotation,
  1118. const D3DXVECTOR3 *pTranslation)
  1119. {
  1120. #if DBG
  1121. if(!pOut)
  1122. return NULL;
  1123. #endif
  1124. D3DXMATRIX matS, matR, matRI;
  1125. if (pScaling)
  1126. {
  1127. if (pScalingRotation)
  1128. {
  1129. matS.m01 = matS.m02 = matS.m03 =
  1130. matS.m10 = matS.m12 = matS.m13 =
  1131. matS.m20 = matS.m21 = matS.m23 =
  1132. matS.m30 = matS.m31 = matS.m32 = 0.0f;
  1133. matS.m00 = pScaling->x;
  1134. matS.m11 = pScaling->y;
  1135. matS.m22 = pScaling->z;
  1136. matS.m33 = 1.0f;
  1137. D3DXMatrixRotationQuaternion(&matR, pScalingRotation);
  1138. if (pScalingCenter)
  1139. {
  1140. // SC-1, SR-1, S, SR, SC
  1141. D3DXMatrixTranspose(&matRI, &matR);
  1142. D3DXMatrixIdentity(pOut);
  1143. pOut->m30 -= pScalingCenter->x;
  1144. pOut->m31 -= pScalingCenter->y;
  1145. pOut->m32 -= pScalingCenter->z;
  1146. D3DXMatrixMultiply(pOut, pOut, &matRI);
  1147. D3DXMatrixMultiply(pOut, pOut, &matS);
  1148. D3DXMatrixMultiply(pOut, pOut, &matR);
  1149. pOut->m30 += pScalingCenter->x;
  1150. pOut->m31 += pScalingCenter->y;
  1151. pOut->m32 += pScalingCenter->z;
  1152. }
  1153. else
  1154. {
  1155. // SR-1, S, SR
  1156. D3DXMatrixTranspose(pOut, &matR);
  1157. D3DXMatrixMultiply(pOut, pOut, &matS);
  1158. D3DXMatrixMultiply(pOut, pOut, &matR);
  1159. }
  1160. }
  1161. else
  1162. {
  1163. // S
  1164. pOut->m01 = pOut->m02 = pOut->m03 =
  1165. pOut->m10 = pOut->m12 = pOut->m13 =
  1166. pOut->m20 = pOut->m21 = pOut->m23 =
  1167. pOut->m30 = pOut->m31 = pOut->m32 = 0.0f;
  1168. pOut->m00 = pScaling->x;
  1169. pOut->m11 = pScaling->y;
  1170. pOut->m22 = pScaling->z;
  1171. pOut->m33 = 1.0f;
  1172. }
  1173. }
  1174. else
  1175. {
  1176. D3DXMatrixIdentity(pOut);
  1177. }
  1178. if (pRotation)
  1179. {
  1180. D3DXMatrixRotationQuaternion(&matR, pRotation);
  1181. if (pRotationCenter)
  1182. {
  1183. // RC-1, R, RC
  1184. pOut->m30 -= pRotationCenter->x;
  1185. pOut->m31 -= pRotationCenter->y;
  1186. pOut->m32 -= pRotationCenter->z;
  1187. D3DXMatrixMultiply(pOut, pOut, &matR);
  1188. pOut->m30 += pRotationCenter->x;
  1189. pOut->m31 += pRotationCenter->y;
  1190. pOut->m32 += pRotationCenter->z;
  1191. }
  1192. else
  1193. {
  1194. // R
  1195. D3DXMatrixMultiply(pOut, pOut, &matR);
  1196. }
  1197. }
  1198. if (pTranslation)
  1199. {
  1200. // T
  1201. pOut->m30 += pTranslation->x;
  1202. pOut->m31 += pTranslation->y;
  1203. pOut->m32 += pTranslation->z;
  1204. }
  1205. return pOut;
  1206. }
  1207. D3DXMATRIX* WINAPI VB_D3DXMatrixAffineTransformation
  1208. ( D3DXMATRIX *pOut, float Scaling, const D3DXVECTOR3 *pRotationCenter,
  1209. const D3DXQUATERNION *pRotation, const D3DXVECTOR3 *pTranslation)
  1210. {
  1211. #if DBG
  1212. if(!pOut)
  1213. return NULL;
  1214. #endif
  1215. // S
  1216. pOut->m01 = pOut->m02 = pOut->m03 =
  1217. pOut->m10 = pOut->m12 = pOut->m13 =
  1218. pOut->m20 = pOut->m21 = pOut->m23 =
  1219. pOut->m30 = pOut->m31 = pOut->m32 = 0.0f;
  1220. pOut->m00 = Scaling;
  1221. pOut->m11 = Scaling;
  1222. pOut->m22 = Scaling;
  1223. pOut->m33 = 1.0f;
  1224. if (pRotation)
  1225. {
  1226. D3DXMATRIX matR;
  1227. D3DXMatrixRotationQuaternion(&matR, pRotation);
  1228. if (pRotationCenter)
  1229. {
  1230. // RC-1, R, RC
  1231. pOut->m30 -= pRotationCenter->x;
  1232. pOut->m31 -= pRotationCenter->y;
  1233. pOut->m32 -= pRotationCenter->z;
  1234. D3DXMatrixMultiply(pOut, pOut, &matR);
  1235. pOut->m30 += pRotationCenter->x;
  1236. pOut->m31 += pRotationCenter->y;
  1237. pOut->m32 += pRotationCenter->z;
  1238. }
  1239. else
  1240. {
  1241. // R
  1242. D3DXMatrixMultiply(pOut, pOut, &matR);
  1243. }
  1244. }
  1245. if (pTranslation)
  1246. {
  1247. // T
  1248. pOut->m30 += pTranslation->x;
  1249. pOut->m31 += pTranslation->y;
  1250. pOut->m32 += pTranslation->z;
  1251. }
  1252. return pOut;
  1253. }
  1254. D3DXMATRIX* WINAPI VB_D3DXMatrixLookAt
  1255. ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
  1256. const D3DXVECTOR3 *pUp )
  1257. {
  1258. #if DBG
  1259. if(!pOut || !pEye || !pAt || !pUp)
  1260. return NULL;
  1261. #endif
  1262. D3DXVECTOR3 XAxis, YAxis, ZAxis;
  1263. // Compute direction of gaze. (-Z)
  1264. VB_D3DXVec3Subtract(&ZAxis, pEye, pAt);
  1265. VB_D3DXVec3Normalize(&ZAxis, &ZAxis);
  1266. // Compute orthogonal axes from cross product of gaze and pUp vector.
  1267. VB_D3DXVec3Cross(&XAxis, pUp, &ZAxis);
  1268. VB_D3DXVec3Normalize(&XAxis, &XAxis);
  1269. VB_D3DXVec3Cross(&YAxis, &ZAxis, &XAxis);
  1270. // Set rotation and translate by pEye
  1271. pOut->m00 = XAxis.x;
  1272. pOut->m10 = XAxis.y;
  1273. pOut->m20 = XAxis.z;
  1274. pOut->m30 = -VB_D3DXVec3Dot(&XAxis, pEye);
  1275. pOut->m01 = YAxis.x;
  1276. pOut->m11 = YAxis.y;
  1277. pOut->m21 = YAxis.z;
  1278. pOut->m31 = -VB_D3DXVec3Dot(&YAxis, pEye);
  1279. pOut->m02 = ZAxis.x;
  1280. pOut->m12 = ZAxis.y;
  1281. pOut->m22 = ZAxis.z;
  1282. pOut->m32 = -VB_D3DXVec3Dot(&ZAxis, pEye);
  1283. pOut->m03 = 0.0f;
  1284. pOut->m13 = 0.0f;
  1285. pOut->m23 = 0.0f;
  1286. pOut->m33 = 1.0f;
  1287. return pOut;
  1288. }
  1289. D3DXMATRIX* WINAPI VB_D3DXMatrixLookAtLH
  1290. ( D3DXMATRIX *pOut, const D3DXVECTOR3 *pEye, const D3DXVECTOR3 *pAt,
  1291. const D3DXVECTOR3 *pUp )
  1292. {
  1293. #if DBG
  1294. if(!pOut || !pEye || !pAt || !pUp)
  1295. return NULL;
  1296. #endif
  1297. D3DXVECTOR3 XAxis, YAxis, ZAxis;
  1298. // Compute direction of gaze. (+Z)
  1299. VB_D3DXVec3Subtract(&ZAxis, pAt, pEye);
  1300. VB_D3DXVec3Normalize(&ZAxis, &ZAxis);
  1301. // Compute orthogonal axes from cross product of gaze and pUp vector.
  1302. VB_D3DXVec3Cross(&XAxis, &ZAxis, pUp);
  1303. VB_D3DXVec3Normalize(&XAxis, &XAxis);
  1304. VB_D3DXVec3Cross(&YAxis, &XAxis, &ZAxis);
  1305. // Set rotation and translate by pEye
  1306. pOut->m00 = XAxis.x;
  1307. pOut->m10 = XAxis.y;
  1308. pOut->m20 = XAxis.z;
  1309. pOut->m30 = -VB_D3DXVec3Dot(&XAxis, pEye);
  1310. pOut->m01 = YAxis.x;
  1311. pOut->m11 = YAxis.y;
  1312. pOut->m21 = YAxis.z;
  1313. pOut->m31 = -VB_D3DXVec3Dot(&YAxis, pEye);
  1314. pOut->m02 = ZAxis.x;
  1315. pOut->m12 = ZAxis.y;
  1316. pOut->m22 = ZAxis.z;
  1317. pOut->m32 = -VB_D3DXVec3Dot(&ZAxis, pEye);
  1318. pOut->m03 = 0.0f;
  1319. pOut->m13 = 0.0f;
  1320. pOut->m23 = 0.0f;
  1321. pOut->m33 = 1.0f;
  1322. return pOut;
  1323. }
  1324. D3DXMATRIX* WINAPI VB_D3DXMatrixPerspective
  1325. ( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
  1326. {
  1327. #if DBG
  1328. if(!pOut)
  1329. return NULL;
  1330. #endif
  1331. pOut->m00 = 2.0f * zn / w;
  1332. pOut->m01 = 0.0f;
  1333. pOut->m02 = 0.0f;
  1334. pOut->m03 = 0.0f;
  1335. pOut->m10 = 0.0f;
  1336. pOut->m11 = 2.0f * zn / h;
  1337. pOut->m12 = 0.0f;
  1338. pOut->m13 = 0.0f;
  1339. pOut->m20 = 0.0f;
  1340. pOut->m21 = 0.0f;
  1341. pOut->m22 = zf / (zn - zf);
  1342. pOut->m23 = -1.0f;
  1343. pOut->m30 = 0.0f;
  1344. pOut->m31 = 0.0f;
  1345. pOut->m32 = pOut->m22 * zn;
  1346. pOut->m33 = 0.0f;
  1347. return pOut;
  1348. }
  1349. D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveLH
  1350. ( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
  1351. {
  1352. #if DBG
  1353. if(!pOut)
  1354. return NULL;
  1355. #endif
  1356. pOut->m00 = 2.0f * zn / w;
  1357. pOut->m01 = 0.0f;
  1358. pOut->m02 = 0.0f;
  1359. pOut->m03 = 0.0f;
  1360. pOut->m10 = 0.0f;
  1361. pOut->m11 = 2.0f * zn / h;
  1362. pOut->m12 = 0.0f;
  1363. pOut->m13 = 0.0f;
  1364. pOut->m20 = 0.0f;
  1365. pOut->m21 = 0.0f;
  1366. pOut->m22 = zf / (zf - zn);
  1367. pOut->m23 = 1.0f;
  1368. pOut->m30 = 0.0f;
  1369. pOut->m31 = 0.0f;
  1370. pOut->m32 = -pOut->m22 * zn;
  1371. pOut->m33 = 0.0f;
  1372. return pOut;
  1373. }
  1374. D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveFov
  1375. ( D3DXMATRIX *pOut, float fovy, float aspect, float zn, float zf )
  1376. {
  1377. #if DBG
  1378. if(!pOut)
  1379. return NULL;
  1380. #endif
  1381. float s, c;
  1382. sincosf(0.5f * fovy, &s, &c);
  1383. float h = c / s;
  1384. float w = aspect * h;
  1385. pOut->m00 = w;
  1386. pOut->m01 = 0.0f;
  1387. pOut->m02 = 0.0f;
  1388. pOut->m03 = 0.0f;
  1389. pOut->m10 = 0.0f;
  1390. pOut->m11 = h;
  1391. pOut->m12 = 0.0f;
  1392. pOut->m13 = 0.0f;
  1393. pOut->m20 = 0.0f;
  1394. pOut->m21 = 0.0f;
  1395. pOut->m22 = zf / (zn - zf);
  1396. pOut->m23 = -1.0f;
  1397. pOut->m30 = 0.0f;
  1398. pOut->m31 = 0.0f;
  1399. pOut->m32 = pOut->m22 * zn;
  1400. pOut->m33 = 0.0f;
  1401. return pOut;
  1402. }
  1403. D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveFovLH
  1404. ( D3DXMATRIX *pOut, float fovy, float aspect, float zn, float zf )
  1405. {
  1406. #if DBG
  1407. if(!pOut)
  1408. return NULL;
  1409. #endif
  1410. float s, c;
  1411. sincosf(0.5f * fovy, &s, &c);
  1412. float h = c / s;
  1413. float w = aspect * h;
  1414. pOut->m00 = w;
  1415. pOut->m01 = 0.0f;
  1416. pOut->m02 = 0.0f;
  1417. pOut->m03 = 0.0f;
  1418. pOut->m10 = 0.0f;
  1419. pOut->m11 = h;
  1420. pOut->m12 = 0.0f;
  1421. pOut->m13 = 0.0f;
  1422. pOut->m20 = 0.0f;
  1423. pOut->m21 = 0.0f;
  1424. pOut->m22 = zf / (zf - zn);
  1425. pOut->m23 = 1.0f;
  1426. pOut->m30 = 0.0f;
  1427. pOut->m31 = 0.0f;
  1428. pOut->m32 = -pOut->m22 * zn;
  1429. pOut->m33 = 0.0f;
  1430. return pOut;
  1431. }
  1432. D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveOffCenter
  1433. ( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
  1434. float zf )
  1435. {
  1436. #if DBG
  1437. if(!pOut)
  1438. return NULL;
  1439. #endif
  1440. float wInv = 1.0f / (r - l);
  1441. float hInv = 1.0f / (t - b);
  1442. pOut->m00 = 2.0f * zn * wInv;
  1443. pOut->m01 = 0.0f;
  1444. pOut->m02 = 0.0f;
  1445. pOut->m03 = 0.0f;
  1446. pOut->m10 = 0.0f;
  1447. pOut->m11 = 2.0f * zn * hInv;
  1448. pOut->m12 = 0.0f;
  1449. pOut->m13 = 0.0f;
  1450. pOut->m20 = (l + r) * wInv;
  1451. pOut->m21 = (t + b) * hInv;
  1452. pOut->m22 = zf / (zn - zf);
  1453. pOut->m23 = -1.0f;
  1454. pOut->m30 = 0.0f;
  1455. pOut->m31 = 0.0f;
  1456. pOut->m32 = pOut->m22 * zn;
  1457. pOut->m33 = 0.0f;
  1458. return pOut;
  1459. }
  1460. D3DXMATRIX* WINAPI VB_D3DXMatrixPerspectiveOffCenterLH
  1461. ( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
  1462. float zf )
  1463. {
  1464. #if DBG
  1465. if(!pOut)
  1466. return NULL;
  1467. #endif
  1468. float wInv = 1.0f / (r - l);
  1469. float hInv = 1.0f / (t - b);
  1470. pOut->m00 = 2.0f * zn * wInv;
  1471. pOut->m01 = 0.0f;
  1472. pOut->m02 = 0.0f;
  1473. pOut->m03 = 0.0f;
  1474. pOut->m10 = 0.0f;
  1475. pOut->m11 = 2.0f * zn * hInv;
  1476. pOut->m12 = 0.0f;
  1477. pOut->m13 = 0.0f;
  1478. pOut->m20 = -(l + r) * wInv;
  1479. pOut->m21 = -(t + b) * hInv;
  1480. pOut->m22 = zf / (zf - zn);
  1481. pOut->m23 = 1.0f;
  1482. pOut->m30 = 0.0f;
  1483. pOut->m31 = 0.0f;
  1484. pOut->m32 = -pOut->m22 * zn;
  1485. pOut->m33 = 0.0f;
  1486. return pOut;
  1487. }
  1488. D3DXMATRIX* WINAPI VB_D3DXMatrixOrtho
  1489. ( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
  1490. {
  1491. #if DBG
  1492. if(!pOut)
  1493. return NULL;
  1494. #endif
  1495. pOut->m00 = 2.0f / w;
  1496. pOut->m01 = 0.0f;
  1497. pOut->m02 = 0.0f;
  1498. pOut->m03 = 0.0f;
  1499. pOut->m10 = 0.0f;
  1500. pOut->m11 = 2.0f / h;
  1501. pOut->m12 = 0.0f;
  1502. pOut->m13 = 0.0f;
  1503. pOut->m20 = 0.0f;
  1504. pOut->m21 = 0.0f;
  1505. pOut->m22 = 1.0f / (zn - zf);
  1506. pOut->m23 = 0.0f;
  1507. pOut->m30 = 0.0f;
  1508. pOut->m31 = 0.0f;
  1509. pOut->m32 = pOut->m22 * zn;
  1510. pOut->m33 = 1.0f;
  1511. return pOut;
  1512. }
  1513. D3DXMATRIX* WINAPI VB_D3DXMatrixOrthoLH
  1514. ( D3DXMATRIX *pOut, float w, float h, float zn, float zf )
  1515. {
  1516. #if DBG
  1517. if(!pOut)
  1518. return NULL;
  1519. #endif
  1520. pOut->m00 = 2.0f / w;
  1521. pOut->m01 = 0.0f;
  1522. pOut->m02 = 0.0f;
  1523. pOut->m03 = 0.0f;
  1524. pOut->m10 = 0.0f;
  1525. pOut->m11 = 2.0f / h;
  1526. pOut->m12 = 0.0f;
  1527. pOut->m13 = 0.0f;
  1528. pOut->m20 = 0.0f;
  1529. pOut->m21 = 0.0f;
  1530. pOut->m22 = 1.0f / (zf - zn);
  1531. pOut->m23 = 0.0f;
  1532. pOut->m30 = 0.0f;
  1533. pOut->m31 = 0.0f;
  1534. pOut->m32 = -pOut->m22 * zn;
  1535. pOut->m33 = 1.0f;
  1536. return pOut;
  1537. }
  1538. D3DXMATRIX* WINAPI VB_D3DXMatrixOrthoOffCenter
  1539. ( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
  1540. float zf )
  1541. {
  1542. #if DBG
  1543. if(!pOut)
  1544. return NULL;
  1545. #endif
  1546. float wInv = 1.0f / (r - l);
  1547. float hInv = 1.0f / (t - b);
  1548. pOut->m00 = 2.0f * wInv;
  1549. pOut->m01 = 0.0f;
  1550. pOut->m02 = 0.0f;
  1551. pOut->m03 = 0.0f;
  1552. pOut->m10 = 0.0f;
  1553. pOut->m11 = 2.0f * hInv;
  1554. pOut->m12 = 0.0f;
  1555. pOut->m13 = 0.0f;
  1556. pOut->m20 = 0.0f;
  1557. pOut->m21 = 0.0f;
  1558. pOut->m22 = 1.0f / (zn - zf);
  1559. pOut->m23 = 0.0f;
  1560. pOut->m30 = -(l + r) * wInv;
  1561. pOut->m31 = -(t + b) * hInv;
  1562. pOut->m32 = pOut->m22 * zn;
  1563. pOut->m33 = 1.0f;
  1564. return pOut;
  1565. }
  1566. D3DXMATRIX* WINAPI VB_D3DXMatrixOrthoOffCenterLH
  1567. ( D3DXMATRIX *pOut, float l, float r, float b, float t, float zn,
  1568. float zf )
  1569. {
  1570. #if DBG
  1571. if(!pOut)
  1572. return NULL;
  1573. #endif
  1574. float wInv = 1.0f / (r - l);
  1575. float hInv = 1.0f / (t - b);
  1576. pOut->m00 = 2.0f * wInv;
  1577. pOut->m01 = 0.0f;
  1578. pOut->m02 = 0.0f;
  1579. pOut->m03 = 0.0f;
  1580. pOut->m10 = 0.0f;
  1581. pOut->m11 = 2.0f * hInv;
  1582. pOut->m12 = 0.0f;
  1583. pOut->m13 = 0.0f;
  1584. pOut->m20 = 0.0f;
  1585. pOut->m21 = 0.0f;
  1586. pOut->m22 = 1.0f / (zf - zn);
  1587. pOut->m23 = 0.0f;
  1588. pOut->m30 = -(l + r) * wInv;
  1589. pOut->m31 = -(t + b) * hInv;
  1590. pOut->m32 = -pOut->m22 * zn;
  1591. pOut->m33 = 1.0f;
  1592. return pOut;
  1593. }
  1594. D3DXMATRIX* WINAPI VB_D3DXMatrixShadow
  1595. ( D3DXMATRIX *pOut, const D3DXVECTOR4 *pLight,
  1596. const D3DXPLANE *pPlane )
  1597. {
  1598. #if DBG
  1599. if(!pOut || !pLight || !pPlane)
  1600. return NULL;
  1601. #endif
  1602. D3DXPLANE p;
  1603. VB_D3DXPlaneNormalize(&p, pPlane);
  1604. float dot = VB_D3DXPlaneDot(&p, pLight);
  1605. p = -p;
  1606. pOut->m00 = p.a * pLight->x + dot;
  1607. pOut->m10 = p.b * pLight->x;
  1608. pOut->m20 = p.c * pLight->x;
  1609. pOut->m30 = p.d * pLight->x;
  1610. pOut->m01 = p.a * pLight->y;
  1611. pOut->m11 = p.b * pLight->y + dot;
  1612. pOut->m21 = p.c * pLight->y;
  1613. pOut->m31 = p.d * pLight->y;
  1614. pOut->m02 = p.a * pLight->z;
  1615. pOut->m12 = p.b * pLight->z;
  1616. pOut->m22 = p.c * pLight->z + dot;
  1617. pOut->m32 = p.d * pLight->z;
  1618. pOut->m03 = p.a * pLight->w;
  1619. pOut->m13 = p.b * pLight->w;
  1620. pOut->m23 = p.c * pLight->w;
  1621. pOut->m33 = p.d * pLight->w + dot;
  1622. return pOut;
  1623. }
  1624. D3DXMATRIX* WINAPI VB_D3DXMatrixReflect
  1625. ( D3DXMATRIX *pOut, const D3DXPLANE *pPlane )
  1626. {
  1627. #if DBG
  1628. if(!pOut || !pPlane)
  1629. return NULL;
  1630. #endif
  1631. D3DXPLANE p;
  1632. VB_D3DXPlaneNormalize(&p, pPlane);
  1633. float fa = -2.0f * p.a;
  1634. float fb = -2.0f * p.b;
  1635. float fc = -2.0f * p.c;
  1636. pOut->m00 = fa * p.a + 1.0f;
  1637. pOut->m01 = fb * p.a;
  1638. pOut->m02 = fc * p.a;
  1639. pOut->m03 = 0.0f;
  1640. pOut->m10 = fa * p.b;
  1641. pOut->m11 = fb * p.b + 1.0f;
  1642. pOut->m12 = fc * p.b;
  1643. pOut->m13 = 0.0f;
  1644. pOut->m20 = fa * p.c;
  1645. pOut->m21 = fb * p.c;
  1646. pOut->m22 = fc * p.c + 1.0f;
  1647. pOut->m23 = 0.0f;
  1648. pOut->m30 = fa * p.d;
  1649. pOut->m31 = fb * p.d;
  1650. pOut->m32 = fc * p.d;
  1651. pOut->m33 = 1.0f;
  1652. return pOut;
  1653. }
  1654. //--------------------------
  1655. // Quaternion
  1656. //--------------------------
  1657. void WINAPI VB_D3DXQuaternionToAxisAngle
  1658. ( const D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, float *pAngle )
  1659. {
  1660. #if DBG
  1661. if(!pQ)
  1662. return;
  1663. #endif
  1664. // expects unit quaternions!
  1665. // q = cos(A/2), sin(A/2) * v
  1666. float lsq = VB_D3DXQuaternionLengthSq(pQ);
  1667. if(lsq > EPSILON * EPSILON)
  1668. {
  1669. if(pAxis)
  1670. {
  1671. float scale = 1.0f / sqrtf(lsq);
  1672. pAxis->x = pQ->x * scale;
  1673. pAxis->y = pQ->y * scale;
  1674. pAxis->z = pQ->z * scale;
  1675. }
  1676. if(pAngle)
  1677. *pAngle = 2.0f * acosf(pQ->w);
  1678. }
  1679. else
  1680. {
  1681. if(pAxis)
  1682. {
  1683. pAxis->x = 1.0;
  1684. pAxis->y = 0.0;
  1685. pAxis->z = 0.0;
  1686. }
  1687. if(pAngle)
  1688. *pAngle = 0.0f;
  1689. }
  1690. }
  1691. D3DXQUATERNION* WINAPI VB_D3DXQuaternionRotationMatrix
  1692. ( D3DXQUATERNION *pOut, const D3DXMATRIX *pM)
  1693. {
  1694. #if DBG
  1695. if(!pOut || !pM)
  1696. return NULL;
  1697. #endif
  1698. // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
  1699. // article "Quaternion Calculus and Fast Animation". (Taken from GDMAG feb'98 p38)
  1700. float trace = pM->m00 + pM->m11 + pM->m22;
  1701. float root;
  1702. if ( trace > 0.0f )
  1703. {
  1704. // |w| > 1/2, may as well choose w > 1/2
  1705. root = sqrtf(trace + 1.0f); // 2w
  1706. pOut->w = 0.5f * root;
  1707. root = 0.5f / root; // 1/(4w)
  1708. pOut->x = (pM->m12 - pM->m21) * root;
  1709. pOut->y = (pM->m20 - pM->m02) * root;
  1710. pOut->z = (pM->m01 - pM->m10) * root;
  1711. }
  1712. else
  1713. {
  1714. // |w| <= 1/2
  1715. static const int next[3] = { 1, 2, 0 };
  1716. int i = 0;
  1717. i += (pM->m11 > pM->m00);
  1718. i += (pM->m22 > pM->m[i][i]);
  1719. int j = next[i];
  1720. int k = next[j];
  1721. root = sqrtf(pM->m[i][i] - pM->m[j][j] - pM->m[k][k] + 1.0f);
  1722. (*pOut)[i] = 0.5f * root;
  1723. if(0.0f != root)
  1724. root = 0.5f / root;
  1725. pOut->w = (pM->m[j][k] - pM->m[k][j]) * root;
  1726. (*pOut)[j] = (pM->m[i][j] + pM->m[j][i]) * root;
  1727. (*pOut)[k] = (pM->m[i][k] + pM->m[k][i]) * root;
  1728. }
  1729. return pOut;
  1730. }
  1731. D3DXQUATERNION* WINAPI VB_D3DXQuaternionRotationAxis
  1732. ( D3DXQUATERNION *pOut, const D3DXVECTOR3 *pV, float angle )
  1733. {
  1734. #if DBG
  1735. if(!pOut || !pV)
  1736. return NULL;
  1737. #endif
  1738. D3DXVECTOR3 v;
  1739. VB_D3DXVec3Normalize(&v, pV);
  1740. float s;
  1741. sincosf(0.5f * angle, &s, &pOut->w);
  1742. pOut->x = v.x * s;
  1743. pOut->y = v.y * s;
  1744. pOut->z = v.z * s;
  1745. return pOut;
  1746. }
  1747. D3DXQUATERNION* WINAPI VB_D3DXQuaternionRotationYawPitchRoll
  1748. ( D3DXQUATERNION *pOut, float yaw, float pitch, float roll )
  1749. {
  1750. #if DBG
  1751. if(!pOut)
  1752. return NULL;
  1753. #endif
  1754. // Roll first, about axis the object is facing, then
  1755. // pitch upward, then yaw to face into the new heading
  1756. float SR, CR, SP, CP, SY, CY;
  1757. sincosf(0.5f * roll, &SR, &CR);
  1758. sincosf(0.5f * pitch, &SP, &CP);
  1759. sincosf(0.5f * yaw, &SY, &CY);
  1760. pOut->x = CY*SP*CR + SY*CP*SR;
  1761. pOut->y = SY*CP*CR - CY*SP*SR;
  1762. pOut->z = CY*CP*SR - SY*SP*CR;
  1763. pOut->w = CY*CP*CR + SY*SP*SR;
  1764. return pOut;
  1765. }
  1766. D3DXQUATERNION* WINAPI VB_D3DXQuaternionMultiply
  1767. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
  1768. const D3DXQUATERNION *pQ2 )
  1769. {
  1770. #if DBG
  1771. if(!pOut || !pQ1 || !pQ2)
  1772. return NULL;
  1773. #endif
  1774. #ifdef _X86_
  1775. __asm {
  1776. mov eax, DWORD PTR [pQ2]
  1777. mov edx, DWORD PTR [pQ1]
  1778. mov ecx, DWORD PTR [pOut]
  1779. fld DWORD PTR [eax+3*4]
  1780. fmul DWORD PTR [edx+0*4] ; wx
  1781. fld DWORD PTR [eax+3*4]
  1782. fmul DWORD PTR [edx+2*4] ; wz
  1783. fld DWORD PTR [eax+3*4]
  1784. fmul DWORD PTR [edx+1*4] ; wy
  1785. fld DWORD PTR [eax+3*4]
  1786. fmul DWORD PTR [edx+3*4] ; ww
  1787. fxch st(3)
  1788. // wx wy wz ww
  1789. fld DWORD PTR [eax+0*4]
  1790. fmul DWORD PTR [edx+3*4] ; xw
  1791. fld DWORD PTR [eax+0*4]
  1792. fmul DWORD PTR [edx+1*4] ; xy
  1793. fld DWORD PTR [eax+0*4]
  1794. fmul DWORD PTR [edx+2*4] ; xz
  1795. fld DWORD PTR [eax+0*4]
  1796. fmul DWORD PTR [edx+0*4] ; xx
  1797. fxch st(3)
  1798. // xw xz xy xx wx wy wz ww
  1799. faddp st(4), st
  1800. fsubp st(4), st
  1801. faddp st(4), st
  1802. fsubp st(4), st
  1803. // wx-xw wy-xz wz+xy ww-xx
  1804. fld DWORD PTR [eax+1*4]
  1805. fmul DWORD PTR [edx+2*4] ; yz
  1806. fld DWORD PTR [eax+1*4]
  1807. fmul DWORD PTR [edx+0*4] ; yx
  1808. fld DWORD PTR [eax+1*4]
  1809. fmul DWORD PTR [edx+3*4] ; yw
  1810. fld DWORD PTR [eax+1*4]
  1811. fmul DWORD PTR [edx+1*4] ; yy
  1812. fxch st(3)
  1813. // yz yw yx yy wx-xw wy-xz wz+xy ww-xx
  1814. faddp st(4), st
  1815. faddp st(4), st
  1816. fsubp st(4), st
  1817. fsubp st(4), st
  1818. // wx-xw+yz wy-xz+yw wz+xy-yx ww-xx-yy
  1819. fld DWORD PTR [eax+2*4]
  1820. fmul DWORD PTR [edx+1*4] ; zy
  1821. fld DWORD PTR [eax+2*4]
  1822. fmul DWORD PTR [edx+3*4] ; zw
  1823. fld DWORD PTR [eax+2*4]
  1824. fmul DWORD PTR [edx+0*4] ; zx
  1825. fld DWORD PTR [eax+2*4]
  1826. fmul DWORD PTR [edx+2*4] ; zz
  1827. fxch st(3)
  1828. // zy zx zw zz wx-xw+yz wy-xz+yw wz+xy-yx ww-xx-yy
  1829. fsubp st(4), st
  1830. faddp st(4), st
  1831. faddp st(4), st
  1832. fsubp st(4), st
  1833. // wx-xw+yz-zy wy-xz+yw+zx wz+xy-yx+zw ww-xx-yy-zz
  1834. fstp DWORD PTR [ecx+0*4]
  1835. fstp DWORD PTR [ecx+1*4]
  1836. fstp DWORD PTR [ecx+2*4]
  1837. fstp DWORD PTR [ecx+3*4]
  1838. }
  1839. return pOut;
  1840. #else // !_X86_
  1841. D3DXQUATERNION Q;
  1842. Q.x = pQ2->w * pQ1->x + pQ2->x * pQ1->w + pQ2->y * pQ1->z - pQ2->z * pQ1->y;
  1843. Q.y = pQ2->w * pQ1->y - pQ2->x * pQ1->z + pQ2->y * pQ1->w + pQ2->z * pQ1->x;
  1844. Q.z = pQ2->w * pQ1->z + pQ2->x * pQ1->y - pQ2->y * pQ1->x + pQ2->z * pQ1->w;
  1845. Q.w = pQ2->w * pQ1->w - pQ2->x * pQ1->x - pQ2->y * pQ1->y - pQ2->z * pQ1->z;
  1846. *pOut = Q;
  1847. return pOut;
  1848. #endif // !_X86_
  1849. }
  1850. D3DXQUATERNION* WINAPI VB_D3DXQuaternionNormalize
  1851. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
  1852. {
  1853. #if DBG
  1854. if(!pOut || !pQ)
  1855. return NULL;
  1856. #endif
  1857. float f = VB_D3DXQuaternionLengthSq(pQ);
  1858. if(WithinEpsilon(f, 1.0f))
  1859. {
  1860. if(pOut != pQ)
  1861. *pOut = *pQ;
  1862. }
  1863. else if(f > EPSILON * EPSILON)
  1864. {
  1865. *pOut = *pQ / sqrtf(f);
  1866. }
  1867. else
  1868. {
  1869. pOut->x = 0.0f;
  1870. pOut->y = 0.0f;
  1871. pOut->z = 0.0f;
  1872. pOut->w = 0.0f;
  1873. }
  1874. return pOut;
  1875. }
  1876. D3DXQUATERNION* WINAPI VB_D3DXQuaternionInverse
  1877. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
  1878. {
  1879. #if DBG
  1880. if(!pOut || !pQ)
  1881. return NULL;
  1882. #endif
  1883. float f = VB_D3DXQuaternionLengthSq(pQ);
  1884. if(f > EPSILON*EPSILON)
  1885. {
  1886. VB_D3DXQuaternionConjugate(pOut, pQ);
  1887. if(!WithinEpsilon(f, 1.0f))
  1888. *pOut /= f;
  1889. }
  1890. else
  1891. {
  1892. pOut->x = 0.0f;
  1893. pOut->y = 0.0f;
  1894. pOut->z = 0.0f;
  1895. pOut->w = 0.0f;
  1896. }
  1897. return pOut;
  1898. }
  1899. D3DXQUATERNION* WINAPI VB_D3DXQuaternionLn
  1900. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
  1901. {
  1902. #if DBG
  1903. if(!pOut || !pQ)
  1904. return NULL;
  1905. #endif
  1906. // expects unit quaternions!
  1907. // q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v)
  1908. float theta, s, scale;
  1909. if(pQ->w < 1.0f)
  1910. {
  1911. theta = acosf(pQ->w);
  1912. s = sinf(theta);
  1913. if(!WithinEpsilon(s, 0.0f))
  1914. {
  1915. float scale = theta / s;
  1916. pOut->x = pQ->x * scale;
  1917. pOut->y = pQ->y * scale;
  1918. pOut->z = pQ->z * scale;
  1919. pOut->w = 0.0f;
  1920. }
  1921. else
  1922. {
  1923. pOut->x = pQ->x;
  1924. pOut->y = pQ->y;
  1925. pOut->z = pQ->z;
  1926. pOut->w = 0.0f;
  1927. }
  1928. }
  1929. else
  1930. {
  1931. pOut->x = pQ->x;
  1932. pOut->y = pQ->y;
  1933. pOut->z = pQ->z;
  1934. pOut->w = 0.0f;
  1935. }
  1936. return pOut;
  1937. }
  1938. D3DXQUATERNION* WINAPI VB_D3DXQuaternionExp
  1939. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ )
  1940. {
  1941. #if DBG
  1942. if(!pOut || !pQ)
  1943. return NULL;
  1944. #endif
  1945. // expects pure quaternions! (w == 0)
  1946. // q = (0, theta * v) ; exp(q) = (cos(theta), sin(theta) * v)
  1947. float theta, s;
  1948. theta = sqrtf(pQ->x * pQ->x + pQ->y * pQ->y + pQ->z * pQ->z);
  1949. sincosf(theta, &s, &pOut->w);
  1950. if(WithinEpsilon(s, 0.0f))
  1951. {
  1952. if(pOut != pQ)
  1953. {
  1954. pOut->x = pQ->x;
  1955. pOut->y = pQ->y;
  1956. pOut->z = pQ->z;
  1957. }
  1958. }
  1959. else
  1960. {
  1961. s /= theta;
  1962. pOut->x = pQ->x * s;
  1963. pOut->y = pQ->y * s;
  1964. pOut->z = pQ->z * s;
  1965. }
  1966. return pOut;
  1967. }
  1968. D3DXQUATERNION* WINAPI VB_D3DXQuaternionSlerp
  1969. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
  1970. const D3DXQUATERNION *pQ2, float b )
  1971. {
  1972. #if DBG
  1973. if(!pOut || !pQ1 || !pQ2)
  1974. return NULL;
  1975. #endif
  1976. // expects unit quaternions!
  1977. float a, c, flip, s, omega, sInv;
  1978. a = 1.0f - b;
  1979. c = VB_D3DXQuaternionDot(pQ1, pQ2);
  1980. flip = (c >= 0.0f) ? 1.0f : -1.0f;
  1981. c *= flip;
  1982. if(1.0f - c > EPSILON) {
  1983. s = sqrtf(1.0f - c * c);
  1984. omega = atan2f(s, c);
  1985. sInv = 1.0f / s;
  1986. a = sinf(a * omega) * sInv;
  1987. b = sinf(b * omega) * sInv;
  1988. }
  1989. b *= flip;
  1990. pOut->x = a * pQ1->x + b * pQ2->x;
  1991. pOut->y = a * pQ1->y + b * pQ2->y;
  1992. pOut->z = a * pQ1->z + b * pQ2->z;
  1993. pOut->w = a * pQ1->w + b * pQ2->w;
  1994. return pOut;
  1995. }
  1996. D3DXQUATERNION* WINAPI VB_D3DXQuaternionSquad
  1997. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
  1998. const D3DXQUATERNION *pQ2, const D3DXQUATERNION *pQ3,
  1999. const D3DXQUATERNION *pQ4, float t )
  2000. {
  2001. #if DBG
  2002. if(!pOut || !pQ1 || !pQ2 || !pQ3 || !pQ4)
  2003. return NULL;
  2004. #endif
  2005. // expects unit quaternions!
  2006. D3DXQUATERNION QA, QB;
  2007. VB_D3DXQuaternionSlerp(&QA, pQ1, pQ4, t);
  2008. VB_D3DXQuaternionSlerp(&QB, pQ2, pQ3, t);
  2009. VB_D3DXQuaternionSlerp(pOut, &QA, &QB, 2.0f * t * (1.0f - t));
  2010. return pOut;
  2011. }
  2012. D3DXQUATERNION* WINAPI VB_D3DXQuaternionBaryCentric
  2013. ( D3DXQUATERNION *pOut, const D3DXQUATERNION *pQ1,
  2014. const D3DXQUATERNION *pQ2, const D3DXQUATERNION *pQ3,
  2015. float f, float g )
  2016. {
  2017. #if DBG
  2018. if(!pOut || !pQ1 || !pQ2 || !pQ3)
  2019. return NULL;
  2020. #endif
  2021. // expects unit quaternions!
  2022. D3DXQUATERNION QA, QB;
  2023. float s = f + g;
  2024. if(WithinEpsilon(s, 0.0f))
  2025. {
  2026. if(pOut != pQ1)
  2027. *pOut = *pQ1;
  2028. }
  2029. else
  2030. {
  2031. VB_D3DXQuaternionSlerp(&QA, pQ1, pQ2, s);
  2032. VB_D3DXQuaternionSlerp(&QB, pQ1, pQ3, s);
  2033. VB_D3DXQuaternionSlerp(pOut, &QA, &QB, g / s);
  2034. }
  2035. return pOut;
  2036. }
  2037. //--------------------------
  2038. // Plane
  2039. //--------------------------
  2040. D3DXPLANE* WINAPI VB_D3DXPlaneNormalize
  2041. ( D3DXPLANE *pOut, const D3DXPLANE *pP )
  2042. {
  2043. #if DBG
  2044. if(!pOut || !pP)
  2045. return NULL;
  2046. #endif
  2047. float f = pP->a * pP->a + pP->b * pP->b + pP->c * pP->c;
  2048. if(WithinEpsilon(f, 1.0f))
  2049. {
  2050. if(pOut != pP)
  2051. *pOut = *pP;
  2052. }
  2053. else if(f > EPSILON * EPSILON)
  2054. {
  2055. float fInv = 1.0f / sqrtf(f);
  2056. pOut->a = pP->a * fInv;
  2057. pOut->b = pP->b * fInv;
  2058. pOut->c = pP->c * fInv;
  2059. pOut->d = pP->d * fInv;
  2060. }
  2061. else
  2062. {
  2063. pOut->a = 0.0f;
  2064. pOut->b = 0.0f;
  2065. pOut->c = 0.0f;
  2066. pOut->d = 0.0f;
  2067. }
  2068. return pOut;
  2069. }
  2070. D3DXVECTOR3* WINAPI VB_D3DXPlaneIntersectLine
  2071. ( D3DXVECTOR3 *pOut, const D3DXPLANE *pP, const D3DXVECTOR3 *pV1,
  2072. const D3DXVECTOR3 *pV2)
  2073. {
  2074. #if DBG
  2075. if(!pOut || !pP || !pV1 || !pV2)
  2076. return NULL;
  2077. #endif
  2078. float d = VB_D3DXPlaneDotNormal(pP, pV1) - VB_D3DXPlaneDotNormal(pP, pV2);
  2079. if(d == 0.0f)
  2080. return NULL;
  2081. float f = VB_D3DXPlaneDotCoord(pP, pV1) / d;
  2082. if(!_finite(f))
  2083. return NULL;
  2084. VB_D3DXVec3Lerp(pOut, pV1, pV2, f);
  2085. return pOut;
  2086. }
  2087. D3DXPLANE* WINAPI VB_D3DXPlaneFromPointNormal
  2088. ( D3DXPLANE *pOut, const D3DXVECTOR3 *pPoint, const D3DXVECTOR3 *pNormal)
  2089. {
  2090. #if DBG
  2091. if(!pOut || !pPoint || !pNormal)
  2092. return NULL;
  2093. #endif
  2094. pOut->a = pNormal->x;
  2095. pOut->b = pNormal->y;
  2096. pOut->c = pNormal->z;
  2097. pOut->d = -VB_D3DXVec3Dot(pPoint, pNormal);
  2098. return pOut;
  2099. }
  2100. D3DXPLANE* WINAPI VB_D3DXPlaneFromPoints
  2101. ( D3DXPLANE *pOut, const D3DXVECTOR3 *pV1, const D3DXVECTOR3 *pV2,
  2102. const D3DXVECTOR3 *pV3)
  2103. {
  2104. #if DBG
  2105. if(!pOut || !pV1 || !pV2 || !pV3)
  2106. return NULL;
  2107. #endif
  2108. D3DXVECTOR3 V12 = *pV1 - *pV2;
  2109. D3DXVECTOR3 V13 = *pV1 - *pV3;
  2110. VB_D3DXVec3Cross((D3DXVECTOR3 *) pOut, &V12, &V13);
  2111. VB_D3DXVec3Normalize((D3DXVECTOR3 *) pOut, (D3DXVECTOR3 *) pOut);
  2112. pOut->d = -VB_D3DXPlaneDotNormal(pOut, pV1);
  2113. return pOut;
  2114. }
  2115. D3DXPLANE* WINAPI VB_D3DXPlaneTransform
  2116. ( D3DXPLANE *pOut, const D3DXPLANE *pP, const D3DXMATRIX *pM )
  2117. {
  2118. #if DBG
  2119. if(!pOut || !pP || !pM)
  2120. return NULL;
  2121. #endif
  2122. D3DXPLANE P;
  2123. VB_D3DXPlaneNormalize(&P, pP);
  2124. D3DXVECTOR3 V(-P.a * P.d, -P.b * P.d, -P.c * P.d);
  2125. VB_D3DXVec3TransformCoord(&V, &V, pM);
  2126. VB_D3DXVec3TransformNormal((D3DXVECTOR3 *) pOut, (const D3DXVECTOR3 *) &P, pM);
  2127. VB_D3DXVec3Normalize((D3DXVECTOR3 *) pOut, (const D3DXVECTOR3 *) pOut);
  2128. pOut->d = -VB_D3DXPlaneDotNormal(pOut, &V);
  2129. return pOut;
  2130. }
  2131. //--------------------------
  2132. // Color
  2133. //--------------------------
  2134. D3DXCOLOR* WINAPI VB_D3DXColorAdjustSaturation
  2135. (D3DXCOLOR *pOut, const D3DXCOLOR *pC, float s)
  2136. {
  2137. #if DBG
  2138. if(!pOut || !pC)
  2139. return NULL;
  2140. #endif
  2141. // Approximate values for each component's contribution to luminance.
  2142. // (Based upon the NTSC standard described in the comp.graphics.algorithms
  2143. // colorspace FAQ)
  2144. float grey = pC->r * 0.2125f + pC->g * 0.7154f + pC->b * 0.0721f;
  2145. pOut->r = grey + s * (pC->r - grey);
  2146. pOut->g = grey + s * (pC->g - grey);
  2147. pOut->b = grey + s * (pC->b - grey);
  2148. pOut->a = pC->a;
  2149. return pOut;
  2150. }
  2151. D3DXCOLOR* WINAPI VB_D3DXColorAdjustContrast
  2152. (D3DXCOLOR *pOut, const D3DXCOLOR *pC, float c)
  2153. {
  2154. #if DBG
  2155. if(!pOut || !pC)
  2156. return NULL;
  2157. #endif
  2158. pOut->r = 0.5f + c * (pC->r - 0.5f);
  2159. pOut->g = 0.5f + c * (pC->g - 0.5f);
  2160. pOut->b = 0.5f + c * (pC->b - 0.5f);
  2161. pOut->a = pC->a;
  2162. return pOut;
  2163. }