1 /***********************************************************************\
2 *                              d3dx10math.d                             *
3 *                                                                       *
4 *                       Windows API header module                       *
5 *                                                                       *
6 *                       Placed into public domain                       *
7 \***********************************************************************/
8 module win32.directx.d3dx10math;
9 
10 version(Tango) {
11     import tango.math.Math;
12     alias sqrt sqrtf;
13 } else {
14     import std.c.math;
15 }
16 
17 private import win32.windows;
18 private import win32.directx.d3dx10;
19 
20 struct D3DVECTOR {
21 	float x;
22 	float y;
23 	float z;
24 }
25 
26 struct D3DMATRIX {
27 	union {
28 		struct {
29 			float _11, _12, _13, _14;
30 			float _21, _22, _23, _24;
31 			float _31, _32, _33, _34;
32 			float _41, _42, _43, _44;
33 		}
34 		float[4][4] m;
35 	}
36 }
37 
38 const D3DX_PI = 3.14159265358979323846;
39 const D3DX_1BYPI = 1.0 / D3DX_PI;
40 
41 float D3DXToRadian(float degree) {
42 	return degree * (D3DX_PI / 180.0);
43 }
44 
45 float D3DXToDegree(float radian) {
46 	return radian * (180.0 / D3DX_PI);
47 }
48 
49 const D3DX_16F_DIG			= 3;
50 const D3DX_16F_EPSILON		= 4.8875809e-4f;
51 const D3DX_16F_MANT_DIG		= 11;
52 const D3DX_16F_MAX			= 6.550400e+004;
53 const D3DX_16F_MAX_10_EXP	= 4;
54 const D3DX_16F_MAX_EXP		= 15;
55 const D3DX_16F_MIN			= 6.1035156e-5f;
56 const D3DX_16F_MIN_10_EXP	= -4;
57 const D3DX_16F_MIN_EXP		= -14;
58 const D3DX_16F_RADIX		= 2;
59 const D3DX_16F_ROUNDS		= 1;
60 const D3DX_16F_SIGN_MASK	= 0x8000;
61 const D3DX_16F_EXP_MASK		= 0x7C00;
62 const D3DX_16F_FRAC_MASK	= 0x03FF;
63 
64 struct D3DXFLOAT16 {
65 	//TODO
66 protected:
67     WORD value;
68 }
69 
70 struct D3DXVECTOR2 {
71 	//TODO
72 	float x, y;
73 }
74 
75 struct D3DXVECTOR2_16F {
76 	//TODO
77 	D3DXFLOAT16 x, y;
78 }
79 
80 struct D3DXVECTOR3 {
81 	//TODO
82 	float x, y, z;
83 }
84 
85 struct D3DXVECTOR3_16F {
86 	//TODO
87 	D3DXFLOAT16 x, y, z;
88 }
89 
90 struct D3DXVECTOR4 {
91 	//TODO
92 	float x, y, z, w;
93 }
94 
95 struct D3DXVECTOR4_16F {
96 	//TODO
97 	D3DXFLOAT16 x, y, z, w;
98 }
99 
100 struct D3DXMATRIX {
101 	//TODO
102 	union {
103 		struct {
104 			float _11, _12, _13, _14;
105 			float _21, _22, _23, _24;
106 			float _31, _32, _33, _34;
107 			float _41, _42, _43, _44;
108 		}
109 		float[4][4] m;
110 	}
111 }
112 
113 //TODO struct _D3DXMATRIXA16 : D3DXMATRIX
114 
115 struct D3DXQUATERNION {
116 	//TODO
117 	float x, y, z, w;
118 }
119 
120 struct D3DXPLANE {
121 	//TODO
122 	float a, b, c, d;
123 }
124 
125 struct D3DXCOLOR {
126 	//TODO
127 	float r, g, b, a;
128 }
129 
130 extern(Windows) {
131 	D3DXFLOAT16* D3DXFloat32To16Array(D3DXFLOAT16* pOut, float* pIn, UINT n);
132 	float* D3DXFloat16To32Array(float* pOut, D3DXFLOAT16* pIn, UINT n);
133 }
134 
135 float D3DXVec2Length(D3DXVECTOR2* pV) {
136 	debug(D3DX10_DEBUG) {
137 		if (pV is null) return 0.0;
138 	}
139 	return sqrtf((pV.x * pV.x) + (pV.y * pV.y));
140 }
141 
142 float D3DXVec2LengthSq(D3DXVECTOR2* pV) {
143 	debug(D3DX10_DEBUG) {
144 		if (pV is null) return 0.0;
145 	}
146 	return (pV.x * pV.x) + (pV.y * pV.y);
147 }
148 
149 float D3DXVec2Dot(D3DXVECTOR2* pV1, D3DXVECTOR2* pV2) {
150 	debug(D3DX10_DEBUG) {
151 		if ((pV1 is null) || (pV2 is null)) return 0.0;
152 	}
153 	return (pV1.x * pV2.x) + (pV1.y * pV2.y);
154 }
155 
156 float D3DXVec2CCW(D3DXVECTOR2* pV1, D3DXVECTOR2* pV2) {
157 	debug(D3DX10_DEBUG) {
158 		if ((pV1 is null) || (pV2 is null)) return 0.0;
159 	}
160 	return (pV1.x * pV2.y) + (pV1.y * pV2.x);
161 }
162 
163 D3DXVECTOR2* D3DXVec2Add(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2) {
164 	debug(D3DX10_DEBUG) {
165 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
166 	}
167 	pOut.x = pV1.x + pV2.x;
168 	pOut.y = pV1.y + pV2.y;
169 	return pOut;
170 }
171 
172 D3DXVECTOR2* D3DXVec2Subtract(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2) {
173 	debug(D3DX10_DEBUG) {
174 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
175 	}
176 	pOut.x = pV1.x - pV2.x;
177 	pOut.y = pV1.y - pV2.y;
178 	return pOut;
179 }
180 
181 D3DXVECTOR2* D3DXVec2Minimize(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2) {
182 	debug(D3DX10_DEBUG) {
183 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
184 	}
185 	pOut.x = pV1.x < pV2.x ? pV1.x : pV2.x;
186 	pOut.y = pV1.y < pV2.y ? pV1.y : pV2.y;
187 	return pOut;
188 }
189 
190 D3DXVECTOR2* D3DXVec2Maximize(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2) {
191 	debug(D3DX10_DEBUG) {
192 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
193 	}
194 	pOut.x = pV1.x > pV2.x ? pV1.x : pV2.x;
195 	pOut.y = pV1.y > pV2.y ? pV1.y : pV2.y;
196 	return pOut;
197 }
198 
199 D3DXVECTOR2* D3DXVec2Scale(D3DXVECTOR2* pOut, D3DXVECTOR2* pV, float s) {
200 	debug(D3DX10_DEBUG) {
201 		if ((pOut is null) || (pV is null)) return null;
202 	}
203 	pOut.x = pV.x * s;
204 	pOut.y = pV.y * s;
205 	return pOut;
206 }
207 
208 D3DXVECTOR2* D3DXVec2Lerp(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2, float s) {
209 	debug(D3DX10_DEBUG) {
210 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
211 	}
212 	pOut.x = pV1.x + s * (pV2.x - pV1.x);
213 	pOut.y = pV1.y + s * (pV2.y - pV1.y);
214 	return pOut;
215 }
216 
217 extern(Windows) {
218 	D3DXVECTOR2* D3DXVec2Normalize(D3DXVECTOR2* pOut, D3DXVECTOR2* pV);
219 	D3DXVECTOR2* D3DXVec2Hermite(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pT1, D3DXVECTOR2* pV2, D3DXVECTOR2* pT2, float s);
220 	D3DXVECTOR2* D3DXVec2CatmullRom(D3DXVECTOR2* pOut, D3DXVECTOR2* pV0, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2, D3DXVECTOR2* pV3, float s);
221 	D3DXVECTOR2* D3DXVec2BaryCentric(D3DXVECTOR2* pOut, D3DXVECTOR2* pV1, D3DXVECTOR2* pV2, D3DXVECTOR2* pV3, float f, float g);
222 	D3DXVECTOR4* D3DXVec2Transform(D3DXVECTOR4* pOut, D3DXVECTOR2* pV, D3DXMATRIX* pM);
223 	D3DXVECTOR2* D3DXVec2TransformCoord(D3DXVECTOR2* pOut, D3DXVECTOR2* pV, D3DXMATRIX* pM);
224 	D3DXVECTOR2* D3DXVec2TransformNormal(D3DXVECTOR2* pOut, D3DXVECTOR2* pV, D3DXMATRIX* pM);
225 	D3DXVECTOR4* D3DXVec2TransformArray(D3DXVECTOR4* pOut, UINT OutStride, D3DXVECTOR2* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
226 	D3DXVECTOR2* D3DXVec2TransformCoordArray(D3DXVECTOR2* pOut, UINT OutStride, D3DXVECTOR2* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
227 	D3DXVECTOR2* D3DXVec2TransformNormalArray(D3DXVECTOR2* pOut, UINT OutStride, D3DXVECTOR2* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
228 }
229 
230 float D3DXVec3Length(D3DXVECTOR3* pV) {
231 	debug(D3DX10_DEBUG) {
232 		if (pV is null) return 0.0;
233 	}
234 	return sqrtf((pV.x * pV.x) + (pV.y * pV.y) + (pV.z * pV.z));
235 }
236 
237 float D3DXVec3LengthSq(D3DXVECTOR3* pV) {
238 	debug(D3DX10_DEBUG) {
239 		if (pV is null) return 0.0;
240 	}
241 	return (pV.x * pV.x) + (pV.y * pV.y) + (pV.z * pV.z);
242 }
243 
244 float D3DXVec3Dot(D3DXVECTOR3* pV1, D3DXVECTOR3* pV2) {
245 	debug(D3DX10_DEBUG) {
246 		if ((pV1 is null) || (pV2 is null)) return 0.0;
247 	}
248 	return (pV1.x * pV2.x) + (pV1.y * pV2.y) + (pV1.z * pV2.z);
249 }
250 
251 D3DXVECTOR3* D3DXVec3Cross(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2) {
252 	debug(D3DX10_DEBUG) {
253 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return 0.0;
254 	}
255 	D3DXVECTOR3 v;
256 	v.x = (pV1.y * pV2.z) - (pV1.z * pV2.y);
257 	v.y = (pV1.z * pV2.x) - (pV1.x * pV2.z);
258 	v.z = (pV1.x * pV2.y) - (pV1.y * pV2.x);
259 	*pOut = v;
260 	return pOut;
261 }
262 
263 D3DXVECTOR3* D3DXVec3Add(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2) {
264 	debug(D3DX10_DEBUG) {
265 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
266 	}
267 	pOut.x = pV1.x + pV2.x;
268 	pOut.y = pV1.y + pV2.y;
269 	pOut.z = pV1.z + pV2.z;
270 	return pOut;
271 }
272 
273 D3DXVECTOR3* D3DXVec3Subtract(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2) {
274 	debug(D3DX10_DEBUG) {
275 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
276 	}
277 	pOut.x = pV1.x - pV2.x;
278 	pOut.y = pV1.y - pV2.y;
279 	pOut.z = pV1.z - pV2.z;
280 	return pOut;
281 }
282 
283 D3DXVECTOR3* D3DXVec3Minimize(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2) {
284 	debug(D3DX10_DEBUG) {
285 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
286 	}
287 	pOut.x = pV1.x < pV2.x ? pV1.x : pV2.x;
288 	pOut.y = pV1.y < pV2.y ? pV1.y : pV2.y;
289 	pOut.z = pV1.z < pV2.z ? pV1.z : pV2.z;
290 	return pOut;
291 }
292 
293 D3DXVECTOR3* D3DXVec3Maximize(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2) {
294 	debug(D3DX10_DEBUG) {
295 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
296 	}
297 	pOut.x = pV1.x > pV2.x ? pV1.x : pV2.x;
298 	pOut.y = pV1.y > pV2.y ? pV1.y : pV2.y;
299 	pOut.z = pV1.z > pV2.z ? pV1.z : pV2.z;
300 	return pOut;
301 }
302 
303 D3DXVECTOR3* D3DXVec3Scale(D3DXVECTOR3* pOut, D3DXVECTOR3* pV, float s) {
304 	debug(D3DX10_DEBUG) {
305 		if ((pOut is null) || (pV is null)) return null;
306 	}
307 	pOut.x = pV.x * s;
308 	pOut.y = pV.y * s;
309 	pOut.z = pV.z * s;
310 	return pOut;
311 }
312 
313 D3DXVECTOR3* D3DXVec3Lerp(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2, float s) {
314 	debug(D3DX10_DEBUG) {
315 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
316 	}
317 	pOut.x = pV1.x + s * (pV2.x - pV1.x);
318 	pOut.y = pV1.y + s * (pV2.y - pV1.y);
319 	pOut.z = pV1.z + s * (pV2.z - pV1.z);
320 	return pOut;
321 }
322 
323 extern(Windows) {
324 	D3DXVECTOR3* D3DXVec3Normalize(D3DXVECTOR3* pOut, D3DXVECTOR3* pV);
325 	D3DXVECTOR3* D3DXVec3Hermite(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pT1, D3DXVECTOR3* pV2, D3DXVECTOR3* pT2, FLOAT s);
326 	D3DXVECTOR3* D3DXVec3CatmullRom(D3DXVECTOR3* pOut, D3DXVECTOR3* pV0, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2, D3DXVECTOR3* pV3, FLOAT s);
327 	D3DXVECTOR3* D3DXVec3BaryCentric(D3DXVECTOR3* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2, D3DXVECTOR3* pV3, FLOAT f, FLOAT g);
328 	D3DXVECTOR4* D3DXVec3Transform(D3DXVECTOR4* pOut, D3DXVECTOR3* pV, D3DXMATRIX* pM);
329 	D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3* pOut, D3DXVECTOR3* pV, D3DXMATRIX* pM);
330 	D3DXVECTOR3* D3DXVec3TransformNormal(D3DXVECTOR3* pOut, D3DXVECTOR3* pV, D3DXMATRIX* pM);
331 	D3DXVECTOR4* D3DXVec3TransformArray(D3DXVECTOR4* pOut, UINT OutStride, D3DXVECTOR3* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
332 	D3DXVECTOR3* D3DXVec3TransformCoordArray(D3DXVECTOR3* pOut, UINT OutStride, D3DXVECTOR3* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
333 	D3DXVECTOR3* D3DXVec3TransformNormalArray(D3DXVECTOR3* pOut, UINT OutStride, D3DXVECTOR3* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
334 	D3DXVECTOR3* D3DXVec3Project(D3DXVECTOR3* pOut, D3DXVECTOR3* pV, D3D10_VIEWPORT* pViewport, D3DXMATRIX* pProjection, D3DXMATRIX* pView, D3DXMATRIX* pWorld);
335 	D3DXVECTOR3* D3DXVec3Unproject(D3DXVECTOR3* pOut, D3DXVECTOR3* pV, D3D10_VIEWPORT* pViewport, D3DXMATRIX* pProjection, D3DXMATRIX* pView, D3DXMATRIX* pWorld);
336 	D3DXVECTOR3* D3DXVec3ProjectArray(D3DXVECTOR3* pOut, UINT OutStride,D3DXVECTOR3* pV, UINT VStride,D3D10_VIEWPORT* pViewport, D3DXMATRIX* pProjection, D3DXMATRIX* pView, D3DXMATRIX* pWorld, UINT n);
337 	D3DXVECTOR3* D3DXVec3UnprojectArray(D3DXVECTOR3* pOut, UINT OutStride, D3DXVECTOR3* pV, UINT VStride, D3D10_VIEWPORT* pViewport, D3DXMATRIX* pProjection, D3DXMATRIX* pView, D3DXMATRIX* pWorld, UINT n);
338 }
339 
340 float D3DXVec4Length(D3DXVECTOR4* pV) {
341 	debug(D3DX10_DEBUG) {
342 		if (pV is null) return 0.0;
343 	}
344 	return sqrtf((pV.x * pV.x) + (pV.y * pV.y) + (pV.z * pV.z) + (pV.w * pV.w));
345 }
346 
347 float D3DXVec4LengthSq(D3DXVECTOR4* pV) {
348 	debug(D3DX10_DEBUG) {
349 		if (pV is null) return 0.0;
350 	}
351 	return (pV.x * pV.x) + (pV.y * pV.y) + (pV.z * pV.z) + (pV.w * pV.w);
352 }
353 
354 float D3DXVec4Dot(D3DXVECTOR4* pV1, D3DXVECTOR4* pV2) {
355 	debug(D3DX10_DEBUG) {
356 		if ((pV1 is null) || (pV2 is null)) return 0.0;
357 	}
358 	return (pV1.x * pV2.x) + (pV1.y * pV2.y) + (pV1.z * pV2.z) + (pV1.w * pV2.w);
359 }
360 
361 D3DXVECTOR4* D3DXVec4Add(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2) {
362 	debug(D3DX10_DEBUG) {
363 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
364 	}
365 	pOut.x = pV1.x + pV2.x;
366 	pOut.y = pV1.y + pV2.y;
367 	pOut.z = pV1.z + pV2.z;
368 	pOut.w = pV1.w + pV2.w;
369 	return pOut;
370 }
371 
372 D3DXVECTOR4* D3DXVec4Subtract(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2) {
373 	debug(D3DX10_DEBUG) {
374 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
375 	}
376 	pOut.x = pV1.x - pV2.x;
377 	pOut.y = pV1.y - pV2.y;
378 	pOut.z = pV1.z - pV2.z;
379 	pOut.w = pV1.w - pV2.w;
380 	return pOut;
381 }
382 
383 D3DXVECTOR4* D3DXVec4Minimize(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2) {
384 	debug(D3DX10_DEBUG) {
385 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
386 	}
387 	pOut.x = pV1.x < pV2.x ? pV1.x : pV2.x;
388 	pOut.y = pV1.y < pV2.y ? pV1.y : pV2.y;
389 	pOut.z = pV1.z < pV2.z ? pV1.z : pV2.z;
390 	pOut.w = pV1.w < pV2.w ? pV1.w : pV2.w;
391 	return pOut;
392 }
393 
394 D3DXVECTOR4* D3DXVec4Maximize(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2) {
395 	debug(D3DX10_DEBUG) {
396 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
397 	}
398 	pOut.x = pV1.x > pV2.x ? pV1.x : pV2.x;
399 	pOut.y = pV1.y > pV2.y ? pV1.y : pV2.y;
400 	pOut.z = pV1.z > pV2.z ? pV1.z : pV2.z;
401 	pOut.w = pV1.w > pV2.w ? pV1.w : pV2.w;
402 	return pOut;
403 }
404 
405 D3DXVECTOR4* D3DXVec4Scale(D3DXVECTOR4* pOut, D3DXVECTOR4* pV, float s) {
406 	debug(D3DX10_DEBUG) {
407 		if ((pOut is null) || (pV is null)) return null;
408 	}
409 	pOut.x = pV.x * s;
410 	pOut.y = pV.y * s;
411 	pOut.z = pV.z * s;
412 	pOut.w = pV.w * s;
413 	return pOut;
414 }
415 
416 D3DXVECTOR4* D3DXVec4Lerp(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2, float s) {
417 	debug(D3DX10_DEBUG) {
418 		if ((pOut is null) || (pV1 is null) || (pV2 is null)) return null;
419 	}
420 	pOut.x = pV1.x + s * (pV2.x - pV1.x);
421 	pOut.y = pV1.y + s * (pV2.y - pV1.y);
422 	pOut.z = pV1.z + s * (pV2.z - pV1.z);
423 	pOut.w = pV1.w + s * (pV2.w - pV1.w);
424 	return pOut;
425 }
426 
427 extern(Windows) {
428 	D3DXVECTOR4* D3DXVec4Cross(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2, D3DXVECTOR4* pV3);
429 	D3DXVECTOR4* D3DXVec4Normalize(D3DXVECTOR4* pOut, D3DXVECTOR4* pV);
430 	D3DXVECTOR4* D3DXVec4Hermite(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pT1, D3DXVECTOR4* pV2, D3DXVECTOR4* pT2, FLOAT s);
431 	D3DXVECTOR4* D3DXVec4CatmullRom(D3DXVECTOR4* pOut, D3DXVECTOR4* pV0, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2, D3DXVECTOR4* pV3, FLOAT s);
432 	D3DXVECTOR4* D3DXVec4BaryCentric(D3DXVECTOR4* pOut, D3DXVECTOR4* pV1, D3DXVECTOR4* pV2, D3DXVECTOR4* pV3, FLOAT f, FLOAT g);
433 	D3DXVECTOR4* D3DXVec4Transform(D3DXVECTOR4* pOut, D3DXVECTOR4* pV, D3DXMATRIX* pM);
434 	D3DXVECTOR4* D3DXVec4TransformArray(D3DXVECTOR4* pOut, UINT OutStride, D3DXVECTOR4* pV, UINT VStride, D3DXMATRIX* pM, UINT n);
435 }
436 
437 D3DXMATRIX* D3DXMatrixIdentity(D3DXMATRIX *pOut) {
438 	debug(D3DX10_DEBUG) {
439 		if (pOut is null) return NULL;
440 	}
441 	pOut.m[0][1] = pOut.m[0][2] = pOut.m[0][3] =
442 	pOut.m[1][0] = pOut.m[1][2] = pOut.m[1][3] =
443 	pOut.m[2][0] = pOut.m[2][1] = pOut.m[2][3] =
444 	pOut.m[3][0] = pOut.m[3][1] = pOut.m[3][2] = 0.0;
445 	pOut.m[0][0] = pOut.m[1][1] = pOut.m[2][2] = pOut.m[3][3] = 1.0;
446 	return pOut;
447 }
448 
449 
450 BOOL D3DXMatrixIsIdentity(D3DXMATRIX *pM) {
451 	debug(D3DX10_DEBUG) {
452 		if(pM is null) return FALSE;
453 	}
454 	return (pM.m[0][0] == 1.0f) && (pM.m[0][1] == 0.0f) && (pM.m[0][2] == 0.0f) && (pM.m[0][3] == 0.0f) &&
455 	       (pM.m[1][0] == 0.0f) && (pM.m[1][1] == 1.0f) && (pM.m[1][2] == 0.0f) && (pM.m[1][3] == 0.0f) &&
456 	       (pM.m[2][0] == 0.0f) && (pM.m[2][1] == 0.0f) && (pM.m[2][2] == 1.0f) && (pM.m[2][3] == 0.0f) &&
457 	       (pM.m[3][0] == 0.0f) && (pM.m[3][1] == 0.0f) && (pM.m[3][2] == 0.0f) && (pM.m[3][3] == 1.0f);
458 }
459 
460 extern(Windows) {
461 	FLOAT D3DXMatrixDeterminant(D3DXMATRIX* pM);
462 	HRESULT D3DXMatrixDecompose(D3DXVECTOR3* pOutScale, D3DXQUATERNION* pOutRotation, D3DXVECTOR3* pOutTranslation, D3DXMATRIX* pM);
463 	D3DXMATRIX* D3DXMatrixTranspose(D3DXMATRIX* pOut, D3DXMATRIX* pM);
464 	D3DXMATRIX* D3DXMatrixMultiply(D3DXMATRIX* pOut, D3DXMATRIX* pM1, D3DXMATRIX* pM2);
465 	D3DXMATRIX* D3DXMatrixMultiplyTranspose(D3DXMATRIX* pOut, D3DXMATRIX* pM1, D3DXMATRIX* pM2);
466 	D3DXMATRIX* D3DXMatrixInverse(D3DXMATRIX* pOut, FLOAT* pDeterminant, D3DXMATRIX* pM);
467 	D3DXMATRIX* D3DXMatrixScaling(D3DXMATRIX* pOut, FLOAT sx, FLOAT sy, FLOAT sz);
468 	D3DXMATRIX* D3DXMatrixTranslation(D3DXMATRIX* pOut, FLOAT x, FLOAT y, FLOAT z);
469 	D3DXMATRIX* D3DXMatrixRotationX(D3DXMATRIX* pOut, FLOAT Angle);
470 	D3DXMATRIX* D3DXMatrixRotationY(D3DXMATRIX* pOut, FLOAT Angle);
471 	D3DXMATRIX* D3DXMatrixRotationZ(D3DXMATRIX* pOut, FLOAT Angle);
472 	D3DXMATRIX* D3DXMatrixRotationAxis(D3DXMATRIX* pOut, D3DXVECTOR3* pV, FLOAT Angle);
473 	D3DXMATRIX* D3DXMatrixRotationQuaternion(D3DXMATRIX* pOut, D3DXQUATERNION* pQ);
474 	D3DXMATRIX* D3DXMatrixRotationYawPitchRoll(D3DXMATRIX* pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll);
475 	D3DXMATRIX* D3DXMatrixTransformation(D3DXMATRIX* pOut, D3DXVECTOR3* pScalingCenter, D3DXQUATERNION* pScalingRotation, D3DXVECTOR3* pScaling, D3DXVECTOR3* pRotationCenter, D3DXQUATERNION* pRotation, D3DXVECTOR3* pTranslation);
476 	D3DXMATRIX* D3DXMatrixTransformation2D(D3DXMATRIX* pOut, D3DXVECTOR2* pScalingCenter, FLOAT ScalingRotation, D3DXVECTOR2* pScaling, D3DXVECTOR2* pRotationCenter, FLOAT Rotation, D3DXVECTOR2* pTranslation);
477 	D3DXMATRIX* D3DXMatrixAffineTransformation(D3DXMATRIX* pOut, FLOAT Scaling, D3DXVECTOR3* pRotationCenter, D3DXQUATERNION* pRotation, D3DXVECTOR3* pTranslation);
478 	D3DXMATRIX* D3DXMatrixAffineTransformation2D(D3DXMATRIX* pOut, FLOAT Scaling, D3DXVECTOR2* pRotationCenter, FLOAT Rotation, D3DXVECTOR2* pTranslation);
479 	D3DXMATRIX* D3DXMatrixLookAtRH(D3DXMATRIX* pOut, D3DXVECTOR3* pEye, D3DXVECTOR3* pAt, D3DXVECTOR3* pUp);
480 	D3DXMATRIX* D3DXMatrixLookAtLH(D3DXMATRIX* pOut, D3DXVECTOR3* pEye, D3DXVECTOR3* pAt, D3DXVECTOR3* pUp);
481 	D3DXMATRIX* D3DXMatrixPerspectiveRH(D3DXMATRIX* pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf);
482 	D3DXMATRIX* D3DXMatrixPerspectiveLH(D3DXMATRIX* pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf);
483 	D3DXMATRIX* D3DXMatrixPerspectiveFovRH(D3DXMATRIX* pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf);
484 	D3DXMATRIX* D3DXMatrixPerspectiveFovLH(D3DXMATRIX* pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf);
485 	D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH(D3DXMATRIX* pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf);
486 	D3DXMATRIX* D3DXMatrixPerspectiveOffCenterLH(D3DXMATRIX* pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf);
487 	D3DXMATRIX* D3DXMatrixOrthoRH(D3DXMATRIX* pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf);
488 	D3DXMATRIX* D3DXMatrixOrthoLH(D3DXMATRIX* pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf);
489 	D3DXMATRIX* D3DXMatrixOrthoOffCenterRH(D3DXMATRIX* pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf);
490 	D3DXMATRIX* D3DXMatrixOrthoOffCenterLH(D3DXMATRIX* pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf);
491 	D3DXMATRIX* D3DXMatrixShadow(D3DXMATRIX* pOut, D3DXVECTOR4* pLight, D3DXPLANE* pPlane);
492 	D3DXMATRIX* D3DXMatrixReflect(D3DXMATRIX* pOut, D3DXPLANE* pPlane);
493 }
494 
495 float D3DXQuaternionLength(D3DXQUATERNION *pQ) {
496 	debug(D3DX10_DEBUG) {
497 		if (pQ is null) return 0.0f;
498 	}
499     return sqrtf((pQ.x * pQ.x) + (pQ.y * pQ.y) + (pQ.z * pQ.z) + (pQ.w * pQ.w));
500 }
501 
502 float D3DXQuaternionLengthSq(D3DXQUATERNION *pQ) {
503 	debug(D3DX10_DEBUG) {
504 		if(pQ is null) return 0.0f;
505 	}
506     return (pQ.x * pQ.x) + (pQ.y * pQ.y) + (pQ.z * pQ.z) + (pQ.w * pQ.w);
507 }
508 
509 float D3DXQuaternionDot(D3DXQUATERNION *pQ1, D3DXQUATERNION *pQ2) {
510 	debug(D3DX10_DEBUG) {
511 		if((pQ1 is null) || (pQ2 is null)) return 0.0f;
512 	}
513     return (pQ1.x * pQ2.x) + (pQ1.y * pQ2.y) + (pQ1.z * pQ2.z) + (pQ1.w * pQ2.w);
514 }
515 
516 D3DXQUATERNION* D3DXQuaternionIdentity(D3DXQUATERNION *pOut) {
517 	debug(D3DX10_DEBUG) {
518 		if(pOut is null) return null;
519 	}
520     pOut.x = pOut.y = pOut.z = 0.0f;
521     pOut.w = 1.0f;
522     return pOut;
523 }
524 
525 bool D3DXQuaternionIsIdentity(D3DXQUATERNION *pQ) {
526 	debug(D3DX10_DEBUG) {
527 		if(pQ is null) return false;
528 	}
529     return (pQ.x == 0.0f) && (pQ.y == 0.0f) && (pQ.z == 0.0f) && (pQ.w == 1.0f);
530 }
531 
532 D3DXQUATERNION* D3DXQuaternionConjugate(D3DXQUATERNION *pOut, D3DXQUATERNION *pQ) {
533 	debug(D3DX10_DEBUG) {
534 		if((pOut is null) || (pQis is null)) return null;
535 	}
536     pOut.x = -pQ.x;
537     pOut.y = -pQ.y;
538     pOut.z = -pQ.z;
539     pOut.w =  pQ.w;
540     return pOut;
541 }
542 
543 extern(Windows) {
544 	void D3DXQuaternionToAxisAngle(D3DXQUATERNION* pQ, D3DXVECTOR3* pAxis, FLOAT* pAngle);
545 	D3DXQUATERNION* D3DXQuaternionRotationMatrix(D3DXQUATERNION* pOut, D3DXMATRIX* pM);
546 	D3DXQUATERNION* D3DXQuaternionRotationAxis(D3DXQUATERNION* pOut, D3DXVECTOR3* pV, FLOAT Angle);
547 	D3DXQUATERNION* D3DXQuaternionRotationYawPitchRoll(D3DXQUATERNION* pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll);
548 	D3DXQUATERNION* D3DXQuaternionMultiply(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ1, D3DXQUATERNION* pQ2);
549 	D3DXQUATERNION* D3DXQuaternionNormalize(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ);
550 	D3DXQUATERNION* D3DXQuaternionInverse(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ);
551 	D3DXQUATERNION* D3DXQuaternionLn(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ);
552 	D3DXQUATERNION* D3DXQuaternionExp(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ);
553 	D3DXQUATERNION* D3DXQuaternionSlerp(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ1, D3DXQUATERNION* pQ2, FLOAT t);
554 	D3DXQUATERNION* D3DXQuaternionSquad(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ1, D3DXQUATERNION* pA, D3DXQUATERNION* pB, D3DXQUATERNION* pC, FLOAT t);
555 	void D3DXQuaternionSquadSetup(D3DXQUATERNION* pAOut, D3DXQUATERNION* pBOut, D3DXQUATERNION* pCOut, D3DXQUATERNION* pQ0, D3DXQUATERNION* pQ1, D3DXQUATERNION* pQ2, D3DXQUATERNION* pQ3);
556 	D3DXQUATERNION* D3DXQuaternionBaryCentric(D3DXQUATERNION* pOut, D3DXQUATERNION* pQ1, D3DXQUATERNION* pQ2, D3DXQUATERNION* pQ3, FLOAT f, FLOAT g);
557 }
558 
559 float D3DXPlaneDot(D3DXPLANE *pP, D3DXVECTOR4 *pV) {
560 	debug(D3DX10_DEBUG) {
561 		if((pP is null) || (pV is null)) return 0.0f;
562 	}
563     return (pP.a * pV.x) + (pP.b * pV.y) + (pP.c * pV.z) + (pP.d * pV.w);
564 }
565 
566 float D3DXPlaneDotCoord(D3DXPLANE *pP, D3DXVECTOR3 *pV) {
567 	debug(D3DX10_DEBUG) {
568 		if((pP is null) || (pV is null)) return 0.0f;
569 	}
570     return (pP.a * pV.x) + (pP.b * pV.y) + (pP.c * pV.z) + pP.d;
571 }
572 
573 float D3DXPlaneDotNormal(D3DXPLANE *pP, D3DXVECTOR3 *pV) {
574 	debug(D3DX10_DEBUG) {
575 		if((pP is null) || (pV is null)) return 0.0f;
576 	}
577     return (pP.a * pV.x) + (pP.b * pV.y) + (pP.c * pV.z);
578 }
579 
580 D3DXPLANE* D3DXPlaneScale(D3DXPLANE *pOut, D3DXPLANE *pP, float s) {
581 	debug(D3DX10_DEBUG) {
582 		if((pOut is null) || (pP is null)) return null;
583 	}
584     pOut.a = pP.a * s;
585     pOut.b = pP.b * s;
586     pOut.c = pP.c * s;
587     pOut.d = pP.d * s;
588     return pOut;
589 }
590 
591 extern(Windows) {
592 	D3DXPLANE* D3DXPlaneNormalize(D3DXPLANE* pOut, D3DXPLANE* pP);
593 	D3DXVECTOR3* D3DXPlaneIntersectLine(D3DXVECTOR3* pOut, D3DXPLANE* pP, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2);
594 	D3DXPLANE* D3DXPlaneFromPointNormal(D3DXPLANE* pOut, D3DXVECTOR3* pPoint, D3DXVECTOR3* pNormal);
595 	D3DXPLANE* D3DXPlaneFromPoints(D3DXPLANE* pOut, D3DXVECTOR3* pV1, D3DXVECTOR3* pV2, D3DXVECTOR3* pV3);
596 	D3DXPLANE* D3DXPlaneTransform(D3DXPLANE* pOut, D3DXPLANE* pP, D3DXMATRIX* pM);
597 	D3DXPLANE* D3DXPlaneTransformArray(D3DXPLANE* pOut, UINT OutStride, D3DXPLANE* pP, UINT PStride, D3DXMATRIX* pM, UINT n);
598 }
599 
600 D3DXCOLOR* D3DXColorNegative(D3DXCOLOR* pOut, D3DXCOLOR* pC) {
601 	debug(D3DX10_DEBUG) {
602 		if((pOut is null) || (pC is null)) return null;
603 	}
604     pOut.r = 1.0f - pC.r;
605     pOut.g = 1.0f - pC.g;
606     pOut.b = 1.0f - pC.b;
607     pOut.a = pC.a;
608     return pOut;
609 }
610 
611 D3DXCOLOR* D3DXColorAdd(D3DXCOLOR* pOut, D3DXCOLOR* pC1, D3DXCOLOR* pC2) {
612 	debug(D3DX10_DEBUG) {
613 		if((pOut is null) || (pC1 is null) || (pC2 is null)) return null;
614 	}
615     pOut.r = pC1.r + pC2.r;
616     pOut.g = pC1.g + pC2.g;
617     pOut.b = pC1.b + pC2.b;
618     pOut.a = pC1.a + pC2.a;
619     return pOut;
620 }
621 
622 D3DXCOLOR* D3DXColorSubtract(D3DXCOLOR* pOut, D3DXCOLOR* pC1, D3DXCOLOR* pC2) {
623 	debug(D3DX10_DEBUG) {
624 		if((pOut is null) || (pC1 is null) || (pC2 is null)) return null;
625 	}
626     pOut.r = pC1.r - pC2.r;
627     pOut.g = pC1.g - pC2.g;
628     pOut.b = pC1.b - pC2.b;
629     pOut.a = pC1.a - pC2.a;
630     return pOut;
631 }
632 
633 D3DXCOLOR* D3DXColorScale(D3DXCOLOR* pOut, D3DXCOLOR* pC, float s) {
634 	debug(D3DX10_DEBUG) {
635 		if((pOut is null) || (pC is null)) return null;
636 	}
637     pOut.r = pC.r * s;
638     pOut.g = pC.g * s;
639     pOut.b = pC.b * s;
640     pOut.a = pC.a * s;
641     return pOut;
642 }
643 
644 D3DXCOLOR* D3DXColorModulate(D3DXCOLOR* pOut, D3DXCOLOR* pC1, D3DXCOLOR* pC2) {
645 	debug(D3DX10_DEBUG) {
646 		if((pOut is null) || (pC1 is null) || (pC2 is null)) return null;
647 	}
648     pOut.r = pC1.r * pC2.r;
649     pOut.g = pC1.g * pC2.g;
650     pOut.b = pC1.b * pC2.b;
651     pOut.a = pC1.a * pC2.a;
652     return pOut;
653 }
654 
655 D3DXCOLOR* D3DXColorLerp(D3DXCOLOR* pOut, D3DXCOLOR* pC1, D3DXCOLOR* pC2, float s) {
656 	debug(D3DX10_DEBUG) {
657 		if((pOut is null) || (pC1 is null) || (pC2 is null)) return null;
658 	}
659     pOut.r = pC1.r + s * (pC2.r - pC1.r);
660     pOut.g = pC1.g + s * (pC2.g - pC1.g);
661     pOut.b = pC1.b + s * (pC2.b - pC1.b);
662     pOut.a = pC1.a + s * (pC2.a - pC1.a);
663     return pOut;
664 }
665 
666 extern(Windows) {
667 	D3DXCOLOR* D3DXColorAdjustSaturation(D3DXCOLOR* pOut, D3DXCOLOR* pC, float s);
668 	D3DXCOLOR* D3DXColorAdjustContrast(D3DXCOLOR* pOut, D3DXCOLOR* pC, float c);
669 	FLOAT D3DXFresnelTerm(float CosTheta, float RefractionIndex);     
670 }
671 
672 extern (C) const GUID IID_ID3DXMatrixStack = {0xc7885ba7, 0xf990, 0x4fe7, [0x92, 0x2d, 0x85, 0x15, 0xe4, 0x77, 0xdd, 0x85]};
673 
674 interface ID3DXMatrixStack : IUnknown {
675 	extern(Windows) :
676 	HRESULT Pop();
677 	HRESULT Push();
678 	HRESULT LoadIdentity();
679 	HRESULT LoadMatrix(D3DXMATRIX* pM );
680 	HRESULT MultMatrix(D3DXMATRIX* pM );
681 	HRESULT MultMatrixLocal(D3DXMATRIX* pM );
682 	HRESULT RotateAxis(D3DXVECTOR3* pV, float Angle);
683 	HRESULT RotateAxisLocal(D3DXVECTOR3* pV, float Angle);
684 	HRESULT RotateYawPitchRoll(float Yaw, float Pitch, float Roll);
685 	HRESULT RotateYawPitchRollLocal(float Yaw, float Pitch, float Roll);
686 	HRESULT Scale(float x, float y, float z);
687 	HRESULT ScaleLocal(float x, float y, float z);
688 	HRESULT Translate(float x, float y, float z );
689 	HRESULT TranslateLocal(float x, float y, float z);
690 	D3DXMATRIX* GetTop();
691 }
692 
693 //TODO extern(Windows) HRESULT D3DXCreateMatrixStack(UINT Flags, D3DXMATRIXSTACK* ppStack);
694 
695 const D3DXSH_MINORDER = 2;
696 const D3DXSH_MAXORDER = 6;
697 
698 extern(Windows) {
699 	float* D3DXSHEvalDirection(float* pOut, UINT Order, D3DXVECTOR3* pDir);
700 	float* D3DXSHRotate(float* pOut, UINT Order, D3DXMATRIX* pMatrix, float* pIn);
701 	float* D3DXSHRotateZ(float* pOut, UINT Order, float Angle, float* pIn);
702 	float* D3DXSHAdd(float* pOut, UINT Order, float* pA, float* pB);
703 	float* D3DXSHScale(float* pOut, UINT Order, float* pIn, float Scale);
704 	float D3DXSHDot(UINT Order, float* pA, float* pB);
705 	float* D3DXSHMultiply2(float* pOut, float* pF, float* pG);
706 	float* D3DXSHMultiply3(float* pOut, float* pF, float* pG);
707 	float* D3DXSHMultiply4(float* pOut, float* pF, float* pG);
708 	float* D3DXSHMultiply5(float* pOut, float* pF, float* pG);
709 	float* D3DXSHMultiply6(float* pOut, float* pF, float* pG);
710 	HRESULT D3DXSHEvalDirectionalLight(UINT Order, D3DXVECTOR3* pDir, float RIntensity, float GIntensity, float BIntensity, float* pROut, float* pGOut, float* pBOut);
711 	HRESULT D3DXSHEvalSphericalLight(UINT Order, D3DXVECTOR3* pPos, float Radius, float RIntensity, float GIntensity, float BIntensity, float* pROut, float* pGOut, float* pBOut);
712 	HRESULT D3DXSHEvalConeLight(UINT Order, D3DXVECTOR3* pDir, float Radius, float RIntensity, float GIntensity, float BIntensity, float* pROut, float* pGOut, float* pBOut);
713 	HRESULT D3DXSHEvalHemisphereLight(UINT Order, D3DXVECTOR3* pDir, D3DXCOLOR Top, D3DXCOLOR Bottom, float* pROut, float* pGOut, float* pBOut);
714 	BOOL D3DXIntersectTri(D3DXVECTOR3* p0, D3DXVECTOR3* p1, D3DXVECTOR3* p2, D3DXVECTOR3* pRayPos, D3DXVECTOR3* pRayDir, float* pU, float* pV, float* pDist);
715 	BOOL D3DXSphereBoundProbe(D3DXVECTOR3* pCenter, float Radius, D3DXVECTOR3* pRayPosition, D3DXVECTOR3* pRayDirection);
716 	BOOL D3DXBoxBoundProbe(D3DXVECTOR3* pMin, D3DXVECTOR3* pMax, D3DXVECTOR3* pRayPosition, D3DXVECTOR3* pRayDirection);
717 	HRESULT D3DXComputeBoundingSphere(D3DXVECTOR3* pFirstPosition, DWORD NumVertices, DWORD dwStride, D3DXVECTOR3* pCenter, float* pRadius);
718 	HRESULT D3DXComputeBoundingBox(D3DXVECTOR3* pFirstPosition, DWORD NumVertices, DWORD dwStride, D3DXVECTOR3* pMin, D3DXVECTOR3* pMax);
719 }
720 
721 enum D3DX_CPU_OPTIMIZATION {
722 	D3DX_NOT_OPTIMIZED = 0,
723 	D3DX_3DNOW_OPTIMIZED,
724 	D3DX_SSE2_OPTIMIZED,
725 	D3DX_SSE_OPTIMIZED
726 }
727 
728 extern(Windows) D3DX_CPU_OPTIMIZATION D3DXCpuOptimizations(bool Enable);