Source code of Windows XP (NT5)
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.

572 lines
17 KiB

  1. /*
  2. ** Copyright 1991, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. **
  17. ** Mathematical subroutines needed by the GL.
  18. **
  19. ** $Revision: 1.12 $
  20. ** $Date: 1993/12/11 01:03:25 $
  21. */
  22. #include "precomp.h"
  23. #pragma hdrstop
  24. #include "xform.h"
  25. #ifdef SGI
  26. // SGIBUG None of the assembly routines copies matrixType!
  27. #ifndef __GL_ASM_COPYMATRIX
  28. /*
  29. ** Copy src to dst
  30. */
  31. void FASTCALL __glCopyMatrix(__GLmatrix *dst, const __GLmatrix *src)
  32. {
  33. dst->matrixType = src->matrixType;
  34. dst->matrix[0][0] = src->matrix[0][0];
  35. dst->matrix[0][1] = src->matrix[0][1];
  36. dst->matrix[0][2] = src->matrix[0][2];
  37. dst->matrix[0][3] = src->matrix[0][3];
  38. dst->matrix[1][0] = src->matrix[1][0];
  39. dst->matrix[1][1] = src->matrix[1][1];
  40. dst->matrix[1][2] = src->matrix[1][2];
  41. dst->matrix[1][3] = src->matrix[1][3];
  42. dst->matrix[2][0] = src->matrix[2][0];
  43. dst->matrix[2][1] = src->matrix[2][1];
  44. dst->matrix[2][2] = src->matrix[2][2];
  45. dst->matrix[2][3] = src->matrix[2][3];
  46. dst->matrix[3][0] = src->matrix[3][0];
  47. dst->matrix[3][1] = src->matrix[3][1];
  48. dst->matrix[3][2] = src->matrix[3][2];
  49. dst->matrix[3][3] = src->matrix[3][3];
  50. }
  51. #endif /* __GL_ASM_COPYMATRIX */
  52. #endif // SGI
  53. /*
  54. ** Make m an identity matrix
  55. */
  56. void FASTCALL __glMakeIdentity(__GLmatrix *m)
  57. {
  58. __GLfloat zer = __glZero;
  59. __GLfloat one = ((__GLfloat) 1.0);;
  60. m->matrix[0][0] = one; m->matrix[0][1] = zer;
  61. m->matrix[0][2] = zer; m->matrix[0][3] = zer;
  62. m->matrix[1][0] = zer; m->matrix[1][1] = one;
  63. m->matrix[1][2] = zer; m->matrix[1][3] = zer;
  64. m->matrix[2][0] = zer; m->matrix[2][1] = zer;
  65. m->matrix[2][2] = one; m->matrix[2][3] = zer;
  66. m->matrix[3][0] = zer; m->matrix[3][1] = zer;
  67. m->matrix[3][2] = zer; m->matrix[3][3] = one;
  68. m->matrixType = __GL_MT_IDENTITY;
  69. }
  70. #ifndef __GL_ASM_MULTMATRIX
  71. /*
  72. ** Compute r = a * b, where r can equal b.
  73. */
  74. void FASTCALL __glMultMatrix(__GLmatrix *r, const __GLmatrix *a, const __GLmatrix *b)
  75. {
  76. __GLfloat b00, b01, b02, b03;
  77. __GLfloat b10, b11, b12, b13;
  78. __GLfloat b20, b21, b22, b23;
  79. __GLfloat b30, b31, b32, b33;
  80. GLint i;
  81. b00 = b->matrix[0][0]; b01 = b->matrix[0][1];
  82. b02 = b->matrix[0][2]; b03 = b->matrix[0][3];
  83. b10 = b->matrix[1][0]; b11 = b->matrix[1][1];
  84. b12 = b->matrix[1][2]; b13 = b->matrix[1][3];
  85. b20 = b->matrix[2][0]; b21 = b->matrix[2][1];
  86. b22 = b->matrix[2][2]; b23 = b->matrix[2][3];
  87. b30 = b->matrix[3][0]; b31 = b->matrix[3][1];
  88. b32 = b->matrix[3][2]; b33 = b->matrix[3][3];
  89. for (i = 0; i < 4; i++) {
  90. r->matrix[i][0] = a->matrix[i][0]*b00 + a->matrix[i][1]*b10
  91. + a->matrix[i][2]*b20 + a->matrix[i][3]*b30;
  92. r->matrix[i][1] = a->matrix[i][0]*b01 + a->matrix[i][1]*b11
  93. + a->matrix[i][2]*b21 + a->matrix[i][3]*b31;
  94. r->matrix[i][2] = a->matrix[i][0]*b02 + a->matrix[i][1]*b12
  95. + a->matrix[i][2]*b22 + a->matrix[i][3]*b32;
  96. r->matrix[i][3] = a->matrix[i][0]*b03 + a->matrix[i][1]*b13
  97. + a->matrix[i][2]*b23 + a->matrix[i][3]*b33;
  98. }
  99. }
  100. #endif /* __GL_ASM_MULTMATRIX */
  101. #ifndef __GL_ASM_NORMALIZE
  102. /*
  103. ** Normalize v into vout.
  104. */
  105. void FASTCALL __glNormalize(__GLfloat vout[3], const __GLfloat v[3])
  106. {
  107. __GLfloat len;
  108. len = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
  109. if (__GL_FLOAT_LEZ(len))
  110. {
  111. vout[0] = __glZero;
  112. vout[1] = __glZero;
  113. vout[2] = __glZero;
  114. return;
  115. } else {
  116. if (len == ((__GLfloat) 1.0))
  117. {
  118. vout[0] = v[0];
  119. vout[1] = v[1];
  120. vout[2] = v[2];
  121. } else {
  122. len = ((__GLfloat) 1.0) / __GL_SQRTF(len);
  123. vout[0] = v[0] * len;
  124. vout[1] = v[1] * len;
  125. vout[2] = v[2] * len;
  126. }
  127. }
  128. }
  129. #endif /* __GL_ASM_NORMALIZE */
  130. #ifndef __GL_ASM_NORMAL_BATCH
  131. /*
  132. ** Normalize normals in a polyarray.
  133. */
  134. void FASTCALL __glNormalizeBatch(POLYARRAY *pa)
  135. {
  136. POLYDATA * const pdLast = pa->pdNextVertex;
  137. POLYDATA *pd = pa->pd0;
  138. for (; pd < pdLast; pd++)
  139. {
  140. if (pd->flags & POLYDATA_NORMAL_VALID)
  141. {
  142. __GLcoord * const v = &pd->normal;
  143. const __GLfloat len = v->x*v->x + v->y*v->y + v->z*v->z;
  144. if (__GL_FLOAT_LEZ(len))
  145. {
  146. v->x = __glZero;
  147. v->y = __glZero;
  148. v->z = __glZero;
  149. } else
  150. {
  151. if (fabs(len - (GLfloat)1.0) > (__GLfloat) 0.0001)
  152. {
  153. const __GLfloat tmp = ((__GLfloat)1.0) / __GL_SQRTF(len);
  154. v->x = v->x * tmp;
  155. v->y = v->y * tmp;
  156. v->z = v->z * tmp;
  157. }
  158. }
  159. }
  160. }
  161. }
  162. #endif /* __GL_ASM_NORMAL_BATCH */
  163. /*
  164. ** inverse = invert(transpose(src))
  165. This code uses Cramer's Rule to calculate the matrix inverse.
  166. In general, the inverse transpose has this form:
  167. [ ] -t [ ]
  168. [ ] [ -t -t t ]
  169. [ Q P ] [ S(SQ - PT) -(SQ - PT) T ]
  170. [ ] [ ]
  171. [ ] [ ]
  172. [ ] = [ ]
  173. [ ] [ -1 t ]
  174. [ ] [ -(Q P) 1 ]
  175. [ T S ] [ ------------- ------------- ]
  176. [ ] [ -1 t t -1 t t ]
  177. [ ] [ S - (Q P) T S - (Q P) T ]
  178. But in the usual case that P,S == [0, 0, 0, 1], this is enough:
  179. [ ] -t [ ]
  180. [ ] [ -t -t t ]
  181. [ Q 0 ] [ Q -Q T ]
  182. [ ] [ ]
  183. [ ] [ ]
  184. [ ] = [ ]
  185. [ ] [ ]
  186. [ ] [ ]
  187. [ T 1 ] [ 0 1 ]
  188. [ ] [ ]
  189. [ ] [ ]
  190. */
  191. void FASTCALL __glInvertTransposeMatrix(__GLmatrix *inverse, const __GLmatrix *src)
  192. {
  193. __GLfloat x00, x01, x02;
  194. __GLfloat x10, x11, x12;
  195. __GLfloat x20, x21, x22;
  196. __GLfloat rcp;
  197. #ifdef NT
  198. // The matrix type of the inverse transpose is not necessarily the
  199. // same as that of the input. Always set it to general here to
  200. // be safe. The type can be refined later if necessary.
  201. inverse->matrixType = __GL_MT_GENERAL;
  202. if (src->matrixType)
  203. #else
  204. /* propagate matrix type & branch if general */
  205. if (inverse->matrixType = src->matrixType)
  206. #endif
  207. {
  208. __GLfloat z00, z01, z02;
  209. __GLfloat z10, z11, z12;
  210. __GLfloat z20, z21, z22;
  211. /* read 3x3 matrix into registers */
  212. x00 = src->matrix[0][0];
  213. x01 = src->matrix[0][1];
  214. x02 = src->matrix[0][2];
  215. x10 = src->matrix[1][0];
  216. x11 = src->matrix[1][1];
  217. x12 = src->matrix[1][2];
  218. x20 = src->matrix[2][0];
  219. x21 = src->matrix[2][1];
  220. x22 = src->matrix[2][2];
  221. /* compute first three 2x2 cofactors */
  222. z20 = x01*x12 - x11*x02;
  223. z10 = x21*x02 - x01*x22;
  224. z00 = x11*x22 - x12*x21;
  225. /* compute 3x3 determinant & its reciprocal */
  226. rcp = x20*z20 + x10*z10 + x00*z00;
  227. if (rcp == (float)0)
  228. return;
  229. rcp = (float)1/rcp;
  230. /* compute other six 2x2 cofactors */
  231. z01 = x20*x12 - x10*x22;
  232. z02 = x10*x21 - x20*x11;
  233. z11 = x00*x22 - x20*x02;
  234. z12 = x20*x01 - x00*x21;
  235. z21 = x10*x02 - x00*x12;
  236. z22 = x00*x11 - x10*x01;
  237. /* multiply all cofactors by reciprocal */
  238. inverse->matrix[0][0] = z00*rcp;
  239. inverse->matrix[0][1] = z01*rcp;
  240. inverse->matrix[0][2] = z02*rcp;
  241. inverse->matrix[1][0] = z10*rcp;
  242. inverse->matrix[1][1] = z11*rcp;
  243. inverse->matrix[1][2] = z12*rcp;
  244. inverse->matrix[2][0] = z20*rcp;
  245. inverse->matrix[2][1] = z21*rcp;
  246. inverse->matrix[2][2] = z22*rcp;
  247. /* read translation vector & negate */
  248. x00 = -src->matrix[3][0];
  249. x01 = -src->matrix[3][1];
  250. x02 = -src->matrix[3][2];
  251. /* store bottom row of inverse transpose */
  252. inverse->matrix[3][0] = 0;
  253. inverse->matrix[3][1] = 0;
  254. inverse->matrix[3][2] = 0;
  255. inverse->matrix[3][3] = 1;
  256. /* finish by tranforming translation vector */
  257. inverse->matrix[0][3] = inverse->matrix[0][0]*x00 +
  258. inverse->matrix[0][1]*x01 +
  259. inverse->matrix[0][2]*x02;
  260. inverse->matrix[1][3] = inverse->matrix[1][0]*x00 +
  261. inverse->matrix[1][1]*x01 +
  262. inverse->matrix[1][2]*x02;
  263. inverse->matrix[2][3] = inverse->matrix[2][0]*x00 +
  264. inverse->matrix[2][1]*x01 +
  265. inverse->matrix[2][2]*x02;
  266. if ((rcp <= ((float)1.0 + __GL_MATRIX_UNITY_SCALE_EPSILON)) &&
  267. (rcp >= ((float)1.0 - __GL_MATRIX_UNITY_SCALE_EPSILON))) {
  268. inverse->nonScaling = GL_TRUE;
  269. } else {
  270. inverse->nonScaling = GL_FALSE;
  271. }
  272. }
  273. else
  274. {
  275. __GLfloat x30, x31, x32;
  276. __GLfloat y01, y02, y03, y12, y13, y23;
  277. __GLfloat z02, z03, z12, z13, z22, z23, z32, z33;
  278. #define x03 x01
  279. #define x13 x11
  280. #define x23 x21
  281. #define x33 x31
  282. #define z00 x02
  283. #define z10 x12
  284. #define z20 x22
  285. #define z30 x32
  286. #define z01 x03
  287. #define z11 x13
  288. #define z21 x23
  289. #define z31 x33
  290. /* read 1st two columns of matrix into registers */
  291. x00 = src->matrix[0][0];
  292. x01 = src->matrix[0][1];
  293. x10 = src->matrix[1][0];
  294. x11 = src->matrix[1][1];
  295. x20 = src->matrix[2][0];
  296. x21 = src->matrix[2][1];
  297. x30 = src->matrix[3][0];
  298. x31 = src->matrix[3][1];
  299. /* compute all six 2x2 determinants of 1st two columns */
  300. y01 = x00*x11 - x10*x01;
  301. y02 = x00*x21 - x20*x01;
  302. y03 = x00*x31 - x30*x01;
  303. y12 = x10*x21 - x20*x11;
  304. y13 = x10*x31 - x30*x11;
  305. y23 = x20*x31 - x30*x21;
  306. /* read 2nd two columns of matrix into registers */
  307. x02 = src->matrix[0][2];
  308. x03 = src->matrix[0][3];
  309. x12 = src->matrix[1][2];
  310. x13 = src->matrix[1][3];
  311. x22 = src->matrix[2][2];
  312. x23 = src->matrix[2][3];
  313. x32 = src->matrix[3][2];
  314. x33 = src->matrix[3][3];
  315. /* compute all 3x3 cofactors for 2nd two columns */
  316. z33 = x02*y12 - x12*y02 + x22*y01;
  317. z23 = x12*y03 - x32*y01 - x02*y13;
  318. z13 = x02*y23 - x22*y03 + x32*y02;
  319. z03 = x22*y13 - x32*y12 - x12*y23;
  320. z32 = x13*y02 - x23*y01 - x03*y12;
  321. z22 = x03*y13 - x13*y03 + x33*y01;
  322. z12 = x23*y03 - x33*y02 - x03*y23;
  323. z02 = x13*y23 - x23*y13 + x33*y12;
  324. /* compute all six 2x2 determinants of 2nd two columns */
  325. y01 = x02*x13 - x12*x03;
  326. y02 = x02*x23 - x22*x03;
  327. y03 = x02*x33 - x32*x03;
  328. y12 = x12*x23 - x22*x13;
  329. y13 = x12*x33 - x32*x13;
  330. y23 = x22*x33 - x32*x23;
  331. /* read 1st two columns of matrix into registers */
  332. x00 = src->matrix[0][0];
  333. x01 = src->matrix[0][1];
  334. x10 = src->matrix[1][0];
  335. x11 = src->matrix[1][1];
  336. x20 = src->matrix[2][0];
  337. x21 = src->matrix[2][1];
  338. x30 = src->matrix[3][0];
  339. x31 = src->matrix[3][1];
  340. /* compute all 3x3 cofactors for 1st column */
  341. z30 = x11*y02 - x21*y01 - x01*y12;
  342. z20 = x01*y13 - x11*y03 + x31*y01;
  343. z10 = x21*y03 - x31*y02 - x01*y23;
  344. z00 = x11*y23 - x21*y13 + x31*y12;
  345. /* compute 4x4 determinant & its reciprocal */
  346. rcp = x30*z30 + x20*z20 + x10*z10 + x00*z00;
  347. if (rcp == (float)0)
  348. return;
  349. rcp = (float)1/rcp;
  350. /* compute all 3x3 cofactors for 2nd column */
  351. z31 = x00*y12 - x10*y02 + x20*y01;
  352. z21 = x10*y03 - x30*y01 - x00*y13;
  353. z11 = x00*y23 - x20*y03 + x30*y02;
  354. z01 = x20*y13 - x30*y12 - x10*y23;
  355. /* multiply all 3x3 cofactors by reciprocal */
  356. inverse->matrix[0][0] = z00*rcp;
  357. inverse->matrix[0][1] = z01*rcp;
  358. inverse->matrix[1][0] = z10*rcp;
  359. inverse->matrix[0][2] = z02*rcp;
  360. inverse->matrix[2][0] = z20*rcp;
  361. inverse->matrix[0][3] = z03*rcp;
  362. inverse->matrix[3][0] = z30*rcp;
  363. inverse->matrix[1][1] = z11*rcp;
  364. inverse->matrix[1][2] = z12*rcp;
  365. inverse->matrix[2][1] = z21*rcp;
  366. inverse->matrix[1][3] = z13*rcp;
  367. inverse->matrix[3][1] = z31*rcp;
  368. inverse->matrix[2][2] = z22*rcp;
  369. inverse->matrix[2][3] = z23*rcp;
  370. inverse->matrix[3][2] = z32*rcp;
  371. inverse->matrix[3][3] = z33*rcp;
  372. if ((inverse->matrix[3][0] == __glZero) &&
  373. (inverse->matrix[3][1] == __glZero) &&
  374. (inverse->matrix[3][2] == __glZero)) {
  375. if (((rcp <= ((float)1.0 + __GL_MATRIX_UNITY_SCALE_EPSILON)) &&
  376. (rcp >= ((float)1.0 - __GL_MATRIX_UNITY_SCALE_EPSILON)))) {
  377. inverse->nonScaling = GL_TRUE;
  378. } else {
  379. inverse->nonScaling = GL_FALSE;
  380. }
  381. } else {
  382. inverse->nonScaling = GL_FALSE;
  383. }
  384. }
  385. }
  386. /*
  387. * Find the 3x3 transpose of a matrix. This is used to calculate the light
  388. * vector in object space for fast infinite lighting.
  389. */
  390. void __glTranspose3x3(__GLmatrix *dst, __GLmatrix *src)
  391. {
  392. __GLfloat x00, x01, x02;
  393. __GLfloat x10, x11, x12;
  394. __GLfloat x20, x21, x22;
  395. x00 = src->matrix[0][0];
  396. x01 = src->matrix[0][1];
  397. x02 = src->matrix[0][2];
  398. x10 = src->matrix[1][0];
  399. x11 = src->matrix[1][1];
  400. x12 = src->matrix[1][2];
  401. x20 = src->matrix[2][0];
  402. x21 = src->matrix[2][1];
  403. x22 = src->matrix[2][2];
  404. dst->matrix[0][0] = x00;
  405. dst->matrix[1][0] = x01;
  406. dst->matrix[2][0] = x02;
  407. dst->matrix[3][0] = __glZero;
  408. dst->matrix[0][1] = x10;
  409. dst->matrix[1][1] = x11;
  410. dst->matrix[2][1] = x12;
  411. dst->matrix[3][1] = __glZero;
  412. dst->matrix[0][2] = x20;
  413. dst->matrix[1][2] = x21;
  414. dst->matrix[2][2] = x22;
  415. dst->matrix[3][2] = __glZero;
  416. dst->matrix[0][3] = __glZero;
  417. dst->matrix[1][3] = __glZero;
  418. dst->matrix[2][3] = __glZero;
  419. dst->matrix[3][3] = __glOne;
  420. }
  421. #ifdef NT
  422. /*
  423. ** Return the closest integer log based 2 of a number
  424. */
  425. static GLubyte logTab[256] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
  426. 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
  427. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  428. 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
  429. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  430. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  431. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  432. 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
  433. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  434. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  435. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  436. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  437. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  438. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  439. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
  440. 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
  441. };
  442. GLint FASTCALL __glIntLog2(__GLfloat f)
  443. {
  444. GLuint i = (GLuint) FTOL(f);
  445. if (i & 0xffff0000) {
  446. if (i & 0xff000000) {
  447. return ((GLint)logTab[i >> 24] + 24);
  448. } else {
  449. return ((GLint)logTab[i >> 16] + 16);
  450. }
  451. } else {
  452. if (i & 0xff00) {
  453. return ((GLint)logTab[i >> 8] + 8);
  454. } else {
  455. return ((GLint)logTab[i]);
  456. }
  457. }
  458. }
  459. #else
  460. GLint __glIntLog2(__GLfloat f)
  461. {
  462. return (GLint)(__GL_LOGF(f) * __GL_M_LN2_INV);
  463. }
  464. #endif
  465. GLfloat FASTCALL __glClampf(GLfloat fval, __GLfloat zero, __GLfloat one)
  466. {
  467. if (fval < zero) return zero;
  468. else if (fval > one) return one;
  469. else return fval;
  470. }
  471. /*
  472. ** r = vector from p1 to p2
  473. */
  474. #ifndef __GL_ASM_VECSUB4
  475. void FASTCALL __glVecSub4(__GLcoord *r,
  476. const __GLcoord *p1, const __GLcoord *p2)
  477. {
  478. __GLfloat oneOverW;
  479. if (p2->w == __glZero) {
  480. if (p1->w == __glZero) {
  481. r->x = p2->x - p1->x;
  482. r->y = p2->y - p1->y;
  483. r->z = p2->z - p1->z;
  484. } else {
  485. r->x = p2->x;
  486. r->y = p2->y;
  487. r->z = p2->z;
  488. }
  489. } else
  490. if (p1->w == __glZero) {
  491. r->x = -p1->x;
  492. r->y = -p1->y;
  493. r->z = -p1->z;
  494. } else{
  495. oneOverW = ((__GLfloat) 1.0) / p2->w;
  496. r->x = p2->x * oneOverW;
  497. r->y = p2->y * oneOverW;
  498. r->z = p2->z * oneOverW;
  499. oneOverW = ((__GLfloat) 1.0) / p1->w;
  500. r->x -= p1->x * oneOverW;
  501. r->y -= p1->y * oneOverW;
  502. r->z -= p1->z * oneOverW;
  503. }
  504. }
  505. #endif // !__GL_ASM_VECSUB4