push 955563f995be8b0942dbb757ceb5b3a4c8ccafbf
[wine/hacks.git] / dlls / d3dx8 / math.c
blob34f6fed04d7f39205c0cd2919dd97f5632abe0b4
1 /*
2 * Copyright 2007 David Adam
3 * Copyright 2008 Jérôme Gardou
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #include <stdarg.h>
22 #define NONAMELESSUNION
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "d3dx8_private.h"
29 #include "wine/debug.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
33 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl;
35 /*_________________D3DXColor____________________*/
37 D3DXCOLOR* WINAPI D3DXColorAdjustContrast(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s)
39 pout->r = 0.5f + s * (pc->r - 0.5f);
40 pout->g = 0.5f + s * (pc->g - 0.5f);
41 pout->b = 0.5f + s * (pc->b - 0.5f);
42 pout->a = pc->a;
43 return pout;
46 D3DXCOLOR* WINAPI D3DXColorAdjustSaturation(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s)
48 FLOAT grey;
50 grey = pc->r * 0.2125f + pc->g * 0.7154f + pc->b * 0.0721f;
51 pout->r = grey + s * (pc->r - grey);
52 pout->g = grey + s * (pc->g - grey);
53 pout->b = grey + s * (pc->b - grey);
54 pout->a = pc->a;
55 return pout;
58 /*_________________Misc__________________________*/
60 FLOAT WINAPI D3DXFresnelTerm(FLOAT costheta, FLOAT refractionindex)
62 FLOAT a, d, g, result;
64 g = sqrt(refractionindex * refractionindex + costheta * costheta - 1.0f);
65 a = g + costheta;
66 d = g - costheta;
67 result = ( costheta * a - 1.0f ) * ( costheta * a - 1.0f ) / ( ( costheta * d + 1.0f ) * ( costheta * d + 1.0f ) ) + 1.0f;
68 result = result * 0.5f * d * d / ( a * a );
69 return result;
72 /*_________________D3DXMatrix____________________*/
74 D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation(D3DXMATRIX *pout, FLOAT scaling, CONST D3DXVECTOR3 *rotationcenter, CONST D3DXQUATERNION *rotation, CONST D3DXVECTOR3 *translation)
76 D3DXMATRIX m1, m2, m3, m4, m5;
78 D3DXMatrixScaling(&m1, scaling, scaling, scaling);
79 if ( !rotationcenter )
81 D3DXMatrixIdentity(&m2);
82 D3DXMatrixIdentity(&m4);
84 else
86 D3DXMatrixTranslation(&m2, -rotationcenter->x, -rotationcenter->y, -rotationcenter->z);
87 D3DXMatrixTranslation(&m4, rotationcenter->x, rotationcenter->y, rotationcenter->z);
89 if ( !rotation )
91 D3DXMatrixIdentity(&m3);
93 else
95 D3DXMatrixRotationQuaternion(&m3, rotation);
97 if ( !translation )
99 D3DXMatrixIdentity(&m5);
101 else
103 D3DXMatrixTranslation(&m5, translation->x, translation->y, translation->z);
105 D3DXMatrixMultiply(&m1, &m1, &m2);
106 D3DXMatrixMultiply(&m1, &m1, &m3);
107 D3DXMatrixMultiply(&m1, &m1, &m4);
108 D3DXMatrixMultiply(pout, &m1, &m5);
109 return pout;
112 FLOAT WINAPI D3DXMatrixfDeterminant(CONST D3DXMATRIX *pm)
114 D3DXVECTOR4 minor, v1, v2, v3;
115 FLOAT det;
117 v1.x = pm->u.m[0][0]; v1.y = pm->u.m[1][0]; v1.z = pm->u.m[2][0]; v1.w = pm->u.m[3][0];
118 v2.x = pm->u.m[0][1]; v2.y = pm->u.m[1][1]; v2.z = pm->u.m[2][1]; v2.w = pm->u.m[3][1];
119 v3.x = pm->u.m[0][2]; v3.y = pm->u.m[1][2]; v3.z = pm->u.m[2][2]; v3.w = pm->u.m[3][2];
120 D3DXVec4Cross(&minor, &v1, &v2, &v3);
121 det = - (pm->u.m[0][3] * minor.x + pm->u.m[1][3] * minor.y + pm->u.m[2][3] * minor.z + pm->u.m[3][3] * minor.w);
122 return det;
125 D3DXMATRIX* WINAPI D3DXMatrixInverse(D3DXMATRIX *pout, FLOAT *pdeterminant, CONST D3DXMATRIX *pm)
127 int a, i, j;
128 D3DXMATRIX out;
129 D3DXVECTOR4 v, vec[3];
130 FLOAT det;
132 det = D3DXMatrixfDeterminant(pm);
133 if ( !det ) return NULL;
134 if ( pdeterminant ) *pdeterminant = det;
135 for (i=0; i<4; i++)
137 for (j=0; j<4; j++)
139 if (j != i )
141 a = j;
142 if ( j > i ) a = a-1;
143 vec[a].x = pm->u.m[j][0];
144 vec[a].y = pm->u.m[j][1];
145 vec[a].z = pm->u.m[j][2];
146 vec[a].w = pm->u.m[j][3];
149 D3DXVec4Cross(&v, &vec[0], &vec[1], &vec[2]);
150 out.u.m[0][i] = pow(-1.0f, i) * v.x / det;
151 out.u.m[1][i] = pow(-1.0f, i) * v.y / det;
152 out.u.m[2][i] = pow(-1.0f, i) * v.z / det;
153 out.u.m[3][i] = pow(-1.0f, i) * v.w / det;
155 *pout = out;
156 return pout;
159 D3DXMATRIX* WINAPI D3DXMatrixLookAtLH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, CONST D3DXVECTOR3 *pat, CONST D3DXVECTOR3 *pup)
161 D3DXVECTOR3 right, rightn, up, upn, vec, vec2;
163 D3DXVec3Subtract(&vec2, pat, peye);
164 D3DXVec3Normalize(&vec, &vec2);
165 D3DXVec3Cross(&right, pup, &vec);
166 D3DXVec3Cross(&up, &vec, &right);
167 D3DXVec3Normalize(&rightn, &right);
168 D3DXVec3Normalize(&upn, &up);
169 pout->u.m[0][0] = rightn.x;
170 pout->u.m[1][0] = rightn.y;
171 pout->u.m[2][0] = rightn.z;
172 pout->u.m[3][0] = -D3DXVec3Dot(&rightn,peye);
173 pout->u.m[0][1] = upn.x;
174 pout->u.m[1][1] = upn.y;
175 pout->u.m[2][1] = upn.z;
176 pout->u.m[3][1] = -D3DXVec3Dot(&upn, peye);
177 pout->u.m[0][2] = vec.x;
178 pout->u.m[1][2] = vec.y;
179 pout->u.m[2][2] = vec.z;
180 pout->u.m[3][2] = -D3DXVec3Dot(&vec, peye);
181 pout->u.m[0][3] = 0.0f;
182 pout->u.m[1][3] = 0.0f;
183 pout->u.m[2][3] = 0.0f;
184 pout->u.m[3][3] = 1.0f;
185 return pout;
188 D3DXMATRIX* WINAPI D3DXMatrixLookAtRH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, CONST D3DXVECTOR3 *pat, CONST D3DXVECTOR3 *pup)
190 D3DXVECTOR3 right, rightn, up, upn, vec, vec2;
192 D3DXVec3Subtract(&vec2, pat, peye);
193 D3DXVec3Normalize(&vec, &vec2);
194 D3DXVec3Cross(&right, pup, &vec);
195 D3DXVec3Cross(&up, &vec, &right);
196 D3DXVec3Normalize(&rightn, &right);
197 D3DXVec3Normalize(&upn, &up);
198 pout->u.m[0][0] = -rightn.x;
199 pout->u.m[1][0] = -rightn.y;
200 pout->u.m[2][0] = -rightn.z;
201 pout->u.m[3][0] = D3DXVec3Dot(&rightn,peye);
202 pout->u.m[0][1] = upn.x;
203 pout->u.m[1][1] = upn.y;
204 pout->u.m[2][1] = upn.z;
205 pout->u.m[3][1] = -D3DXVec3Dot(&upn, peye);
206 pout->u.m[0][2] = -vec.x;
207 pout->u.m[1][2] = -vec.y;
208 pout->u.m[2][2] = -vec.z;
209 pout->u.m[3][2] = D3DXVec3Dot(&vec, peye);
210 pout->u.m[0][3] = 0.0f;
211 pout->u.m[1][3] = 0.0f;
212 pout->u.m[2][3] = 0.0f;
213 pout->u.m[3][3] = 1.0f;
214 return pout;
217 D3DXMATRIX* WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
219 D3DXMATRIX out;
220 int i,j;
222 for (i=0; i<4; i++)
224 for (j=0; j<4; j++)
226 out.u.m[i][j] = pm1->u.m[i][0] * pm2->u.m[0][j] + pm1->u.m[i][1] * pm2->u.m[1][j] + pm1->u.m[i][2] * pm2->u.m[2][j] + pm1->u.m[i][3] * pm2->u.m[3][j];
229 *pout = out;
230 return pout;
233 D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
235 D3DXMatrixMultiply(pout, pm1, pm2);
236 D3DXMatrixTranspose(pout, pout);
237 return pout;
240 D3DXMATRIX* WINAPI D3DXMatrixOrthoLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
242 D3DXMatrixIdentity(pout);
243 pout->u.m[0][0] = 2.0f / w;
244 pout->u.m[1][1] = 2.0f / h;
245 pout->u.m[2][2] = 1.0f / (zf - zn);
246 pout->u.m[3][2] = zn / (zn - zf);
247 return pout;
250 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
252 D3DXMatrixIdentity(pout);
253 pout->u.m[0][0] = 2.0f / (r - l);
254 pout->u.m[1][1] = 2.0f / (t - b);
255 pout->u.m[2][2] = 1.0f / (zf -zn);
256 pout->u.m[3][0] = -1.0f -2.0f *l / (r - l);
257 pout->u.m[3][1] = 1.0f + 2.0f * t / (b - t);
258 pout->u.m[3][2] = zn / (zn -zf);
259 return pout;
262 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
264 D3DXMatrixIdentity(pout);
265 pout->u.m[0][0] = 2.0f / (r - l);
266 pout->u.m[1][1] = 2.0f / (t - b);
267 pout->u.m[2][2] = 1.0f / (zn -zf);
268 pout->u.m[3][0] = -1.0f -2.0f *l / (r - l);
269 pout->u.m[3][1] = 1.0f + 2.0f * t / (b - t);
270 pout->u.m[3][2] = zn / (zn -zf);
271 return pout;
274 D3DXMATRIX* WINAPI D3DXMatrixOrthoRH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
276 D3DXMatrixIdentity(pout);
277 pout->u.m[0][0] = 2.0f / w;
278 pout->u.m[1][1] = 2.0f / h;
279 pout->u.m[2][2] = 1.0f / (zn - zf);
280 pout->u.m[3][2] = zn / (zn - zf);
281 return pout;
284 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH(D3DXMATRIX *pout, FLOAT fovy, FLOAT aspect, FLOAT zn, FLOAT zf)
286 D3DXMatrixIdentity(pout);
287 pout->u.m[0][0] = 1.0f / (aspect * tan(fovy/2.0f));
288 pout->u.m[1][1] = 1.0f / tan(fovy/2.0f);
289 pout->u.m[2][2] = zf / (zf - zn);
290 pout->u.m[2][3] = 1.0f;
291 pout->u.m[3][2] = (zf * zn) / (zn - zf);
292 pout->u.m[3][3] = 0.0f;
293 return pout;
296 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH(D3DXMATRIX *pout, FLOAT fovy, FLOAT aspect, FLOAT zn, FLOAT zf)
298 D3DXMatrixIdentity(pout);
299 pout->u.m[0][0] = 1.0f / (aspect * tan(fovy/2.0f));
300 pout->u.m[1][1] = 1.0f / tan(fovy/2.0f);
301 pout->u.m[2][2] = zf / (zn - zf);
302 pout->u.m[2][3] = -1.0f;
303 pout->u.m[3][2] = (zf * zn) / (zn - zf);
304 pout->u.m[3][3] = 0.0f;
305 return pout;
308 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
310 D3DXMatrixIdentity(pout);
311 pout->u.m[0][0] = 2.0f * zn / w;
312 pout->u.m[1][1] = 2.0f * zn / h;
313 pout->u.m[2][2] = zf / (zf - zn);
314 pout->u.m[3][2] = (zn * zf) / (zn - zf);
315 pout->u.m[2][3] = 1.0f;
316 pout->u.m[3][3] = 0.0f;
317 return pout;
320 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
322 D3DXMatrixIdentity(pout);
323 pout->u.m[0][0] = 2.0f * zn / (r - l);
324 pout->u.m[1][1] = -2.0f * zn / (b - t);
325 pout->u.m[2][0] = -1.0f - 2.0f * l / (r - l);
326 pout->u.m[2][1] = 1.0f + 2.0f * t / (b - t);
327 pout->u.m[2][2] = - zf / (zn - zf);
328 pout->u.m[3][2] = (zn * zf) / (zn -zf);
329 pout->u.m[2][3] = 1.0f;
330 pout->u.m[3][3] = 0.0f;
331 return pout;
334 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
336 D3DXMatrixIdentity(pout);
337 pout->u.m[0][0] = 2.0f * zn / (r - l);
338 pout->u.m[1][1] = -2.0f * zn / (b - t);
339 pout->u.m[2][0] = 1.0f + 2.0f * l / (r - l);
340 pout->u.m[2][1] = -1.0f -2.0f * t / (b - t);
341 pout->u.m[2][2] = zf / (zn - zf);
342 pout->u.m[3][2] = (zn * zf) / (zn -zf);
343 pout->u.m[2][3] = -1.0f;
344 pout->u.m[3][3] = 0.0f;
345 return pout;
348 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
350 D3DXMatrixIdentity(pout);
351 pout->u.m[0][0] = 2.0f * zn / w;
352 pout->u.m[1][1] = 2.0f * zn / h;
353 pout->u.m[2][2] = zf / (zn - zf);
354 pout->u.m[3][2] = (zn * zf) / (zn - zf);
355 pout->u.m[2][3] = -1.0f;
356 pout->u.m[3][3] = 0.0f;
357 return pout;
360 D3DXMATRIX* WINAPI D3DXMatrixReflect(D3DXMATRIX *pout, CONST D3DXPLANE *pplane)
362 D3DXPLANE Nplane;
364 D3DXPlaneNormalize(&Nplane, pplane);
365 D3DXMatrixIdentity(pout);
366 pout->u.m[0][0] = 1.0f - 2.0f * Nplane.a * Nplane.a;
367 pout->u.m[0][1] = -2.0f * Nplane.a * Nplane.b;
368 pout->u.m[0][2] = -2.0f * Nplane.a * Nplane.c;
369 pout->u.m[1][0] = -2.0f * Nplane.a * Nplane.b;
370 pout->u.m[1][1] = 1.0f - 2.0f * Nplane.b * Nplane.b;
371 pout->u.m[1][2] = -2.0f * Nplane.b * Nplane.c;
372 pout->u.m[2][0] = -2.0f * Nplane.c * Nplane.a;
373 pout->u.m[2][1] = -2.0f * Nplane.c * Nplane.b;
374 pout->u.m[2][2] = 1.0f - 2.0f * Nplane.c * Nplane.c;
375 pout->u.m[3][0] = -2.0f * Nplane.d * Nplane.a;
376 pout->u.m[3][1] = -2.0f * Nplane.d * Nplane.b;
377 pout->u.m[3][2] = -2.0f * Nplane.d * Nplane.c;
378 return pout;
381 D3DXMATRIX* WINAPI D3DXMatrixRotationAxis(D3DXMATRIX *pout, CONST D3DXVECTOR3 *pv, FLOAT angle)
383 D3DXVECTOR3 v;
385 D3DXVec3Normalize(&v,pv);
386 D3DXMatrixIdentity(pout);
387 pout->u.m[0][0] = (1.0f - cos(angle)) * v.x * v.x + cos(angle);
388 pout->u.m[1][0] = (1.0f - cos(angle)) * v.x * v.y - sin(angle) * v.z;
389 pout->u.m[2][0] = (1.0f - cos(angle)) * v.x * v.z + sin(angle) * v.y;
390 pout->u.m[0][1] = (1.0f - cos(angle)) * v.y * v.x + sin(angle) * v.z;
391 pout->u.m[1][1] = (1.0f - cos(angle)) * v.y * v.y + cos(angle);
392 pout->u.m[2][1] = (1.0f - cos(angle)) * v.y * v.z - sin(angle) * v.x;
393 pout->u.m[0][2] = (1.0f - cos(angle)) * v.z * v.x - sin(angle) * v.y;
394 pout->u.m[1][2] = (1.0f - cos(angle)) * v.z * v.y + sin(angle) * v.x;
395 pout->u.m[2][2] = (1.0f - cos(angle)) * v.z * v.z + cos(angle);
396 return pout;
399 D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion(D3DXMATRIX *pout, CONST D3DXQUATERNION *pq)
401 D3DXMatrixIdentity(pout);
402 pout->u.m[0][0] = 1.0f - 2.0f * (pq->y * pq->y + pq->z * pq->z);
403 pout->u.m[0][1] = 2.0f * (pq->x *pq->y + pq->z * pq->w);
404 pout->u.m[0][2] = 2.0f * (pq->x * pq->z - pq->y * pq->w);
405 pout->u.m[1][0] = 2.0f * (pq->x * pq->y - pq->z * pq->w);
406 pout->u.m[1][1] = 1.0f - 2.0f * (pq->x * pq->x + pq->z * pq->z);
407 pout->u.m[1][2] = 2.0f * (pq->y *pq->z + pq->x *pq->w);
408 pout->u.m[2][0] = 2.0f * (pq->x * pq->z + pq->y * pq->w);
409 pout->u.m[2][1] = 2.0f * (pq->y *pq->z - pq->x *pq->w);
410 pout->u.m[2][2] = 1.0f - 2.0f * (pq->x * pq->x + pq->y * pq->y);
411 return pout;
414 D3DXMATRIX* WINAPI D3DXMatrixRotationX(D3DXMATRIX *pout, FLOAT angle)
416 D3DXMatrixIdentity(pout);
417 pout->u.m[1][1] = cos(angle);
418 pout->u.m[2][2] = cos(angle);
419 pout->u.m[1][2] = sin(angle);
420 pout->u.m[2][1] = -sin(angle);
421 return pout;
424 D3DXMATRIX* WINAPI D3DXMatrixRotationY(D3DXMATRIX *pout, FLOAT angle)
426 D3DXMatrixIdentity(pout);
427 pout->u.m[0][0] = cos(angle);
428 pout->u.m[2][2] = cos(angle);
429 pout->u.m[0][2] = -sin(angle);
430 pout->u.m[2][0] = sin(angle);
431 return pout;
434 D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll(D3DXMATRIX *pout, FLOAT yaw, FLOAT pitch, FLOAT roll)
436 D3DXMATRIX m;
438 D3DXMatrixIdentity(pout);
439 D3DXMatrixRotationZ(&m, roll);
440 D3DXMatrixMultiply(pout, pout, &m);
441 D3DXMatrixRotationX(&m, pitch);
442 D3DXMatrixMultiply(pout, pout, &m);
443 D3DXMatrixRotationY(&m, yaw);
444 D3DXMatrixMultiply(pout, pout, &m);
445 return pout;
447 D3DXMATRIX* WINAPI D3DXMatrixRotationZ(D3DXMATRIX *pout, FLOAT angle)
449 D3DXMatrixIdentity(pout);
450 pout->u.m[0][0] = cos(angle);
451 pout->u.m[1][1] = cos(angle);
452 pout->u.m[0][1] = sin(angle);
453 pout->u.m[1][0] = -sin(angle);
454 return pout;
457 D3DXMATRIX* WINAPI D3DXMatrixScaling(D3DXMATRIX *pout, FLOAT sx, FLOAT sy, FLOAT sz)
459 D3DXMatrixIdentity(pout);
460 pout->u.m[0][0] = sx;
461 pout->u.m[1][1] = sy;
462 pout->u.m[2][2] = sz;
463 return pout;
466 D3DXMATRIX* WINAPI D3DXMatrixShadow(D3DXMATRIX *pout, CONST D3DXVECTOR4 *plight, CONST D3DXPLANE *pplane)
468 D3DXPLANE Nplane;
469 FLOAT dot;
471 D3DXPlaneNormalize(&Nplane, pplane);
472 dot = D3DXPlaneDot(&Nplane, plight);
473 pout->u.m[0][0] = dot - Nplane.a * plight->x;
474 pout->u.m[0][1] = -Nplane.a * plight->y;
475 pout->u.m[0][2] = -Nplane.a * plight->z;
476 pout->u.m[0][3] = -Nplane.a * plight->w;
477 pout->u.m[1][0] = -Nplane.b * plight->x;
478 pout->u.m[1][1] = dot - Nplane.b * plight->y;
479 pout->u.m[1][2] = -Nplane.b * plight->z;
480 pout->u.m[1][3] = -Nplane.b * plight->w;
481 pout->u.m[2][0] = -Nplane.c * plight->x;
482 pout->u.m[2][1] = -Nplane.c * plight->y;
483 pout->u.m[2][2] = dot - Nplane.c * plight->z;
484 pout->u.m[2][3] = -Nplane.c * plight->w;
485 pout->u.m[3][0] = -Nplane.d * plight->x;
486 pout->u.m[3][1] = -Nplane.d * plight->y;
487 pout->u.m[3][2] = -Nplane.d * plight->z;
488 pout->u.m[3][3] = dot - Nplane.d * plight->w;
489 return pout;
492 D3DXMATRIX* WINAPI D3DXMatrixTransformation(D3DXMATRIX *pout, CONST D3DXVECTOR3 *pscalingcenter, CONST D3DXQUATERNION *pscalingrotation, CONST D3DXVECTOR3 *pscaling, CONST D3DXVECTOR3 *protationcenter, CONST D3DXQUATERNION *protation, CONST D3DXVECTOR3 *ptranslation)
494 D3DXMATRIX m1, m2, m3, m4, m5, m6, m7;
495 D3DXQUATERNION prc;
496 D3DXVECTOR3 psc, pt;
498 if ( !pscalingcenter )
500 psc.x = 0.0f;
501 psc.y = 0.0f;
502 psc.z = 0.0f;
504 else
506 psc.x = pscalingcenter->x;
507 psc.y = pscalingcenter->y;
508 psc.z = pscalingcenter->z;
510 if ( !protationcenter )
512 prc.x = 0.0f;
513 prc.y = 0.0f;
514 prc.z = 0.0f;
516 else
518 prc.x = protationcenter->x;
519 prc.y = protationcenter->y;
520 prc.z = protationcenter->z;
522 if ( !ptranslation )
524 pt.x = 0.0f;
525 pt.y = 0.0f;
526 pt.z = 0.0f;
528 else
530 pt.x = ptranslation->x;
531 pt.y = ptranslation->y;
532 pt.z = ptranslation->z;
534 D3DXMatrixTranslation(&m1, -psc.x, -psc.y, -psc.z);
535 if ( !pscalingrotation )
537 D3DXMatrixIdentity(&m2);
538 D3DXMatrixIdentity(&m4);
540 else
542 D3DXMatrixRotationQuaternion(&m4, pscalingrotation);
543 D3DXMatrixInverse(&m2, NULL, &m4);
545 if ( !pscaling )
547 D3DXMatrixIdentity(&m3);
549 else
551 D3DXMatrixScaling(&m3, pscaling->x, pscaling->y, pscaling->z);
553 if ( !protation )
555 D3DXMatrixIdentity(&m6);
557 else
559 D3DXMatrixRotationQuaternion(&m6, protation);
561 D3DXMatrixTranslation(&m5, psc.x - prc.x, psc.y - prc.y, psc.z - prc.z);
562 D3DXMatrixTranslation(&m7, prc.x + pt.x, prc.y + pt.y, prc.z + pt.z);
563 D3DXMatrixMultiply(&m1, &m1, &m2);
564 D3DXMatrixMultiply(&m1, &m1, &m3);
565 D3DXMatrixMultiply(&m1, &m1, &m4);
566 D3DXMatrixMultiply(&m1, &m1, &m5);
567 D3DXMatrixMultiply(&m1, &m1, &m6);
568 D3DXMatrixMultiply(pout, &m1, &m7);
569 return pout;
572 D3DXMATRIX* WINAPI D3DXMatrixTranslation(D3DXMATRIX *pout, FLOAT x, FLOAT y, FLOAT z)
574 D3DXMatrixIdentity(pout);
575 pout->u.m[3][0] = x;
576 pout->u.m[3][1] = y;
577 pout->u.m[3][2] = z;
578 return pout;
581 D3DXMATRIX* WINAPI D3DXMatrixTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm)
583 CONST D3DXMATRIX m = *pm;
584 int i,j;
586 for (i=0; i<4; i++)
588 for (j=0; j<4; j++)
590 pout->u.m[i][j] = m.u.m[j][i];
593 return pout;
596 /*_________________D3DXMatrixStack____________________*/
598 static const unsigned int INITIAL_STACK_SIZE = 32;
600 HRESULT WINAPI D3DXCreateMatrixStack(DWORD flags, LPD3DXMATRIXSTACK* ppstack)
602 ID3DXMatrixStackImpl* object;
604 TRACE("flags %#x, ppstack %p\n", flags, ppstack);
606 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXMatrixStackImpl));
607 if ( object == NULL )
609 *ppstack = NULL;
610 return E_OUTOFMEMORY;
612 object->lpVtbl = &ID3DXMatrixStack_Vtbl;
613 object->ref = 1;
615 object->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_STACK_SIZE * sizeof(D3DXMATRIX));
616 if (!object->stack)
618 HeapFree(GetProcessHeap(), 0, object);
619 *ppstack = NULL;
620 return E_OUTOFMEMORY;
623 object->current = 0;
624 object->stack_size = INITIAL_STACK_SIZE;
625 D3DXMatrixIdentity(&object->stack[0]);
627 TRACE("Created matrix stack %p\n", object);
629 *ppstack = (LPD3DXMATRIXSTACK)object;
630 return D3D_OK;
633 static HRESULT WINAPI ID3DXMatrixStackImpl_QueryInterface(ID3DXMatrixStack *iface, REFIID riid, void **ppobj)
635 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
636 if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_ID3DXMatrixStack))
638 ID3DXMatrixStack_AddRef(iface);
639 *ppobj = This;
640 return S_OK;
642 *ppobj = NULL;
643 ERR("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
644 return E_NOINTERFACE;
647 static ULONG WINAPI ID3DXMatrixStackImpl_AddRef(ID3DXMatrixStack *iface)
649 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
650 ULONG ref = InterlockedIncrement(&This->ref);
651 TRACE("(%p) : AddRef from %d\n", This, ref - 1);
652 return ref;
655 static ULONG WINAPI ID3DXMatrixStackImpl_Release(ID3DXMatrixStack* iface)
657 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
658 ULONG ref = InterlockedDecrement(&This->ref);
659 if (!ref)
661 HeapFree(GetProcessHeap(), 0, This->stack);
662 HeapFree(GetProcessHeap(), 0, This);
664 TRACE("(%p) : ReleaseRef to %d\n", This, ref);
665 return ref;
668 static D3DXMATRIX* WINAPI ID3DXMatrixStackImpl_GetTop(ID3DXMatrixStack *iface)
670 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
672 TRACE("iface %p\n", iface);
674 return &This->stack[This->current];
677 static HRESULT WINAPI ID3DXMatrixStackImpl_LoadIdentity(ID3DXMatrixStack *iface)
679 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
681 TRACE("iface %p\n", iface);
683 D3DXMatrixIdentity(&This->stack[This->current]);
685 return D3D_OK;
688 static HRESULT WINAPI ID3DXMatrixStackImpl_LoadMatrix(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
690 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
692 TRACE("iface %p\n", iface);
694 if (!pm) return D3DERR_INVALIDCALL;
695 This->stack[This->current] = *pm;
697 return D3D_OK;
700 static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrix(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
702 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
704 TRACE("iface %p\n", iface);
706 if (!pm) return D3DERR_INVALIDCALL;
707 D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], pm);
709 return D3D_OK;
712 static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrixLocal(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
714 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
716 TRACE("iface %p\n", iface);
718 if (!pm) return D3DERR_INVALIDCALL;
719 D3DXMatrixMultiply(&This->stack[This->current], pm, &This->stack[This->current]);
721 return D3D_OK;
724 static HRESULT WINAPI ID3DXMatrixStackImpl_Pop(ID3DXMatrixStack *iface)
726 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
728 TRACE("iface %p\n", iface);
730 /* Popping the last element on the stack returns D3D_OK, but does nothing. */
731 if (!This->current) return D3D_OK;
733 if (This->current <= This->stack_size / 4 && This->stack_size >= INITIAL_STACK_SIZE * 2)
735 unsigned int new_size;
736 D3DXMATRIX *new_stack;
738 new_size = This->stack_size / 2;
739 new_stack = HeapReAlloc(GetProcessHeap(), 0, This->stack, new_size * sizeof(D3DXMATRIX));
740 if (new_stack)
742 This->stack_size = new_size;
743 This->stack = new_stack;
747 --This->current;
749 return D3D_OK;
752 static HRESULT WINAPI ID3DXMatrixStackImpl_Push(ID3DXMatrixStack *iface)
754 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
756 TRACE("iface %p\n", iface);
758 if (This->current == This->stack_size - 1)
760 unsigned int new_size;
761 D3DXMATRIX *new_stack;
763 if (This->stack_size > UINT_MAX / 2) return E_OUTOFMEMORY;
765 new_size = This->stack_size * 2;
766 new_stack = HeapReAlloc(GetProcessHeap(), 0, This->stack, new_size * sizeof(D3DXMATRIX));
767 if (!new_stack) return E_OUTOFMEMORY;
769 This->stack_size = new_size;
770 This->stack = new_stack;
773 ++This->current;
774 This->stack[This->current] = This->stack[This->current - 1];
776 return D3D_OK;
779 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxis(ID3DXMatrixStack *iface, CONST D3DXVECTOR3 *pv, FLOAT angle)
781 D3DXMATRIX temp;
782 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
784 TRACE("iface %p\n", iface);
786 if (!pv) return D3DERR_INVALIDCALL;
787 D3DXMatrixRotationAxis(&temp, pv, angle);
788 D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
790 return D3D_OK;
793 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxisLocal(ID3DXMatrixStack *iface, CONST D3DXVECTOR3 *pv, FLOAT angle)
795 D3DXMATRIX temp;
796 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
798 TRACE("iface %p\n", iface);
800 if (!pv) return D3DERR_INVALIDCALL;
801 D3DXMatrixRotationAxis(&temp, pv, angle);
802 D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
804 return D3D_OK;
807 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRoll(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
809 D3DXMATRIX temp;
810 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
812 TRACE("iface %p\n", iface);
814 D3DXMatrixRotationYawPitchRoll(&temp, x, y, z);
815 D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
817 return D3D_OK;
820 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRollLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
822 D3DXMATRIX temp;
823 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
825 TRACE("iface %p\n", iface);
827 D3DXMatrixRotationYawPitchRoll(&temp, x, y, z);
828 D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
830 return D3D_OK;
833 static HRESULT WINAPI ID3DXMatrixStackImpl_Scale(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
835 D3DXMATRIX temp;
836 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
838 TRACE("iface %p\n", iface);
840 D3DXMatrixScaling(&temp, x, y, z);
841 D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
843 return D3D_OK;
846 static HRESULT WINAPI ID3DXMatrixStackImpl_ScaleLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
848 D3DXMATRIX temp;
849 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
851 TRACE("iface %p\n", iface);
853 D3DXMatrixScaling(&temp, x, y, z);
854 D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
856 return D3D_OK;
859 static HRESULT WINAPI ID3DXMatrixStackImpl_Translate(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
861 D3DXMATRIX temp;
862 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
864 TRACE("iface %p\n", iface);
866 D3DXMatrixTranslation(&temp, x, y, z);
867 D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
869 return D3D_OK;
872 static HRESULT WINAPI ID3DXMatrixStackImpl_TranslateLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
874 D3DXMATRIX temp;
875 ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
877 TRACE("iface %p\n", iface);
879 D3DXMatrixTranslation(&temp, x, y, z);
880 D3DXMatrixMultiply(&This->stack[This->current], &temp,&This->stack[This->current]);
882 return D3D_OK;
885 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl =
887 ID3DXMatrixStackImpl_QueryInterface,
888 ID3DXMatrixStackImpl_AddRef,
889 ID3DXMatrixStackImpl_Release,
890 ID3DXMatrixStackImpl_Pop,
891 ID3DXMatrixStackImpl_Push,
892 ID3DXMatrixStackImpl_LoadIdentity,
893 ID3DXMatrixStackImpl_LoadMatrix,
894 ID3DXMatrixStackImpl_MultMatrix,
895 ID3DXMatrixStackImpl_MultMatrixLocal,
896 ID3DXMatrixStackImpl_RotateAxis,
897 ID3DXMatrixStackImpl_RotateAxisLocal,
898 ID3DXMatrixStackImpl_RotateYawPitchRoll,
899 ID3DXMatrixStackImpl_RotateYawPitchRollLocal,
900 ID3DXMatrixStackImpl_Scale,
901 ID3DXMatrixStackImpl_ScaleLocal,
902 ID3DXMatrixStackImpl_Translate,
903 ID3DXMatrixStackImpl_TranslateLocal,
904 ID3DXMatrixStackImpl_GetTop
907 /*_________________D3DXPLANE________________*/
909 D3DXPLANE* WINAPI D3DXPlaneFromPointNormal(D3DXPLANE *pout, CONST D3DXVECTOR3 *pvpoint, CONST D3DXVECTOR3 *pvnormal)
911 pout->a = pvnormal->x;
912 pout->b = pvnormal->y;
913 pout->c = pvnormal->z;
914 pout->d = -D3DXVec3Dot(pvpoint, pvnormal);
915 return pout;
918 D3DXPLANE* WINAPI D3DXPlaneFromPoints(D3DXPLANE *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3)
920 D3DXVECTOR3 edge1, edge2, normal, Nnormal;
922 edge1.x = 0.0f; edge1.y = 0.0f; edge1.z = 0.0f;
923 edge2.x = 0.0f; edge2.y = 0.0f; edge2.z = 0.0f;
924 D3DXVec3Subtract(&edge1, pv2, pv1);
925 D3DXVec3Subtract(&edge2, pv3, pv1);
926 D3DXVec3Cross(&normal, &edge1, &edge2);
927 D3DXVec3Normalize(&Nnormal, &normal);
928 D3DXPlaneFromPointNormal(pout, pv1, &Nnormal);
929 return pout;
932 D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine(D3DXVECTOR3 *pout, CONST D3DXPLANE *pp, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2)
934 D3DXVECTOR3 direction, normal;
935 FLOAT dot, temp;
937 normal.x = pp->a;
938 normal.y = pp->b;
939 normal.z = pp->c;
940 direction.x = pv2->x - pv1->x;
941 direction.y = pv2->y - pv1->y;
942 direction.z = pv2->z - pv1->z;
943 dot = D3DXVec3Dot(&normal, &direction);
944 if ( !dot ) return NULL;
945 temp = ( pp->d + D3DXVec3Dot(&normal, pv1) ) / dot;
946 pout->x = pv1->x - temp * direction.x;
947 pout->y = pv1->y - temp * direction.y;
948 pout->z = pv1->z - temp * direction.z;
949 return pout;
952 D3DXPLANE* WINAPI D3DXPlaneNormalize(D3DXPLANE *pout, CONST D3DXPLANE *pp)
954 D3DXPLANE out;
955 FLOAT norm;
957 norm = sqrt(pp->a * pp->a + pp->b * pp->b + pp->c * pp->c);
958 if ( norm )
960 out.a = pp->a / norm;
961 out.b = pp->b / norm;
962 out.c = pp->c / norm;
963 out.d = pp->d / norm;
965 else
967 out.a = 0.0f;
968 out.b = 0.0f;
969 out.c = 0.0f;
970 out.d = 0.0f;
972 *pout = out;
973 return pout;
976 D3DXPLANE* WINAPI D3DXPlaneTransform(D3DXPLANE *pout, CONST D3DXPLANE *pplane, CONST D3DXMATRIX *pm)
978 CONST D3DXPLANE plane = *pplane;
979 pout->a = pm->u.m[0][0] * plane.a + pm->u.m[1][0] * plane.b + pm->u.m[2][0] * plane.c + pm->u.m[3][0] * plane.d;
980 pout->b = pm->u.m[0][1] * plane.a + pm->u.m[1][1] * plane.b + pm->u.m[2][1] * plane.c + pm->u.m[3][1] * plane.d;
981 pout->c = pm->u.m[0][2] * plane.a + pm->u.m[1][2] * plane.b + pm->u.m[2][2] * plane.c + pm->u.m[3][2] * plane.d;
982 pout->d = pm->u.m[0][3] * plane.a + pm->u.m[1][3] * plane.b + pm->u.m[2][3] * plane.c + pm->u.m[3][3] * plane.d;
983 return pout;
986 /*_________________D3DXQUATERNION________________*/
988 D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, FLOAT f, FLOAT g)
990 D3DXQUATERNION temp1, temp2;
991 D3DXQuaternionSlerp(pout, D3DXQuaternionSlerp(&temp1, pq1, pq2, f + g), D3DXQuaternionSlerp(&temp2, pq1, pq3, f+g), g / (f + g));
992 return pout;
995 D3DXQUATERNION* WINAPI D3DXQuaternionExp(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
997 FLOAT norm;
999 norm = sqrt(pq->x * pq->x + pq->y * pq->y + pq->z * pq->z);
1000 if (norm )
1002 pout->x = sin(norm) * pq->x / norm;
1003 pout->y = sin(norm) * pq->y / norm;
1004 pout->z = sin(norm) * pq->z / norm;
1005 pout->w = cos(norm);
1007 else
1009 pout->x = 0.0f;
1010 pout->y = 0.0f;
1011 pout->z = 0.0f;
1012 pout->w = 1.0f;
1014 return pout;
1017 D3DXQUATERNION* WINAPI D3DXQuaternionInverse(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
1019 FLOAT norm;
1021 norm = D3DXQuaternionLengthSq(pq);
1022 if ( !norm )
1024 pout->x = 0.0f;
1025 pout->y = 0.0f;
1026 pout->z = 0.0f;
1027 pout->w = 0.0f;
1029 else
1031 pout->x = -pq->x / norm;
1032 pout->y = -pq->y / norm;
1033 pout->z = -pq->z / norm;
1034 pout->w = pq->w / norm;
1036 return pout;
1039 D3DXQUATERNION* WINAPI D3DXQuaternionLn(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
1041 FLOAT norm, normvec, theta;
1043 norm = D3DXQuaternionLengthSq(pq);
1044 if ( norm > 1.0001f )
1046 pout->x = pq->x;
1047 pout->y = pq->y;
1048 pout->z = pq->z;
1049 pout->w = 0.0f;
1051 else if( norm > 0.99999f)
1053 normvec = sqrt( pq->x * pq->x + pq->y * pq->y + pq->z * pq->z );
1054 theta = atan2(normvec, pq->w) / normvec;
1055 pout->x = theta * pq->x;
1056 pout->y = theta * pq->y;
1057 pout->z = theta * pq->z;
1058 pout->w = 0.0f;
1060 else
1062 FIXME("The quaternion (%f, %f, %f, %f) has a norm <1. This should not happen. Windows returns a result anyway. This case is not implemented yet.\n", pq->x, pq->y, pq->z, pq->w);
1064 return pout;
1067 D3DXQUATERNION* WINAPI D3DXQuaternionMultiply(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2)
1069 D3DXQUATERNION out;
1070 out.x = pq2->w * pq1->x + pq2->x * pq1->w + pq2->y * pq1->z - pq2->z * pq1->y;
1071 out.y = pq2->w * pq1->y - pq2->x * pq1->z + pq2->y * pq1->w + pq2->z * pq1->x;
1072 out.z = pq2->w * pq1->z + pq2->x * pq1->y - pq2->y * pq1->x + pq2->z * pq1->w;
1073 out.w = pq2->w * pq1->w - pq2->x * pq1->x - pq2->y * pq1->y - pq2->z * pq1->z;
1074 *pout = out;
1075 return pout;
1078 D3DXQUATERNION* WINAPI D3DXQuaternionNormalize(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
1080 D3DXQUATERNION out;
1081 FLOAT norm;
1083 norm = D3DXQuaternionLength(pq);
1084 if ( !norm )
1086 out.x = 0.0f;
1087 out.y = 0.0f;
1088 out.z = 0.0f;
1089 out.w = 0.0f;
1091 else
1093 out.x = pq->x / norm;
1094 out.y = pq->y / norm;
1095 out.z = pq->z / norm;
1096 out.w = pq->w / norm;
1098 *pout=out;
1099 return pout;
1102 D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis(D3DXQUATERNION *pout, CONST D3DXVECTOR3 *pv, FLOAT angle)
1104 D3DXVECTOR3 temp;
1106 D3DXVec3Normalize(&temp, pv);
1107 pout->x = sin( angle / 2.0f ) * temp.x;
1108 pout->y = sin( angle / 2.0f ) * temp.y;
1109 pout->z = sin( angle / 2.0f ) * temp.z;
1110 pout->w = cos( angle / 2.0f );
1111 return pout;
1114 D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix(D3DXQUATERNION *pout, CONST D3DXMATRIX *pm)
1116 int i, maxi;
1117 FLOAT maxdiag, S, trace;
1119 trace = pm->u.m[0][0] + pm->u.m[1][1] + pm->u.m[2][2] + 1.0f;
1120 if ( trace > 1.0f)
1122 pout->x = ( pm->u.m[1][2] - pm->u.m[2][1] ) / ( 2.0f * sqrt(trace) );
1123 pout->y = ( pm->u.m[2][0] - pm->u.m[0][2] ) / ( 2.0f * sqrt(trace) );
1124 pout->z = ( pm->u.m[0][1] - pm->u.m[1][0] ) / ( 2.0f * sqrt(trace) );
1125 pout->w = sqrt(trace) / 2.0f;
1126 return pout;
1128 maxi = 0;
1129 maxdiag = pm->u.m[0][0];
1130 for (i=1; i<3; i++)
1132 if ( pm->u.m[i][i] > maxdiag )
1134 maxi = i;
1135 maxdiag = pm->u.m[i][i];
1138 switch( maxi )
1140 case 0:
1141 S = 2.0f * sqrt(1.0f + pm->u.m[0][0] - pm->u.m[1][1] - pm->u.m[2][2]);
1142 pout->x = 0.25f * S;
1143 pout->y = ( pm->u.m[0][1] + pm->u.m[1][0] ) / S;
1144 pout->z = ( pm->u.m[0][2] + pm->u.m[2][0] ) / S;
1145 pout->w = ( pm->u.m[1][2] - pm->u.m[2][1] ) / S;
1146 break;
1147 case 1:
1148 S = 2.0f * sqrt(1.0f + pm->u.m[1][1] - pm->u.m[0][0] - pm->u.m[2][2]);
1149 pout->x = ( pm->u.m[0][1] + pm->u.m[1][0] ) / S;
1150 pout->y = 0.25f * S;
1151 pout->z = ( pm->u.m[1][2] + pm->u.m[2][1] ) / S;
1152 pout->w = ( pm->u.m[2][0] - pm->u.m[0][2] ) / S;
1153 break;
1154 case 2:
1155 S = 2.0f * sqrt(1.0f + pm->u.m[2][2] - pm->u.m[0][0] - pm->u.m[1][1]);
1156 pout->x = ( pm->u.m[0][2] + pm->u.m[2][0] ) / S;
1157 pout->y = ( pm->u.m[1][2] + pm->u.m[2][1] ) / S;
1158 pout->z = 0.25f * S;
1159 pout->w = ( pm->u.m[0][1] - pm->u.m[1][0] ) / S;
1160 break;
1162 return pout;
1165 D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION *pout, FLOAT yaw, FLOAT pitch, FLOAT roll)
1167 pout->x = sin( yaw / 2.0f) * cos(pitch / 2.0f) * sin(roll / 2.0f) + cos(yaw / 2.0f) * sin(pitch / 2.0f) * cos(roll / 2.0f);
1168 pout->y = sin( yaw / 2.0f) * cos(pitch / 2.0f) * cos(roll / 2.0f) - cos(yaw / 2.0f) * sin(pitch / 2.0f) * sin(roll / 2.0f);
1169 pout->z = cos(yaw / 2.0f) * cos(pitch / 2.0f) * sin(roll / 2.0f) - sin( yaw / 2.0f) * sin(pitch / 2.0f) * cos(roll / 2.0f);
1170 pout->w = cos( yaw / 2.0f) * cos(pitch / 2.0f) * cos(roll / 2.0f) + sin(yaw / 2.0f) * sin(pitch / 2.0f) * sin(roll / 2.0f);
1171 return pout;
1174 D3DXQUATERNION* WINAPI D3DXQuaternionSlerp(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, FLOAT t)
1176 FLOAT dot, epsilon, temp, theta, u;
1178 epsilon = 1.0f;
1179 temp = 1.0f - t;
1180 u = t;
1181 dot = D3DXQuaternionDot(pq1, pq2);
1182 if ( dot < 0.0f )
1184 epsilon = -1.0f;
1185 dot = -dot;
1187 if( 1.0f - dot > 0.001f )
1189 theta = acos(dot);
1190 temp = sin(theta * temp) / sin(theta);
1191 u = sin(theta * u) / sin(theta);
1193 pout->x = temp * pq1->x + epsilon * u * pq2->x;
1194 pout->y = temp * pq1->y + epsilon * u * pq2->y;
1195 pout->z = temp * pq1->z + epsilon * u * pq2->z;
1196 pout->w = temp * pq1->w + epsilon * u * pq2->w;
1197 return pout;
1200 D3DXQUATERNION* WINAPI D3DXQuaternionSquad(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, CONST D3DXQUATERNION *pq4, FLOAT t)
1202 D3DXQUATERNION temp1, temp2;
1204 D3DXQuaternionSlerp(pout, D3DXQuaternionSlerp(&temp1, pq1, pq4, t), D3DXQuaternionSlerp(&temp2, pq2, pq3, t), 2.0f * t * (1.0f - t));
1205 return pout;
1208 void WINAPI D3DXQuaternionToAxisAngle(CONST D3DXQUATERNION *pq, D3DXVECTOR3 *paxis, FLOAT *pangle)
1210 FLOAT norm;
1212 *pangle = 0.0f;
1213 norm = D3DXQuaternionLength(pq);
1214 if ( norm )
1216 paxis->x = pq->x / norm;
1217 paxis->y = pq->y / norm;
1218 paxis->z = pq->z / norm;
1219 if ( fabs( pq->w ) <= 1.0f ) *pangle = 2.0f * acos(pq->w);
1221 else
1223 paxis->x = 1.0f;
1224 paxis->y = 0.0f;
1225 paxis->z = 0.0f;
1229 /*_________________D3DXVec2_____________________*/
1231 D3DXVECTOR2* WINAPI D3DXVec2BaryCentric(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT f, FLOAT g)
1233 pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
1234 pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
1235 return pout;
1238 D3DXVECTOR2* WINAPI D3DXVec2CatmullRom(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv0, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT s)
1240 pout->x = 0.5f * (2.0f * pv1->x + (pv2->x - pv0->x) *s + (2.0f *pv0->x - 5.0f * pv1->x + 4.0f * pv2->x - pv3->x) * s * s + (pv3->x -3.0f * pv2->x + 3.0f * pv1->x - pv0->x) * s * s * s);
1241 pout->y = 0.5f * (2.0f * pv1->y + (pv2->y - pv0->y) *s + (2.0f *pv0->y - 5.0f * pv1->y + 4.0f * pv2->y - pv3->y) * s * s + (pv3->y -3.0f * pv2->y + 3.0f * pv1->y - pv0->y) * s * s * s);
1242 return pout;
1245 D3DXVECTOR2* WINAPI D3DXVec2Hermite(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pt1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pt2, FLOAT s)
1247 FLOAT h1, h2, h3, h4;
1249 h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
1250 h2 = s * s * s - 2.0f * s * s + s;
1251 h3 = -2.0f * s * s * s + 3.0f * s * s;
1252 h4 = s * s * s - s * s;
1254 pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
1255 pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
1256 return pout;
1259 D3DXVECTOR2* WINAPI D3DXVec2Normalize(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv)
1261 D3DXVECTOR2 out;
1262 FLOAT norm;
1264 norm = D3DXVec2Length(pv);
1265 if ( !norm )
1267 out.x = 0.0f;
1268 out.y = 0.0f;
1270 else
1272 out.x = pv->x / norm;
1273 out.y = pv->y / norm;
1275 *pout=out;
1276 return pout;
1279 D3DXVECTOR4* WINAPI D3DXVec2Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
1281 pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[3][0];
1282 pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[3][1];
1283 pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[3][2];
1284 pout->w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[3][3];
1285 return pout;
1288 D3DXVECTOR2* WINAPI D3DXVec2TransformCoord(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
1290 FLOAT norm;
1292 norm = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[3][3];
1293 if ( norm )
1295 CONST D3DXVECTOR2 v = *pv;
1296 pout->x = (pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[3][0]) / norm;
1297 pout->y = (pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[3][1]) / norm;
1299 else
1301 pout->x = 0.0f;
1302 pout->y = 0.0f;
1304 return pout;
1307 D3DXVECTOR2* WINAPI D3DXVec2TransformNormal(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
1309 CONST D3DXVECTOR2 v = *pv;
1310 pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y;
1311 pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y;
1312 return pout;
1315 /*_________________D3DXVec3_____________________*/
1317 D3DXVECTOR3* WINAPI D3DXVec3BaryCentric(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3, FLOAT f, FLOAT g)
1319 pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
1320 pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
1321 pout->z = (1.0f-f-g) * (pv1->z) + f * (pv2->z) + g * (pv3->z);
1322 return pout;
1325 D3DXVECTOR3* WINAPI D3DXVec3CatmullRom( D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv0, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3, FLOAT s)
1327 pout->x = 0.5f * (2.0f * pv1->x + (pv2->x - pv0->x) *s + (2.0f *pv0->x - 5.0f * pv1->x + 4.0f * pv2->x - pv3->x) * s * s + (pv3->x -3.0f * pv2->x + 3.0f * pv1->x - pv0->x) * s * s * s);
1328 pout->y = 0.5f * (2.0f * pv1->y + (pv2->y - pv0->y) *s + (2.0f *pv0->y - 5.0f * pv1->y + 4.0f * pv2->y - pv3->y) * s * s + (pv3->y -3.0f * pv2->y + 3.0f * pv1->y - pv0->y) * s * s * s);
1329 pout->z = 0.5f * (2.0f * pv1->z + (pv2->z - pv0->z) *s + (2.0f *pv0->z - 5.0f * pv1->z + 4.0f * pv2->z - pv3->z) * s * s + (pv3->z -3.0f * pv2->z + 3.0f * pv1->z - pv0->z) * s * s * s);
1330 return pout;
1333 D3DXVECTOR3* WINAPI D3DXVec3Hermite(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pt1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pt2, FLOAT s)
1335 FLOAT h1, h2, h3, h4;
1337 h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
1338 h2 = s * s * s - 2.0f * s * s + s;
1339 h3 = -2.0f * s * s * s + 3.0f * s * s;
1340 h4 = s * s * s - s * s;
1342 pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
1343 pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
1344 pout->z = h1 * (pv1->z) + h2 * (pt1->z) + h3 * (pv2->z) + h4 * (pt2->z);
1345 return pout;
1348 D3DXVECTOR3* WINAPI D3DXVec3Normalize(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv)
1350 D3DXVECTOR3 out;
1351 FLOAT norm;
1353 norm = D3DXVec3Length(pv);
1354 if ( !norm )
1356 out.x = 0.0f;
1357 out.y = 0.0f;
1358 out.z = 0.0f;
1360 else
1362 out.x = pv->x / norm;
1363 out.y = pv->y / norm;
1364 out.z = pv->z / norm;
1366 *pout = out;
1367 return pout;
1370 D3DXVECTOR3* WINAPI D3DXVec3Project(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DVIEWPORT8 *pviewport, CONST D3DXMATRIX *pprojection, CONST D3DXMATRIX *pview, CONST D3DXMATRIX *pworld)
1372 D3DXMATRIX m;
1373 D3DXVECTOR3 out;
1375 D3DXMatrixMultiply(&m, pworld, pview);
1376 D3DXMatrixMultiply(&m, &m, pprojection);
1377 D3DXVec3TransformCoord(&out, pv, &m);
1378 out.x = pviewport->X + ( 1.0f + out.x ) * pviewport->Width / 2.0f;
1379 out.y = pviewport->Y + ( 1.0f - out.y ) * pviewport->Height / 2.0f;
1380 out.z = pviewport->MinZ + out.z * ( pviewport->MaxZ - pviewport->MinZ );
1381 *pout = out;
1382 return pout;
1385 D3DXVECTOR4* WINAPI D3DXVec3Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
1387 pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0];
1388 pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1];
1389 pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2];
1390 pout->w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] * pv->z + pm->u.m[3][3];
1391 return pout;
1394 D3DXVECTOR3* WINAPI D3DXVec3TransformCoord(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
1396 D3DXVECTOR3 out;
1397 FLOAT norm;
1399 norm = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] *pv->z + pm->u.m[3][3];
1401 if ( norm )
1403 CONST D3DXVECTOR3 v = *pv;
1404 out.x = (pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[2][0] * v.z + pm->u.m[3][0]) / norm;
1405 out.y = (pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[2][1] * v.z + pm->u.m[3][1]) / norm;
1406 out.z = (pm->u.m[0][2] * v.x + pm->u.m[1][2] * v.y + pm->u.m[2][2] * v.z + pm->u.m[3][2]) / norm;
1408 else
1410 out.x = 0.0f;
1411 out.y = 0.0f;
1412 out.z = 0.0f;
1414 *pout = out;
1415 return pout;
1418 D3DXVECTOR3* WINAPI D3DXVec3TransformNormal(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
1420 CONST D3DXVECTOR3 v = *pv;
1421 pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[2][0] * v.z;
1422 pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[2][1] * v.z;
1423 pout->z = pm->u.m[0][2] * v.x + pm->u.m[1][2] * v.y + pm->u.m[2][2] * v.z;
1424 return pout;
1428 D3DXVECTOR3* WINAPI D3DXVec3Unproject(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DVIEWPORT8 *pviewport, CONST D3DXMATRIX *pprojection, CONST D3DXMATRIX *pview, CONST D3DXMATRIX *pworld)
1430 D3DXMATRIX m;
1431 D3DXVECTOR3 out;
1433 D3DXMatrixMultiply(&m, pworld, pview);
1434 D3DXMatrixMultiply(&m, &m, pprojection);
1435 D3DXMatrixInverse(&m, NULL, &m);
1436 out.x = 2.0f * ( pv->x - pviewport->X ) / pviewport->Width - 1.0f;
1437 out.y = 1.0f - 2.0f * ( pv->y - pviewport->Y ) / pviewport->Height;
1438 out.z = ( pv->z - pviewport->MinZ) / ( pviewport->MaxZ - pviewport->MinZ );
1439 D3DXVec3TransformCoord(&out, &out, &m);
1440 *pout = out;
1441 return pout;
1444 /*_________________D3DXVec4_____________________*/
1446 D3DXVECTOR4* WINAPI D3DXVec4BaryCentric(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3, FLOAT f, FLOAT g)
1448 pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
1449 pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
1450 pout->z = (1.0f-f-g) * (pv1->z) + f * (pv2->z) + g * (pv3->z);
1451 pout->w = (1.0f-f-g) * (pv1->w) + f * (pv2->w) + g * (pv3->w);
1452 return pout;
1455 D3DXVECTOR4* WINAPI D3DXVec4CatmullRom(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv0, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3, FLOAT s)
1457 pout->x = 0.5f * (2.0f * pv1->x + (pv2->x - pv0->x) *s + (2.0f *pv0->x - 5.0f * pv1->x + 4.0f * pv2->x - pv3->x) * s * s + (pv3->x -3.0f * pv2->x + 3.0f * pv1->x - pv0->x) * s * s * s);
1458 pout->y = 0.5f * (2.0f * pv1->y + (pv2->y - pv0->y) *s + (2.0f *pv0->y - 5.0f * pv1->y + 4.0f * pv2->y - pv3->y) * s * s + (pv3->y -3.0f * pv2->y + 3.0f * pv1->y - pv0->y) * s * s * s);
1459 pout->z = 0.5f * (2.0f * pv1->z + (pv2->z - pv0->z) *s + (2.0f *pv0->z - 5.0f * pv1->z + 4.0f * pv2->z - pv3->z) * s * s + (pv3->z -3.0f * pv2->z + 3.0f * pv1->z - pv0->z) * s * s * s);
1460 pout->w = 0.5f * (2.0f * pv1->w + (pv2->w - pv0->w) *s + (2.0f *pv0->w - 5.0f * pv1->w + 4.0f * pv2->w - pv3->w) * s * s + (pv3->w -3.0f * pv2->w + 3.0f * pv1->w - pv0->w) * s * s * s);
1461 return pout;
1464 D3DXVECTOR4* WINAPI D3DXVec4Cross(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3)
1466 D3DXVECTOR4 out;
1467 out.x = pv1->y * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->y * pv3->w - pv3->y * pv2->w) + pv1->w * (pv2->y * pv3->z - pv2->z *pv3->y);
1468 out.y = -(pv1->x * (pv2->z * pv3->w - pv3->z * pv2->w) - pv1->z * (pv2->x * pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->z - pv3->x * pv2->z));
1469 out.z = pv1->x * (pv2->y * pv3->w - pv3->y * pv2->w) - pv1->y * (pv2->x *pv3->w - pv3->x * pv2->w) + pv1->w * (pv2->x * pv3->y - pv3->x * pv2->y);
1470 out.w = -(pv1->x * (pv2->y * pv3->z - pv3->y * pv2->z) - pv1->y * (pv2->x * pv3->z - pv3->x *pv2->z) + pv1->z * (pv2->x * pv3->y - pv3->x * pv2->y));
1471 *pout = out;
1472 return pout;
1475 D3DXVECTOR4* WINAPI D3DXVec4Hermite(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pt1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pt2, FLOAT s)
1477 FLOAT h1, h2, h3, h4;
1479 h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
1480 h2 = s * s * s - 2.0f * s * s + s;
1481 h3 = -2.0f * s * s * s + 3.0f * s * s;
1482 h4 = s * s * s - s * s;
1484 pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
1485 pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
1486 pout->z = h1 * (pv1->z) + h2 * (pt1->z) + h3 * (pv2->z) + h4 * (pt2->z);
1487 pout->w = h1 * (pv1->w) + h2 * (pt1->w) + h3 * (pv2->w) + h4 * (pt2->w);
1488 return pout;
1491 D3DXVECTOR4* WINAPI D3DXVec4Normalize(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv)
1493 D3DXVECTOR4 out;
1494 FLOAT norm;
1496 norm = D3DXVec4Length(pv);
1497 if ( !norm )
1499 out.x = 0.0f;
1500 out.y = 0.0f;
1501 out.z = 0.0f;
1502 out.w = 0.0f;
1504 else
1506 out.x = pv->x / norm;
1507 out.y = pv->y / norm;
1508 out.z = pv->z / norm;
1509 out.w = pv->w / norm;
1511 *pout = out;
1512 return pout;
1515 D3DXVECTOR4* WINAPI D3DXVec4Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv, CONST D3DXMATRIX *pm)
1517 D3DXVECTOR4 out;
1518 out.x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y + pm->u.m[2][0] * pv->z + pm->u.m[3][0] * pv->w;
1519 out.y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y + pm->u.m[2][1] * pv->z + pm->u.m[3][1] * pv->w;
1520 out.z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y + pm->u.m[2][2] * pv->z + pm->u.m[3][2] * pv->w;
1521 out.w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[2][3] * pv->z + pm->u.m[3][3] * pv->w;
1522 *pout = out;
1523 return pout;