shell32: Indentation fix.
[wine] / dlls / d3dx9_36 / math.c
1 /*
2  * Mathematical operations specific to D3DX9.
3  *
4  * Copyright (C) 2008 David Adam
5  * Copyright (C) 2008 Luis Busquets
6  * Copyright (C) 2008 Jérôme Gardou
7  * Copyright (C) 2008 Philip Nilsson
8  * Copyright (C) 2008 Henri Verbeet
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24
25 #define NONAMELESSUNION
26
27 #include "config.h"
28 #include "wine/port.h"
29
30 #include "windef.h"
31 #include "wingdi.h"
32 #include "d3dx9_36_private.h"
33
34 #include "wine/debug.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
37
38 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl;
39
40 struct ID3DXMatrixStackImpl
41 {
42   ID3DXMatrixStack ID3DXMatrixStack_iface;
43   LONG ref;
44
45   unsigned int current;
46   unsigned int stack_size;
47   D3DXMATRIX *stack;
48 };
49
50
51 /*_________________D3DXColor____________________*/
52
53 D3DXCOLOR* WINAPI D3DXColorAdjustContrast(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s)
54 {
55     TRACE("(%p, %p, %f)\n", pout, pc, s);
56
57     pout->r = 0.5f + s * (pc->r - 0.5f);
58     pout->g = 0.5f + s * (pc->g - 0.5f);
59     pout->b = 0.5f + s * (pc->b - 0.5f);
60     pout->a = pc->a;
61     return pout;
62 }
63
64 D3DXCOLOR* WINAPI D3DXColorAdjustSaturation(D3DXCOLOR *pout, CONST D3DXCOLOR *pc, FLOAT s)
65 {
66     FLOAT grey;
67
68     TRACE("(%p, %p, %f)\n", pout, pc, s);
69
70     grey = pc->r * 0.2125f + pc->g * 0.7154f + pc->b * 0.0721f;
71     pout->r = grey + s * (pc->r - grey);
72     pout->g = grey + s * (pc->g - grey);
73     pout->b = grey + s * (pc->b - grey);
74     pout->a = pc->a;
75     return pout;
76 }
77
78 /*_________________Misc__________________________*/
79
80 FLOAT WINAPI D3DXFresnelTerm(FLOAT costheta, FLOAT refractionindex)
81 {
82     FLOAT a, d, g, result;
83
84     TRACE("costheta %f, refractionindex %f\n", costheta, refractionindex);
85
86     g = sqrtf(refractionindex * refractionindex + costheta * costheta - 1.0f);
87     a = g + costheta;
88     d = g - costheta;
89     result = (costheta * a - 1.0f) * (costheta * a - 1.0f) / ((costheta * d + 1.0f) * (costheta * d + 1.0f)) + 1.0f;
90     result *= 0.5f * d * d / (a * a);
91
92     return result;
93 }
94
95 /*_________________D3DXMatrix____________________*/
96
97 D3DXMATRIX * WINAPI D3DXMatrixAffineTransformation(D3DXMATRIX *out, FLOAT scaling, const D3DXVECTOR3 *rotationcenter,
98         const D3DXQUATERNION *rotation, const D3DXVECTOR3 *translation)
99 {
100     TRACE("out %p, scaling %f, rotationcenter %p, rotation %p, translation %p\n",
101             out, scaling, rotationcenter, rotation, translation);
102
103     D3DXMatrixIdentity(out);
104
105     if (rotationcenter)
106     {
107         out->u.m[3][0] = -rotationcenter->x;
108         out->u.m[3][1] = -rotationcenter->y;
109         out->u.m[3][2] = -rotationcenter->z;
110     }
111
112     if (rotation)
113     {
114         FLOAT temp00, temp01, temp02, temp10, temp11, temp12, temp20, temp21, temp22;
115
116         temp00 = 1.0f - 2.0f * (rotation->y * rotation->y + rotation->z * rotation->z);
117         temp01 = 2.0f * (rotation->x * rotation->y + rotation->z * rotation->w);
118         temp02 = 2.0f * (rotation->x * rotation->z - rotation->y * rotation->w);
119         temp10 = 2.0f * (rotation->x * rotation->y - rotation->z * rotation->w);
120         temp11 = 1.0f - 2.0f * (rotation->x * rotation->x + rotation->z * rotation->z);
121         temp12 = 2.0f * (rotation->y * rotation->z + rotation->x * rotation->w);
122         temp20 = 2.0f * (rotation->x * rotation->z + rotation->y * rotation->w);
123         temp21 = 2.0f * (rotation->y * rotation->z - rotation->x * rotation->w);
124         temp22 = 1.0f - 2.0f * (rotation->x * rotation->x + rotation->y * rotation->y);
125
126         out->u.m[0][0] = scaling * temp00;
127         out->u.m[0][1] = scaling * temp01;
128         out->u.m[0][2] = scaling * temp02;
129         out->u.m[1][0] = scaling * temp10;
130         out->u.m[1][1] = scaling * temp11;
131         out->u.m[1][2] = scaling * temp12;
132         out->u.m[2][0] = scaling * temp20;
133         out->u.m[2][1] = scaling * temp21;
134         out->u.m[2][2] = scaling * temp22;
135
136         if (rotationcenter)
137         {
138             FLOAT x, y, z;
139
140             x = out->u.m[3][0];
141             y = out->u.m[3][1];
142             z = out->u.m[3][2];
143
144             out->u.m[3][0] = x * temp00 + y * temp10 + z * temp20;
145             out->u.m[3][1] = x * temp01 + y * temp11 + z * temp21;
146             out->u.m[3][2] = x * temp02 + y * temp12 + z * temp22;
147         }
148     }
149     else
150     {
151         out->u.m[0][0] = scaling;
152         out->u.m[1][1] = scaling;
153         out->u.m[2][2] = scaling;
154     }
155
156     if (rotationcenter)
157     {
158         out->u.m[3][0] += rotationcenter->x;
159         out->u.m[3][1] += rotationcenter->y;
160         out->u.m[3][2] += rotationcenter->z;
161     }
162
163     if (translation)
164     {
165         out->u.m[3][0] += translation->x;
166         out->u.m[3][1] += translation->y;
167         out->u.m[3][2] += translation->z;
168     }
169
170     return out;
171 }
172
173 D3DXMATRIX * WINAPI D3DXMatrixAffineTransformation2D(D3DXMATRIX *out, FLOAT scaling,
174         const D3DXVECTOR2 *rotationcenter, FLOAT rotation, const D3DXVECTOR2 *translation)
175 {
176     FLOAT tmp1, tmp2, s;
177
178     TRACE("out %p, scaling %f, rotationcenter %p, rotation %f, translation %p\n",
179             out, scaling, rotationcenter, rotation, translation);
180
181     s = sinf(rotation / 2.0f);
182     tmp1 = 1.0f - 2.0f * s * s;
183     tmp2 = 2.0 * s * cosf(rotation / 2.0f);
184
185     D3DXMatrixIdentity(out);
186     out->u.m[0][0] = scaling * tmp1;
187     out->u.m[0][1] = scaling * tmp2;
188     out->u.m[1][0] = -scaling * tmp2;
189     out->u.m[1][1] = scaling * tmp1;
190
191     if (rotationcenter)
192     {
193         FLOAT x, y;
194
195         x = rotationcenter->x;
196         y = rotationcenter->y;
197
198         out->u.m[3][0] = y * tmp2 - x * tmp1 + x;
199         out->u.m[3][1] = -x * tmp2 - y * tmp1 + y;
200     }
201
202     if (translation)
203     {
204         out->u.m[3][0] += translation->x;
205         out->u.m[3][1] += translation->y;
206     }
207
208     return out;
209 }
210
211 HRESULT WINAPI D3DXMatrixDecompose(D3DXVECTOR3 *poutscale, D3DXQUATERNION *poutrotation, D3DXVECTOR3 *pouttranslation, CONST D3DXMATRIX *pm)
212 {
213     D3DXMATRIX normalized;
214     D3DXVECTOR3 vec;
215
216     TRACE("(%p, %p, %p, %p)\n", poutscale, poutrotation, pouttranslation, pm);
217
218     /*Compute the scaling part.*/
219     vec.x=pm->u.m[0][0];
220     vec.y=pm->u.m[0][1];
221     vec.z=pm->u.m[0][2];
222     poutscale->x=D3DXVec3Length(&vec);
223
224     vec.x=pm->u.m[1][0];
225     vec.y=pm->u.m[1][1];
226     vec.z=pm->u.m[1][2];
227     poutscale->y=D3DXVec3Length(&vec);
228
229     vec.x=pm->u.m[2][0];
230     vec.y=pm->u.m[2][1];
231     vec.z=pm->u.m[2][2];
232     poutscale->z=D3DXVec3Length(&vec);
233
234     /*Compute the translation part.*/
235     pouttranslation->x=pm->u.m[3][0];
236     pouttranslation->y=pm->u.m[3][1];
237     pouttranslation->z=pm->u.m[3][2];
238
239     /*Let's calculate the rotation now*/
240     if ( (poutscale->x == 0.0f) || (poutscale->y == 0.0f) || (poutscale->z == 0.0f) ) return D3DERR_INVALIDCALL;
241
242     normalized.u.m[0][0]=pm->u.m[0][0]/poutscale->x;
243     normalized.u.m[0][1]=pm->u.m[0][1]/poutscale->x;
244     normalized.u.m[0][2]=pm->u.m[0][2]/poutscale->x;
245     normalized.u.m[1][0]=pm->u.m[1][0]/poutscale->y;
246     normalized.u.m[1][1]=pm->u.m[1][1]/poutscale->y;
247     normalized.u.m[1][2]=pm->u.m[1][2]/poutscale->y;
248     normalized.u.m[2][0]=pm->u.m[2][0]/poutscale->z;
249     normalized.u.m[2][1]=pm->u.m[2][1]/poutscale->z;
250     normalized.u.m[2][2]=pm->u.m[2][2]/poutscale->z;
251
252     D3DXQuaternionRotationMatrix(poutrotation,&normalized);
253     return S_OK;
254 }
255
256 FLOAT WINAPI D3DXMatrixDeterminant(CONST D3DXMATRIX *pm)
257 {
258     D3DXVECTOR4 minor, v1, v2, v3;
259     FLOAT det;
260
261     TRACE("(%p)\n", pm);
262
263     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];
264     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];
265     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];
266     D3DXVec4Cross(&minor, &v1, &v2, &v3);
267     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);
268     return det;
269 }
270
271 D3DXMATRIX* WINAPI D3DXMatrixInverse(D3DXMATRIX *pout, FLOAT *pdeterminant, CONST D3DXMATRIX *pm)
272 {
273     int a, i, j;
274     D3DXMATRIX out;
275     D3DXVECTOR4 v, vec[3];
276     FLOAT det;
277
278     TRACE("(%p, %p, %p)\n", pout, pdeterminant, pm);
279
280     det = D3DXMatrixDeterminant(pm);
281     if ( !det ) return NULL;
282     if ( pdeterminant ) *pdeterminant = det;
283     for (i=0; i<4; i++)
284     {
285         for (j=0; j<4; j++)
286         {
287             if (j != i )
288             {
289                 a = j;
290                 if ( j > i ) a = a-1;
291                 vec[a].x = pm->u.m[j][0];
292                 vec[a].y = pm->u.m[j][1];
293                 vec[a].z = pm->u.m[j][2];
294                 vec[a].w = pm->u.m[j][3];
295             }
296         }
297     D3DXVec4Cross(&v, &vec[0], &vec[1], &vec[2]);
298     out.u.m[0][i] = pow(-1.0f, i) * v.x / det;
299     out.u.m[1][i] = pow(-1.0f, i) * v.y / det;
300     out.u.m[2][i] = pow(-1.0f, i) * v.z / det;
301     out.u.m[3][i] = pow(-1.0f, i) * v.w / det;
302    }
303
304    *pout = out;
305    return pout;
306 }
307
308 D3DXMATRIX* WINAPI D3DXMatrixLookAtLH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, CONST D3DXVECTOR3 *pat, CONST D3DXVECTOR3 *pup)
309 {
310     D3DXVECTOR3 right, rightn, up, upn, vec, vec2;
311
312     TRACE("(%p, %p, %p, %p)\n", pout, peye, pat, pup);
313
314     D3DXVec3Subtract(&vec2, pat, peye);
315     D3DXVec3Normalize(&vec, &vec2);
316     D3DXVec3Cross(&right, pup, &vec);
317     D3DXVec3Cross(&up, &vec, &right);
318     D3DXVec3Normalize(&rightn, &right);
319     D3DXVec3Normalize(&upn, &up);
320     pout->u.m[0][0] = rightn.x;
321     pout->u.m[1][0] = rightn.y;
322     pout->u.m[2][0] = rightn.z;
323     pout->u.m[3][0] = -D3DXVec3Dot(&rightn,peye);
324     pout->u.m[0][1] = upn.x;
325     pout->u.m[1][1] = upn.y;
326     pout->u.m[2][1] = upn.z;
327     pout->u.m[3][1] = -D3DXVec3Dot(&upn, peye);
328     pout->u.m[0][2] = vec.x;
329     pout->u.m[1][2] = vec.y;
330     pout->u.m[2][2] = vec.z;
331     pout->u.m[3][2] = -D3DXVec3Dot(&vec, peye);
332     pout->u.m[0][3] = 0.0f;
333     pout->u.m[1][3] = 0.0f;
334     pout->u.m[2][3] = 0.0f;
335     pout->u.m[3][3] = 1.0f;
336     return pout;
337 }
338
339 D3DXMATRIX* WINAPI D3DXMatrixLookAtRH(D3DXMATRIX *pout, CONST D3DXVECTOR3 *peye, CONST D3DXVECTOR3 *pat, CONST D3DXVECTOR3 *pup)
340 {
341     D3DXVECTOR3 right, rightn, up, upn, vec, vec2;
342
343     TRACE("(%p, %p, %p, %p)\n", pout, peye, pat, pup);
344
345     D3DXVec3Subtract(&vec2, pat, peye);
346     D3DXVec3Normalize(&vec, &vec2);
347     D3DXVec3Cross(&right, pup, &vec);
348     D3DXVec3Cross(&up, &vec, &right);
349     D3DXVec3Normalize(&rightn, &right);
350     D3DXVec3Normalize(&upn, &up);
351     pout->u.m[0][0] = -rightn.x;
352     pout->u.m[1][0] = -rightn.y;
353     pout->u.m[2][0] = -rightn.z;
354     pout->u.m[3][0] = D3DXVec3Dot(&rightn,peye);
355     pout->u.m[0][1] = upn.x;
356     pout->u.m[1][1] = upn.y;
357     pout->u.m[2][1] = upn.z;
358     pout->u.m[3][1] = -D3DXVec3Dot(&upn, peye);
359     pout->u.m[0][2] = -vec.x;
360     pout->u.m[1][2] = -vec.y;
361     pout->u.m[2][2] = -vec.z;
362     pout->u.m[3][2] = D3DXVec3Dot(&vec, peye);
363     pout->u.m[0][3] = 0.0f;
364     pout->u.m[1][3] = 0.0f;
365     pout->u.m[2][3] = 0.0f;
366     pout->u.m[3][3] = 1.0f;
367     return pout;
368 }
369
370 D3DXMATRIX* WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
371 {
372     D3DXMATRIX out;
373     int i,j;
374
375     TRACE("(%p, %p, %p)\n", pout, pm1, pm2);
376
377     for (i=0; i<4; i++)
378     {
379         for (j=0; j<4; j++)
380         {
381             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];
382         }
383     }
384
385     *pout = out;
386     return pout;
387 }
388
389 D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2)
390 {
391     TRACE("%p, %p, %p)\n", pout, pm1, pm2);
392
393     D3DXMatrixMultiply(pout, pm1, pm2);
394     D3DXMatrixTranspose(pout, pout);
395     return pout;
396 }
397
398 D3DXMATRIX* WINAPI D3DXMatrixOrthoLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
399 {
400     TRACE("(%p, %f, %f, %f, %f)\n", pout, w, h, zn, zf);
401
402     D3DXMatrixIdentity(pout);
403     pout->u.m[0][0] = 2.0f / w;
404     pout->u.m[1][1] = 2.0f / h;
405     pout->u.m[2][2] = 1.0f / (zf - zn);
406     pout->u.m[3][2] = zn / (zn - zf);
407     return pout;
408 }
409
410 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
411 {
412     TRACE("(%p, %f, %f, %f, %f, %f, %f)\n", pout, l, r, b, t, zn, zf);
413
414     D3DXMatrixIdentity(pout);
415     pout->u.m[0][0] = 2.0f / (r - l);
416     pout->u.m[1][1] = 2.0f / (t - b);
417     pout->u.m[2][2] = 1.0f / (zf -zn);
418     pout->u.m[3][0] = -1.0f -2.0f *l / (r - l);
419     pout->u.m[3][1] = 1.0f + 2.0f * t / (b - t);
420     pout->u.m[3][2] = zn / (zn -zf);
421     return pout;
422 }
423
424 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
425 {
426     TRACE("(%p, %f, %f, %f, %f, %f, %f)\n", pout, l, r, b, t, zn, zf);
427
428     D3DXMatrixIdentity(pout);
429     pout->u.m[0][0] = 2.0f / (r - l);
430     pout->u.m[1][1] = 2.0f / (t - b);
431     pout->u.m[2][2] = 1.0f / (zn -zf);
432     pout->u.m[3][0] = -1.0f -2.0f *l / (r - l);
433     pout->u.m[3][1] = 1.0f + 2.0f * t / (b - t);
434     pout->u.m[3][2] = zn / (zn -zf);
435     return pout;
436 }
437
438 D3DXMATRIX* WINAPI D3DXMatrixOrthoRH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
439 {
440     TRACE("(%p, %f, %f, %f, %f)\n", pout, w, h, zn, zf);
441
442     D3DXMatrixIdentity(pout);
443     pout->u.m[0][0] = 2.0f / w;
444     pout->u.m[1][1] = 2.0f / h;
445     pout->u.m[2][2] = 1.0f / (zn - zf);
446     pout->u.m[3][2] = zn / (zn - zf);
447     return pout;
448 }
449
450 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH(D3DXMATRIX *pout, FLOAT fovy, FLOAT aspect, FLOAT zn, FLOAT zf)
451 {
452     TRACE("(%p, %f, %f, %f, %f)\n", pout, fovy, aspect, zn, zf);
453
454     D3DXMatrixIdentity(pout);
455     pout->u.m[0][0] = 1.0f / (aspect * tan(fovy/2.0f));
456     pout->u.m[1][1] = 1.0f / tan(fovy/2.0f);
457     pout->u.m[2][2] = zf / (zf - zn);
458     pout->u.m[2][3] = 1.0f;
459     pout->u.m[3][2] = (zf * zn) / (zn - zf);
460     pout->u.m[3][3] = 0.0f;
461     return pout;
462 }
463
464 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH(D3DXMATRIX *pout, FLOAT fovy, FLOAT aspect, FLOAT zn, FLOAT zf)
465 {
466     TRACE("(%p, %f, %f, %f, %f)\n", pout, fovy, aspect, zn, zf);
467
468     D3DXMatrixIdentity(pout);
469     pout->u.m[0][0] = 1.0f / (aspect * tan(fovy/2.0f));
470     pout->u.m[1][1] = 1.0f / tan(fovy/2.0f);
471     pout->u.m[2][2] = zf / (zn - zf);
472     pout->u.m[2][3] = -1.0f;
473     pout->u.m[3][2] = (zf * zn) / (zn - zf);
474     pout->u.m[3][3] = 0.0f;
475     return pout;
476 }
477
478 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
479 {
480     TRACE("(%p, %f, %f, %f, %f)\n", pout, w, h, zn, zf);
481
482     D3DXMatrixIdentity(pout);
483     pout->u.m[0][0] = 2.0f * zn / w;
484     pout->u.m[1][1] = 2.0f * zn / h;
485     pout->u.m[2][2] = zf / (zf - zn);
486     pout->u.m[3][2] = (zn * zf) / (zn - zf);
487     pout->u.m[2][3] = 1.0f;
488     pout->u.m[3][3] = 0.0f;
489     return pout;
490 }
491
492 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
493 {
494     TRACE("(%p, %f, %f, %f, %f, %f, %f)\n", pout, l, r, b, t, zn, zf);
495
496     D3DXMatrixIdentity(pout);
497     pout->u.m[0][0] = 2.0f * zn / (r - l);
498     pout->u.m[1][1] = -2.0f * zn / (b - t);
499     pout->u.m[2][0] = -1.0f - 2.0f * l / (r - l);
500     pout->u.m[2][1] = 1.0f + 2.0f * t / (b - t);
501     pout->u.m[2][2] = - zf / (zn - zf);
502     pout->u.m[3][2] = (zn * zf) / (zn -zf);
503     pout->u.m[2][3] = 1.0f;
504     pout->u.m[3][3] = 0.0f;
505     return pout;
506 }
507
508 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH(D3DXMATRIX *pout, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf)
509 {
510     TRACE("(%p, %f, %f, %f, %f, %f, %f)\n", pout, l, r, b, t, zn, zf);
511
512     D3DXMatrixIdentity(pout);
513     pout->u.m[0][0] = 2.0f * zn / (r - l);
514     pout->u.m[1][1] = -2.0f * zn / (b - t);
515     pout->u.m[2][0] = 1.0f + 2.0f * l / (r - l);
516     pout->u.m[2][1] = -1.0f -2.0f * t / (b - t);
517     pout->u.m[2][2] = zf / (zn - zf);
518     pout->u.m[3][2] = (zn * zf) / (zn -zf);
519     pout->u.m[2][3] = -1.0f;
520     pout->u.m[3][3] = 0.0f;
521     return pout;
522 }
523
524 D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH(D3DXMATRIX *pout, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf)
525 {
526     TRACE("(%p, %f, %f, %f, %f)\n", pout, w, h, zn, zf);
527
528     D3DXMatrixIdentity(pout);
529     pout->u.m[0][0] = 2.0f * zn / w;
530     pout->u.m[1][1] = 2.0f * zn / h;
531     pout->u.m[2][2] = zf / (zn - zf);
532     pout->u.m[3][2] = (zn * zf) / (zn - zf);
533     pout->u.m[2][3] = -1.0f;
534     pout->u.m[3][3] = 0.0f;
535     return pout;
536 }
537
538 D3DXMATRIX* WINAPI D3DXMatrixReflect(D3DXMATRIX *pout, CONST D3DXPLANE *pplane)
539 {
540     D3DXPLANE Nplane;
541
542     TRACE("(%p, %p)\n", pout, pplane);
543
544     D3DXPlaneNormalize(&Nplane, pplane);
545     D3DXMatrixIdentity(pout);
546     pout->u.m[0][0] = 1.0f - 2.0f * Nplane.a * Nplane.a;
547     pout->u.m[0][1] = -2.0f * Nplane.a * Nplane.b;
548     pout->u.m[0][2] = -2.0f * Nplane.a * Nplane.c;
549     pout->u.m[1][0] = -2.0f * Nplane.a * Nplane.b;
550     pout->u.m[1][1] = 1.0f - 2.0f * Nplane.b * Nplane.b;
551     pout->u.m[1][2] = -2.0f * Nplane.b * Nplane.c;
552     pout->u.m[2][0] = -2.0f * Nplane.c * Nplane.a;
553     pout->u.m[2][1] = -2.0f * Nplane.c * Nplane.b;
554     pout->u.m[2][2] = 1.0f - 2.0f * Nplane.c * Nplane.c;
555     pout->u.m[3][0] = -2.0f * Nplane.d * Nplane.a;
556     pout->u.m[3][1] = -2.0f * Nplane.d * Nplane.b;
557     pout->u.m[3][2] = -2.0f * Nplane.d * Nplane.c;
558     return pout;
559 }
560
561 D3DXMATRIX * WINAPI D3DXMatrixRotationAxis(D3DXMATRIX *out, const D3DXVECTOR3 *v, FLOAT angle)
562 {
563     D3DXVECTOR3 nv;
564     FLOAT sangle, cangle, cdiff;
565
566     TRACE("out %p, v %p, angle %f\n", out, v, angle);
567
568     D3DXVec3Normalize(&nv, v);
569     sangle = sinf(angle);
570     cangle = cosf(angle);
571     cdiff = 1.0f - cangle;
572
573     out->u.m[0][0] = cdiff * nv.x * nv.x + cangle;
574     out->u.m[1][0] = cdiff * nv.x * nv.y - sangle * nv.z;
575     out->u.m[2][0] = cdiff * nv.x * nv.z + sangle * nv.y;
576     out->u.m[3][0] = 0.0f;
577     out->u.m[0][1] = cdiff * nv.y * nv.x + sangle * nv.z;
578     out->u.m[1][1] = cdiff * nv.y * nv.y + cangle;
579     out->u.m[2][1] = cdiff * nv.y * nv.z - sangle * nv.x;
580     out->u.m[3][1] = 0.0f;
581     out->u.m[0][2] = cdiff * nv.z * nv.x - sangle * nv.y;
582     out->u.m[1][2] = cdiff * nv.z * nv.y + sangle * nv.x;
583     out->u.m[2][2] = cdiff * nv.z * nv.z + cangle;
584     out->u.m[3][2] = 0.0f;
585     out->u.m[0][3] = 0.0f;
586     out->u.m[1][3] = 0.0f;
587     out->u.m[2][3] = 0.0f;
588     out->u.m[3][3] = 1.0f;
589
590     return out;
591 }
592
593 D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion(D3DXMATRIX *pout, CONST D3DXQUATERNION *pq)
594 {
595     TRACE("(%p, %p)\n", pout, pq);
596
597     D3DXMatrixIdentity(pout);
598     pout->u.m[0][0] = 1.0f - 2.0f * (pq->y * pq->y + pq->z * pq->z);
599     pout->u.m[0][1] = 2.0f * (pq->x *pq->y + pq->z * pq->w);
600     pout->u.m[0][2] = 2.0f * (pq->x * pq->z - pq->y * pq->w);
601     pout->u.m[1][0] = 2.0f * (pq->x * pq->y - pq->z * pq->w);
602     pout->u.m[1][1] = 1.0f - 2.0f * (pq->x * pq->x + pq->z * pq->z);
603     pout->u.m[1][2] = 2.0f * (pq->y *pq->z + pq->x *pq->w);
604     pout->u.m[2][0] = 2.0f * (pq->x * pq->z + pq->y * pq->w);
605     pout->u.m[2][1] = 2.0f * (pq->y *pq->z - pq->x *pq->w);
606     pout->u.m[2][2] = 1.0f - 2.0f * (pq->x * pq->x + pq->y * pq->y);
607     return pout;
608 }
609
610 D3DXMATRIX* WINAPI D3DXMatrixRotationX(D3DXMATRIX *pout, FLOAT angle)
611 {
612     TRACE("(%p, %f)\n", pout, angle);
613
614     D3DXMatrixIdentity(pout);
615     pout->u.m[1][1] = cos(angle);
616     pout->u.m[2][2] = cos(angle);
617     pout->u.m[1][2] = sin(angle);
618     pout->u.m[2][1] = -sin(angle);
619     return pout;
620 }
621
622 D3DXMATRIX* WINAPI D3DXMatrixRotationY(D3DXMATRIX *pout, FLOAT angle)
623 {
624     TRACE("(%p, %f)\n", pout, angle);
625
626     D3DXMatrixIdentity(pout);
627     pout->u.m[0][0] = cos(angle);
628     pout->u.m[2][2] = cos(angle);
629     pout->u.m[0][2] = -sin(angle);
630     pout->u.m[2][0] = sin(angle);
631     return pout;
632 }
633
634 D3DXMATRIX * WINAPI D3DXMatrixRotationYawPitchRoll(D3DXMATRIX *out, FLOAT yaw, FLOAT pitch, FLOAT roll)
635 {
636     FLOAT sroll, croll, spitch, cpitch, syaw, cyaw;
637
638     TRACE("out %p, yaw %f, pitch %f, roll %f\n", out, yaw, pitch, roll);
639
640     sroll = sinf(roll);
641     croll = cosf(roll);
642     spitch = sinf(pitch);
643     cpitch = cosf(pitch);
644     syaw = sinf(yaw);
645     cyaw = cosf(yaw);
646
647     out->u.m[0][0] = sroll * spitch * syaw + croll * cyaw;
648     out->u.m[0][1] = sroll * cpitch;
649     out->u.m[0][2] = sroll * spitch * cyaw - croll * syaw;
650     out->u.m[0][3] = 0.0f;
651     out->u.m[1][0] = croll * spitch * syaw - sroll * cyaw;
652     out->u.m[1][1] = croll * cpitch;
653     out->u.m[1][2] = croll * spitch * cyaw + sroll * syaw;
654     out->u.m[1][3] = 0.0f;
655     out->u.m[2][0] = cpitch * syaw;
656     out->u.m[2][1] = -spitch;
657     out->u.m[2][2] = cpitch * cyaw;
658     out->u.m[2][3] = 0.0f;
659     out->u.m[3][0] = 0.0f;
660     out->u.m[3][1] = 0.0f;
661     out->u.m[3][2] = 0.0f;
662     out->u.m[3][3] = 1.0f;
663
664     return out;
665 }
666
667 D3DXMATRIX* WINAPI D3DXMatrixRotationZ(D3DXMATRIX *pout, FLOAT angle)
668 {
669     TRACE("(%p, %f)\n", pout, angle);
670
671     D3DXMatrixIdentity(pout);
672     pout->u.m[0][0] = cos(angle);
673     pout->u.m[1][1] = cos(angle);
674     pout->u.m[0][1] = sin(angle);
675     pout->u.m[1][0] = -sin(angle);
676     return pout;
677 }
678
679 D3DXMATRIX* WINAPI D3DXMatrixScaling(D3DXMATRIX *pout, FLOAT sx, FLOAT sy, FLOAT sz)
680 {
681     TRACE("(%p, %f, %f, %f)\n", pout, sx, sy, sz);
682
683     D3DXMatrixIdentity(pout);
684     pout->u.m[0][0] = sx;
685     pout->u.m[1][1] = sy;
686     pout->u.m[2][2] = sz;
687     return pout;
688 }
689
690 D3DXMATRIX* WINAPI D3DXMatrixShadow(D3DXMATRIX *pout, CONST D3DXVECTOR4 *plight, CONST D3DXPLANE *pplane)
691 {
692     D3DXPLANE Nplane;
693     FLOAT dot;
694
695     TRACE("(%p, %p, %p)\n", pout, plight, pplane);
696
697     D3DXPlaneNormalize(&Nplane, pplane);
698     dot = D3DXPlaneDot(&Nplane, plight);
699     pout->u.m[0][0] = dot - Nplane.a * plight->x;
700     pout->u.m[0][1] = -Nplane.a * plight->y;
701     pout->u.m[0][2] = -Nplane.a * plight->z;
702     pout->u.m[0][3] = -Nplane.a * plight->w;
703     pout->u.m[1][0] = -Nplane.b * plight->x;
704     pout->u.m[1][1] = dot - Nplane.b * plight->y;
705     pout->u.m[1][2] = -Nplane.b * plight->z;
706     pout->u.m[1][3] = -Nplane.b * plight->w;
707     pout->u.m[2][0] = -Nplane.c * plight->x;
708     pout->u.m[2][1] = -Nplane.c * plight->y;
709     pout->u.m[2][2] = dot - Nplane.c * plight->z;
710     pout->u.m[2][3] = -Nplane.c * plight->w;
711     pout->u.m[3][0] = -Nplane.d * plight->x;
712     pout->u.m[3][1] = -Nplane.d * plight->y;
713     pout->u.m[3][2] = -Nplane.d * plight->z;
714     pout->u.m[3][3] = dot - Nplane.d * plight->w;
715     return pout;
716 }
717
718 D3DXMATRIX* WINAPI D3DXMatrixTransformation(D3DXMATRIX *pout, CONST D3DXVECTOR3 *pscalingcenter, CONST D3DXQUATERNION *pscalingrotation, CONST D3DXVECTOR3 *pscaling, CONST D3DXVECTOR3 *protationcenter, CONST D3DXQUATERNION *protation, CONST D3DXVECTOR3 *ptranslation)
719 {
720     D3DXMATRIX m1, m2, m3, m4, m5, m6, m7;
721     D3DXQUATERNION prc;
722     D3DXVECTOR3 psc, pt;
723
724     TRACE("(%p, %p, %p, %p, %p, %p, %p)\n", pout, pscalingcenter, pscalingrotation, pscaling, protationcenter, protation, ptranslation);
725
726     if ( !pscalingcenter )
727     {
728         psc.x = 0.0f;
729         psc.y = 0.0f;
730         psc.z = 0.0f;
731     }
732     else
733     {
734         psc.x = pscalingcenter->x;
735         psc.y = pscalingcenter->y;
736         psc.z = pscalingcenter->z;
737     }
738
739     if ( !protationcenter )
740     {
741         prc.x = 0.0f;
742         prc.y = 0.0f;
743         prc.z = 0.0f;
744     }
745     else
746     {
747         prc.x = protationcenter->x;
748         prc.y = protationcenter->y;
749         prc.z = protationcenter->z;
750     }
751
752     if ( !ptranslation )
753     {
754         pt.x = 0.0f;
755         pt.y = 0.0f;
756         pt.z = 0.0f;
757     }
758     else
759     {
760         pt.x = ptranslation->x;
761         pt.y = ptranslation->y;
762         pt.z = ptranslation->z;
763     }
764
765     D3DXMatrixTranslation(&m1, -psc.x, -psc.y, -psc.z);
766
767     if ( !pscalingrotation )
768     {
769         D3DXMatrixIdentity(&m2);
770         D3DXMatrixIdentity(&m4);
771     }
772     else
773     {
774         D3DXMatrixRotationQuaternion(&m4, pscalingrotation);
775         D3DXMatrixInverse(&m2, NULL, &m4);
776     }
777
778     if ( !pscaling ) D3DXMatrixIdentity(&m3);
779     else D3DXMatrixScaling(&m3, pscaling->x, pscaling->y, pscaling->z);
780
781     if ( !protation ) D3DXMatrixIdentity(&m6);
782     else D3DXMatrixRotationQuaternion(&m6, protation);
783
784     D3DXMatrixTranslation(&m5, psc.x - prc.x,  psc.y - prc.y,  psc.z - prc.z);
785     D3DXMatrixTranslation(&m7, prc.x + pt.x, prc.y + pt.y, prc.z + pt.z);
786     D3DXMatrixMultiply(&m1, &m1, &m2);
787     D3DXMatrixMultiply(&m1, &m1, &m3);
788     D3DXMatrixMultiply(&m1, &m1, &m4);
789     D3DXMatrixMultiply(&m1, &m1, &m5);
790     D3DXMatrixMultiply(&m1, &m1, &m6);
791     D3DXMatrixMultiply(pout, &m1, &m7);
792     return pout;
793 }
794
795 D3DXMATRIX* WINAPI D3DXMatrixTransformation2D(D3DXMATRIX *pout, CONST D3DXVECTOR2 *pscalingcenter, FLOAT scalingrotation, CONST D3DXVECTOR2 *pscaling, CONST D3DXVECTOR2 *protationcenter, FLOAT rotation, CONST D3DXVECTOR2 *ptranslation)
796 {
797     D3DXQUATERNION rot, sca_rot;
798     D3DXVECTOR3 rot_center, sca, sca_center, trans;
799
800     TRACE("(%p, %p, %f, %p, %p, %f, %p)\n", pout, pscalingcenter, scalingrotation, pscaling, protationcenter, rotation, ptranslation);
801
802     if ( pscalingcenter )
803     {
804         sca_center.x=pscalingcenter->x;
805         sca_center.y=pscalingcenter->y;
806         sca_center.z=0.0f;
807     }
808     else
809     {
810         sca_center.x=0.0f;
811         sca_center.y=0.0f;
812         sca_center.z=0.0f;
813     }
814
815     if ( pscaling )
816     {
817         sca.x=pscaling->x;
818         sca.y=pscaling->y;
819         sca.z=1.0f;
820     }
821     else
822     {
823         sca.x=1.0f;
824         sca.y=1.0f;
825         sca.z=1.0f;
826     }
827
828     if ( protationcenter )
829     {
830         rot_center.x=protationcenter->x;
831         rot_center.y=protationcenter->y;
832         rot_center.z=0.0f;
833     }
834     else
835     {
836         rot_center.x=0.0f;
837         rot_center.y=0.0f;
838         rot_center.z=0.0f;
839     }
840
841     if ( ptranslation )
842     {
843         trans.x=ptranslation->x;
844         trans.y=ptranslation->y;
845         trans.z=0.0f;
846     }
847     else
848     {
849         trans.x=0.0f;
850         trans.y=0.0f;
851         trans.z=0.0f;
852     }
853
854     rot.w=cos(rotation/2.0f);
855     rot.x=0.0f;
856     rot.y=0.0f;
857     rot.z=sin(rotation/2.0f);
858
859     sca_rot.w=cos(scalingrotation/2.0f);
860     sca_rot.x=0.0f;
861     sca_rot.y=0.0f;
862     sca_rot.z=sin(scalingrotation/2.0f);
863
864     D3DXMatrixTransformation(pout, &sca_center, &sca_rot, &sca, &rot_center, &rot, &trans);
865
866     return pout;
867 }
868
869 D3DXMATRIX* WINAPI D3DXMatrixTranslation(D3DXMATRIX *pout, FLOAT x, FLOAT y, FLOAT z)
870 {
871     TRACE("(%p, %f, %f, %f)\n", pout, x, y, z);
872
873     D3DXMatrixIdentity(pout);
874     pout->u.m[3][0] = x;
875     pout->u.m[3][1] = y;
876     pout->u.m[3][2] = z;
877     return pout;
878 }
879
880 D3DXMATRIX* WINAPI D3DXMatrixTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm)
881 {
882     CONST D3DXMATRIX m = *pm;
883     int i,j;
884
885     TRACE("(%p, %p)\n", pout, pm);
886
887     for (i=0; i<4; i++)
888         for (j=0; j<4; j++) pout->u.m[i][j] = m.u.m[j][i];
889
890     return pout;
891 }
892
893 /*_________________D3DXMatrixStack____________________*/
894
895 static const unsigned int INITIAL_STACK_SIZE = 32;
896
897 HRESULT WINAPI D3DXCreateMatrixStack(DWORD flags, ID3DXMatrixStack **ppstack)
898 {
899     struct ID3DXMatrixStackImpl *object;
900
901     TRACE("flags %#x, ppstack %p\n", flags, ppstack);
902
903     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
904     if (object == NULL)
905     {
906         *ppstack = NULL;
907         return E_OUTOFMEMORY;
908     }
909     object->ID3DXMatrixStack_iface.lpVtbl = &ID3DXMatrixStack_Vtbl;
910     object->ref = 1;
911
912     object->stack = HeapAlloc(GetProcessHeap(), 0, INITIAL_STACK_SIZE * sizeof(*object->stack));
913     if (!object->stack)
914     {
915         HeapFree(GetProcessHeap(), 0, object);
916         *ppstack = NULL;
917         return E_OUTOFMEMORY;
918     }
919
920     object->current = 0;
921     object->stack_size = INITIAL_STACK_SIZE;
922     D3DXMatrixIdentity(&object->stack[0]);
923
924     TRACE("Created matrix stack %p\n", object);
925
926     *ppstack = &object->ID3DXMatrixStack_iface;
927     return D3D_OK;
928 }
929
930 static inline struct ID3DXMatrixStackImpl *impl_from_ID3DXMatrixStack(ID3DXMatrixStack *iface)
931 {
932   return CONTAINING_RECORD(iface, struct ID3DXMatrixStackImpl, ID3DXMatrixStack_iface);
933 }
934
935 static HRESULT WINAPI ID3DXMatrixStackImpl_QueryInterface(ID3DXMatrixStack *iface, REFIID riid, void **out)
936 {
937     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
938
939     if (IsEqualGUID(riid, &IID_ID3DXMatrixStack)
940             || IsEqualGUID(riid, &IID_IUnknown))
941     {
942         ID3DXMatrixStack_AddRef(iface);
943         *out = iface;
944         return S_OK;
945     }
946
947     WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
948
949     *out = NULL;
950     return E_NOINTERFACE;
951 }
952
953 static ULONG WINAPI ID3DXMatrixStackImpl_AddRef(ID3DXMatrixStack *iface)
954 {
955     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
956     ULONG ref = InterlockedIncrement(&This->ref);
957     TRACE("(%p) : AddRef from %d\n", This, ref - 1);
958     return ref;
959 }
960
961 static ULONG WINAPI ID3DXMatrixStackImpl_Release(ID3DXMatrixStack *iface)
962 {
963     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
964     ULONG ref = InterlockedDecrement(&This->ref);
965     if (!ref)
966     {
967         HeapFree(GetProcessHeap(), 0, This->stack);
968         HeapFree(GetProcessHeap(), 0, This);
969     }
970     TRACE("(%p) : ReleaseRef to %d\n", This, ref);
971     return ref;
972 }
973
974 static D3DXMATRIX* WINAPI ID3DXMatrixStackImpl_GetTop(ID3DXMatrixStack *iface)
975 {
976     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
977
978     TRACE("iface %p\n", iface);
979
980     return &This->stack[This->current];
981 }
982
983 static HRESULT WINAPI ID3DXMatrixStackImpl_LoadIdentity(ID3DXMatrixStack *iface)
984 {
985     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
986
987     TRACE("iface %p\n", iface);
988
989     D3DXMatrixIdentity(&This->stack[This->current]);
990
991     return D3D_OK;
992 }
993
994 static HRESULT WINAPI ID3DXMatrixStackImpl_LoadMatrix(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
995 {
996     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
997
998     TRACE("iface %p\n", iface);
999
1000     This->stack[This->current] = *pm;
1001
1002     return D3D_OK;
1003 }
1004
1005 static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrix(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
1006 {
1007     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1008
1009     TRACE("iface %p\n", iface);
1010
1011     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], pm);
1012
1013     return D3D_OK;
1014 }
1015
1016 static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrixLocal(ID3DXMatrixStack *iface, CONST D3DXMATRIX *pm)
1017 {
1018     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1019
1020     TRACE("iface %p\n", iface);
1021
1022     D3DXMatrixMultiply(&This->stack[This->current], pm, &This->stack[This->current]);
1023
1024     return D3D_OK;
1025 }
1026
1027 static HRESULT WINAPI ID3DXMatrixStackImpl_Pop(ID3DXMatrixStack *iface)
1028 {
1029     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1030
1031     TRACE("iface %p\n", iface);
1032
1033     /* Popping the last element on the stack returns D3D_OK, but does nothing. */
1034     if (!This->current) return D3D_OK;
1035
1036     if (This->current <= This->stack_size / 4 && This->stack_size >= INITIAL_STACK_SIZE * 2)
1037     {
1038         unsigned int new_size;
1039         D3DXMATRIX *new_stack;
1040
1041         new_size = This->stack_size / 2;
1042         new_stack = HeapReAlloc(GetProcessHeap(), 0, This->stack, new_size * sizeof(*new_stack));
1043         if (new_stack)
1044         {
1045             This->stack_size = new_size;
1046             This->stack = new_stack;
1047         }
1048     }
1049
1050     --This->current;
1051
1052     return D3D_OK;
1053 }
1054
1055 static HRESULT WINAPI ID3DXMatrixStackImpl_Push(ID3DXMatrixStack *iface)
1056 {
1057     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1058
1059     TRACE("iface %p\n", iface);
1060
1061     if (This->current == This->stack_size - 1)
1062     {
1063         unsigned int new_size;
1064         D3DXMATRIX *new_stack;
1065
1066         if (This->stack_size > UINT_MAX / 2) return E_OUTOFMEMORY;
1067
1068         new_size = This->stack_size * 2;
1069         new_stack = HeapReAlloc(GetProcessHeap(), 0, This->stack, new_size * sizeof(*new_stack));
1070         if (!new_stack) return E_OUTOFMEMORY;
1071
1072         This->stack_size = new_size;
1073         This->stack = new_stack;
1074     }
1075
1076     ++This->current;
1077     This->stack[This->current] = This->stack[This->current - 1];
1078
1079     return D3D_OK;
1080 }
1081
1082 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxis(ID3DXMatrixStack *iface, CONST D3DXVECTOR3 *pv, FLOAT angle)
1083 {
1084     D3DXMATRIX temp;
1085     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1086
1087     TRACE("iface %p\n", iface);
1088
1089     D3DXMatrixRotationAxis(&temp, pv, angle);
1090     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
1091
1092     return D3D_OK;
1093 }
1094
1095 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxisLocal(ID3DXMatrixStack *iface, CONST D3DXVECTOR3 *pv, FLOAT angle)
1096 {
1097     D3DXMATRIX temp;
1098     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1099
1100     TRACE("iface %p\n", iface);
1101
1102     D3DXMatrixRotationAxis(&temp, pv, angle);
1103     D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
1104
1105     return D3D_OK;
1106 }
1107
1108 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRoll(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
1109 {
1110     D3DXMATRIX temp;
1111     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1112
1113     TRACE("iface %p\n", iface);
1114
1115     D3DXMatrixRotationYawPitchRoll(&temp, x, y, z);
1116     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
1117
1118     return D3D_OK;
1119 }
1120
1121 static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRollLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
1122 {
1123     D3DXMATRIX temp;
1124     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1125
1126     TRACE("iface %p\n", iface);
1127
1128     D3DXMatrixRotationYawPitchRoll(&temp, x, y, z);
1129     D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
1130
1131     return D3D_OK;
1132 }
1133
1134 static HRESULT WINAPI ID3DXMatrixStackImpl_Scale(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
1135 {
1136     D3DXMATRIX temp;
1137     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1138
1139     TRACE("iface %p\n", iface);
1140
1141     D3DXMatrixScaling(&temp, x, y, z);
1142     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
1143
1144     return D3D_OK;
1145 }
1146
1147 static HRESULT WINAPI ID3DXMatrixStackImpl_ScaleLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
1148 {
1149     D3DXMATRIX temp;
1150     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1151
1152     TRACE("iface %p\n", iface);
1153
1154     D3DXMatrixScaling(&temp, x, y, z);
1155     D3DXMatrixMultiply(&This->stack[This->current], &temp, &This->stack[This->current]);
1156
1157     return D3D_OK;
1158 }
1159
1160 static HRESULT WINAPI ID3DXMatrixStackImpl_Translate(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
1161 {
1162     D3DXMATRIX temp;
1163     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1164
1165     TRACE("iface %p\n", iface);
1166
1167     D3DXMatrixTranslation(&temp, x, y, z);
1168     D3DXMatrixMultiply(&This->stack[This->current], &This->stack[This->current], &temp);
1169
1170     return D3D_OK;
1171 }
1172
1173 static HRESULT WINAPI ID3DXMatrixStackImpl_TranslateLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
1174 {
1175     D3DXMATRIX temp;
1176     struct ID3DXMatrixStackImpl *This = impl_from_ID3DXMatrixStack(iface);
1177
1178     TRACE("iface %p\n", iface);
1179
1180     D3DXMatrixTranslation(&temp, x, y, z);
1181     D3DXMatrixMultiply(&This->stack[This->current], &temp,&This->stack[This->current]);
1182
1183     return D3D_OK;
1184 }
1185
1186 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl =
1187 {
1188     ID3DXMatrixStackImpl_QueryInterface,
1189     ID3DXMatrixStackImpl_AddRef,
1190     ID3DXMatrixStackImpl_Release,
1191     ID3DXMatrixStackImpl_Pop,
1192     ID3DXMatrixStackImpl_Push,
1193     ID3DXMatrixStackImpl_LoadIdentity,
1194     ID3DXMatrixStackImpl_LoadMatrix,
1195     ID3DXMatrixStackImpl_MultMatrix,
1196     ID3DXMatrixStackImpl_MultMatrixLocal,
1197     ID3DXMatrixStackImpl_RotateAxis,
1198     ID3DXMatrixStackImpl_RotateAxisLocal,
1199     ID3DXMatrixStackImpl_RotateYawPitchRoll,
1200     ID3DXMatrixStackImpl_RotateYawPitchRollLocal,
1201     ID3DXMatrixStackImpl_Scale,
1202     ID3DXMatrixStackImpl_ScaleLocal,
1203     ID3DXMatrixStackImpl_Translate,
1204     ID3DXMatrixStackImpl_TranslateLocal,
1205     ID3DXMatrixStackImpl_GetTop
1206 };
1207
1208 /*_________________D3DXPLANE________________*/
1209
1210 D3DXPLANE* WINAPI D3DXPlaneFromPointNormal(D3DXPLANE *pout, CONST D3DXVECTOR3 *pvpoint, CONST D3DXVECTOR3 *pvnormal)
1211 {
1212     TRACE("(%p, %p, %p)\n", pout, pvpoint, pvnormal);
1213
1214     pout->a = pvnormal->x;
1215     pout->b = pvnormal->y;
1216     pout->c = pvnormal->z;
1217     pout->d = -D3DXVec3Dot(pvpoint, pvnormal);
1218     return pout;
1219 }
1220
1221 D3DXPLANE* WINAPI D3DXPlaneFromPoints(D3DXPLANE *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3)
1222 {
1223     D3DXVECTOR3 edge1, edge2, normal, Nnormal;
1224
1225     TRACE("(%p, %p, %p, %p)\n", pout, pv1, pv2, pv3);
1226
1227     edge1.x = 0.0f; edge1.y = 0.0f; edge1.z = 0.0f;
1228     edge2.x = 0.0f; edge2.y = 0.0f; edge2.z = 0.0f;
1229     D3DXVec3Subtract(&edge1, pv2, pv1);
1230     D3DXVec3Subtract(&edge2, pv3, pv1);
1231     D3DXVec3Cross(&normal, &edge1, &edge2);
1232     D3DXVec3Normalize(&Nnormal, &normal);
1233     D3DXPlaneFromPointNormal(pout, pv1, &Nnormal);
1234     return pout;
1235 }
1236
1237 D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine(D3DXVECTOR3 *pout, CONST D3DXPLANE *pp, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2)
1238 {
1239     D3DXVECTOR3 direction, normal;
1240     FLOAT dot, temp;
1241
1242     TRACE("(%p, %p, %p, %p)\n", pout, pp, pv1, pv2);
1243
1244     normal.x = pp->a;
1245     normal.y = pp->b;
1246     normal.z = pp->c;
1247     direction.x = pv2->x - pv1->x;
1248     direction.y = pv2->y - pv1->y;
1249     direction.z = pv2->z - pv1->z;
1250     dot = D3DXVec3Dot(&normal, &direction);
1251     if ( !dot ) return NULL;
1252     temp = ( pp->d + D3DXVec3Dot(&normal, pv1) ) / dot;
1253     pout->x = pv1->x - temp * direction.x;
1254     pout->y = pv1->y - temp * direction.y;
1255     pout->z = pv1->z - temp * direction.z;
1256     return pout;
1257 }
1258
1259 D3DXPLANE * WINAPI D3DXPlaneNormalize(D3DXPLANE *out, const D3DXPLANE *p)
1260 {
1261     FLOAT norm;
1262
1263     TRACE("out %p, p %p\n", out, p);
1264
1265     norm = sqrtf(p->a * p->a + p->b * p->b + p->c * p->c);
1266     if (norm)
1267     {
1268         out->a = p->a / norm;
1269         out->b = p->b / norm;
1270         out->c = p->c / norm;
1271         out->d = p->d / norm;
1272     }
1273     else
1274     {
1275         out->a = 0.0f;
1276         out->b = 0.0f;
1277         out->c = 0.0f;
1278         out->d = 0.0f;
1279     }
1280
1281     return out;
1282 }
1283
1284 D3DXPLANE* WINAPI D3DXPlaneTransform(D3DXPLANE *pout, CONST D3DXPLANE *pplane, CONST D3DXMATRIX *pm)
1285 {
1286     CONST D3DXPLANE plane = *pplane;
1287
1288     TRACE("(%p, %p, %p)\n", pout, pplane, pm);
1289
1290     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;
1291     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;
1292     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;
1293     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;
1294     return pout;
1295 }
1296
1297 D3DXPLANE* WINAPI D3DXPlaneTransformArray(D3DXPLANE* out, UINT outstride, CONST D3DXPLANE* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
1298 {
1299     UINT i;
1300
1301     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1302
1303     for (i = 0; i < elements; ++i) {
1304         D3DXPlaneTransform(
1305             (D3DXPLANE*)((char*)out + outstride * i),
1306             (CONST D3DXPLANE*)((const char*)in + instride * i),
1307             matrix);
1308     }
1309     return out;
1310 }
1311
1312 /*_________________D3DXQUATERNION________________*/
1313
1314 D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, FLOAT f, FLOAT g)
1315 {
1316     D3DXQUATERNION temp1, temp2;
1317
1318     TRACE("(%p, %p, %p, %p, %f, %f)\n", pout, pq1, pq2, pq3, f, g);
1319
1320     D3DXQuaternionSlerp(pout, D3DXQuaternionSlerp(&temp1, pq1, pq2, f + g), D3DXQuaternionSlerp(&temp2, pq1, pq3, f+g), g / (f + g));
1321     return pout;
1322 }
1323
1324 D3DXQUATERNION * WINAPI D3DXQuaternionExp(D3DXQUATERNION *out, const D3DXQUATERNION *q)
1325 {
1326     FLOAT norm;
1327
1328     TRACE("out %p, q %p\n", out, q);
1329
1330     norm = sqrtf(q->x * q->x + q->y * q->y + q->z * q->z);
1331     if (norm)
1332     {
1333         out->x = sinf(norm) * q->x / norm;
1334         out->y = sinf(norm) * q->y / norm;
1335         out->z = sinf(norm) * q->z / norm;
1336         out->w = cosf(norm);
1337     }
1338     else
1339     {
1340         out->x = 0.0f;
1341         out->y = 0.0f;
1342         out->z = 0.0f;
1343         out->w = 1.0f;
1344     }
1345
1346     return out;
1347 }
1348
1349 D3DXQUATERNION* WINAPI D3DXQuaternionInverse(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq)
1350 {
1351     D3DXQUATERNION out;
1352     FLOAT norm;
1353
1354     TRACE("(%p, %p)\n", pout, pq);
1355
1356     norm = D3DXQuaternionLengthSq(pq);
1357
1358     out.x = -pq->x / norm;
1359     out.y = -pq->y / norm;
1360     out.z = -pq->z / norm;
1361     out.w = pq->w / norm;
1362
1363     *pout =out;
1364     return pout;
1365 }
1366
1367 D3DXQUATERNION * WINAPI D3DXQuaternionLn(D3DXQUATERNION *out, const D3DXQUATERNION *q)
1368 {
1369     FLOAT t;
1370
1371     TRACE("out %p, q %p\n", out, q);
1372
1373     if ((q->w >= 1.0f) || (q->w == -1.0f))
1374         t = 1.0f;
1375     else
1376         t = acosf(q->w) / sqrtf(1.0f - q->w * q->w);
1377
1378     out->x = t * q->x;
1379     out->y = t * q->y;
1380     out->z = t * q->z;
1381     out->w = 0.0f;
1382
1383     return out;
1384 }
1385
1386 D3DXQUATERNION* WINAPI D3DXQuaternionMultiply(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2)
1387 {
1388     D3DXQUATERNION out;
1389
1390     TRACE("(%p, %p, %p)\n", pout, pq1, pq2);
1391
1392     out.x = pq2->w * pq1->x + pq2->x * pq1->w + pq2->y * pq1->z - pq2->z * pq1->y;
1393     out.y = pq2->w * pq1->y - pq2->x * pq1->z + pq2->y * pq1->w + pq2->z * pq1->x;
1394     out.z = pq2->w * pq1->z + pq2->x * pq1->y - pq2->y * pq1->x + pq2->z * pq1->w;
1395     out.w = pq2->w * pq1->w - pq2->x * pq1->x - pq2->y * pq1->y - pq2->z * pq1->z;
1396     *pout = out;
1397     return pout;
1398 }
1399
1400 D3DXQUATERNION * WINAPI D3DXQuaternionNormalize(D3DXQUATERNION *out, const D3DXQUATERNION *q)
1401 {
1402     FLOAT norm;
1403
1404     TRACE("out %p, q %p\n", out, q);
1405
1406     norm = D3DXQuaternionLength(q);
1407
1408     out->x = q->x / norm;
1409     out->y = q->y / norm;
1410     out->z = q->z / norm;
1411     out->w = q->w / norm;
1412
1413     return out;
1414 }
1415
1416 D3DXQUATERNION * WINAPI D3DXQuaternionRotationAxis(D3DXQUATERNION *out, const D3DXVECTOR3 *v, FLOAT angle)
1417 {
1418     D3DXVECTOR3 temp;
1419
1420     TRACE("out %p, v %p, angle %f\n", out, v, angle);
1421
1422     D3DXVec3Normalize(&temp, v);
1423
1424     out->x = sinf(angle / 2.0f) * temp.x;
1425     out->y = sinf(angle / 2.0f) * temp.y;
1426     out->z = sinf(angle / 2.0f) * temp.z;
1427     out->w = cosf(angle / 2.0f);
1428
1429     return out;
1430 }
1431
1432 D3DXQUATERNION * WINAPI D3DXQuaternionRotationMatrix(D3DXQUATERNION *out, const D3DXMATRIX *m)
1433 {
1434     FLOAT s, trace;
1435
1436     TRACE("out %p, m %p\n", out, m);
1437
1438     trace = m->u.m[0][0] + m->u.m[1][1] + m->u.m[2][2] + 1.0f;
1439     if (trace > 1.0f)
1440     {
1441         s = 2.0f * sqrtf(trace);
1442         out->x = (m->u.m[1][2] - m->u.m[2][1]) / s;
1443         out->y = (m->u.m[2][0] - m->u.m[0][2]) / s;
1444         out->z = (m->u.m[0][1] - m->u.m[1][0]) / s;
1445         out->w = 0.25f * s;
1446     }
1447     else
1448     {
1449         int i, maxi = 0;
1450
1451         for (i = 1; i < 3; i++)
1452         {
1453             if (m->u.m[i][i] > m->u.m[maxi][maxi])
1454                 maxi = i;
1455         }
1456
1457         switch (maxi)
1458         {
1459             case 0:
1460                 s = 2.0f * sqrtf(1.0f + m->u.m[0][0] - m->u.m[1][1] - m->u.m[2][2]);
1461                 out->x = 0.25f * s;
1462                 out->y = (m->u.m[0][1] + m->u.m[1][0]) / s;
1463                 out->z = (m->u.m[0][2] + m->u.m[2][0]) / s;
1464                 out->w = (m->u.m[1][2] - m->u.m[2][1]) / s;
1465                 break;
1466
1467             case 1:
1468                 s = 2.0f * sqrtf(1.0f + m->u.m[1][1] - m->u.m[0][0] - m->u.m[2][2]);
1469                 out->x = (m->u.m[0][1] + m->u.m[1][0]) / s;
1470                 out->y = 0.25f * s;
1471                 out->z = (m->u.m[1][2] + m->u.m[2][1]) / s;
1472                 out->w = (m->u.m[2][0] - m->u.m[0][2]) / s;
1473                 break;
1474
1475             case 2:
1476                 s = 2.0f * sqrtf(1.0f + m->u.m[2][2] - m->u.m[0][0] - m->u.m[1][1]);
1477                 out->x = (m->u.m[0][2] + m->u.m[2][0]) / s;
1478                 out->y = (m->u.m[1][2] + m->u.m[2][1]) / s;
1479                 out->z = 0.25f * s;
1480                 out->w = (m->u.m[0][1] - m->u.m[1][0]) / s;
1481                 break;
1482         }
1483     }
1484
1485     return out;
1486 }
1487
1488 D3DXQUATERNION * WINAPI D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION *out, FLOAT yaw, FLOAT pitch, FLOAT roll)
1489 {
1490     FLOAT syaw, cyaw, spitch, cpitch, sroll, croll;
1491
1492     TRACE("out %p, yaw %f, pitch %f, roll %f\n", out, yaw, pitch, roll);
1493
1494     syaw = sinf(yaw / 2.0f);
1495     cyaw = cosf(yaw / 2.0f);
1496     spitch = sinf(pitch / 2.0f);
1497     cpitch = cosf(pitch / 2.0f);
1498     sroll = sinf(roll / 2.0f);
1499     croll = cosf(roll / 2.0f);
1500
1501     out->x = syaw * cpitch * sroll + cyaw * spitch * croll;
1502     out->y = syaw * cpitch * croll - cyaw * spitch * sroll;
1503     out->z = cyaw * cpitch * sroll - syaw * spitch * croll;
1504     out->w = cyaw * cpitch * croll + syaw * spitch * sroll;
1505
1506     return out;
1507 }
1508
1509 D3DXQUATERNION * WINAPI D3DXQuaternionSlerp(D3DXQUATERNION *out, const D3DXQUATERNION *q1,
1510         const D3DXQUATERNION *q2, FLOAT t)
1511 {
1512     FLOAT dot, temp;
1513
1514     TRACE("out %p, q1 %p, q2 %p, t %f\n", out, q1, q2, t);
1515
1516     temp = 1.0f - t;
1517     dot = D3DXQuaternionDot(q1, q2);
1518     if (dot < 0.0f)
1519     {
1520         t = -t;
1521         dot = -dot;
1522     }
1523
1524     if (1.0f - dot > 0.001f)
1525     {
1526         FLOAT theta = acosf(dot);
1527
1528         temp = sinf(theta * temp) / sinf(theta);
1529         t = sinf(theta * t) / sinf(theta);
1530     }
1531
1532     out->x = temp * q1->x + t * q2->x;
1533     out->y = temp * q1->y + t * q2->y;
1534     out->z = temp * q1->z + t * q2->z;
1535     out->w = temp * q1->w + t * q2->w;
1536
1537     return out;
1538 }
1539
1540 D3DXQUATERNION* WINAPI D3DXQuaternionSquad(D3DXQUATERNION *pout, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3, CONST D3DXQUATERNION *pq4, FLOAT t)
1541 {
1542     D3DXQUATERNION temp1, temp2;
1543
1544     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pq1, pq2, pq3, pq4, t);
1545
1546     D3DXQuaternionSlerp(pout, D3DXQuaternionSlerp(&temp1, pq1, pq4, t), D3DXQuaternionSlerp(&temp2, pq2, pq3, t), 2.0f * t * (1.0f - t));
1547     return pout;
1548 }
1549
1550 static D3DXQUATERNION add_diff(CONST D3DXQUATERNION *q1, CONST D3DXQUATERNION *q2, CONST FLOAT add)
1551 {
1552     D3DXQUATERNION temp;
1553
1554     temp.x = q1->x + add * q2->x;
1555     temp.y = q1->y + add * q2->y;
1556     temp.z = q1->z + add * q2->z;
1557     temp.w = q1->w + add * q2->w;
1558
1559     return temp;
1560 }
1561
1562 void WINAPI D3DXQuaternionSquadSetup(D3DXQUATERNION *paout, D3DXQUATERNION *pbout, D3DXQUATERNION *pcout, CONST D3DXQUATERNION *pq0, CONST D3DXQUATERNION *pq1, CONST D3DXQUATERNION *pq2, CONST D3DXQUATERNION *pq3)
1563 {
1564     D3DXQUATERNION q, temp1, temp2, temp3, zero;
1565
1566     TRACE("(%p, %p, %p, %p, %p, %p, %p)\n", paout, pbout, pcout, pq0, pq1, pq2, pq3);
1567
1568     zero.x = 0.0f;
1569     zero.y = 0.0f;
1570     zero.z = 0.0f;
1571     zero.w = 0.0f;
1572
1573     if ( D3DXQuaternionDot(pq0, pq1) <  0.0f )
1574         temp2 = add_diff(&zero, pq0, -1.0f);
1575     else
1576         temp2 = *pq0;
1577
1578     if ( D3DXQuaternionDot(pq1, pq2) < 0.0f )
1579         *pcout = add_diff(&zero, pq2, -1.0f);
1580     else
1581         *pcout = *pq2;
1582
1583     if ( D3DXQuaternionDot(pcout, pq3) < 0.0f )
1584         temp3 = add_diff(&zero, pq3, -1.0f);
1585     else
1586         temp3 = *pq3;
1587
1588     D3DXQuaternionInverse(&temp1, pq1);
1589     D3DXQuaternionMultiply(&temp2, &temp1, &temp2);
1590     D3DXQuaternionLn(&temp2, &temp2);
1591     D3DXQuaternionMultiply(&q, &temp1, pcout);
1592     D3DXQuaternionLn(&q, &q);
1593     temp1 = add_diff(&temp2, &q, 1.0f);
1594     temp1.x *= -0.25f;
1595     temp1.y *= -0.25f;
1596     temp1.z *= -0.25f;
1597     temp1.w *= -0.25f;
1598     D3DXQuaternionExp(&temp1, &temp1);
1599     D3DXQuaternionMultiply(paout, pq1, &temp1);
1600
1601     D3DXQuaternionInverse(&temp1, pcout);
1602     D3DXQuaternionMultiply(&temp2, &temp1, pq1);
1603     D3DXQuaternionLn(&temp2, &temp2);
1604     D3DXQuaternionMultiply(&q, &temp1, &temp3);
1605     D3DXQuaternionLn(&q, &q);
1606     temp1 = add_diff(&temp2, &q, 1.0f);
1607     temp1.x *= -0.25f;
1608     temp1.y *= -0.25f;
1609     temp1.z *= -0.25f;
1610     temp1.w *= -0.25f;
1611     D3DXQuaternionExp(&temp1, &temp1);
1612     D3DXQuaternionMultiply(pbout, pcout, &temp1);
1613
1614     return;
1615 }
1616
1617 void WINAPI D3DXQuaternionToAxisAngle(CONST D3DXQUATERNION *pq, D3DXVECTOR3 *paxis, FLOAT *pangle)
1618 {
1619     TRACE("(%p, %p, %p)\n", pq, paxis, pangle);
1620
1621     paxis->x = pq->x;
1622     paxis->y = pq->y;
1623     paxis->z = pq->z;
1624     *pangle = 2.0f * acos(pq->w);
1625 }
1626
1627 /*_________________D3DXVec2_____________________*/
1628
1629 D3DXVECTOR2* WINAPI D3DXVec2BaryCentric(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT f, FLOAT g)
1630 {
1631     TRACE("(%p, %p, %p, %p, %f, %f)\n", pout, pv1, pv2, pv3, f, g);
1632
1633     pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
1634     pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
1635     return pout;
1636 }
1637
1638 D3DXVECTOR2* WINAPI D3DXVec2CatmullRom(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv0, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pv3, FLOAT s)
1639 {
1640     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pv0, pv1, pv2, pv3, s);
1641
1642     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);
1643     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);
1644     return pout;
1645 }
1646
1647 D3DXVECTOR2* WINAPI D3DXVec2Hermite(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv1, CONST D3DXVECTOR2 *pt1, CONST D3DXVECTOR2 *pv2, CONST D3DXVECTOR2 *pt2, FLOAT s)
1648 {
1649     FLOAT h1, h2, h3, h4;
1650
1651     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pv1, pt1, pv2, pt2, s);
1652
1653     h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
1654     h2 = s * s * s - 2.0f * s * s + s;
1655     h3 = -2.0f * s * s * s + 3.0f * s * s;
1656     h4 = s * s * s - s * s;
1657
1658     pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
1659     pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
1660     return pout;
1661 }
1662
1663 D3DXVECTOR2* WINAPI D3DXVec2Normalize(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv)
1664 {
1665     FLOAT norm;
1666
1667     TRACE("(%p, %p)\n", pout, pv);
1668
1669     norm = D3DXVec2Length(pv);
1670     if ( !norm )
1671     {
1672         pout->x = 0.0f;
1673         pout->y = 0.0f;
1674     }
1675     else
1676     {
1677         pout->x = pv->x / norm;
1678         pout->y = pv->y / norm;
1679     }
1680
1681     return pout;
1682 }
1683
1684 D3DXVECTOR4* WINAPI D3DXVec2Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
1685 {
1686     TRACE("(%p, %p, %p)\n", pout, pv, pm);
1687
1688     pout->x = pm->u.m[0][0] * pv->x + pm->u.m[1][0] * pv->y  + pm->u.m[3][0];
1689     pout->y = pm->u.m[0][1] * pv->x + pm->u.m[1][1] * pv->y  + pm->u.m[3][1];
1690     pout->z = pm->u.m[0][2] * pv->x + pm->u.m[1][2] * pv->y  + pm->u.m[3][2];
1691     pout->w = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y  + pm->u.m[3][3];
1692     return pout;
1693 }
1694
1695 D3DXVECTOR4* WINAPI D3DXVec2TransformArray(D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
1696 {
1697     UINT i;
1698
1699     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1700
1701     for (i = 0; i < elements; ++i) {
1702         D3DXVec2Transform(
1703             (D3DXVECTOR4*)((char*)out + outstride * i),
1704             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
1705             matrix);
1706     }
1707     return out;
1708 }
1709
1710 D3DXVECTOR2* WINAPI D3DXVec2TransformCoord(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
1711 {
1712     D3DXVECTOR2 v;
1713     FLOAT norm;
1714
1715     TRACE("(%p, %p, %p)\n", pout, pv, pm);
1716
1717     v = *pv;
1718     norm = pm->u.m[0][3] * pv->x + pm->u.m[1][3] * pv->y + pm->u.m[3][3];
1719
1720     pout->x = (pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[3][0]) / norm;
1721     pout->y = (pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[3][1]) / norm;
1722
1723     return pout;
1724 }
1725
1726 D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray(D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
1727 {
1728     UINT i;
1729
1730     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1731
1732     for (i = 0; i < elements; ++i) {
1733         D3DXVec2TransformCoord(
1734             (D3DXVECTOR2*)((char*)out + outstride * i),
1735             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
1736             matrix);
1737     }
1738     return out;
1739 }
1740
1741 D3DXVECTOR2* WINAPI D3DXVec2TransformNormal(D3DXVECTOR2 *pout, CONST D3DXVECTOR2 *pv, CONST D3DXMATRIX *pm)
1742 {
1743     CONST D3DXVECTOR2 v = *pv;
1744     pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y;
1745     pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y;
1746     return pout;
1747 }
1748
1749 D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray(D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2 *in, UINT instride, CONST D3DXMATRIX *matrix, UINT elements)
1750 {
1751     UINT i;
1752
1753     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1754
1755     for (i = 0; i < elements; ++i) {
1756         D3DXVec2TransformNormal(
1757             (D3DXVECTOR2*)((char*)out + outstride * i),
1758             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
1759             matrix);
1760     }
1761     return out;
1762 }
1763
1764 /*_________________D3DXVec3_____________________*/
1765
1766 D3DXVECTOR3* WINAPI D3DXVec3BaryCentric(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3, FLOAT f, FLOAT g)
1767 {
1768     TRACE("(%p, %p, %p, %p, %f, %f)\n", pout, pv1, pv2, pv3, f, g);
1769
1770     pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
1771     pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
1772     pout->z = (1.0f-f-g) * (pv1->z) + f * (pv2->z) + g * (pv3->z);
1773     return pout;
1774 }
1775
1776 D3DXVECTOR3* WINAPI D3DXVec3CatmullRom( D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv0, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pv3, FLOAT s)
1777 {
1778     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pv0, pv1, pv2, pv3, s);
1779
1780     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);
1781     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);
1782     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);
1783     return pout;
1784 }
1785
1786 D3DXVECTOR3* WINAPI D3DXVec3Hermite(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv1, CONST D3DXVECTOR3 *pt1, CONST D3DXVECTOR3 *pv2, CONST D3DXVECTOR3 *pt2, FLOAT s)
1787 {
1788     FLOAT h1, h2, h3, h4;
1789
1790     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pv1, pt1, pv2, pt2, s);
1791
1792     h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
1793     h2 = s * s * s - 2.0f * s * s + s;
1794     h3 = -2.0f * s * s * s + 3.0f * s * s;
1795     h4 = s * s * s - s * s;
1796
1797     pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
1798     pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
1799     pout->z = h1 * (pv1->z) + h2 * (pt1->z) + h3 * (pv2->z) + h4 * (pt2->z);
1800     return pout;
1801 }
1802
1803 D3DXVECTOR3* WINAPI D3DXVec3Normalize(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv)
1804 {
1805     FLOAT norm;
1806
1807     TRACE("(%p, %p)\n", pout, pv);
1808
1809     norm = D3DXVec3Length(pv);
1810     if ( !norm )
1811     {
1812         pout->x = 0.0f;
1813         pout->y = 0.0f;
1814         pout->z = 0.0f;
1815     }
1816     else
1817     {
1818         pout->x = pv->x / norm;
1819         pout->y = pv->y / norm;
1820         pout->z = pv->z / norm;
1821     }
1822
1823     return pout;
1824 }
1825
1826 D3DXVECTOR3* WINAPI D3DXVec3Project(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DVIEWPORT9 *pviewport, CONST D3DXMATRIX *pprojection, CONST D3DXMATRIX *pview, CONST D3DXMATRIX *pworld)
1827 {
1828     D3DXMATRIX m;
1829
1830     TRACE("(%p, %p, %p, %p, %p, %p)\n", pout, pv, pviewport, pprojection, pview, pworld);
1831
1832     D3DXMatrixIdentity(&m);
1833     if (pworld) D3DXMatrixMultiply(&m, &m, pworld);
1834     if (pview) D3DXMatrixMultiply(&m, &m, pview);
1835     if (pprojection) D3DXMatrixMultiply(&m, &m, pprojection);
1836
1837     D3DXVec3TransformCoord(pout, pv, &m);
1838
1839     if (pviewport)
1840     {
1841         pout->x = pviewport->X +  ( 1.0f + pout->x ) * pviewport->Width / 2.0f;
1842         pout->y = pviewport->Y +  ( 1.0f - pout->y ) * pviewport->Height / 2.0f;
1843         pout->z = pviewport->MinZ + pout->z * ( pviewport->MaxZ - pviewport->MinZ );
1844     }
1845     return pout;
1846 }
1847
1848 D3DXVECTOR3* WINAPI D3DXVec3ProjectArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements)
1849 {
1850     UINT i;
1851
1852     TRACE("(%p, %u, %p, %u, %p, %p, %p, %p, %u)\n", out, outstride, in, instride, viewport, projection, view, world, elements);
1853
1854     for (i = 0; i < elements; ++i) {
1855         D3DXVec3Project(
1856             (D3DXVECTOR3*)((char*)out + outstride * i),
1857             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
1858             viewport, projection, view, world);
1859     }
1860     return out;
1861 }
1862
1863 D3DXVECTOR4* WINAPI D3DXVec3Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
1864 {
1865     TRACE("(%p, %p, %p)\n", pout, pv, pm);
1866
1867     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];
1868     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];
1869     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];
1870     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];
1871     return pout;
1872 }
1873
1874 D3DXVECTOR4* WINAPI D3DXVec3TransformArray(D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
1875 {
1876     UINT i;
1877
1878     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1879
1880     for (i = 0; i < elements; ++i) {
1881         D3DXVec3Transform(
1882             (D3DXVECTOR4*)((char*)out + outstride * i),
1883             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
1884             matrix);
1885     }
1886     return out;
1887 }
1888
1889 D3DXVECTOR3* WINAPI D3DXVec3TransformCoord(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
1890 {
1891     D3DXVECTOR3 out;
1892     FLOAT norm;
1893
1894     TRACE("(%p, %p, %p)\n", pout, pv, pm);
1895
1896     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];
1897
1898     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]) / norm;
1899     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]) / norm;
1900     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]) / norm;
1901
1902     *pout = out;
1903
1904     return pout;
1905 }
1906
1907 D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
1908 {
1909     UINT i;
1910
1911     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1912
1913     for (i = 0; i < elements; ++i) {
1914         D3DXVec3TransformCoord(
1915             (D3DXVECTOR3*)((char*)out + outstride * i),
1916             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
1917             matrix);
1918     }
1919     return out;
1920 }
1921
1922 D3DXVECTOR3* WINAPI D3DXVec3TransformNormal(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DXMATRIX *pm)
1923 {
1924     CONST D3DXVECTOR3 v = *pv;
1925
1926     TRACE("(%p, %p, %p)\n", pout, pv, pm);
1927
1928     pout->x = pm->u.m[0][0] * v.x + pm->u.m[1][0] * v.y + pm->u.m[2][0] * v.z;
1929     pout->y = pm->u.m[0][1] * v.x + pm->u.m[1][1] * v.y + pm->u.m[2][1] * v.z;
1930     pout->z = pm->u.m[0][2] * v.x + pm->u.m[1][2] * v.y + pm->u.m[2][2] * v.z;
1931     return pout;
1932
1933 }
1934
1935 D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
1936 {
1937     UINT i;
1938
1939     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
1940
1941     for (i = 0; i < elements; ++i) {
1942         D3DXVec3TransformNormal(
1943             (D3DXVECTOR3*)((char*)out + outstride * i),
1944             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
1945             matrix);
1946     }
1947     return out;
1948 }
1949
1950 D3DXVECTOR3* WINAPI D3DXVec3Unproject(D3DXVECTOR3 *pout, CONST D3DXVECTOR3 *pv, CONST D3DVIEWPORT9 *pviewport, CONST D3DXMATRIX *pprojection, CONST D3DXMATRIX *pview, CONST D3DXMATRIX *pworld)
1951 {
1952     D3DXMATRIX m;
1953
1954     TRACE("(%p, %p, %p, %p, %p, %p)\n", pout, pv, pviewport, pprojection, pview, pworld);
1955
1956     D3DXMatrixIdentity(&m);
1957     if (pworld) D3DXMatrixMultiply(&m, &m, pworld);
1958     if (pview) D3DXMatrixMultiply(&m, &m, pview);
1959     if (pprojection) D3DXMatrixMultiply(&m, &m, pprojection);
1960     D3DXMatrixInverse(&m, NULL, &m);
1961
1962     *pout = *pv;
1963     if (pviewport)
1964     {
1965         pout->x = 2.0f * ( pout->x - pviewport->X ) / pviewport->Width - 1.0f;
1966         pout->y = 1.0f - 2.0f * ( pout->y - pviewport->Y ) / pviewport->Height;
1967         pout->z = ( pout->z - pviewport->MinZ) / ( pviewport->MaxZ - pviewport->MinZ );
1968     }
1969     D3DXVec3TransformCoord(pout, pout, &m);
1970     return pout;
1971 }
1972
1973 D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray(D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride, CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection, CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements)
1974 {
1975     UINT i;
1976
1977     TRACE("(%p, %u, %p, %u, %p, %p, %p, %p, %u)\n", out, outstride, in, instride, viewport, projection, view, world, elements);
1978
1979     for (i = 0; i < elements; ++i) {
1980         D3DXVec3Unproject(
1981             (D3DXVECTOR3*)((char*)out + outstride * i),
1982             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
1983             viewport, projection, view, world);
1984     }
1985     return out;
1986 }
1987
1988 /*_________________D3DXVec4_____________________*/
1989
1990 D3DXVECTOR4* WINAPI D3DXVec4BaryCentric(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3, FLOAT f, FLOAT g)
1991 {
1992     TRACE("(%p, %p, %p, %p, %f, %f)\n", pout, pv1, pv2, pv3, f, g);
1993
1994     pout->x = (1.0f-f-g) * (pv1->x) + f * (pv2->x) + g * (pv3->x);
1995     pout->y = (1.0f-f-g) * (pv1->y) + f * (pv2->y) + g * (pv3->y);
1996     pout->z = (1.0f-f-g) * (pv1->z) + f * (pv2->z) + g * (pv3->z);
1997     pout->w = (1.0f-f-g) * (pv1->w) + f * (pv2->w) + g * (pv3->w);
1998     return pout;
1999 }
2000
2001 D3DXVECTOR4* WINAPI D3DXVec4CatmullRom(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv0, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3, FLOAT s)
2002 {
2003     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pv0, pv1, pv2, pv3, s);
2004
2005     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);
2006     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);
2007     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);
2008     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);
2009     return pout;
2010 }
2011
2012 D3DXVECTOR4* WINAPI D3DXVec4Cross(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pv3)
2013 {
2014     D3DXVECTOR4 out;
2015
2016     TRACE("(%p, %p, %p, %p)\n", pout, pv1, pv2, pv3);
2017
2018     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);
2019     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));
2020     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);
2021     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));
2022     *pout = out;
2023     return pout;
2024 }
2025
2026 D3DXVECTOR4* WINAPI D3DXVec4Hermite(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv1, CONST D3DXVECTOR4 *pt1, CONST D3DXVECTOR4 *pv2, CONST D3DXVECTOR4 *pt2, FLOAT s)
2027 {
2028     FLOAT h1, h2, h3, h4;
2029
2030     TRACE("(%p, %p, %p, %p, %p, %f)\n", pout, pv1, pt1, pv2, pt2, s);
2031
2032     h1 = 2.0f * s * s * s - 3.0f * s * s + 1.0f;
2033     h2 = s * s * s - 2.0f * s * s + s;
2034     h3 = -2.0f * s * s * s + 3.0f * s * s;
2035     h4 = s * s * s - s * s;
2036
2037     pout->x = h1 * (pv1->x) + h2 * (pt1->x) + h3 * (pv2->x) + h4 * (pt2->x);
2038     pout->y = h1 * (pv1->y) + h2 * (pt1->y) + h3 * (pv2->y) + h4 * (pt2->y);
2039     pout->z = h1 * (pv1->z) + h2 * (pt1->z) + h3 * (pv2->z) + h4 * (pt2->z);
2040     pout->w = h1 * (pv1->w) + h2 * (pt1->w) + h3 * (pv2->w) + h4 * (pt2->w);
2041     return pout;
2042 }
2043
2044 D3DXVECTOR4* WINAPI D3DXVec4Normalize(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv)
2045 {
2046     FLOAT norm;
2047
2048     TRACE("(%p, %p)\n", pout, pv);
2049
2050     norm = D3DXVec4Length(pv);
2051
2052     pout->x = pv->x / norm;
2053     pout->y = pv->y / norm;
2054     pout->z = pv->z / norm;
2055     pout->w = pv->w / norm;
2056
2057     return pout;
2058 }
2059
2060 D3DXVECTOR4* WINAPI D3DXVec4Transform(D3DXVECTOR4 *pout, CONST D3DXVECTOR4 *pv, CONST D3DXMATRIX *pm)
2061 {
2062     D3DXVECTOR4 out;
2063
2064     TRACE("(%p, %p, %p)\n", pout, pv, pm);
2065
2066     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;
2067     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;
2068     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;
2069     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;
2070     *pout = out;
2071     return pout;
2072 }
2073
2074 D3DXVECTOR4* WINAPI D3DXVec4TransformArray(D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR4* in, UINT instride, CONST D3DXMATRIX* matrix, UINT elements)
2075 {
2076     UINT i;
2077
2078     TRACE("(%p, %u, %p, %u, %p, %u)\n", out, outstride, in, instride, matrix, elements);
2079
2080     for (i = 0; i < elements; ++i) {
2081         D3DXVec4Transform(
2082             (D3DXVECTOR4*)((char*)out + outstride * i),
2083             (CONST D3DXVECTOR4*)((const char*)in + instride * i),
2084             matrix);
2085     }
2086     return out;
2087 }
2088
2089 static inline unsigned short float_32_to_16(const float in)
2090 {
2091     int exp = 0, origexp;
2092     float tmp = fabs(in);
2093     int sign = (copysignf(1, in) < 0);
2094     unsigned int mantissa;
2095     unsigned short ret;
2096
2097     /* Deal with special numbers */
2098     if (isinf(in)) return (sign ? 0xffff : 0x7fff);
2099     if (isnan(in)) return (sign ? 0xffff : 0x7fff);
2100     if (in == 0.0f) return (sign ? 0x8000 : 0x0000);
2101
2102     if (tmp < powf(2, 10))
2103     {
2104         do
2105         {
2106             tmp *= 2.0f;
2107             exp--;
2108         } while (tmp < powf(2, 10));
2109     }
2110     else if (tmp >= powf(2, 11))
2111     {
2112         do
2113         {
2114             tmp /= 2.0f;
2115             exp++;
2116         } while (tmp >= powf(2, 11));
2117     }
2118
2119     exp += 10;  /* Normalize the mantissa */
2120     exp += 15;  /* Exponent is encoded with excess 15 */
2121
2122     origexp = exp;
2123
2124     mantissa = (unsigned int) tmp;
2125     if ((tmp - mantissa == 0.5f && mantissa % 2 == 1) || /* round half to even */
2126         (tmp - mantissa > 0.5f))
2127     {
2128         mantissa++; /* round to nearest, away from zero */
2129     }
2130     if (mantissa == 2048)
2131     {
2132         mantissa = 1024;
2133         exp++;
2134     }
2135
2136     if (exp > 31)
2137     {
2138         /* too big */
2139         ret = 0x7fff; /* INF */
2140     }
2141     else if (exp <= 0)
2142     {
2143         unsigned int rounding = 0;
2144
2145         /* Denormalized half float */
2146
2147         /* return 0x0000 (=0.0) for numbers too small to represent in half floats */
2148         if (exp < -11)
2149             return (sign ? 0x8000 : 0x0000);
2150
2151         exp = origexp;
2152
2153         /* the 13 extra bits from single precision are used for rounding */
2154         mantissa = (unsigned int)(tmp * powf(2, 13));
2155         mantissa >>= 1 - exp; /* denormalize */
2156
2157         mantissa -= ~(mantissa >> 13) & 1; /* round half to even */
2158         /* remove 13 least significant bits to get half float precision */
2159         mantissa >>= 12;
2160         rounding = mantissa & 1;
2161         mantissa >>= 1;
2162
2163         ret = mantissa + rounding;
2164     }
2165     else
2166     {
2167         ret = (exp << 10) | (mantissa & 0x3ff);
2168     }
2169
2170     ret |= ((sign ? 1 : 0) << 15); /* Add the sign */
2171     return ret;
2172 }
2173
2174 D3DXFLOAT16 *WINAPI D3DXFloat32To16Array(D3DXFLOAT16 *pout, CONST FLOAT *pin, UINT n)
2175 {
2176     unsigned int i;
2177
2178     TRACE("(%p, %p, %u)\n", pout, pin, n);
2179
2180     for (i = 0; i < n; ++i)
2181     {
2182         pout[i].value = float_32_to_16(pin[i]);
2183     }
2184
2185     return pout;
2186 }
2187
2188 /* Native d3dx9's D3DXFloat16to32Array lacks support for NaN and Inf. Specifically, e = 16 is treated as a
2189  * regular number - e.g., 0x7fff is converted to 131008.0 and 0xffff to -131008.0. */
2190 static inline float float_16_to_32(const unsigned short in)
2191 {
2192     const unsigned short s = (in & 0x8000);
2193     const unsigned short e = (in & 0x7C00) >> 10;
2194     const unsigned short m = in & 0x3FF;
2195     const float sgn = (s ? -1.0f : 1.0f);
2196
2197     if (e == 0)
2198     {
2199         if (m == 0) return sgn * 0.0f; /* +0.0 or -0.0 */
2200         else return sgn * powf(2, -14.0f) * (m / 1024.0f);
2201     }
2202     else
2203     {
2204         return sgn * powf(2, e - 15.0f) * (1.0f + (m / 1024.0f));
2205     }
2206 }
2207
2208 FLOAT *WINAPI D3DXFloat16To32Array(FLOAT *pout, CONST D3DXFLOAT16 *pin, UINT n)
2209 {
2210     unsigned int i;
2211
2212     TRACE("(%p, %p, %u)\n", pout, pin, n);
2213
2214     for (i = 0; i < n; ++i)
2215     {
2216         pout[i] = float_16_to_32(pin[i].value);
2217     }
2218
2219     return pout;
2220 }
2221
2222 /*_________________D3DXSH________________*/
2223
2224 FLOAT* WINAPI D3DXSHAdd(FLOAT *out, UINT order, const FLOAT *a, const FLOAT *b)
2225 {
2226     UINT i;
2227
2228     TRACE("out %p, order %u, a %p, b %p\n", out, order, a, b);
2229
2230     for (i = 0; i < order * order; i++)
2231         out[i] = a[i] + b[i];
2232
2233     return out;
2234 }
2235
2236 FLOAT WINAPI D3DXSHDot(UINT order, CONST FLOAT *a, CONST FLOAT *b)
2237 {
2238     FLOAT s;
2239     UINT i;
2240
2241     TRACE("order %u, a %p, b %p\n", order, a, b);
2242
2243     s = a[0] * b[0];
2244     for (i = 1; i < order * order; i++)
2245         s += a[i] * b[i];
2246
2247     return s;
2248 }
2249
2250 FLOAT* WINAPI D3DXSHEvalDirection(FLOAT *out, UINT order, CONST D3DXVECTOR3 *dir)
2251 {
2252
2253     TRACE("(%p, %u, %p)\n", out, order, dir);
2254
2255     if ( (order < D3DXSH_MINORDER) || (order > D3DXSH_MAXORDER) )
2256         return out;
2257
2258     out[0] = 0.5f / sqrt(D3DX_PI);
2259     out[1] = -0.5f / sqrt(D3DX_PI / 3.0f) * dir->y;
2260     out[2] = 0.5f / sqrt(D3DX_PI / 3.0f) * dir->z;
2261     out[3] = -0.5f / sqrt(D3DX_PI / 3.0f) * dir->x;
2262     if ( order == 2 )
2263         return out;
2264
2265     out[4] = 0.5f / sqrt(D3DX_PI / 15.0f) * dir->x * dir->y;
2266     out[5] = -0.5f / sqrt(D3DX_PI / 15.0f) * dir->y * dir->z;
2267     out[6] = 0.25f / sqrt(D3DX_PI / 5.0f) * ( 3.0f * dir->z * dir->z - 1.0f );
2268     out[7] = -0.5f / sqrt(D3DX_PI / 15.0f) * dir->x * dir->z;
2269     out[8] = 0.25f / sqrt(D3DX_PI / 15.0f) * ( dir->x * dir->x - dir->y * dir->y );
2270     if ( order == 3 )
2271         return out;
2272
2273     out[9] = -sqrt(70.0f / D3DX_PI) / 8.0f * dir->y * (3.0f * dir->x * dir->x - dir->y * dir->y );
2274     out[10] = sqrt(105.0f / D3DX_PI) / 2.0f * dir->x * dir->y * dir->z;
2275     out[11] = -sqrt(42.0 / D3DX_PI) / 8.0f * dir->y * ( -1.0f + 5.0f * dir->z * dir->z );
2276     out[12] = sqrt(7.0f / D3DX_PI) / 4.0f * dir->z * ( 5.0f * dir->z * dir->z - 3.0f );
2277     out[13] = sqrt(42.0 / D3DX_PI) / 8.0f * dir->x * ( 1.0f - 5.0f * dir->z * dir->z );
2278     out[14] = sqrt(105.0f / D3DX_PI) / 4.0f * dir->z * ( dir->x * dir->x - dir->y * dir->y );
2279     out[15] = -sqrt(70.0f / D3DX_PI) / 8.0f * dir->x * ( dir->x * dir->x - 3.0f * dir->y * dir->y );
2280     if ( order == 4 )
2281         return out;
2282
2283     out[16] = 0.75f * sqrt(35.0f / D3DX_PI) * dir->x * dir->y * (dir->x * dir->x - dir->y * dir->y );
2284     out[17] = 3.0f * dir->z * out[9];
2285     out[18] = 0.75f * sqrt(5.0f / D3DX_PI) * dir->x * dir->y * ( 7.0f * dir->z * dir->z - 1.0f );
2286     out[19] = 0.375f * sqrt(10.0f / D3DX_PI) * dir->y * dir->z * ( 3.0f - 7.0f * dir->z * dir->z );
2287     out[20] = 3.0f / ( 16.0f * sqrt(D3DX_PI) ) * ( 35.0f * dir->z * dir->z * dir->z * dir->z - 30.f * dir->z * dir->z + 3.0f );
2288     out[21] = 0.375f * sqrt(10.0f / D3DX_PI) * dir->x * dir->z * ( 3.0f - 7.0f * dir->z * dir->z );
2289     out[22] = 0.375f * sqrt(5.0f / D3DX_PI) * ( dir->x * dir->x - dir->y * dir->y ) * ( 7.0f * dir->z * dir->z - 1.0f);
2290     out[23] = 3.0 * dir->z * out[15];
2291     out[24] = 3.0f / 16.0f * sqrt(35.0f / D3DX_PI) * ( dir->x * dir->x * dir->x * dir->x- 6.0f * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y );
2292     if ( order == 5 )
2293         return out;
2294
2295     out[25] = -3.0f/ 32.0f * sqrt(154.0f / D3DX_PI) * dir->y * ( 5.0f * dir->x * dir->x * dir->x * dir->x - 10.0f * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y );
2296     out[26] = 0.75f * sqrt(385.0f / D3DX_PI) * dir->x * dir->y * dir->z * ( dir->x * dir->x - dir->y * dir->y );
2297     out[27] = sqrt(770.0f / D3DX_PI) / 32.0f * dir->y * ( 3.0f * dir->x * dir->x - dir->y * dir->y ) * ( 1.0f - 9.0f * dir->z * dir->z );
2298     out[28] = sqrt(1155.0f / D3DX_PI) / 4.0f * dir->x * dir->y * dir->z * ( 3.0f * dir->z * dir->z - 1.0f);
2299     out[29] = sqrt(165.0f / D3DX_PI) / 16.0f * dir->y * ( 14.0f * dir->z * dir->z - 21.0f * dir->z * dir->z * dir->z * dir->z - 1.0f );
2300     out[30] = sqrt(11.0f / D3DX_PI) / 16.0f * dir->z * ( 63.0f * dir->z * dir->z * dir->z * dir->z - 70.0f * dir->z * dir->z + 15.0f );
2301     out[31] = sqrt(165.0f / D3DX_PI) / 16.0f * dir->x * ( 14.0f * dir->z * dir->z - 21.0f * dir->z * dir->z * dir->z * dir->z - 1.0f );
2302     out[32] = sqrt(1155.0f / D3DX_PI) / 8.0f * dir->z * ( dir->x * dir->x - dir->y * dir->y ) * ( 3.0f * dir->z * dir->z - 1.0f );
2303     out[33] = sqrt(770.0f / D3DX_PI) / 32.0f * dir->x * ( dir->x * dir->x - 3.0f * dir->y * dir->y ) * ( 1.0f - 9.0f * dir->z * dir->z );
2304     out[34] = 3.0f / 16.0f * sqrt(385.0f / D3DX_PI) * dir->z * ( dir->x * dir->x * dir->x * dir->x - 6.0 * dir->x * dir->x * dir->y * dir->y + dir->y * dir->y * dir->y * dir->y );
2305     out[35] = -3.0f/ 32.0f * sqrt(154.0f / D3DX_PI) * dir->x * ( dir->x * dir->x * dir->x * dir->x - 10.0f * dir->x * dir->x * dir->y * dir->y + 5.0f * dir->y * dir->y * dir->y * dir->y );
2306
2307     return out;
2308 }
2309
2310 HRESULT WINAPI D3DXSHEvalDirectionalLight(UINT order, CONST D3DXVECTOR3 *dir, FLOAT Rintensity, FLOAT Gintensity, FLOAT Bintensity, FLOAT *Rout, FLOAT *Gout, FLOAT *Bout)
2311 {
2312     FLOAT s, temp;
2313     UINT j;
2314
2315     TRACE("Order %u, Vector %p, Red %f, Green %f, Blue %f, Rout %p, Gout %p, Bout %p\n", order, dir, Rintensity, Gintensity, Bintensity, Rout, Gout, Bout);
2316
2317     s = 0.75f;
2318     if ( order > 2 )
2319         s += 5.0f / 16.0f;
2320     if ( order > 4 )
2321         s -= 3.0f / 32.0f;
2322     s /= D3DX_PI;
2323
2324     D3DXSHEvalDirection(Rout, order, dir);
2325     for (j = 0; j < order * order; j++)
2326     {
2327         temp = Rout[j] / s;
2328
2329         Rout[j] = Rintensity * temp;
2330         if ( Gout )
2331             Gout[j] = Gintensity * temp;
2332         if ( Bout )
2333             Bout[j] = Bintensity * temp;
2334     }
2335
2336     return D3D_OK;
2337 }
2338
2339 FLOAT * WINAPI D3DXSHMultiply2(FLOAT *out, const FLOAT *a, const FLOAT *b)
2340 {
2341     FLOAT ta, tb;
2342
2343     TRACE("out %p, a %p, b %p\n", out, a, b);
2344
2345     ta = 0.28209479f * a[0];
2346     tb = 0.28209479f * b[0];
2347
2348     out[0] = 0.28209479f * D3DXSHDot(2, a, b);
2349     out[1] = ta * b[1] + tb * a[1];
2350     out[2] = ta * b[2] + tb * a[2];
2351     out[3] = ta * b[3] + tb * a[3];
2352
2353     return out;
2354 }
2355
2356 FLOAT * WINAPI D3DXSHMultiply3(FLOAT *out, const FLOAT *a, const FLOAT *b)
2357 {
2358     FLOAT t, ta, tb;
2359
2360     TRACE("out %p, a %p, b %p\n", out, a, b);
2361
2362     out[0] = 0.28209479f * a[0] * b[0];
2363
2364     ta = 0.28209479f * a[0] - 0.12615662f * a[6] - 0.21850968f * a[8];
2365     tb = 0.28209479f * b[0] - 0.12615662f * b[6] - 0.21850968f * b[8];
2366     out[1] = ta * b[1] + tb * a[1];
2367     t = a[1] * b[1];
2368     out[0] += 0.28209479f * t;
2369     out[6] = -0.12615662f * t;
2370     out[8] = -0.21850968f * t;
2371
2372     ta = 0.21850968f * a[5];
2373     tb = 0.21850968f * b[5];
2374     out[1] += ta * b[2] + tb * a[2];
2375     out[2] = ta * b[1] + tb * a[1];
2376     t = a[1] * b[2] +a[2] * b[1];
2377     out[5] = 0.21850968f * t;
2378
2379     ta = 0.21850968f * a[4];
2380     tb = 0.21850968f * b[4];
2381     out[1] += ta * b[3] + tb * a[3];
2382     out[3]  = ta * b[1] + tb * a[1];
2383     t = a[1] * b[3] + a[3] * b[1];
2384     out[4] = 0.21850968f * t;
2385
2386     ta = 0.28209480f * a[0] + 0.25231326f * a[6];
2387     tb = 0.28209480f * b[0] + 0.25231326f * b[6];
2388     out[2] += ta * b[2] + tb * a[2];
2389     t = a[2] * b[2];
2390     out[0] += 0.28209480f * t;
2391     out[6] += 0.25231326f * t;
2392
2393     ta = 0.21850969f * a[7];
2394     tb = 0.21850969f * b[7];
2395     out[2] += ta * b[3] + tb * a[3];
2396     out[3] += ta * b[2] + tb * a[2];
2397     t = a[2] * b[3] + a[3] * b[2];
2398     out[7] = 0.21850969f * t;
2399
2400     ta = 0.28209479f * a[0] - 0.12615663f * a[6] + 0.21850969f * a[8];
2401     tb = 0.28209479f * b[0] - 0.12615663f * b[6] + 0.21850969f * b[8];
2402     out[3] += ta * b[3] + tb * a[3];
2403     t = a[3] * b[3];
2404     out[0] += 0.28209479f * t;
2405     out[6] -= 0.12615663f * t;
2406     out[8] += 0.21850969f * t;
2407
2408     ta = 0.28209479f * a[0] - 0.18022375f * a[6];
2409     tb = 0.28209479f * b[0] - 0.18022375f * b[6];
2410     out[4] += ta * b[4] + tb * a[4];
2411     t = a[4] * b[4];
2412     out[0] += 0.28209479f * t;
2413     out[6] -= 0.18022375f * t;
2414
2415     ta = 0.15607835f * a[7];
2416     tb = 0.15607835f * b[7];
2417     out[4] += ta * b[5] + tb * a[5];
2418     out[5] += ta * b[4] + tb * a[4];
2419     t = a[4] * b[5] + a[5] * b[4];
2420     out[7] += 0.15607834f * t;
2421
2422     ta = 0.28209479f * a[0] + 0.09011186 * a[6] - 0.15607835f * a[8];
2423     tb = 0.28209479f * b[0] + 0.09011186 * b[6] - 0.15607835f * b[8];
2424     out[5] += ta * b[5] + tb * a[5];
2425     t = a[5] * b[5];
2426     out[0] += 0.28209479f * t;
2427     out[6] += 0.09011186f * t;
2428     out[8] -= 0.15607835f * t;
2429
2430     ta = 0.28209480f * a[0];
2431     tb = 0.28209480f * b[0];
2432     out[6] += ta * b[6] + tb * a[6];
2433     t = a[6] * b[6];
2434     out[0] += 0.28209480f * t;
2435     out[6] += 0.18022376f * t;
2436
2437     ta = 0.28209479f * a[0] + 0.09011186 * a[6] + 0.15607835f * a[8];
2438     tb = 0.28209479f * b[0] + 0.09011186 * b[6] + 0.15607835f * b[8];
2439     out[7] += ta * b[7] + tb * a[7];
2440     t = a[7] * b[7];
2441     out[0] += 0.28209479f * t;
2442     out[6] += 0.09011186f * t;
2443     out[8] += 0.15607835f * t;
2444
2445     ta = 0.28209479f * a[0] - 0.18022375f * a[6];
2446     tb = 0.28209479f * b[0] - 0.18022375f * b[6];
2447     out[8] += ta * b[8] + tb * a[8];
2448     t = a[8] * b[8];
2449     out[0] += 0.28209479f * t;
2450     out[6] -= 0.18022375f * t;
2451
2452     return out;
2453 }
2454
2455 FLOAT * WINAPI D3DXSHMultiply4(FLOAT *out, CONST FLOAT *a, CONST FLOAT *b)
2456 {
2457     FLOAT ta, tb, t;
2458
2459     TRACE("out %p, a %p, b %p\n", out, a, b);
2460
2461     out[0] = 0.28209479f * a[0] * b[0];
2462
2463     ta = 0.28209479f * a[0] - 0.12615663f * a[6] - 0.21850969f * a[8];
2464     tb = 0.28209479f * b[0] - 0.12615663f * b[6] - 0.21850969f * b[8];
2465     out[1] = ta * b[1] + tb * a[1];
2466     t = a[1] * b[1];
2467     out[0] += 0.28209479f * t;
2468     out[6] = -0.12615663f * t;
2469     out[8] = -0.21850969f * t;
2470
2471     ta = 0.21850969f * a[3] - 0.05839917f * a[13] - 0.22617901f * a[15];
2472     tb = 0.21850969f * b[3] - 0.05839917f * b[13] - 0.22617901f * b[15];
2473     out[1] += ta * b[4] + tb * a[4];
2474     out[4] = ta * b[1] + tb * a[1];
2475     t = a[1] * b[4] + a[4] * b[1];
2476     out[3] = 0.21850969f * t;
2477     out[13] = -0.05839917f * t;
2478     out[15] = -0.22617901f * t;
2479
2480     ta = 0.21850969f * a[2] - 0.14304817f * a[12] - 0.18467439f * a[14];
2481     tb = 0.21850969f * b[2] - 0.14304817f * b[12] - 0.18467439f * b[14];
2482     out[1] += ta * b[5] + tb * a[5];
2483     out[5] = ta * b[1] + tb * a[1];
2484     t = a[1] * b[5] + a[5] * b[1];
2485     out[2] = 0.21850969f * t;
2486     out[12] = -0.14304817f * t;
2487     out[14] = -0.18467439f * t;
2488
2489     ta = 0.20230066f * a[11];
2490     tb = 0.20230066f * b[11];
2491     out[1] += ta * b[6] + tb * a[6];
2492     out[6] += ta * b[1] + tb * a[1];
2493     t = a[1] * b[6] + a[6] * b[1];
2494     out[11] = 0.20230066f * t;
2495
2496     ta = 0.22617901f * a[9] + 0.05839917f * a[11];
2497     tb = 0.22617901f * b[9] + 0.05839917f * b[11];
2498     out[1] += ta * b[8] + tb * a[8];
2499     out[8] += ta * b[1] + tb * a[1];
2500     t = a[1] * b[8] + a[8] * b[1];
2501     out[9] = 0.22617901f * t;
2502     out[11] += 0.05839917f * t;
2503
2504     ta = 0.28209480f * a[0] + 0.25231326f * a[6];
2505     tb = 0.28209480f * b[0] + 0.25231326f * b[6];
2506     out[2] += ta * b[2] + tb * a[2];
2507     t = a[2] * b[2];
2508     out[0] += 0.28209480f * t;
2509     out[6] += 0.25231326f * t;
2510
2511     ta = 0.24776671f * a[12];
2512     tb = 0.24776671f * b[12];
2513     out[2] += ta * b[6] + tb * a[6];
2514     out[6] += ta * b[2] + tb * a[2];
2515     t = a[2] * b[6] + a[6] * b[2];
2516     out[12] += 0.24776671f * t;
2517
2518     ta = 0.28209480f * a[0] - 0.12615663f * a[6] + 0.21850969f * a[8];
2519     tb = 0.28209480f * b[0] - 0.12615663f * b[6] + 0.21850969f * b[8];
2520     out[3] += ta * b[3] + tb * a[3];
2521     t = a[3] * b[3];
2522     out[0] += 0.28209480f * t;
2523     out[6] -= 0.12615663f * t;
2524     out[8] += 0.21850969f * t;
2525
2526     ta = 0.20230066f * a[13];
2527     tb = 0.20230066f * b[13];
2528     out[3] += ta * b[6] + tb * a[6];
2529     out[6] += ta * b[3] + tb * a[3];
2530     t = a[3] * b[6] + a[6] * b[3];
2531     out[13] += 0.20230066f * t;
2532
2533     ta = 0.21850969f * a[2] - 0.14304817f * a[12] + 0.18467439f * a[14];
2534     tb = 0.21850969f * b[2] - 0.14304817f * b[12] + 0.18467439f * b[14];
2535     out[3] += ta * b[7] + tb * a[7];
2536     out[7] = ta * b[3] + tb * a[3];
2537     t = a[3] * b[7] + a[7] * b[3];
2538     out[2] += 0.21850969f * t;
2539     out[12] -= 0.14304817f * t;
2540     out[14] += 0.18467439f * t;
2541
2542     ta = -0.05839917f * a[13] + 0.22617901f * a[15];
2543     tb = -0.05839917f * b[13] + 0.22617901f * b[15];
2544     out[3] += ta * b[8] + tb * a[8];
2545     out[8] += ta * b[3] + tb * a[3];
2546     t = a[3] * b[8] + a[8] * b[3];
2547     out[13] -= 0.05839917f * t;
2548     out[15] += 0.22617901f * t;
2549
2550     ta = 0.28209479f * a[0] - 0.18022375f * a[6];
2551     tb = 0.28209479f * b[0] - 0.18022375f * b[6];
2552     out[4] += ta * b[4] + tb * a[4];
2553     t = a[4] * b[4];
2554     out[0] += 0.28209479f * t;
2555     out[6] -= 0.18022375f * t;
2556
2557     ta = 0.15607835f * a[7];
2558     tb = 0.15607835f * b[7];
2559     out[4] += ta * b[5] + tb * a[5];
2560     out[5] += ta * b[4] + tb * a[4];
2561     t = a[4] * b[5] + a[5] * b[4];
2562     out[7] += 0.15607835f * t;
2563
2564     ta = 0.22617901f * a[3] - 0.09403160f * a[13];
2565     tb = 0.22617901f * b[3] - 0.09403160f * b[13];
2566     out[4] += ta * b[9] + tb * a[9];
2567     out[9] += ta * b[4] + tb * a[4];
2568     t = a[4] * b[9] + a[9] * b[4];
2569     out[3] += 0.22617901f * t;
2570     out[13] -= 0.09403160f * t;
2571
2572     ta = 0.18467439f * a[2] - 0.18806319f * a[12];
2573     tb = 0.18467439f * b[2] - 0.18806319f * b[12];
2574     out[4] += ta * b[10] + tb * a [10];
2575     out[10] = ta * b[4] + tb * a[4];
2576     t = a[4] * b[10] + a[10] * b[4];
2577     out[2] += 0.18467439f * t;
2578     out[12] -= 0.18806319f * t;
2579
2580     ta = -0.05839917f * a[3] + 0.14567312f * a[13] + 0.09403160f * a[15];
2581     tb = -0.05839917f * b[3] + 0.14567312f * b[13] + 0.09403160f * b[15];
2582     out[4] += ta * b[11] + tb * a[11];
2583     out[11] += ta * b[4] + tb * a[4];
2584     t = a[4] * b[11] + a[11] * b[4];
2585     out[3] -= 0.05839917f * t;
2586     out[13] += 0.14567312f * t;
2587     out[15] += 0.09403160f * t;
2588
2589     ta = 0.28209479f * a[0] + 0.09011186f * a[6] - 0.15607835f * a[8];
2590     tb = 0.28209479f * b[0] + 0.09011186f * b[6] - 0.15607835f * b[8];
2591     out[5] += ta * b[5] + tb * a[5];
2592     t = a[5] * b[5];
2593     out[0] += 0.28209479f * t;
2594     out[6] += 0.09011186f * t;
2595     out[8] -= 0.15607835f * t;
2596
2597     ta = 0.14867701f * a[14];
2598     tb = 0.14867701f * b[14];
2599     out[5] += ta * b[9] + tb * a[9];
2600     out[9] += ta * b[5] + tb * a[5];
2601     t = a[5] * b[9] + a[9] * b[5];
2602     out[14] += 0.14867701f * t;
2603
2604     ta = 0.18467439f * a[3] + 0.11516472f * a[13] - 0.14867701f * a[15];
2605     tb = 0.18467439f * b[3] + 0.11516472f * b[13] - 0.14867701f * b[15];
2606     out[5] += ta * b[10] + tb * a[10];
2607     out[10] += ta * b[5] + tb * a[5];
2608     t = a[5] * b[10] + a[10] * b[5];
2609     out[3] += 0.18467439f * t;
2610     out[13] += 0.11516472f * t;
2611     out[15] -= 0.14867701f * t;
2612
2613     ta = 0.23359668f * a[2] + 0.05947080f * a[12] - 0.11516472f * a[14];
2614     tb = 0.23359668f * b[2] + 0.05947080f * b[12] - 0.11516472f * b[14];
2615     out[5] += ta * b[11] + tb * a[11];
2616     out[11] += ta * b[5] + tb * a[5];
2617     t = a[5] * b[11] + a[11] * b[5];
2618     out[2] += 0.23359668f * t;
2619     out[12] += 0.05947080f * t;
2620     out[14] -= 0.11516472f * t;
2621
2622     ta = 0.28209479f * a[0];
2623     tb = 0.28209479f * b[0];
2624     out[6] += ta * b[6] + tb * a[6];
2625     t = a[6] * b[6];
2626     out[0] += 0.28209479f * t;
2627     out[6] += 0.18022376f * t;
2628
2629     ta = 0.09011186f * a[6] + 0.28209479f * a[0] + 0.15607835f * a[8];
2630     tb = 0.09011186f * b[6] + 0.28209479f * b[0] + 0.15607835f * b[8];
2631     out[7] += ta * b[7] + tb * a[7];
2632     t = a[7] * b[7];
2633     out[6] += 0.09011186f * t;
2634     out[0] += 0.28209479f * t;
2635     out[8] += 0.15607835f * t;
2636
2637     ta = 0.14867701f * a[9] + 0.18467439f * a[1] + 0.11516472f * a[11];
2638     tb = 0.14867701f * b[9] + 0.18467439f * b[1] + 0.11516472f * b[11];
2639     out[7] += ta * b[10] + tb * a[10];
2640     out[10] += ta * b[7] + tb * a[7];
2641     t = a[7] * b[10] + a[10] * b[7];
2642     out[9] += 0.14867701f * t;
2643     out[1] += 0.18467439f * t;
2644     out[11] += 0.11516472f * t;
2645
2646     ta = 0.05947080f * a[12] + 0.23359668f * a[2] + 0.11516472f * a[14];
2647     tb = 0.05947080f * b[12] + 0.23359668f * b[2] + 0.11516472f * b[14];
2648     out[7] += ta * b[13] + tb * a[13];
2649     out[13] += ta * b[7]+ tb * a[7];
2650     t = a[7] * b[13] + a[13] * b[7];
2651     out[12] += 0.05947080f * t;
2652     out[2] += 0.23359668f * t;
2653     out[14] += 0.11516472f * t;
2654
2655     ta = 0.14867701f * a[15];
2656     tb = 0.14867701f * b[15];
2657     out[7] += ta * b[14] + tb * a[14];
2658     out[14] += ta * b[7] + tb * a[7];
2659     t = a[7] * b[14] + a[14] * b[7];
2660     out[15] += 0.14867701f * t;
2661
2662     ta = 0.28209479f * a[0] - 0.18022375f * a[6];
2663     tb = 0.28209479f * b[0] - 0.18022375f * b[6];
2664     out[8] += ta * b[8] + tb * a[8];
2665     t = a[8] * b[8];
2666     out[0] += 0.28209479f * t;
2667     out[6] -= 0.18022375f * t;
2668
2669     ta = -0.09403160f * a[11];
2670     tb = -0.09403160f * b[11];
2671     out[8] += ta * b[9] + tb * a[9];
2672     out[9] += ta * b[8] + tb * a[8];
2673     t = a[8] * b[9] + a[9] * b[8];
2674     out[11] -= 0.09403160f * t;
2675
2676     ta = -0.09403160f * a[15];
2677     tb = -0.09403160f * b[15];
2678     out[8] += ta * b[13] + tb * a[13];
2679     out[13] += ta * b[8] + tb * a[8];
2680     t = a[8] * b[13] + a[13] * b[8];
2681     out[15] -= 0.09403160f * t;
2682
2683     ta = 0.18467439f * a[2] - 0.18806319f * a[12];
2684     tb = 0.18467439f * b[2] - 0.18806319f * b[12];
2685     out[8] += ta * b[14] + tb * a[14];
2686     out[14] += ta * b[8] + tb * a[8];
2687     t = a[8] * b[14] + a[14] * b[8];
2688     out[2] += 0.18467439f * t;
2689     out[12] -= 0.18806319f * t;
2690
2691     ta = -0.21026104f * a[6] + 0.28209479f * a[0];
2692     tb = -0.21026104f * b[6] + 0.28209479f * b[0];
2693     out[9] += ta * b[9] + tb * a[9];
2694     t = a[9] * b[9];
2695     out[6] -= 0.21026104f * t;
2696     out[0] += 0.28209479f * t;
2697
2698     ta = 0.28209479f * a[0];
2699     tb = 0.28209479f * b[0];
2700     out[10] += ta * b[10] + tb * a[10];
2701     t = a[10] * b[10];
2702     out[0] += 0.28209479f * t;
2703
2704     ta = 0.28209479f * a[0] + 0.12615663f * a[6] - 0.14567312f * a[8];
2705     tb = 0.28209479f * b[0] + 0.12615663f * b[6] - 0.14567312f * b[8];
2706     out[11] += ta * b[11] + tb * a[11];
2707     t = a[11] * b[11];
2708     out[0] += 0.28209479f * t;
2709     out[6] += 0.12615663f * t;
2710     out[8] -= 0.14567312f * t;
2711
2712     ta = 0.28209479f * a[0] + 0.16820885f * a[6];
2713     tb = 0.28209479f * b[0] + 0.16820885f * b[6];
2714     out[12] += ta * b[12] + tb * a[12];
2715     t = a[12] * b[12];
2716     out[0] += 0.28209479f * t;
2717     out[6] += 0.16820885f * t;
2718
2719     ta =0.28209479f * a[0] + 0.14567312f * a[8] + 0.12615663f * a[6];
2720     tb =0.28209479f * b[0] + 0.14567312f * b[8] + 0.12615663f * b[6];
2721     out[13] += ta * b[13] + tb * a[13];
2722     t = a[13] * b[13];
2723     out[0] += 0.28209479f * t;
2724     out[8] += 0.14567312f * t;
2725     out[6] += 0.12615663f * t;
2726
2727     ta = 0.28209479f * a[0];
2728     tb = 0.28209479f * b[0];
2729     out[14] += ta * b[14] + tb * a[14];
2730     t = a[14] * b[14];
2731     out[0] += 0.28209479f * t;
2732
2733     ta = 0.28209479f * a[0] - 0.21026104f * a[6];
2734     tb = 0.28209479f * b[0] - 0.21026104f * b[6];
2735     out[15] += ta * b[15] + tb * a[15];
2736     t = a[15] * b[15];
2737     out[0] += 0.28209479f * t;
2738     out[6] -= 0.21026104f * t;
2739
2740     return out;
2741 }
2742
2743 static void rotate_X(FLOAT *out, UINT order, FLOAT a, FLOAT *in)
2744 {
2745     out[0] = in[0];
2746
2747     out[1] = a * in[2];
2748     out[2] = -a * in[1];
2749     out[3] = in[3];
2750
2751     out[4] = a * in[7];
2752     out[5] = -in[5];
2753     out[6] = -0.5f * in[6] - 0.8660253882f * in[8];
2754     out[7] = -a * in[4];
2755     out[8] = -0.8660253882f * in[6] + 0.5f * in[8];
2756     out[9] = -a * 0.7905694842f * in[12] + a * 0.6123724580f * in[14];
2757
2758     out[10] = -in[10];
2759     out[11] = -a * 0.6123724580f * in[12] - a * 0.7905694842f * in[14];
2760     out[12] = a * 0.7905694842f * in[9] + a * 0.6123724580f * in[11];
2761     out[13] = -0.25f * in[13] - 0.9682458639f * in[15];
2762     out[14] = -a * 0.6123724580f * in[9] + a * 0.7905694842f * in[11];
2763     out[15] = -0.9682458639f * in[13] + 0.25f * in[15];
2764     if (order == 4)
2765         return;
2766
2767     out[16] = -a * 0.9354143739f * in[21] + a * 0.3535533845f * in[23];
2768     out[17] = -0.75f * in[17] + 0.6614378095f * in[19];
2769     out[18] = -a * 0.3535533845f * in[21] - a * 0.9354143739f * in[23];
2770     out[19] = 0.6614378095f * in[17] + 0.75f * in[19];
2771     out[20] = 0.375f * in[20] + 0.5590170026f * in[22] + 0.7395099998f * in[24];
2772     out[21] = a * 0.9354143739f * in[16] + a * 0.3535533845f * in[18];
2773     out[22] = 0.5590170026f * in[20] + 0.5f * in[22] - 0.6614378691f * in[24];
2774     out[23] = -a * 0.3535533845f * in[16] + a * 0.9354143739f * in[18];
2775     out[24] = 0.7395099998f * in[20] - 0.6614378691f * in[22] + 0.125f * in[24];
2776     if (order == 5)
2777         return;
2778
2779     out[25] = a * 0.7015607357f * in[30] - a * 0.6846531630f * in[32] + a * 0.1976423711f * in[34];
2780     out[26] = -0.5f * in[26] + 0.8660253882f * in[28];
2781     out[27] = a * 0.5229125023f * in[30] + a * 0.3061861992f * in[32] - a * 0.7954951525 * in[34];
2782     out[28] = 0.8660253882f * in[26] + 0.5f * in[28];
2783     out[29] = a * 0.4841229022f * in[30] + a * 0.6614378691f * in[32] + a * 0.5728219748f * in[34];
2784     out[30] = -a * 0.7015607357f * in[25] - a * 0.5229125023f * in[27] - a * 0.4841229022f * in[29];
2785     out[31] = 0.125f * in[31] + 0.4050463140f * in[33] + 0.9057110548f * in[35];
2786     out[32] = a * 0.6846531630f * in[25] - a * 0.3061861992f * in[27] - a * 0.6614378691f * in[29];
2787     out[33] = 0.4050463140f * in[31] + 0.8125f * in[33] - 0.4192627370f * in[35];
2788     out[34] = -a * 0.1976423711f * in[25] + a * 0.7954951525f * in[27] - a * 0.5728219748f * in[29];
2789     out[35] = 0.9057110548f * in[31] - 0.4192627370f * in[33] + 0.0624999329f * in[35];
2790 }
2791
2792 FLOAT* WINAPI D3DXSHRotate(FLOAT *out, UINT order, CONST D3DXMATRIX *matrix, CONST FLOAT *in)
2793 {
2794     FLOAT alpha, beta, gamma, sinb, temp[36], temp1[36];
2795
2796     TRACE("out %p, order %u, matrix %p, in %p\n", out, order, matrix, in);
2797
2798     out[0] = in[0];
2799
2800     if ((order > D3DXSH_MAXORDER) || (order < D3DXSH_MINORDER))
2801         return out;
2802
2803     if (order <= 3)
2804     {
2805         out[1] = matrix->u.m[1][1] * in[1] - matrix->u.m[2][1] * in[2] + matrix->u.m[0][1] * in[3];
2806         out[2] = -matrix->u.m[1][2] * in[1] + matrix->u.m[2][2] * in[2] - matrix->u.m[0][2] * in[3];
2807         out[3] = matrix->u.m[1][0] * in[1] - matrix->u.m[2][0] * in[2] + matrix->u.m[0][0] * in[3];
2808
2809         if (order == 3)
2810         {
2811             FLOAT coeff[]={
2812                 matrix->u.m[1][0] * matrix->u.m[0][0], matrix->u.m[1][1] * matrix->u.m[0][1],
2813                 matrix->u.m[1][1] * matrix->u.m[2][1], matrix->u.m[1][0] * matrix->u.m[2][0],
2814                 matrix->u.m[2][0] * matrix->u.m[2][0], matrix->u.m[2][1] * matrix->u.m[2][1],
2815                 matrix->u.m[0][0] * matrix->u.m[2][0], matrix->u.m[0][1] * matrix->u.m[2][1],
2816                 matrix->u.m[0][1] * matrix->u.m[0][1], matrix->u.m[1][0] * matrix->u.m[1][0],
2817                 matrix->u.m[1][1] * matrix->u.m[1][1], matrix->u.m[0][0] * matrix->u.m[0][0], };
2818
2819             out[4] = (matrix->u.m[1][1] * matrix->u.m[0][0] + matrix->u.m[0][1] * matrix->u.m[1][0]) * in[4];
2820             out[4] -= (matrix->u.m[1][0] * matrix->u.m[2][1] + matrix->u.m[1][1] * matrix->u.m[2][0]) * in[5];
2821             out[4] += 1.7320508076f * matrix->u.m[2][0] * matrix->u.m[2][1] * in[6];
2822             out[4] -= (matrix->u.m[0][1] * matrix->u.m[2][0] + matrix->u.m[0][0] * matrix->u.m[2][1]) * in[7];
2823             out[4] += (matrix->u.m[0][0] * matrix->u.m[0][1] - matrix->u.m[1][0] * matrix->u.m[1][1]) * in[8];
2824
2825             out[5] = (matrix->u.m[1][1] * matrix->u.m[2][2] + matrix->u.m[1][2] * matrix->u.m[2][1]) * in[5];
2826             out[5] -= (matrix->u.m[1][1] * matrix->u.m[0][2] + matrix->u.m[1][2] * matrix->u.m[0][1]) * in[4];
2827             out[5] -= 1.7320508076f * matrix->u.m[2][2] * matrix->u.m[2][1] * in[6];
2828             out[5] += (matrix->u.m[0][2] * matrix->u.m[2][1] + matrix->u.m[0][1] * matrix->u.m[2][2]) * in[7];
2829             out[5] -= (matrix->u.m[0][1] * matrix->u.m[0][2] - matrix->u.m[1][1] * matrix->u.m[1][2]) * in[8];
2830
2831             out[6] = (matrix->u.m[2][2] * matrix->u.m[2][2] - 0.5f * (coeff[4] + coeff[5])) * in[6];
2832             out[6] -= (0.5773502692f * (coeff[0] + coeff[1]) - 1.1547005384f * matrix->u.m[1][2] * matrix->u.m[0][2]) * in[4];
2833             out[6] += (0.5773502692f * (coeff[2] + coeff[3]) - 1.1547005384f * matrix->u.m[1][2] * matrix->u.m[2][2]) * in[5];
2834             out[6] += (0.5773502692f * (coeff[6] + coeff[7]) - 1.1547005384f * matrix->u.m[0][2] * matrix->u.m[2][2]) * in[7];
2835             out[6] += (0.2886751347f * (coeff[9] - coeff[8] + coeff[10] - coeff[11]) - 0.5773502692f *
2836                   (matrix->u.m[1][2] * matrix->u.m[1][2] - matrix->u.m[0][2] * matrix->u.m[0][2])) * in[8];
2837
2838             out[7] = (matrix->u.m[0][0] * matrix->u.m[2][2] + matrix->u.m[0][2] * matrix->u.m[2][0]) * in[7];
2839             out[7] -= (matrix->u.m[1][0] * matrix->u.m[0][2] + matrix->u.m[1][2] * matrix->u.m[0][0]) * in[4];
2840             out[7] += (matrix->u.m[1][0] * matrix->u.m[2][2] + matrix->u.m[1][2] * matrix->u.m[2][0]) * in[5];
2841             out[7] -= 1.7320508076f * matrix->u.m[2][2] * matrix->u.m[2][0] * in[6];
2842             out[7] -= (matrix->u.m[0][0] * matrix->u.m[0][2] - matrix->u.m[1][0] * matrix->u.m[1][2]) * in[8];
2843
2844             out[8] = 0.5f * (coeff[11] - coeff[8] - coeff[9] + coeff[10]) * in[8];
2845             out[8] += (coeff[0] - coeff[1]) * in[4];
2846             out[8] += (coeff[2] - coeff[3]) * in[5];
2847             out[8] += 0.86602540f * (coeff[4] - coeff[5]) * in[6];
2848             out[8] += (coeff[7] - coeff[6]) * in[7];
2849         }
2850
2851         return out;
2852     }
2853
2854     if (fabsf(matrix->u.m[2][2]) != 1.0f)
2855     {
2856         sinb = sqrtf(1.0f - matrix->u.m[2][2] * matrix->u.m[2][2]);
2857         alpha = atan2f(matrix->u.m[2][1] / sinb, matrix->u.m[2][0] / sinb);
2858         beta = atan2f(sinb, matrix->u.m[2][2]);
2859         gamma = atan2f(matrix->u.m[1][2] / sinb, -matrix->u.m[0][2] / sinb);
2860     }
2861     else
2862     {
2863         alpha = atan2f(matrix->u.m[0][1], matrix->u.m[0][0]);
2864         beta = 0.0f;
2865         gamma = 0.0f;
2866     }
2867
2868     D3DXSHRotateZ(temp, order, gamma, in);
2869     rotate_X(temp1, order, 1.0f, temp);
2870     D3DXSHRotateZ(temp, order, beta, temp1);
2871     rotate_X(temp1, order, -1.0f, temp);
2872     D3DXSHRotateZ(out, order, alpha, temp1);
2873
2874     return out;
2875 }
2876
2877 FLOAT * WINAPI D3DXSHRotateZ(FLOAT *out, UINT order, FLOAT angle, const FLOAT *in)
2878 {
2879     UINT i, sum = 0;
2880     FLOAT c[5], s[5];
2881
2882     TRACE("out %p, order %u, angle %f, in %p\n", out, order, angle, in);
2883
2884     order = min(max(order, D3DXSH_MINORDER), D3DXSH_MAXORDER);
2885
2886     out[0] = in[0];
2887
2888     for (i = 1; i < order; i++)
2889     {
2890         UINT j;
2891
2892         c[i - 1] = cosf(i * angle);
2893         s[i - 1] = sinf(i * angle);
2894         sum += i * 2;
2895
2896         out[sum - i] = c[i - 1] * in[sum - i];
2897         out[sum - i] += s[i - 1] * in[sum + i];
2898         for (j = i - 1; j > 0; j--)
2899         {
2900             out[sum - j] = 0.0f;
2901             out[sum - j] = c[j - 1] * in[sum - j];
2902             out[sum - j] += s[j - 1] * in[sum + j];
2903         }
2904
2905         if (in == out)
2906             out[sum] = 0.0f;
2907         else
2908             out[sum] = in[sum];
2909
2910         for (j = 1; j < i; j++)
2911         {
2912             out[sum + j] = 0.0f;
2913             out[sum + j] = -s[j - 1] * in[sum - j];
2914             out[sum + j] += c[j - 1] * in[sum + j];
2915         }
2916         out[sum + i] = -s[i - 1] * in[sum - i];
2917         out[sum + i] += c[i - 1] * in[sum + i];
2918     }
2919
2920     return out;
2921 }
2922
2923 FLOAT* WINAPI D3DXSHScale(FLOAT *out, UINT order, CONST FLOAT *a, CONST FLOAT scale)
2924 {
2925     UINT i;
2926
2927     TRACE("out %p, order %u, a %p, scale %f\n", out, order, a, scale);
2928
2929     for (i = 0; i < order * order; i++)
2930         out[i] = a[i] * scale;
2931
2932     return out;
2933 }