2 * Mathematical operations specific to D3DX9.
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
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.
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.
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
25 #define NONAMELESSUNION
28 #include "wine/port.h"
32 #include "d3dx9_36_private.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(d3dx
);
38 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl
;
40 typedef struct ID3DXMatrixStackImpl
42 ID3DXMatrixStack ID3DXMatrixStack_iface
;
46 unsigned int stack_size
;
48 } ID3DXMatrixStackImpl
;
51 /*_________________D3DXColor____________________*/
53 D3DXCOLOR
* WINAPI
D3DXColorAdjustContrast(D3DXCOLOR
*pout
, CONST D3DXCOLOR
*pc
, FLOAT s
)
55 pout
->r
= 0.5f
+ s
* (pc
->r
- 0.5f
);
56 pout
->g
= 0.5f
+ s
* (pc
->g
- 0.5f
);
57 pout
->b
= 0.5f
+ s
* (pc
->b
- 0.5f
);
62 D3DXCOLOR
* WINAPI
D3DXColorAdjustSaturation(D3DXCOLOR
*pout
, CONST D3DXCOLOR
*pc
, FLOAT s
)
66 grey
= pc
->r
* 0.2125f
+ pc
->g
* 0.7154f
+ pc
->b
* 0.0721f
;
67 pout
->r
= grey
+ s
* (pc
->r
- grey
);
68 pout
->g
= grey
+ s
* (pc
->g
- grey
);
69 pout
->b
= grey
+ s
* (pc
->b
- grey
);
74 /*_________________Misc__________________________*/
76 FLOAT WINAPI
D3DXFresnelTerm(FLOAT costheta
, FLOAT refractionindex
)
78 FLOAT a
, d
, g
, result
;
80 g
= sqrt(refractionindex
* refractionindex
+ costheta
* costheta
- 1.0f
);
83 result
= ( costheta
* a
- 1.0f
) * ( costheta
* a
- 1.0f
) / ( ( costheta
* d
+ 1.0f
) * ( costheta
* d
+ 1.0f
) ) + 1.0f
;
84 result
= result
* 0.5f
* d
* d
/ ( a
* a
);
88 /*_________________D3DXMatrix____________________*/
90 D3DXMATRIX
* WINAPI
D3DXMatrixAffineTransformation(D3DXMATRIX
*pout
, FLOAT scaling
, CONST D3DXVECTOR3
*rotationcenter
, CONST D3DXQUATERNION
*rotation
, CONST D3DXVECTOR3
*translation
)
92 D3DXMATRIX m1
, m2
, m3
, m4
, m5
;
94 D3DXMatrixScaling(&m1
, scaling
, scaling
, scaling
);
96 if ( !rotationcenter
)
98 D3DXMatrixIdentity(&m2
);
99 D3DXMatrixIdentity(&m4
);
103 D3DXMatrixTranslation(&m2
, -rotationcenter
->x
, -rotationcenter
->y
, -rotationcenter
->z
);
104 D3DXMatrixTranslation(&m4
, rotationcenter
->x
, rotationcenter
->y
, rotationcenter
->z
);
107 if ( !rotation
) D3DXMatrixIdentity(&m3
);
108 else D3DXMatrixRotationQuaternion(&m3
, rotation
);
110 if ( !translation
) D3DXMatrixIdentity(&m5
);
111 else D3DXMatrixTranslation(&m5
, translation
->x
, translation
->y
, translation
->z
);
113 D3DXMatrixMultiply(&m1
, &m1
, &m2
);
114 D3DXMatrixMultiply(&m1
, &m1
, &m3
);
115 D3DXMatrixMultiply(&m1
, &m1
, &m4
);
116 D3DXMatrixMultiply(pout
, &m1
, &m5
);
120 D3DXMATRIX
* WINAPI
D3DXMatrixAffineTransformation2D(D3DXMATRIX
*pout
, FLOAT scaling
, CONST D3DXVECTOR2
*protationcenter
, FLOAT rotation
, CONST D3DXVECTOR2
*ptranslation
)
122 D3DXMATRIX m1
, m2
, m3
, m4
, m5
;
124 D3DXVECTOR3 rot_center
, trans
;
126 rot
.w
=cos(rotation
/2.0f
);
129 rot
.z
=sin(rotation
/2.0f
);
131 if ( protationcenter
)
133 rot_center
.x
=protationcenter
->x
;
134 rot_center
.y
=protationcenter
->y
;
146 trans
.x
=ptranslation
->x
;
147 trans
.y
=ptranslation
->y
;
157 D3DXMatrixScaling(&m1
, scaling
, scaling
, 1.0f
);
158 D3DXMatrixTranslation(&m2
, -rot_center
.x
, -rot_center
.y
, -rot_center
.z
);
159 D3DXMatrixTranslation(&m4
, rot_center
.x
, rot_center
.y
, rot_center
.z
);
160 D3DXMatrixRotationQuaternion(&m3
, &rot
);
161 D3DXMatrixTranslation(&m5
, trans
.x
, trans
.y
, trans
.z
);
163 D3DXMatrixMultiply(&m1
, &m1
, &m2
);
164 D3DXMatrixMultiply(&m1
, &m1
, &m3
);
165 D3DXMatrixMultiply(&m1
, &m1
, &m4
);
166 D3DXMatrixMultiply(pout
, &m1
, &m5
);
171 HRESULT WINAPI
D3DXMatrixDecompose(D3DXVECTOR3
*poutscale
, D3DXQUATERNION
*poutrotation
, D3DXVECTOR3
*pouttranslation
, CONST D3DXMATRIX
*pm
)
173 D3DXMATRIX normalized
;
176 /*Compute the scaling part.*/
180 poutscale
->x
=D3DXVec3Length(&vec
);
185 poutscale
->y
=D3DXVec3Length(&vec
);
190 poutscale
->z
=D3DXVec3Length(&vec
);
192 /*Compute the translation part.*/
193 pouttranslation
->x
=pm
->u
.m
[3][0];
194 pouttranslation
->y
=pm
->u
.m
[3][1];
195 pouttranslation
->z
=pm
->u
.m
[3][2];
197 /*Let's calculate the rotation now*/
198 if ( (poutscale
->x
== 0.0f
) || (poutscale
->y
== 0.0f
) || (poutscale
->z
== 0.0f
) ) return D3DERR_INVALIDCALL
;
200 normalized
.u
.m
[0][0]=pm
->u
.m
[0][0]/poutscale
->x
;
201 normalized
.u
.m
[0][1]=pm
->u
.m
[0][1]/poutscale
->x
;
202 normalized
.u
.m
[0][2]=pm
->u
.m
[0][2]/poutscale
->x
;
203 normalized
.u
.m
[1][0]=pm
->u
.m
[1][0]/poutscale
->y
;
204 normalized
.u
.m
[1][1]=pm
->u
.m
[1][1]/poutscale
->y
;
205 normalized
.u
.m
[1][2]=pm
->u
.m
[1][2]/poutscale
->y
;
206 normalized
.u
.m
[2][0]=pm
->u
.m
[2][0]/poutscale
->z
;
207 normalized
.u
.m
[2][1]=pm
->u
.m
[2][1]/poutscale
->z
;
208 normalized
.u
.m
[2][2]=pm
->u
.m
[2][2]/poutscale
->z
;
210 D3DXQuaternionRotationMatrix(poutrotation
,&normalized
);
214 FLOAT WINAPI
D3DXMatrixDeterminant(CONST D3DXMATRIX
*pm
)
216 D3DXVECTOR4 minor
, v1
, v2
, v3
;
219 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];
220 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];
221 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];
222 D3DXVec4Cross(&minor
, &v1
, &v2
, &v3
);
223 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
);
227 D3DXMATRIX
* WINAPI
D3DXMatrixInverse(D3DXMATRIX
*pout
, FLOAT
*pdeterminant
, CONST D3DXMATRIX
*pm
)
231 D3DXVECTOR4 v
, vec
[3];
234 det
= D3DXMatrixDeterminant(pm
);
235 if ( !det
) return NULL
;
236 if ( pdeterminant
) *pdeterminant
= det
;
244 if ( j
> i
) a
= a
-1;
245 vec
[a
].x
= pm
->u
.m
[j
][0];
246 vec
[a
].y
= pm
->u
.m
[j
][1];
247 vec
[a
].z
= pm
->u
.m
[j
][2];
248 vec
[a
].w
= pm
->u
.m
[j
][3];
251 D3DXVec4Cross(&v
, &vec
[0], &vec
[1], &vec
[2]);
252 out
.u
.m
[0][i
] = pow(-1.0f
, i
) * v
.x
/ det
;
253 out
.u
.m
[1][i
] = pow(-1.0f
, i
) * v
.y
/ det
;
254 out
.u
.m
[2][i
] = pow(-1.0f
, i
) * v
.z
/ det
;
255 out
.u
.m
[3][i
] = pow(-1.0f
, i
) * v
.w
/ det
;
262 D3DXMATRIX
* WINAPI
D3DXMatrixLookAtLH(D3DXMATRIX
*pout
, CONST D3DXVECTOR3
*peye
, CONST D3DXVECTOR3
*pat
, CONST D3DXVECTOR3
*pup
)
264 D3DXVECTOR3 right
, rightn
, up
, upn
, vec
, vec2
;
266 D3DXVec3Subtract(&vec2
, pat
, peye
);
267 D3DXVec3Normalize(&vec
, &vec2
);
268 D3DXVec3Cross(&right
, pup
, &vec
);
269 D3DXVec3Cross(&up
, &vec
, &right
);
270 D3DXVec3Normalize(&rightn
, &right
);
271 D3DXVec3Normalize(&upn
, &up
);
272 pout
->u
.m
[0][0] = rightn
.x
;
273 pout
->u
.m
[1][0] = rightn
.y
;
274 pout
->u
.m
[2][0] = rightn
.z
;
275 pout
->u
.m
[3][0] = -D3DXVec3Dot(&rightn
,peye
);
276 pout
->u
.m
[0][1] = upn
.x
;
277 pout
->u
.m
[1][1] = upn
.y
;
278 pout
->u
.m
[2][1] = upn
.z
;
279 pout
->u
.m
[3][1] = -D3DXVec3Dot(&upn
, peye
);
280 pout
->u
.m
[0][2] = vec
.x
;
281 pout
->u
.m
[1][2] = vec
.y
;
282 pout
->u
.m
[2][2] = vec
.z
;
283 pout
->u
.m
[3][2] = -D3DXVec3Dot(&vec
, peye
);
284 pout
->u
.m
[0][3] = 0.0f
;
285 pout
->u
.m
[1][3] = 0.0f
;
286 pout
->u
.m
[2][3] = 0.0f
;
287 pout
->u
.m
[3][3] = 1.0f
;
291 D3DXMATRIX
* WINAPI
D3DXMatrixLookAtRH(D3DXMATRIX
*pout
, CONST D3DXVECTOR3
*peye
, CONST D3DXVECTOR3
*pat
, CONST D3DXVECTOR3
*pup
)
293 D3DXVECTOR3 right
, rightn
, up
, upn
, vec
, vec2
;
295 D3DXVec3Subtract(&vec2
, pat
, peye
);
296 D3DXVec3Normalize(&vec
, &vec2
);
297 D3DXVec3Cross(&right
, pup
, &vec
);
298 D3DXVec3Cross(&up
, &vec
, &right
);
299 D3DXVec3Normalize(&rightn
, &right
);
300 D3DXVec3Normalize(&upn
, &up
);
301 pout
->u
.m
[0][0] = -rightn
.x
;
302 pout
->u
.m
[1][0] = -rightn
.y
;
303 pout
->u
.m
[2][0] = -rightn
.z
;
304 pout
->u
.m
[3][0] = D3DXVec3Dot(&rightn
,peye
);
305 pout
->u
.m
[0][1] = upn
.x
;
306 pout
->u
.m
[1][1] = upn
.y
;
307 pout
->u
.m
[2][1] = upn
.z
;
308 pout
->u
.m
[3][1] = -D3DXVec3Dot(&upn
, peye
);
309 pout
->u
.m
[0][2] = -vec
.x
;
310 pout
->u
.m
[1][2] = -vec
.y
;
311 pout
->u
.m
[2][2] = -vec
.z
;
312 pout
->u
.m
[3][2] = D3DXVec3Dot(&vec
, peye
);
313 pout
->u
.m
[0][3] = 0.0f
;
314 pout
->u
.m
[1][3] = 0.0f
;
315 pout
->u
.m
[2][3] = 0.0f
;
316 pout
->u
.m
[3][3] = 1.0f
;
320 D3DXMATRIX
* WINAPI
D3DXMatrixMultiply(D3DXMATRIX
*pout
, CONST D3DXMATRIX
*pm1
, CONST D3DXMATRIX
*pm2
)
329 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
];
337 D3DXMATRIX
* WINAPI
D3DXMatrixMultiplyTranspose(D3DXMATRIX
*pout
, CONST D3DXMATRIX
*pm1
, CONST D3DXMATRIX
*pm2
)
339 D3DXMatrixMultiply(pout
, pm1
, pm2
);
340 D3DXMatrixTranspose(pout
, pout
);
344 D3DXMATRIX
* WINAPI
D3DXMatrixOrthoLH(D3DXMATRIX
*pout
, FLOAT w
, FLOAT h
, FLOAT zn
, FLOAT zf
)
346 D3DXMatrixIdentity(pout
);
347 pout
->u
.m
[0][0] = 2.0f
/ w
;
348 pout
->u
.m
[1][1] = 2.0f
/ h
;
349 pout
->u
.m
[2][2] = 1.0f
/ (zf
- zn
);
350 pout
->u
.m
[3][2] = zn
/ (zn
- zf
);
354 D3DXMATRIX
* WINAPI
D3DXMatrixOrthoOffCenterLH(D3DXMATRIX
*pout
, FLOAT l
, FLOAT r
, FLOAT b
, FLOAT t
, FLOAT zn
, FLOAT zf
)
356 D3DXMatrixIdentity(pout
);
357 pout
->u
.m
[0][0] = 2.0f
/ (r
- l
);
358 pout
->u
.m
[1][1] = 2.0f
/ (t
- b
);
359 pout
->u
.m
[2][2] = 1.0f
/ (zf
-zn
);
360 pout
->u
.m
[3][0] = -1.0f
-2.0f
*l
/ (r
- l
);
361 pout
->u
.m
[3][1] = 1.0f
+ 2.0f
* t
/ (b
- t
);
362 pout
->u
.m
[3][2] = zn
/ (zn
-zf
);
366 D3DXMATRIX
* WINAPI
D3DXMatrixOrthoOffCenterRH(D3DXMATRIX
*pout
, FLOAT l
, FLOAT r
, FLOAT b
, FLOAT t
, FLOAT zn
, FLOAT zf
)
368 D3DXMatrixIdentity(pout
);
369 pout
->u
.m
[0][0] = 2.0f
/ (r
- l
);
370 pout
->u
.m
[1][1] = 2.0f
/ (t
- b
);
371 pout
->u
.m
[2][2] = 1.0f
/ (zn
-zf
);
372 pout
->u
.m
[3][0] = -1.0f
-2.0f
*l
/ (r
- l
);
373 pout
->u
.m
[3][1] = 1.0f
+ 2.0f
* t
/ (b
- t
);
374 pout
->u
.m
[3][2] = zn
/ (zn
-zf
);
378 D3DXMATRIX
* WINAPI
D3DXMatrixOrthoRH(D3DXMATRIX
*pout
, FLOAT w
, FLOAT h
, FLOAT zn
, FLOAT zf
)
380 D3DXMatrixIdentity(pout
);
381 pout
->u
.m
[0][0] = 2.0f
/ w
;
382 pout
->u
.m
[1][1] = 2.0f
/ h
;
383 pout
->u
.m
[2][2] = 1.0f
/ (zn
- zf
);
384 pout
->u
.m
[3][2] = zn
/ (zn
- zf
);
388 D3DXMATRIX
* WINAPI
D3DXMatrixPerspectiveFovLH(D3DXMATRIX
*pout
, FLOAT fovy
, FLOAT aspect
, FLOAT zn
, FLOAT zf
)
390 D3DXMatrixIdentity(pout
);
391 pout
->u
.m
[0][0] = 1.0f
/ (aspect
* tan(fovy
/2.0f
));
392 pout
->u
.m
[1][1] = 1.0f
/ tan(fovy
/2.0f
);
393 pout
->u
.m
[2][2] = zf
/ (zf
- zn
);
394 pout
->u
.m
[2][3] = 1.0f
;
395 pout
->u
.m
[3][2] = (zf
* zn
) / (zn
- zf
);
396 pout
->u
.m
[3][3] = 0.0f
;
400 D3DXMATRIX
* WINAPI
D3DXMatrixPerspectiveFovRH(D3DXMATRIX
*pout
, FLOAT fovy
, FLOAT aspect
, FLOAT zn
, FLOAT zf
)
402 D3DXMatrixIdentity(pout
);
403 pout
->u
.m
[0][0] = 1.0f
/ (aspect
* tan(fovy
/2.0f
));
404 pout
->u
.m
[1][1] = 1.0f
/ tan(fovy
/2.0f
);
405 pout
->u
.m
[2][2] = zf
/ (zn
- zf
);
406 pout
->u
.m
[2][3] = -1.0f
;
407 pout
->u
.m
[3][2] = (zf
* zn
) / (zn
- zf
);
408 pout
->u
.m
[3][3] = 0.0f
;
412 D3DXMATRIX
* WINAPI
D3DXMatrixPerspectiveLH(D3DXMATRIX
*pout
, FLOAT w
, FLOAT h
, FLOAT zn
, FLOAT zf
)
414 D3DXMatrixIdentity(pout
);
415 pout
->u
.m
[0][0] = 2.0f
* zn
/ w
;
416 pout
->u
.m
[1][1] = 2.0f
* zn
/ h
;
417 pout
->u
.m
[2][2] = zf
/ (zf
- zn
);
418 pout
->u
.m
[3][2] = (zn
* zf
) / (zn
- zf
);
419 pout
->u
.m
[2][3] = 1.0f
;
420 pout
->u
.m
[3][3] = 0.0f
;
424 D3DXMATRIX
* WINAPI
D3DXMatrixPerspectiveOffCenterLH(D3DXMATRIX
*pout
, FLOAT l
, FLOAT r
, FLOAT b
, FLOAT t
, FLOAT zn
, FLOAT zf
)
426 D3DXMatrixIdentity(pout
);
427 pout
->u
.m
[0][0] = 2.0f
* zn
/ (r
- l
);
428 pout
->u
.m
[1][1] = -2.0f
* zn
/ (b
- t
);
429 pout
->u
.m
[2][0] = -1.0f
- 2.0f
* l
/ (r
- l
);
430 pout
->u
.m
[2][1] = 1.0f
+ 2.0f
* t
/ (b
- t
);
431 pout
->u
.m
[2][2] = - zf
/ (zn
- zf
);
432 pout
->u
.m
[3][2] = (zn
* zf
) / (zn
-zf
);
433 pout
->u
.m
[2][3] = 1.0f
;
434 pout
->u
.m
[3][3] = 0.0f
;
438 D3DXMATRIX
* WINAPI
D3DXMatrixPerspectiveOffCenterRH(D3DXMATRIX
*pout
, FLOAT l
, FLOAT r
, FLOAT b
, FLOAT t
, FLOAT zn
, FLOAT zf
)
440 D3DXMatrixIdentity(pout
);
441 pout
->u
.m
[0][0] = 2.0f
* zn
/ (r
- l
);
442 pout
->u
.m
[1][1] = -2.0f
* zn
/ (b
- t
);
443 pout
->u
.m
[2][0] = 1.0f
+ 2.0f
* l
/ (r
- l
);
444 pout
->u
.m
[2][1] = -1.0f
-2.0f
* t
/ (b
- t
);
445 pout
->u
.m
[2][2] = zf
/ (zn
- zf
);
446 pout
->u
.m
[3][2] = (zn
* zf
) / (zn
-zf
);
447 pout
->u
.m
[2][3] = -1.0f
;
448 pout
->u
.m
[3][3] = 0.0f
;
452 D3DXMATRIX
* WINAPI
D3DXMatrixPerspectiveRH(D3DXMATRIX
*pout
, FLOAT w
, FLOAT h
, FLOAT zn
, FLOAT zf
)
454 D3DXMatrixIdentity(pout
);
455 pout
->u
.m
[0][0] = 2.0f
* zn
/ w
;
456 pout
->u
.m
[1][1] = 2.0f
* zn
/ h
;
457 pout
->u
.m
[2][2] = zf
/ (zn
- zf
);
458 pout
->u
.m
[3][2] = (zn
* zf
) / (zn
- zf
);
459 pout
->u
.m
[2][3] = -1.0f
;
460 pout
->u
.m
[3][3] = 0.0f
;
464 D3DXMATRIX
* WINAPI
D3DXMatrixReflect(D3DXMATRIX
*pout
, CONST D3DXPLANE
*pplane
)
468 D3DXPlaneNormalize(&Nplane
, pplane
);
469 D3DXMatrixIdentity(pout
);
470 pout
->u
.m
[0][0] = 1.0f
- 2.0f
* Nplane
.a
* Nplane
.a
;
471 pout
->u
.m
[0][1] = -2.0f
* Nplane
.a
* Nplane
.b
;
472 pout
->u
.m
[0][2] = -2.0f
* Nplane
.a
* Nplane
.c
;
473 pout
->u
.m
[1][0] = -2.0f
* Nplane
.a
* Nplane
.b
;
474 pout
->u
.m
[1][1] = 1.0f
- 2.0f
* Nplane
.b
* Nplane
.b
;
475 pout
->u
.m
[1][2] = -2.0f
* Nplane
.b
* Nplane
.c
;
476 pout
->u
.m
[2][0] = -2.0f
* Nplane
.c
* Nplane
.a
;
477 pout
->u
.m
[2][1] = -2.0f
* Nplane
.c
* Nplane
.b
;
478 pout
->u
.m
[2][2] = 1.0f
- 2.0f
* Nplane
.c
* Nplane
.c
;
479 pout
->u
.m
[3][0] = -2.0f
* Nplane
.d
* Nplane
.a
;
480 pout
->u
.m
[3][1] = -2.0f
* Nplane
.d
* Nplane
.b
;
481 pout
->u
.m
[3][2] = -2.0f
* Nplane
.d
* Nplane
.c
;
485 D3DXMATRIX
* WINAPI
D3DXMatrixRotationAxis(D3DXMATRIX
*pout
, CONST D3DXVECTOR3
*pv
, FLOAT angle
)
489 D3DXVec3Normalize(&v
,pv
);
490 D3DXMatrixIdentity(pout
);
491 pout
->u
.m
[0][0] = (1.0f
- cos(angle
)) * v
.x
* v
.x
+ cos(angle
);
492 pout
->u
.m
[1][0] = (1.0f
- cos(angle
)) * v
.x
* v
.y
- sin(angle
) * v
.z
;
493 pout
->u
.m
[2][0] = (1.0f
- cos(angle
)) * v
.x
* v
.z
+ sin(angle
) * v
.y
;
494 pout
->u
.m
[0][1] = (1.0f
- cos(angle
)) * v
.y
* v
.x
+ sin(angle
) * v
.z
;
495 pout
->u
.m
[1][1] = (1.0f
- cos(angle
)) * v
.y
* v
.y
+ cos(angle
);
496 pout
->u
.m
[2][1] = (1.0f
- cos(angle
)) * v
.y
* v
.z
- sin(angle
) * v
.x
;
497 pout
->u
.m
[0][2] = (1.0f
- cos(angle
)) * v
.z
* v
.x
- sin(angle
) * v
.y
;
498 pout
->u
.m
[1][2] = (1.0f
- cos(angle
)) * v
.z
* v
.y
+ sin(angle
) * v
.x
;
499 pout
->u
.m
[2][2] = (1.0f
- cos(angle
)) * v
.z
* v
.z
+ cos(angle
);
503 D3DXMATRIX
* WINAPI
D3DXMatrixRotationQuaternion(D3DXMATRIX
*pout
, CONST D3DXQUATERNION
*pq
)
505 D3DXMatrixIdentity(pout
);
506 pout
->u
.m
[0][0] = 1.0f
- 2.0f
* (pq
->y
* pq
->y
+ pq
->z
* pq
->z
);
507 pout
->u
.m
[0][1] = 2.0f
* (pq
->x
*pq
->y
+ pq
->z
* pq
->w
);
508 pout
->u
.m
[0][2] = 2.0f
* (pq
->x
* pq
->z
- pq
->y
* pq
->w
);
509 pout
->u
.m
[1][0] = 2.0f
* (pq
->x
* pq
->y
- pq
->z
* pq
->w
);
510 pout
->u
.m
[1][1] = 1.0f
- 2.0f
* (pq
->x
* pq
->x
+ pq
->z
* pq
->z
);
511 pout
->u
.m
[1][2] = 2.0f
* (pq
->y
*pq
->z
+ pq
->x
*pq
->w
);
512 pout
->u
.m
[2][0] = 2.0f
* (pq
->x
* pq
->z
+ pq
->y
* pq
->w
);
513 pout
->u
.m
[2][1] = 2.0f
* (pq
->y
*pq
->z
- pq
->x
*pq
->w
);
514 pout
->u
.m
[2][2] = 1.0f
- 2.0f
* (pq
->x
* pq
->x
+ pq
->y
* pq
->y
);
518 D3DXMATRIX
* WINAPI
D3DXMatrixRotationX(D3DXMATRIX
*pout
, FLOAT angle
)
520 D3DXMatrixIdentity(pout
);
521 pout
->u
.m
[1][1] = cos(angle
);
522 pout
->u
.m
[2][2] = cos(angle
);
523 pout
->u
.m
[1][2] = sin(angle
);
524 pout
->u
.m
[2][1] = -sin(angle
);
528 D3DXMATRIX
* WINAPI
D3DXMatrixRotationY(D3DXMATRIX
*pout
, FLOAT angle
)
530 D3DXMatrixIdentity(pout
);
531 pout
->u
.m
[0][0] = cos(angle
);
532 pout
->u
.m
[2][2] = cos(angle
);
533 pout
->u
.m
[0][2] = -sin(angle
);
534 pout
->u
.m
[2][0] = sin(angle
);
538 D3DXMATRIX
* WINAPI
D3DXMatrixRotationYawPitchRoll(D3DXMATRIX
*pout
, FLOAT yaw
, FLOAT pitch
, FLOAT roll
)
542 D3DXMatrixIdentity(pout
);
543 D3DXMatrixRotationZ(&m
, roll
);
544 D3DXMatrixMultiply(pout
, pout
, &m
);
545 D3DXMatrixRotationX(&m
, pitch
);
546 D3DXMatrixMultiply(pout
, pout
, &m
);
547 D3DXMatrixRotationY(&m
, yaw
);
548 D3DXMatrixMultiply(pout
, pout
, &m
);
551 D3DXMATRIX
* WINAPI
D3DXMatrixRotationZ(D3DXMATRIX
*pout
, FLOAT angle
)
553 D3DXMatrixIdentity(pout
);
554 pout
->u
.m
[0][0] = cos(angle
);
555 pout
->u
.m
[1][1] = cos(angle
);
556 pout
->u
.m
[0][1] = sin(angle
);
557 pout
->u
.m
[1][0] = -sin(angle
);
561 D3DXMATRIX
* WINAPI
D3DXMatrixScaling(D3DXMATRIX
*pout
, FLOAT sx
, FLOAT sy
, FLOAT sz
)
563 D3DXMatrixIdentity(pout
);
564 pout
->u
.m
[0][0] = sx
;
565 pout
->u
.m
[1][1] = sy
;
566 pout
->u
.m
[2][2] = sz
;
570 D3DXMATRIX
* WINAPI
D3DXMatrixShadow(D3DXMATRIX
*pout
, CONST D3DXVECTOR4
*plight
, CONST D3DXPLANE
*pplane
)
575 D3DXPlaneNormalize(&Nplane
, pplane
);
576 dot
= D3DXPlaneDot(&Nplane
, plight
);
577 pout
->u
.m
[0][0] = dot
- Nplane
.a
* plight
->x
;
578 pout
->u
.m
[0][1] = -Nplane
.a
* plight
->y
;
579 pout
->u
.m
[0][2] = -Nplane
.a
* plight
->z
;
580 pout
->u
.m
[0][3] = -Nplane
.a
* plight
->w
;
581 pout
->u
.m
[1][0] = -Nplane
.b
* plight
->x
;
582 pout
->u
.m
[1][1] = dot
- Nplane
.b
* plight
->y
;
583 pout
->u
.m
[1][2] = -Nplane
.b
* plight
->z
;
584 pout
->u
.m
[1][3] = -Nplane
.b
* plight
->w
;
585 pout
->u
.m
[2][0] = -Nplane
.c
* plight
->x
;
586 pout
->u
.m
[2][1] = -Nplane
.c
* plight
->y
;
587 pout
->u
.m
[2][2] = dot
- Nplane
.c
* plight
->z
;
588 pout
->u
.m
[2][3] = -Nplane
.c
* plight
->w
;
589 pout
->u
.m
[3][0] = -Nplane
.d
* plight
->x
;
590 pout
->u
.m
[3][1] = -Nplane
.d
* plight
->y
;
591 pout
->u
.m
[3][2] = -Nplane
.d
* plight
->z
;
592 pout
->u
.m
[3][3] = dot
- Nplane
.d
* plight
->w
;
596 D3DXMATRIX
* WINAPI
D3DXMatrixTransformation(D3DXMATRIX
*pout
, CONST D3DXVECTOR3
*pscalingcenter
, CONST D3DXQUATERNION
*pscalingrotation
, CONST D3DXVECTOR3
*pscaling
, CONST D3DXVECTOR3
*protationcenter
, CONST D3DXQUATERNION
*protation
, CONST D3DXVECTOR3
*ptranslation
)
598 D3DXMATRIX m1
, m2
, m3
, m4
, m5
, m6
, m7
;
602 if ( !pscalingcenter
)
610 psc
.x
= pscalingcenter
->x
;
611 psc
.y
= pscalingcenter
->y
;
612 psc
.z
= pscalingcenter
->z
;
615 if ( !protationcenter
)
623 prc
.x
= protationcenter
->x
;
624 prc
.y
= protationcenter
->y
;
625 prc
.z
= protationcenter
->z
;
636 pt
.x
= ptranslation
->x
;
637 pt
.y
= ptranslation
->y
;
638 pt
.z
= ptranslation
->z
;
641 D3DXMatrixTranslation(&m1
, -psc
.x
, -psc
.y
, -psc
.z
);
643 if ( !pscalingrotation
)
645 D3DXMatrixIdentity(&m2
);
646 D3DXMatrixIdentity(&m4
);
650 D3DXMatrixRotationQuaternion(&m4
, pscalingrotation
);
651 D3DXMatrixInverse(&m2
, NULL
, &m4
);
654 if ( !pscaling
) D3DXMatrixIdentity(&m3
);
655 else D3DXMatrixScaling(&m3
, pscaling
->x
, pscaling
->y
, pscaling
->z
);
657 if ( !protation
) D3DXMatrixIdentity(&m6
);
658 else D3DXMatrixRotationQuaternion(&m6
, protation
);
660 D3DXMatrixTranslation(&m5
, psc
.x
- prc
.x
, psc
.y
- prc
.y
, psc
.z
- prc
.z
);
661 D3DXMatrixTranslation(&m7
, prc
.x
+ pt
.x
, prc
.y
+ pt
.y
, prc
.z
+ pt
.z
);
662 D3DXMatrixMultiply(&m1
, &m1
, &m2
);
663 D3DXMatrixMultiply(&m1
, &m1
, &m3
);
664 D3DXMatrixMultiply(&m1
, &m1
, &m4
);
665 D3DXMatrixMultiply(&m1
, &m1
, &m5
);
666 D3DXMatrixMultiply(&m1
, &m1
, &m6
);
667 D3DXMatrixMultiply(pout
, &m1
, &m7
);
670 D3DXMATRIX
* WINAPI
D3DXMatrixTransformation2D(D3DXMATRIX
*pout
, CONST D3DXVECTOR2
*pscalingcenter
, FLOAT scalingrotation
, CONST D3DXVECTOR2
*pscaling
, CONST D3DXVECTOR2
*protationcenter
, FLOAT rotation
, CONST D3DXVECTOR2
*ptranslation
)
672 D3DXQUATERNION rot
, sca_rot
;
673 D3DXVECTOR3 rot_center
, sca
, sca_center
, trans
;
675 if ( pscalingcenter
)
677 sca_center
.x
=pscalingcenter
->x
;
678 sca_center
.y
=pscalingcenter
->y
;
701 if ( protationcenter
)
703 rot_center
.x
=protationcenter
->x
;
704 rot_center
.y
=protationcenter
->y
;
716 trans
.x
=ptranslation
->x
;
717 trans
.y
=ptranslation
->y
;
727 rot
.w
=cos(rotation
/2.0f
);
730 rot
.z
=sin(rotation
/2.0f
);
732 sca_rot
.w
=cos(scalingrotation
/2.0f
);
735 sca_rot
.z
=sin(scalingrotation
/2.0f
);
737 D3DXMatrixTransformation(pout
, &sca_center
, &sca_rot
, &sca
, &rot_center
, &rot
, &trans
);
742 D3DXMATRIX
* WINAPI
D3DXMatrixTranslation(D3DXMATRIX
*pout
, FLOAT x
, FLOAT y
, FLOAT z
)
744 D3DXMatrixIdentity(pout
);
751 D3DXMATRIX
* WINAPI
D3DXMatrixTranspose(D3DXMATRIX
*pout
, CONST D3DXMATRIX
*pm
)
753 CONST D3DXMATRIX m
= *pm
;
757 for (j
=0; j
<4; j
++) pout
->u
.m
[i
][j
] = m
.u
.m
[j
][i
];
762 /*_________________D3DXMatrixStack____________________*/
764 static const unsigned int INITIAL_STACK_SIZE
= 32;
766 HRESULT WINAPI
D3DXCreateMatrixStack(DWORD flags
, LPD3DXMATRIXSTACK
* ppstack
)
768 ID3DXMatrixStackImpl
* object
;
770 TRACE("flags %#x, ppstack %p\n", flags
, ppstack
);
772 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(ID3DXMatrixStackImpl
));
773 if ( object
== NULL
)
776 return E_OUTOFMEMORY
;
778 object
->ID3DXMatrixStack_iface
.lpVtbl
= &ID3DXMatrixStack_Vtbl
;
781 object
->stack
= HeapAlloc(GetProcessHeap(), 0, INITIAL_STACK_SIZE
* sizeof(D3DXMATRIX
));
784 HeapFree(GetProcessHeap(), 0, object
);
786 return E_OUTOFMEMORY
;
790 object
->stack_size
= INITIAL_STACK_SIZE
;
791 D3DXMatrixIdentity(&object
->stack
[0]);
793 TRACE("Created matrix stack %p\n", object
);
795 *ppstack
= &object
->ID3DXMatrixStack_iface
;
799 static inline ID3DXMatrixStackImpl
*impl_from_ID3DXMatrixStack(ID3DXMatrixStack
*iface
)
801 return CONTAINING_RECORD(iface
, ID3DXMatrixStackImpl
, ID3DXMatrixStack_iface
);
804 static HRESULT WINAPI
ID3DXMatrixStackImpl_QueryInterface(ID3DXMatrixStack
*iface
, REFIID riid
, void **out
)
806 TRACE("iface %p, riid %s, out %p.\n", iface
, debugstr_guid(riid
), out
);
808 if (IsEqualGUID(riid
, &IID_ID3DXMatrixStack
)
809 || IsEqualGUID(riid
, &IID_IUnknown
))
811 ID3DXMatrixStack_AddRef(iface
);
816 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid
));
819 return E_NOINTERFACE
;
822 static ULONG WINAPI
ID3DXMatrixStackImpl_AddRef(ID3DXMatrixStack
*iface
)
824 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
825 ULONG ref
= InterlockedIncrement(&This
->ref
);
826 TRACE("(%p) : AddRef from %d\n", This
, ref
- 1);
830 static ULONG WINAPI
ID3DXMatrixStackImpl_Release(ID3DXMatrixStack
* iface
)
832 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
833 ULONG ref
= InterlockedDecrement(&This
->ref
);
836 HeapFree(GetProcessHeap(), 0, This
->stack
);
837 HeapFree(GetProcessHeap(), 0, This
);
839 TRACE("(%p) : ReleaseRef to %d\n", This
, ref
);
843 static D3DXMATRIX
* WINAPI
ID3DXMatrixStackImpl_GetTop(ID3DXMatrixStack
*iface
)
845 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
847 TRACE("iface %p\n", iface
);
849 return &This
->stack
[This
->current
];
852 static HRESULT WINAPI
ID3DXMatrixStackImpl_LoadIdentity(ID3DXMatrixStack
*iface
)
854 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
856 TRACE("iface %p\n", iface
);
858 D3DXMatrixIdentity(&This
->stack
[This
->current
]);
863 static HRESULT WINAPI
ID3DXMatrixStackImpl_LoadMatrix(ID3DXMatrixStack
*iface
, CONST D3DXMATRIX
*pm
)
865 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
867 TRACE("iface %p\n", iface
);
869 This
->stack
[This
->current
] = *pm
;
874 static HRESULT WINAPI
ID3DXMatrixStackImpl_MultMatrix(ID3DXMatrixStack
*iface
, CONST D3DXMATRIX
*pm
)
876 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
878 TRACE("iface %p\n", iface
);
880 D3DXMatrixMultiply(&This
->stack
[This
->current
], &This
->stack
[This
->current
], pm
);
885 static HRESULT WINAPI
ID3DXMatrixStackImpl_MultMatrixLocal(ID3DXMatrixStack
*iface
, CONST D3DXMATRIX
*pm
)
887 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
889 TRACE("iface %p\n", iface
);
891 D3DXMatrixMultiply(&This
->stack
[This
->current
], pm
, &This
->stack
[This
->current
]);
896 static HRESULT WINAPI
ID3DXMatrixStackImpl_Pop(ID3DXMatrixStack
*iface
)
898 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
900 TRACE("iface %p\n", iface
);
902 /* Popping the last element on the stack returns D3D_OK, but does nothing. */
903 if (!This
->current
) return D3D_OK
;
905 if (This
->current
<= This
->stack_size
/ 4 && This
->stack_size
>= INITIAL_STACK_SIZE
* 2)
907 unsigned int new_size
;
908 D3DXMATRIX
*new_stack
;
910 new_size
= This
->stack_size
/ 2;
911 new_stack
= HeapReAlloc(GetProcessHeap(), 0, This
->stack
, new_size
* sizeof(D3DXMATRIX
));
914 This
->stack_size
= new_size
;
915 This
->stack
= new_stack
;
924 static HRESULT WINAPI
ID3DXMatrixStackImpl_Push(ID3DXMatrixStack
*iface
)
926 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
928 TRACE("iface %p\n", iface
);
930 if (This
->current
== This
->stack_size
- 1)
932 unsigned int new_size
;
933 D3DXMATRIX
*new_stack
;
935 if (This
->stack_size
> UINT_MAX
/ 2) return E_OUTOFMEMORY
;
937 new_size
= This
->stack_size
* 2;
938 new_stack
= HeapReAlloc(GetProcessHeap(), 0, This
->stack
, new_size
* sizeof(D3DXMATRIX
));
939 if (!new_stack
) return E_OUTOFMEMORY
;
941 This
->stack_size
= new_size
;
942 This
->stack
= new_stack
;
946 This
->stack
[This
->current
] = This
->stack
[This
->current
- 1];
951 static HRESULT WINAPI
ID3DXMatrixStackImpl_RotateAxis(ID3DXMatrixStack
*iface
, CONST D3DXVECTOR3
*pv
, FLOAT angle
)
954 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
956 TRACE("iface %p\n", iface
);
958 D3DXMatrixRotationAxis(&temp
, pv
, angle
);
959 D3DXMatrixMultiply(&This
->stack
[This
->current
], &This
->stack
[This
->current
], &temp
);
964 static HRESULT WINAPI
ID3DXMatrixStackImpl_RotateAxisLocal(ID3DXMatrixStack
*iface
, CONST D3DXVECTOR3
*pv
, FLOAT angle
)
967 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
969 TRACE("iface %p\n", iface
);
971 D3DXMatrixRotationAxis(&temp
, pv
, angle
);
972 D3DXMatrixMultiply(&This
->stack
[This
->current
], &temp
, &This
->stack
[This
->current
]);
977 static HRESULT WINAPI
ID3DXMatrixStackImpl_RotateYawPitchRoll(ID3DXMatrixStack
*iface
, FLOAT x
, FLOAT y
, FLOAT z
)
980 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
982 TRACE("iface %p\n", iface
);
984 D3DXMatrixRotationYawPitchRoll(&temp
, x
, y
, z
);
985 D3DXMatrixMultiply(&This
->stack
[This
->current
], &This
->stack
[This
->current
], &temp
);
990 static HRESULT WINAPI
ID3DXMatrixStackImpl_RotateYawPitchRollLocal(ID3DXMatrixStack
*iface
, FLOAT x
, FLOAT y
, FLOAT z
)
993 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
995 TRACE("iface %p\n", iface
);
997 D3DXMatrixRotationYawPitchRoll(&temp
, x
, y
, z
);
998 D3DXMatrixMultiply(&This
->stack
[This
->current
], &temp
, &This
->stack
[This
->current
]);
1003 static HRESULT WINAPI
ID3DXMatrixStackImpl_Scale(ID3DXMatrixStack
*iface
, FLOAT x
, FLOAT y
, FLOAT z
)
1006 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
1008 TRACE("iface %p\n", iface
);
1010 D3DXMatrixScaling(&temp
, x
, y
, z
);
1011 D3DXMatrixMultiply(&This
->stack
[This
->current
], &This
->stack
[This
->current
], &temp
);
1016 static HRESULT WINAPI
ID3DXMatrixStackImpl_ScaleLocal(ID3DXMatrixStack
*iface
, FLOAT x
, FLOAT y
, FLOAT z
)
1019 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
1021 TRACE("iface %p\n", iface
);
1023 D3DXMatrixScaling(&temp
, x
, y
, z
);
1024 D3DXMatrixMultiply(&This
->stack
[This
->current
], &temp
, &This
->stack
[This
->current
]);
1029 static HRESULT WINAPI
ID3DXMatrixStackImpl_Translate(ID3DXMatrixStack
*iface
, FLOAT x
, FLOAT y
, FLOAT z
)
1032 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
1034 TRACE("iface %p\n", iface
);
1036 D3DXMatrixTranslation(&temp
, x
, y
, z
);
1037 D3DXMatrixMultiply(&This
->stack
[This
->current
], &This
->stack
[This
->current
], &temp
);
1042 static HRESULT WINAPI
ID3DXMatrixStackImpl_TranslateLocal(ID3DXMatrixStack
*iface
, FLOAT x
, FLOAT y
, FLOAT z
)
1045 ID3DXMatrixStackImpl
*This
= impl_from_ID3DXMatrixStack(iface
);
1047 TRACE("iface %p\n", iface
);
1049 D3DXMatrixTranslation(&temp
, x
, y
, z
);
1050 D3DXMatrixMultiply(&This
->stack
[This
->current
], &temp
,&This
->stack
[This
->current
]);
1055 static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl
=
1057 ID3DXMatrixStackImpl_QueryInterface
,
1058 ID3DXMatrixStackImpl_AddRef
,
1059 ID3DXMatrixStackImpl_Release
,
1060 ID3DXMatrixStackImpl_Pop
,
1061 ID3DXMatrixStackImpl_Push
,
1062 ID3DXMatrixStackImpl_LoadIdentity
,
1063 ID3DXMatrixStackImpl_LoadMatrix
,
1064 ID3DXMatrixStackImpl_MultMatrix
,
1065 ID3DXMatrixStackImpl_MultMatrixLocal
,
1066 ID3DXMatrixStackImpl_RotateAxis
,
1067 ID3DXMatrixStackImpl_RotateAxisLocal
,
1068 ID3DXMatrixStackImpl_RotateYawPitchRoll
,
1069 ID3DXMatrixStackImpl_RotateYawPitchRollLocal
,
1070 ID3DXMatrixStackImpl_Scale
,
1071 ID3DXMatrixStackImpl_ScaleLocal
,
1072 ID3DXMatrixStackImpl_Translate
,
1073 ID3DXMatrixStackImpl_TranslateLocal
,
1074 ID3DXMatrixStackImpl_GetTop
1077 /*_________________D3DXPLANE________________*/
1079 D3DXPLANE
* WINAPI
D3DXPlaneFromPointNormal(D3DXPLANE
*pout
, CONST D3DXVECTOR3
*pvpoint
, CONST D3DXVECTOR3
*pvnormal
)
1081 pout
->a
= pvnormal
->x
;
1082 pout
->b
= pvnormal
->y
;
1083 pout
->c
= pvnormal
->z
;
1084 pout
->d
= -D3DXVec3Dot(pvpoint
, pvnormal
);
1088 D3DXPLANE
* WINAPI
D3DXPlaneFromPoints(D3DXPLANE
*pout
, CONST D3DXVECTOR3
*pv1
, CONST D3DXVECTOR3
*pv2
, CONST D3DXVECTOR3
*pv3
)
1090 D3DXVECTOR3 edge1
, edge2
, normal
, Nnormal
;
1092 edge1
.x
= 0.0f
; edge1
.y
= 0.0f
; edge1
.z
= 0.0f
;
1093 edge2
.x
= 0.0f
; edge2
.y
= 0.0f
; edge2
.z
= 0.0f
;
1094 D3DXVec3Subtract(&edge1
, pv2
, pv1
);
1095 D3DXVec3Subtract(&edge2
, pv3
, pv1
);
1096 D3DXVec3Cross(&normal
, &edge1
, &edge2
);
1097 D3DXVec3Normalize(&Nnormal
, &normal
);
1098 D3DXPlaneFromPointNormal(pout
, pv1
, &Nnormal
);
1102 D3DXVECTOR3
* WINAPI
D3DXPlaneIntersectLine(D3DXVECTOR3
*pout
, CONST D3DXPLANE
*pp
, CONST D3DXVECTOR3
*pv1
, CONST D3DXVECTOR3
*pv2
)
1104 D3DXVECTOR3 direction
, normal
;
1110 direction
.x
= pv2
->x
- pv1
->x
;
1111 direction
.y
= pv2
->y
- pv1
->y
;
1112 direction
.z
= pv2
->z
- pv1
->z
;
1113 dot
= D3DXVec3Dot(&normal
, &direction
);
1114 if ( !dot
) return NULL
;
1115 temp
= ( pp
->d
+ D3DXVec3Dot(&normal
, pv1
) ) / dot
;
1116 pout
->x
= pv1
->x
- temp
* direction
.x
;
1117 pout
->y
= pv1
->y
- temp
* direction
.y
;
1118 pout
->z
= pv1
->z
- temp
* direction
.z
;
1122 D3DXPLANE
* WINAPI
D3DXPlaneNormalize(D3DXPLANE
*pout
, CONST D3DXPLANE
*pp
)
1127 norm
= sqrt(pp
->a
* pp
->a
+ pp
->b
* pp
->b
+ pp
->c
* pp
->c
);
1130 out
.a
= pp
->a
/ norm
;
1131 out
.b
= pp
->b
/ norm
;
1132 out
.c
= pp
->c
/ norm
;
1133 out
.d
= pp
->d
/ norm
;
1146 D3DXPLANE
* WINAPI
D3DXPlaneTransform(D3DXPLANE
*pout
, CONST D3DXPLANE
*pplane
, CONST D3DXMATRIX
*pm
)
1148 CONST D3DXPLANE plane
= *pplane
;
1149 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
;
1150 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
;
1151 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
;
1152 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
;
1156 D3DXPLANE
* WINAPI
D3DXPlaneTransformArray(D3DXPLANE
* out
, UINT outstride
, CONST D3DXPLANE
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1160 for (i
= 0; i
< elements
; ++i
) {
1162 (D3DXPLANE
*)((char*)out
+ outstride
* i
),
1163 (CONST D3DXPLANE
*)((const char*)in
+ instride
* i
),
1169 /*_________________D3DXQUATERNION________________*/
1171 D3DXQUATERNION
* WINAPI
D3DXQuaternionBaryCentric(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq1
, CONST D3DXQUATERNION
*pq2
, CONST D3DXQUATERNION
*pq3
, FLOAT f
, FLOAT g
)
1173 D3DXQUATERNION temp1
, temp2
;
1174 D3DXQuaternionSlerp(pout
, D3DXQuaternionSlerp(&temp1
, pq1
, pq2
, f
+ g
), D3DXQuaternionSlerp(&temp2
, pq1
, pq3
, f
+g
), g
/ (f
+ g
));
1178 D3DXQUATERNION
* WINAPI
D3DXQuaternionExp(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq
)
1182 norm
= sqrt(pq
->x
* pq
->x
+ pq
->y
* pq
->y
+ pq
->z
* pq
->z
);
1185 pout
->x
= sin(norm
) * pq
->x
/ norm
;
1186 pout
->y
= sin(norm
) * pq
->y
/ norm
;
1187 pout
->z
= sin(norm
) * pq
->z
/ norm
;
1188 pout
->w
= cos(norm
);
1200 D3DXQUATERNION
* WINAPI
D3DXQuaternionInverse(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq
)
1205 norm
= D3DXQuaternionLengthSq(pq
);
1207 out
.x
= -pq
->x
/ norm
;
1208 out
.y
= -pq
->y
/ norm
;
1209 out
.z
= -pq
->z
/ norm
;
1210 out
.w
= pq
->w
/ norm
;
1216 D3DXQUATERNION
* WINAPI
D3DXQuaternionLn(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq
)
1218 FLOAT norm
, normvec
, theta
;
1220 norm
= D3DXQuaternionLengthSq(pq
);
1221 if ( norm
> 1.0001f
)
1228 else if( norm
> 0.99999f
)
1230 normvec
= sqrt( pq
->x
* pq
->x
+ pq
->y
* pq
->y
+ pq
->z
* pq
->z
);
1231 theta
= atan2(normvec
, pq
->w
) / normvec
;
1232 pout
->x
= theta
* pq
->x
;
1233 pout
->y
= theta
* pq
->y
;
1234 pout
->z
= theta
* pq
->z
;
1239 FIXME("The quaternion (%f, %f, %f, %f) has a norm <1. This should not happen. Windows returns a result anyway. This case is not implemented yet.\n", pq
->x
, pq
->y
, pq
->z
, pq
->w
);
1244 D3DXQUATERNION
* WINAPI
D3DXQuaternionMultiply(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq1
, CONST D3DXQUATERNION
*pq2
)
1247 out
.x
= pq2
->w
* pq1
->x
+ pq2
->x
* pq1
->w
+ pq2
->y
* pq1
->z
- pq2
->z
* pq1
->y
;
1248 out
.y
= pq2
->w
* pq1
->y
- pq2
->x
* pq1
->z
+ pq2
->y
* pq1
->w
+ pq2
->z
* pq1
->x
;
1249 out
.z
= pq2
->w
* pq1
->z
+ pq2
->x
* pq1
->y
- pq2
->y
* pq1
->x
+ pq2
->z
* pq1
->w
;
1250 out
.w
= pq2
->w
* pq1
->w
- pq2
->x
* pq1
->x
- pq2
->y
* pq1
->y
- pq2
->z
* pq1
->z
;
1255 D3DXQUATERNION
* WINAPI
D3DXQuaternionNormalize(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq
)
1260 norm
= D3DXQuaternionLength(pq
);
1262 out
.x
= pq
->x
/ norm
;
1263 out
.y
= pq
->y
/ norm
;
1264 out
.z
= pq
->z
/ norm
;
1265 out
.w
= pq
->w
/ norm
;
1272 D3DXQUATERNION
* WINAPI
D3DXQuaternionRotationAxis(D3DXQUATERNION
*pout
, CONST D3DXVECTOR3
*pv
, FLOAT angle
)
1276 D3DXVec3Normalize(&temp
, pv
);
1277 pout
->x
= sin( angle
/ 2.0f
) * temp
.x
;
1278 pout
->y
= sin( angle
/ 2.0f
) * temp
.y
;
1279 pout
->z
= sin( angle
/ 2.0f
) * temp
.z
;
1280 pout
->w
= cos( angle
/ 2.0f
);
1284 D3DXQUATERNION
* WINAPI
D3DXQuaternionRotationMatrix(D3DXQUATERNION
*pout
, CONST D3DXMATRIX
*pm
)
1287 FLOAT maxdiag
, S
, trace
;
1289 trace
= pm
->u
.m
[0][0] + pm
->u
.m
[1][1] + pm
->u
.m
[2][2] + 1.0f
;
1292 pout
->x
= ( pm
->u
.m
[1][2] - pm
->u
.m
[2][1] ) / ( 2.0f
* sqrt(trace
) );
1293 pout
->y
= ( pm
->u
.m
[2][0] - pm
->u
.m
[0][2] ) / ( 2.0f
* sqrt(trace
) );
1294 pout
->z
= ( pm
->u
.m
[0][1] - pm
->u
.m
[1][0] ) / ( 2.0f
* sqrt(trace
) );
1295 pout
->w
= sqrt(trace
) / 2.0f
;
1299 maxdiag
= pm
->u
.m
[0][0];
1302 if ( pm
->u
.m
[i
][i
] > maxdiag
)
1305 maxdiag
= pm
->u
.m
[i
][i
];
1311 S
= 2.0f
* sqrt(1.0f
+ pm
->u
.m
[0][0] - pm
->u
.m
[1][1] - pm
->u
.m
[2][2]);
1312 pout
->x
= 0.25f
* S
;
1313 pout
->y
= ( pm
->u
.m
[0][1] + pm
->u
.m
[1][0] ) / S
;
1314 pout
->z
= ( pm
->u
.m
[0][2] + pm
->u
.m
[2][0] ) / S
;
1315 pout
->w
= ( pm
->u
.m
[1][2] - pm
->u
.m
[2][1] ) / S
;
1318 S
= 2.0f
* sqrt(1.0f
+ pm
->u
.m
[1][1] - pm
->u
.m
[0][0] - pm
->u
.m
[2][2]);
1319 pout
->x
= ( pm
->u
.m
[0][1] + pm
->u
.m
[1][0] ) / S
;
1320 pout
->y
= 0.25f
* S
;
1321 pout
->z
= ( pm
->u
.m
[1][2] + pm
->u
.m
[2][1] ) / S
;
1322 pout
->w
= ( pm
->u
.m
[2][0] - pm
->u
.m
[0][2] ) / S
;
1325 S
= 2.0f
* sqrt(1.0f
+ pm
->u
.m
[2][2] - pm
->u
.m
[0][0] - pm
->u
.m
[1][1]);
1326 pout
->x
= ( pm
->u
.m
[0][2] + pm
->u
.m
[2][0] ) / S
;
1327 pout
->y
= ( pm
->u
.m
[1][2] + pm
->u
.m
[2][1] ) / S
;
1328 pout
->z
= 0.25f
* S
;
1329 pout
->w
= ( pm
->u
.m
[0][1] - pm
->u
.m
[1][0] ) / S
;
1335 D3DXQUATERNION
* WINAPI
D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION
*pout
, FLOAT yaw
, FLOAT pitch
, FLOAT roll
)
1337 pout
->x
= sin( yaw
/ 2.0f
) * cos(pitch
/ 2.0f
) * sin(roll
/ 2.0f
) + cos(yaw
/ 2.0f
) * sin(pitch
/ 2.0f
) * cos(roll
/ 2.0f
);
1338 pout
->y
= sin( yaw
/ 2.0f
) * cos(pitch
/ 2.0f
) * cos(roll
/ 2.0f
) - cos(yaw
/ 2.0f
) * sin(pitch
/ 2.0f
) * sin(roll
/ 2.0f
);
1339 pout
->z
= cos(yaw
/ 2.0f
) * cos(pitch
/ 2.0f
) * sin(roll
/ 2.0f
) - sin( yaw
/ 2.0f
) * sin(pitch
/ 2.0f
) * cos(roll
/ 2.0f
);
1340 pout
->w
= cos( yaw
/ 2.0f
) * cos(pitch
/ 2.0f
) * cos(roll
/ 2.0f
) + sin(yaw
/ 2.0f
) * sin(pitch
/ 2.0f
) * sin(roll
/ 2.0f
);
1344 D3DXQUATERNION
* WINAPI
D3DXQuaternionSlerp(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq1
, CONST D3DXQUATERNION
*pq2
, FLOAT t
)
1346 FLOAT dot
, epsilon
, temp
, theta
, u
;
1351 dot
= D3DXQuaternionDot(pq1
, pq2
);
1357 if( 1.0f
- dot
> 0.001f
)
1360 temp
= sin(theta
* temp
) / sin(theta
);
1361 u
= sin(theta
* u
) / sin(theta
);
1363 pout
->x
= temp
* pq1
->x
+ epsilon
* u
* pq2
->x
;
1364 pout
->y
= temp
* pq1
->y
+ epsilon
* u
* pq2
->y
;
1365 pout
->z
= temp
* pq1
->z
+ epsilon
* u
* pq2
->z
;
1366 pout
->w
= temp
* pq1
->w
+ epsilon
* u
* pq2
->w
;
1370 D3DXQUATERNION
* WINAPI
D3DXQuaternionSquad(D3DXQUATERNION
*pout
, CONST D3DXQUATERNION
*pq1
, CONST D3DXQUATERNION
*pq2
, CONST D3DXQUATERNION
*pq3
, CONST D3DXQUATERNION
*pq4
, FLOAT t
)
1372 D3DXQUATERNION temp1
, temp2
;
1374 D3DXQuaternionSlerp(pout
, D3DXQuaternionSlerp(&temp1
, pq1
, pq4
, t
), D3DXQuaternionSlerp(&temp2
, pq2
, pq3
, t
), 2.0f
* t
* (1.0f
- t
));
1378 void WINAPI
D3DXQuaternionToAxisAngle(CONST D3DXQUATERNION
*pq
, D3DXVECTOR3
*paxis
, FLOAT
*pangle
)
1383 *pangle
= 2.0f
* acos(pq
->w
);
1386 /*_________________D3DXVec2_____________________*/
1388 D3DXVECTOR2
* WINAPI
D3DXVec2BaryCentric(D3DXVECTOR2
*pout
, CONST D3DXVECTOR2
*pv1
, CONST D3DXVECTOR2
*pv2
, CONST D3DXVECTOR2
*pv3
, FLOAT f
, FLOAT g
)
1390 pout
->x
= (1.0f
-f
-g
) * (pv1
->x
) + f
* (pv2
->x
) + g
* (pv3
->x
);
1391 pout
->y
= (1.0f
-f
-g
) * (pv1
->y
) + f
* (pv2
->y
) + g
* (pv3
->y
);
1395 D3DXVECTOR2
* WINAPI
D3DXVec2CatmullRom(D3DXVECTOR2
*pout
, CONST D3DXVECTOR2
*pv0
, CONST D3DXVECTOR2
*pv1
, CONST D3DXVECTOR2
*pv2
, CONST D3DXVECTOR2
*pv3
, FLOAT s
)
1397 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
);
1398 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
);
1402 D3DXVECTOR2
* WINAPI
D3DXVec2Hermite(D3DXVECTOR2
*pout
, CONST D3DXVECTOR2
*pv1
, CONST D3DXVECTOR2
*pt1
, CONST D3DXVECTOR2
*pv2
, CONST D3DXVECTOR2
*pt2
, FLOAT s
)
1404 FLOAT h1
, h2
, h3
, h4
;
1406 h1
= 2.0f
* s
* s
* s
- 3.0f
* s
* s
+ 1.0f
;
1407 h2
= s
* s
* s
- 2.0f
* s
* s
+ s
;
1408 h3
= -2.0f
* s
* s
* s
+ 3.0f
* s
* s
;
1409 h4
= s
* s
* s
- s
* s
;
1411 pout
->x
= h1
* (pv1
->x
) + h2
* (pt1
->x
) + h3
* (pv2
->x
) + h4
* (pt2
->x
);
1412 pout
->y
= h1
* (pv1
->y
) + h2
* (pt1
->y
) + h3
* (pv2
->y
) + h4
* (pt2
->y
);
1416 D3DXVECTOR2
* WINAPI
D3DXVec2Normalize(D3DXVECTOR2
*pout
, CONST D3DXVECTOR2
*pv
)
1421 norm
= D3DXVec2Length(pv
);
1429 out
.x
= pv
->x
/ norm
;
1430 out
.y
= pv
->y
/ norm
;
1436 D3DXVECTOR4
* WINAPI
D3DXVec2Transform(D3DXVECTOR4
*pout
, CONST D3DXVECTOR2
*pv
, CONST D3DXMATRIX
*pm
)
1438 pout
->x
= pm
->u
.m
[0][0] * pv
->x
+ pm
->u
.m
[1][0] * pv
->y
+ pm
->u
.m
[3][0];
1439 pout
->y
= pm
->u
.m
[0][1] * pv
->x
+ pm
->u
.m
[1][1] * pv
->y
+ pm
->u
.m
[3][1];
1440 pout
->z
= pm
->u
.m
[0][2] * pv
->x
+ pm
->u
.m
[1][2] * pv
->y
+ pm
->u
.m
[3][2];
1441 pout
->w
= pm
->u
.m
[0][3] * pv
->x
+ pm
->u
.m
[1][3] * pv
->y
+ pm
->u
.m
[3][3];
1445 D3DXVECTOR4
* WINAPI
D3DXVec2TransformArray(D3DXVECTOR4
* out
, UINT outstride
, CONST D3DXVECTOR2
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1449 for (i
= 0; i
< elements
; ++i
) {
1451 (D3DXVECTOR4
*)((char*)out
+ outstride
* i
),
1452 (CONST D3DXVECTOR2
*)((const char*)in
+ instride
* i
),
1458 D3DXVECTOR2
* WINAPI
D3DXVec2TransformCoord(D3DXVECTOR2
*pout
, CONST D3DXVECTOR2
*pv
, CONST D3DXMATRIX
*pm
)
1464 norm
= pm
->u
.m
[0][3] * pv
->x
+ pm
->u
.m
[1][3] * pv
->y
+ pm
->u
.m
[3][3];
1466 pout
->x
= (pm
->u
.m
[0][0] * v
.x
+ pm
->u
.m
[1][0] * v
.y
+ pm
->u
.m
[3][0]) / norm
;
1467 pout
->y
= (pm
->u
.m
[0][1] * v
.x
+ pm
->u
.m
[1][1] * v
.y
+ pm
->u
.m
[3][1]) / norm
;
1472 D3DXVECTOR2
* WINAPI
D3DXVec2TransformCoordArray(D3DXVECTOR2
* out
, UINT outstride
, CONST D3DXVECTOR2
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1476 for (i
= 0; i
< elements
; ++i
) {
1477 D3DXVec2TransformCoord(
1478 (D3DXVECTOR2
*)((char*)out
+ outstride
* i
),
1479 (CONST D3DXVECTOR2
*)((const char*)in
+ instride
* i
),
1485 D3DXVECTOR2
* WINAPI
D3DXVec2TransformNormal(D3DXVECTOR2
*pout
, CONST D3DXVECTOR2
*pv
, CONST D3DXMATRIX
*pm
)
1487 CONST D3DXVECTOR2 v
= *pv
;
1488 pout
->x
= pm
->u
.m
[0][0] * v
.x
+ pm
->u
.m
[1][0] * v
.y
;
1489 pout
->y
= pm
->u
.m
[0][1] * v
.x
+ pm
->u
.m
[1][1] * v
.y
;
1493 D3DXVECTOR2
* WINAPI
D3DXVec2TransformNormalArray(D3DXVECTOR2
* out
, UINT outstride
, CONST D3DXVECTOR2
*in
, UINT instride
, CONST D3DXMATRIX
*matrix
, UINT elements
)
1497 for (i
= 0; i
< elements
; ++i
) {
1498 D3DXVec2TransformNormal(
1499 (D3DXVECTOR2
*)((char*)out
+ outstride
* i
),
1500 (CONST D3DXVECTOR2
*)((const char*)in
+ instride
* i
),
1506 /*_________________D3DXVec3_____________________*/
1508 D3DXVECTOR3
* WINAPI
D3DXVec3BaryCentric(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv1
, CONST D3DXVECTOR3
*pv2
, CONST D3DXVECTOR3
*pv3
, FLOAT f
, FLOAT g
)
1510 pout
->x
= (1.0f
-f
-g
) * (pv1
->x
) + f
* (pv2
->x
) + g
* (pv3
->x
);
1511 pout
->y
= (1.0f
-f
-g
) * (pv1
->y
) + f
* (pv2
->y
) + g
* (pv3
->y
);
1512 pout
->z
= (1.0f
-f
-g
) * (pv1
->z
) + f
* (pv2
->z
) + g
* (pv3
->z
);
1516 D3DXVECTOR3
* WINAPI
D3DXVec3CatmullRom( D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv0
, CONST D3DXVECTOR3
*pv1
, CONST D3DXVECTOR3
*pv2
, CONST D3DXVECTOR3
*pv3
, FLOAT s
)
1518 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
);
1519 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
);
1520 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
);
1524 D3DXVECTOR3
* WINAPI
D3DXVec3Hermite(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv1
, CONST D3DXVECTOR3
*pt1
, CONST D3DXVECTOR3
*pv2
, CONST D3DXVECTOR3
*pt2
, FLOAT s
)
1526 FLOAT h1
, h2
, h3
, h4
;
1528 h1
= 2.0f
* s
* s
* s
- 3.0f
* s
* s
+ 1.0f
;
1529 h2
= s
* s
* s
- 2.0f
* s
* s
+ s
;
1530 h3
= -2.0f
* s
* s
* s
+ 3.0f
* s
* s
;
1531 h4
= s
* s
* s
- s
* s
;
1533 pout
->x
= h1
* (pv1
->x
) + h2
* (pt1
->x
) + h3
* (pv2
->x
) + h4
* (pt2
->x
);
1534 pout
->y
= h1
* (pv1
->y
) + h2
* (pt1
->y
) + h3
* (pv2
->y
) + h4
* (pt2
->y
);
1535 pout
->z
= h1
* (pv1
->z
) + h2
* (pt1
->z
) + h3
* (pv2
->z
) + h4
* (pt2
->z
);
1539 D3DXVECTOR3
* WINAPI
D3DXVec3Normalize(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv
)
1544 norm
= D3DXVec3Length(pv
);
1553 out
.x
= pv
->x
/ norm
;
1554 out
.y
= pv
->y
/ norm
;
1555 out
.z
= pv
->z
/ norm
;
1561 D3DXVECTOR3
* WINAPI
D3DXVec3Project(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv
, CONST D3DVIEWPORT9
*pviewport
, CONST D3DXMATRIX
*pprojection
, CONST D3DXMATRIX
*pview
, CONST D3DXMATRIX
*pworld
)
1566 D3DXMatrixMultiply(&m
, pworld
, pview
);
1567 D3DXMatrixMultiply(&m
, &m
, pprojection
);
1568 D3DXVec3TransformCoord(&out
, pv
, &m
);
1569 out
.x
= pviewport
->X
+ ( 1.0f
+ out
.x
) * pviewport
->Width
/ 2.0f
;
1570 out
.y
= pviewport
->Y
+ ( 1.0f
- out
.y
) * pviewport
->Height
/ 2.0f
;
1571 out
.z
= pviewport
->MinZ
+ out
.z
* ( pviewport
->MaxZ
- pviewport
->MinZ
);
1576 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
)
1580 for (i
= 0; i
< elements
; ++i
) {
1582 (D3DXVECTOR3
*)((char*)out
+ outstride
* i
),
1583 (CONST D3DXVECTOR3
*)((const char*)in
+ instride
* i
),
1584 viewport
, projection
, view
, world
);
1589 D3DXVECTOR4
* WINAPI
D3DXVec3Transform(D3DXVECTOR4
*pout
, CONST D3DXVECTOR3
*pv
, CONST D3DXMATRIX
*pm
)
1591 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];
1592 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];
1593 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];
1594 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];
1598 D3DXVECTOR4
* WINAPI
D3DXVec3TransformArray(D3DXVECTOR4
* out
, UINT outstride
, CONST D3DXVECTOR3
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1602 for (i
= 0; i
< elements
; ++i
) {
1604 (D3DXVECTOR4
*)((char*)out
+ outstride
* i
),
1605 (CONST D3DXVECTOR3
*)((const char*)in
+ instride
* i
),
1611 D3DXVECTOR3
* WINAPI
D3DXVec3TransformCoord(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv
, CONST D3DXMATRIX
*pm
)
1616 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];
1618 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
;
1619 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
;
1620 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
;
1627 D3DXVECTOR3
* WINAPI
D3DXVec3TransformCoordArray(D3DXVECTOR3
* out
, UINT outstride
, CONST D3DXVECTOR3
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1631 for (i
= 0; i
< elements
; ++i
) {
1632 D3DXVec3TransformCoord(
1633 (D3DXVECTOR3
*)((char*)out
+ outstride
* i
),
1634 (CONST D3DXVECTOR3
*)((const char*)in
+ instride
* i
),
1640 D3DXVECTOR3
* WINAPI
D3DXVec3TransformNormal(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv
, CONST D3DXMATRIX
*pm
)
1642 CONST D3DXVECTOR3 v
= *pv
;
1643 pout
->x
= pm
->u
.m
[0][0] * v
.x
+ pm
->u
.m
[1][0] * v
.y
+ pm
->u
.m
[2][0] * v
.z
;
1644 pout
->y
= pm
->u
.m
[0][1] * v
.x
+ pm
->u
.m
[1][1] * v
.y
+ pm
->u
.m
[2][1] * v
.z
;
1645 pout
->z
= pm
->u
.m
[0][2] * v
.x
+ pm
->u
.m
[1][2] * v
.y
+ pm
->u
.m
[2][2] * v
.z
;
1650 D3DXVECTOR3
* WINAPI
D3DXVec3TransformNormalArray(D3DXVECTOR3
* out
, UINT outstride
, CONST D3DXVECTOR3
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1654 for (i
= 0; i
< elements
; ++i
) {
1655 D3DXVec3TransformNormal(
1656 (D3DXVECTOR3
*)((char*)out
+ outstride
* i
),
1657 (CONST D3DXVECTOR3
*)((const char*)in
+ instride
* i
),
1663 D3DXVECTOR3
* WINAPI
D3DXVec3Unproject(D3DXVECTOR3
*pout
, CONST D3DXVECTOR3
*pv
, CONST D3DVIEWPORT9
*pviewport
, CONST D3DXMATRIX
*pprojection
, CONST D3DXMATRIX
*pview
, CONST D3DXMATRIX
*pworld
)
1669 D3DXMatrixMultiply(&m
, pworld
, pview
);
1670 D3DXMatrixMultiply(&m
, &m
, pprojection
);
1672 D3DXMatrixMultiply(&m
, pview
, pprojection
);
1674 D3DXMatrixInverse(&m
, NULL
, &m
);
1675 out
.x
= 2.0f
* ( pv
->x
- pviewport
->X
) / pviewport
->Width
- 1.0f
;
1676 out
.y
= 1.0f
- 2.0f
* ( pv
->y
- pviewport
->Y
) / pviewport
->Height
;
1677 out
.z
= ( pv
->z
- pviewport
->MinZ
) / ( pviewport
->MaxZ
- pviewport
->MinZ
);
1678 D3DXVec3TransformCoord(&out
, &out
, &m
);
1683 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
)
1687 for (i
= 0; i
< elements
; ++i
) {
1689 (D3DXVECTOR3
*)((char*)out
+ outstride
* i
),
1690 (CONST D3DXVECTOR3
*)((const char*)in
+ instride
* i
),
1691 viewport
, projection
, view
, world
);
1696 /*_________________D3DXVec4_____________________*/
1698 D3DXVECTOR4
* WINAPI
D3DXVec4BaryCentric(D3DXVECTOR4
*pout
, CONST D3DXVECTOR4
*pv1
, CONST D3DXVECTOR4
*pv2
, CONST D3DXVECTOR4
*pv3
, FLOAT f
, FLOAT g
)
1700 pout
->x
= (1.0f
-f
-g
) * (pv1
->x
) + f
* (pv2
->x
) + g
* (pv3
->x
);
1701 pout
->y
= (1.0f
-f
-g
) * (pv1
->y
) + f
* (pv2
->y
) + g
* (pv3
->y
);
1702 pout
->z
= (1.0f
-f
-g
) * (pv1
->z
) + f
* (pv2
->z
) + g
* (pv3
->z
);
1703 pout
->w
= (1.0f
-f
-g
) * (pv1
->w
) + f
* (pv2
->w
) + g
* (pv3
->w
);
1707 D3DXVECTOR4
* WINAPI
D3DXVec4CatmullRom(D3DXVECTOR4
*pout
, CONST D3DXVECTOR4
*pv0
, CONST D3DXVECTOR4
*pv1
, CONST D3DXVECTOR4
*pv2
, CONST D3DXVECTOR4
*pv3
, FLOAT s
)
1709 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
);
1710 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
);
1711 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
);
1712 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
);
1716 D3DXVECTOR4
* WINAPI
D3DXVec4Cross(D3DXVECTOR4
*pout
, CONST D3DXVECTOR4
*pv1
, CONST D3DXVECTOR4
*pv2
, CONST D3DXVECTOR4
*pv3
)
1719 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
);
1720 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
));
1721 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
);
1722 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
));
1727 D3DXVECTOR4
* WINAPI
D3DXVec4Hermite(D3DXVECTOR4
*pout
, CONST D3DXVECTOR4
*pv1
, CONST D3DXVECTOR4
*pt1
, CONST D3DXVECTOR4
*pv2
, CONST D3DXVECTOR4
*pt2
, FLOAT s
)
1729 FLOAT h1
, h2
, h3
, h4
;
1731 h1
= 2.0f
* s
* s
* s
- 3.0f
* s
* s
+ 1.0f
;
1732 h2
= s
* s
* s
- 2.0f
* s
* s
+ s
;
1733 h3
= -2.0f
* s
* s
* s
+ 3.0f
* s
* s
;
1734 h4
= s
* s
* s
- s
* s
;
1736 pout
->x
= h1
* (pv1
->x
) + h2
* (pt1
->x
) + h3
* (pv2
->x
) + h4
* (pt2
->x
);
1737 pout
->y
= h1
* (pv1
->y
) + h2
* (pt1
->y
) + h3
* (pv2
->y
) + h4
* (pt2
->y
);
1738 pout
->z
= h1
* (pv1
->z
) + h2
* (pt1
->z
) + h3
* (pv2
->z
) + h4
* (pt2
->z
);
1739 pout
->w
= h1
* (pv1
->w
) + h2
* (pt1
->w
) + h3
* (pv2
->w
) + h4
* (pt2
->w
);
1743 D3DXVECTOR4
* WINAPI
D3DXVec4Normalize(D3DXVECTOR4
*pout
, CONST D3DXVECTOR4
*pv
)
1748 norm
= D3DXVec4Length(pv
);
1750 out
.x
= pv
->x
/ norm
;
1751 out
.y
= pv
->y
/ norm
;
1752 out
.z
= pv
->z
/ norm
;
1753 out
.w
= pv
->w
/ norm
;
1759 D3DXVECTOR4
* WINAPI
D3DXVec4Transform(D3DXVECTOR4
*pout
, CONST D3DXVECTOR4
*pv
, CONST D3DXMATRIX
*pm
)
1762 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
;
1763 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
;
1764 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
;
1765 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
;
1770 D3DXVECTOR4
* WINAPI
D3DXVec4TransformArray(D3DXVECTOR4
* out
, UINT outstride
, CONST D3DXVECTOR4
* in
, UINT instride
, CONST D3DXMATRIX
* matrix
, UINT elements
)
1774 for (i
= 0; i
< elements
; ++i
) {
1776 (D3DXVECTOR4
*)((char*)out
+ outstride
* i
),
1777 (CONST D3DXVECTOR4
*)((const char*)in
+ instride
* i
),
1783 static inline unsigned short float_32_to_16(const float in
)
1785 int exp
= 0, origexp
;
1786 float tmp
= fabs(in
);
1787 int sign
= (copysignf(1, in
) < 0);
1788 unsigned int mantissa
;
1791 /* Deal with special numbers */
1792 if (isinf(in
)) return (sign
? 0xffff : 0x7fff);
1793 if (isnan(in
)) return (sign
? 0xffff : 0x7fff);
1794 if (in
== 0.0f
) return (sign
? 0x8000 : 0x0000);
1796 if (tmp
< powf(2, 10))
1802 } while (tmp
< powf(2, 10));
1804 else if (tmp
>= powf(2, 11))
1810 } while (tmp
>= powf(2, 11));
1813 exp
+= 10; /* Normalize the mantissa */
1814 exp
+= 15; /* Exponent is encoded with excess 15 */
1818 mantissa
= (unsigned int) tmp
;
1819 if ((tmp
- mantissa
== 0.5f
&& mantissa
% 2 == 1) || /* round half to even */
1820 (tmp
- mantissa
> 0.5f
))
1822 mantissa
++; /* round to nearest, away from zero */
1824 if (mantissa
== 2048)
1833 ret
= 0x7fff; /* INF */
1837 unsigned int rounding
= 0;
1839 /* Denormalized half float */
1841 /* return 0x0000 (=0.0) for numbers too small to represent in half floats */
1843 return (sign
? 0x8000 : 0x0000);
1847 /* the 13 extra bits from single precision are used for rounding */
1848 mantissa
= (unsigned int)(tmp
* powf(2, 13));
1849 mantissa
>>= 1 - exp
; /* denormalize */
1851 mantissa
-= ~(mantissa
>> 13) & 1; /* round half to even */
1852 /* remove 13 least significant bits to get half float precision */
1854 rounding
= mantissa
& 1;
1857 ret
= mantissa
+ rounding
;
1861 ret
= (exp
<< 10) | (mantissa
& 0x3ff);
1864 ret
|= ((sign
? 1 : 0) << 15); /* Add the sign */
1868 D3DXFLOAT16
*WINAPI
D3DXFloat32To16Array(D3DXFLOAT16
*pout
, CONST FLOAT
*pin
, UINT n
)
1872 for (i
= 0; i
< n
; ++i
)
1874 pout
[i
].value
= float_32_to_16(pin
[i
]);
1880 /* Native d3dx9's D3DXFloat16to32Array lacks support for NaN and Inf. Specifically, e = 16 is treated as a
1881 * regular number - e.g., 0x7fff is converted to 131008.0 and 0xffff to -131008.0. */
1882 static inline float float_16_to_32(const unsigned short in
)
1884 const unsigned short s
= (in
& 0x8000);
1885 const unsigned short e
= (in
& 0x7C00) >> 10;
1886 const unsigned short m
= in
& 0x3FF;
1887 const float sgn
= (s
? -1.0f
: 1.0f
);
1891 if (m
== 0) return sgn
* 0.0f
; /* +0.0 or -0.0 */
1892 else return sgn
* powf(2, -14.0f
) * (m
/ 1024.0f
);
1896 return sgn
* powf(2, e
- 15.0f
) * (1.0f
+ (m
/ 1024.0f
));
1900 FLOAT
*WINAPI
D3DXFloat16To32Array(FLOAT
*pout
, CONST D3DXFLOAT16
*pin
, UINT n
)
1904 for (i
= 0; i
< n
; ++i
)
1906 pout
[i
] = float_16_to_32(pin
[i
].value
);
1912 FLOAT
* WINAPI
D3DXSHAdd(FLOAT
*out
, UINT order
, const FLOAT
*a
, const FLOAT
*b
)
1916 TRACE("out %p, order %u, a %p, b %p\n", out
, order
, a
, b
);
1918 for (i
= 0; i
< order
* order
; i
++)
1919 out
[i
] = a
[i
] + b
[i
];