wined3d: Fix the value of HIGHEST_TRANSFORMSTATE.
[wine] / dlls / d3dx9_36 / math.c
1 /*
2  * Mathematical operations specific to D3DX9.
3  *
4  * Copyright (C) 2008 David Adam
5  * Copyright (C) 2008 Philip Nilsson
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #define NONAMELESSUNION
23
24 #include "config.h"
25 #include "windef.h"
26 #include "wingdi.h"
27 #include "wine/debug.h"
28 #include "d3dx9.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
31
32 /*************************************************************************
33  * D3DXMatrixAffineTransformation2D
34  */
35 D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D(
36     D3DXMATRIX *pout, FLOAT scaling,
37     CONST D3DXVECTOR2 *protationcenter, FLOAT rotation,
38     CONST D3DXVECTOR2 *ptranslation)
39 {
40     D3DXQUATERNION rot;
41     D3DXVECTOR3 rot_center, trans;
42
43     rot.w=cos(rotation/2.0f);
44     rot.x=0.0f;
45     rot.y=0.0f;
46     rot.z=sin(rotation/2.0f);
47
48     if ( protationcenter )
49     {
50         rot_center.x=protationcenter->x;
51         rot_center.y=protationcenter->y;
52         rot_center.z=0.0f;
53     }
54     else
55     {
56         rot_center.x=0.0f;
57         rot_center.y=0.0f;
58         rot_center.z=0.0f;
59     }
60
61     if ( ptranslation )
62     {
63         trans.x=ptranslation->x;
64         trans.y=ptranslation->y;
65         trans.z=0.0f;
66     }
67     else
68     {
69         trans.x=0.0f;
70         trans.y=0.0f;
71         trans.z=0.0f;
72     }
73
74     D3DXMatrixAffineTransformation(pout, scaling, &rot_center, &rot, &trans);
75
76     return pout;
77 }
78
79 /*************************************************************************
80  * D3DXMatrixDecompose
81  */
82 HRESULT WINAPI D3DXMatrixDecompose(D3DXVECTOR3 *poutscale, D3DXQUATERNION *poutrotation, D3DXVECTOR3 *pouttranslation, D3DXMATRIX *pm)
83 {
84     D3DXMATRIX normalized;
85     D3DXVECTOR3 vec;
86
87     if (!pm)
88     {
89      return D3DERR_INVALIDCALL;
90     }
91
92     /*Compute the scaling part.*/
93     vec.x=pm->u.m[0][0];
94     vec.y=pm->u.m[0][1];
95     vec.z=pm->u.m[0][2];
96     poutscale->x=D3DXVec3Length(&vec);
97
98     vec.x=pm->u.m[1][0];
99     vec.y=pm->u.m[1][1];
100     vec.z=pm->u.m[1][2];
101     poutscale->y=D3DXVec3Length(&vec);
102
103     vec.x=pm->u.m[2][0];
104     vec.y=pm->u.m[2][1];
105     vec.z=pm->u.m[2][2];
106     poutscale->z=D3DXVec3Length(&vec);
107
108     /*Compute the translation part.*/
109     pouttranslation->x=pm->u.m[3][0];
110     pouttranslation->y=pm->u.m[3][1];
111     pouttranslation->z=pm->u.m[3][2];
112
113     /*Let's calculate the rotation now*/
114     if ( (poutscale->x == 0.0f) || (poutscale->y == 0.0f) || (poutscale->z == 0.0f) )
115     {
116      return D3DERR_INVALIDCALL;
117     }
118
119     normalized.u.m[0][0]=pm->u.m[0][0]/poutscale->x;
120     normalized.u.m[0][1]=pm->u.m[0][1]/poutscale->x;
121     normalized.u.m[0][2]=pm->u.m[0][2]/poutscale->x;
122     normalized.u.m[1][0]=pm->u.m[1][0]/poutscale->y;
123     normalized.u.m[1][1]=pm->u.m[1][1]/poutscale->y;
124     normalized.u.m[1][2]=pm->u.m[1][2]/poutscale->y;
125     normalized.u.m[2][0]=pm->u.m[2][0]/poutscale->z;
126     normalized.u.m[2][1]=pm->u.m[2][1]/poutscale->z;
127     normalized.u.m[2][2]=pm->u.m[2][2]/poutscale->z;
128
129     D3DXQuaternionRotationMatrix(poutrotation,&normalized);
130     return S_OK;
131 }
132
133 /*************************************************************************
134  * D3DXMatrixTransformation2D
135  */
136 D3DXMATRIX* WINAPI D3DXMatrixTransformation2D(
137     D3DXMATRIX *pout, CONST D3DXVECTOR2 *pscalingcenter,
138     FLOAT scalingrotation, CONST D3DXVECTOR2 *pscaling,
139     CONST D3DXVECTOR2 *protationcenter, FLOAT rotation,
140     CONST D3DXVECTOR2 *ptranslation)
141 {
142     D3DXQUATERNION rot, sca_rot;
143     D3DXVECTOR3 rot_center, sca, sca_center, trans;
144
145     if ( pscalingcenter )
146     {
147         sca_center.x=pscalingcenter->x;
148         sca_center.y=pscalingcenter->y;
149         sca_center.z=0.0f;
150     }
151     else
152     {
153         sca_center.x=0.0f;
154         sca_center.y=0.0f;
155         sca_center.z=0.0f;
156     }
157
158     if ( pscaling )
159     {
160         sca.x=pscaling->x;
161         sca.y=pscaling->y;
162         sca.z=0.0f;
163     }
164     else
165     {
166         sca.x=0.0f;
167         sca.y=0.0f;
168         sca.z=0.0f;
169     }
170
171     if ( protationcenter )
172     {
173         rot_center.x=protationcenter->x;
174         rot_center.y=protationcenter->y;
175         rot_center.z=0.0f;
176     }
177     else
178     {
179         rot_center.x=0.0f;
180         rot_center.y=0.0f;
181         rot_center.z=0.0f;
182     }
183
184     if ( ptranslation )
185     {
186         trans.x=ptranslation->x;
187         trans.y=ptranslation->y;
188         trans.z=0.0f;
189     }
190     else
191     {
192         trans.x=0.0f;
193         trans.y=0.0f;
194         trans.z=0.0f;
195     }
196
197     rot.w=cos(rotation/2.0f);
198     rot.x=0.0f;
199     rot.y=0.0f;
200     rot.z=sin(rotation/2.0f);
201
202     sca_rot.w=cos(scalingrotation/2.0f);
203     sca_rot.x=0.0f;
204     sca_rot.y=0.0f;
205     sca_rot.z=sin(scalingrotation/2.0f);
206
207     D3DXMatrixTransformation(pout, &sca_center, &sca_rot, &sca, &rot_center, &rot, &trans);
208
209     return pout;
210 }
211
212 /*************************************************************************
213  * D3DXPlaneTransformArray
214  */
215 D3DXPLANE* WINAPI D3DXPlaneTransformArray(
216     D3DXPLANE* out, UINT outstride, CONST D3DXPLANE* in, UINT instride,
217     CONST D3DXMATRIX* matrix, UINT elements)
218 {
219     UINT i;
220     TRACE("\n");
221     for (i = 0; i < elements; ++i) {
222         D3DXPlaneTransform(
223             (D3DXPLANE*)((char*)out + outstride * i),
224             (CONST D3DXPLANE*)((const char*)in + instride * i),
225             matrix);
226     }
227     return out;
228 }
229
230 /*************************************************************************
231  * D3DXVec2TransformArray
232  *
233  * Transform an array of vectors by a matrix.
234  */
235 D3DXVECTOR4* WINAPI D3DXVec2TransformArray(
236     D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride,
237     CONST D3DXMATRIX* matrix, UINT elements)
238 {
239     UINT i;
240     TRACE("\n");
241     for (i = 0; i < elements; ++i) {
242         D3DXVec2Transform(
243             (D3DXVECTOR4*)((char*)out + outstride * i),
244             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
245             matrix);
246     }
247     return out;
248 }
249
250 /*************************************************************************
251  * D3DXVec2TransformCoordArray
252  */
253 D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray(
254     D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2* in, UINT instride,
255     CONST D3DXMATRIX* matrix, UINT elements)
256 {
257     UINT i;
258     TRACE("\n");
259     for (i = 0; i < elements; ++i) {
260         D3DXVec2TransformCoord(
261             (D3DXVECTOR2*)((char*)out + outstride * i),
262             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
263             matrix);
264     }
265     return out;
266 }
267
268 /*************************************************************************
269  * D3DXVec2TransformNormalArray
270  */
271 D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray(
272     D3DXVECTOR2* out, UINT outstride, CONST D3DXVECTOR2 *in, UINT instride,
273     CONST D3DXMATRIX *matrix, UINT elements)
274 {
275     UINT i;
276     TRACE("\n");
277     for (i = 0; i < elements; ++i) {
278         D3DXVec2TransformNormal(
279             (D3DXVECTOR2*)((char*)out + outstride * i),
280             (CONST D3DXVECTOR2*)((const char*)in + instride * i),
281             matrix);
282     }
283     return out;
284 }
285
286 /*************************************************************************
287  * D3DXVec3ProjectArray
288  *
289  * Projects an array of vectors to the screen.
290  */
291 D3DXVECTOR3* WINAPI D3DXVec3ProjectArray(
292     D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride,
293     CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection,
294     CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements)
295 {
296     UINT i;
297     TRACE("\n");
298     for (i = 0; i < elements; ++i) {
299         D3DXVec3Project(
300             (D3DXVECTOR3*)((char*)out + outstride * i),
301             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
302             viewport, projection, view, world);
303     }
304     return out;
305 }
306
307 /*************************************************************************
308  * D3DXVec3TransformArray
309  */
310 D3DXVECTOR4* WINAPI D3DXVec3TransformArray(
311     D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride,
312     CONST D3DXMATRIX* matrix, UINT elements)
313 {
314     UINT i;
315     TRACE("\n");
316     for (i = 0; i < elements; ++i) {
317         D3DXVec3Transform(
318             (D3DXVECTOR4*)((char*)out + outstride * i),
319             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
320             matrix);
321     }
322     return out;
323 }
324
325 /*************************************************************************
326  * D3DXVec3TransformCoordArray
327  */
328 D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray(
329     D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride,
330     CONST D3DXMATRIX* matrix, UINT elements)
331 {
332     UINT i;
333     TRACE("\n");
334     for (i = 0; i < elements; ++i) {
335         D3DXVec3TransformCoord(
336             (D3DXVECTOR3*)((char*)out + outstride * i),
337             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
338             matrix);
339     }
340     return out;
341 }
342
343 /*************************************************************************
344  * D3DXVec3TransformNormalArray
345  */
346 D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray(
347     D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride,
348     CONST D3DXMATRIX* matrix, UINT elements)
349 {
350     UINT i;
351     TRACE("\n");
352     for (i = 0; i < elements; ++i) {
353         D3DXVec3TransformNormal(
354             (D3DXVECTOR3*)((char*)out + outstride * i),
355             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
356             matrix);
357     }
358     return out;
359 }
360
361 /*************************************************************************
362  * D3DXVec3UnprojectArray
363  */
364 D3DXVECTOR3* WINAPI D3DXVec3UnprojectArray(
365     D3DXVECTOR3* out, UINT outstride, CONST D3DXVECTOR3* in, UINT instride,
366     CONST D3DVIEWPORT9* viewport, CONST D3DXMATRIX* projection,
367     CONST D3DXMATRIX* view, CONST D3DXMATRIX* world, UINT elements)
368 {
369     UINT i;
370     TRACE("\n");
371     for (i = 0; i < elements; ++i) {
372         D3DXVec3Unproject(
373             (D3DXVECTOR3*)((char*)out + outstride * i),
374             (CONST D3DXVECTOR3*)((const char*)in + instride * i),
375             viewport, projection, view, world);
376     }
377     return out;
378 }
379
380 /*************************************************************************
381  * D3DXVec4TransformArray
382  */
383 D3DXVECTOR4* WINAPI D3DXVec4TransformArray(
384     D3DXVECTOR4* out, UINT outstride, CONST D3DXVECTOR4* in, UINT instride,
385     CONST D3DXMATRIX* matrix, UINT elements)
386 {
387     UINT i;
388     TRACE("\n");
389     for (i = 0; i < elements; ++i) {
390         D3DXVec4Transform(
391             (D3DXVECTOR4*)((char*)out + outstride * i),
392             (CONST D3DXVECTOR4*)((const char*)in + instride * i),
393             matrix);
394     }
395     return out;
396 }