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.

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