1 /*
2 
3 Boost Software License - Version 1.0 - August 17th, 2003
4 
5 Permission is hereby granted, free of charge, to any person or organization
6 obtaining a copy of the software and accompanying documentation covered by
7 this license (the "Software") to use, reproduce, display, distribute,
8 execute, and transmit the Software, and to prepare derivative works of the
9 Software, and to permit third-parties to whom the Software is furnished to
10 do so, all subject to the following:
11 
12 The copyright notices in the Software and this entire statement, including
13 the above license grant, this restriction and the following disclaimer,
14 must be included in all copies of the Software, in whole or in part, and
15 all derivative works of the Software, unless such copies or derivative
16 works are solely in the form of machine-executable object code generated by
17 a source language processor.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 
27 */
28 module derelict.ode.types;
29 
30 private {
31     import std.math;
32     import core.vararg;
33     import core.stdc.config;
34     import core.stdc.time;
35     import derelict.util.system;
36 }
37 
38 // version.h
39 enum dODE_VERSION = "0.15.2";
40 
41 // odeconfig.h
42 alias dint64 = long;
43 alias duint64 = ulong;
44 alias dint32 = int;
45 alias duint32 = uint;
46 alias dint16 = short;
47 alias duint16 = ushort;
48 alias dint8 = byte;
49 alias duint8 = ubyte;
50 
51 alias dintptr = ptrdiff_t;
52 alias duintptr = size_t;
53 alias ddiffint = ptrdiff_t;
54 alias dsizeint = size_t;
55 
56 version(DerelictODE_Single) {
57     enum dDOUBLE = false;
58     enum dSINGLE = true;
59 } else {
60     enum dDOUBLE = true;
61     enum dSINGLE = false;
62 }
63 
64 static if(dSINGLE)
65     enum dInfinity = float.infinity;
66 else
67     enum dInfinity = double.infinity;
68 
69 // common.h
70 alias M_PI = PI;
71 alias M_PI_2 = PI_2;
72 alias M_SQRT1_2 = SQRT1_2;
73 
74 static if(dSINGLE)
75     alias dReal = float;
76 else
77     alias dReal = double;
78 
79 version (DerelictOde_TriMesh_16Bit_Indices) {
80     version (DerelictOde_TriMesh_GIMPACT)
81         alias dTriIndex = duint32;
82     else
83         alias dTriIndex = duint16;
84 } else {
85     alias dTriIndex = duint32;
86 }
87 
88 int dPAD(int a) {
89     return (a > 1) ? (((a - 1)|3)+1) : a;
90 }
91 
92 alias dSpaceAxis = int;
93 enum {
94     dSA__MIN,
95     dSA_X = dSA__MIN,
96     dSA_Y,
97     dSA_Z,
98     dSA__MAX,
99 }
100 
101 alias dMotionDynamics = int;
102 enum {
103     dMD__MIN,
104     dMD_LINEAR = dMD__MIN,
105     dMD_ANGULAR,
106     dMD__MAX,
107 }
108 
109 alias dDynamicsAxis = int;
110 enum {
111     dDA__MIN,
112     dDA__L_MIN = dDA__MIN + dMD_LINEAR * dSA__MAX,
113     dDA_LX = dDA__L_MIN + dSA_X,
114     dDA_LY = dDA__L_MIN + dSA_Y,
115     dDA_LZ = dDA__L_MIN + dSA_Z,
116     dDA__L_MAX = dDA__L_MIN + dSA__MAX,
117     dDA__A_MIN = dDA__MIN + dMD_ANGULAR * dSA__MAX,
118     dDA_AX = dDA__A_MIN + dSA_X,
119     dDA_AY = dDA__A_MIN + dSA_Y,
120     dDA_AZ = dDA__A_MIN + dSA_Z,
121     dDA__A_MAX = dDA__A_MIN + dSA__MAX,
122     dDA__MAX = dDA__MIN + dMD__MAX * dSA__MAX,
123 }
124 
125 alias dVec3Element = int;
126 enum {
127     dV3E__MIN,
128     dV3E__AXES_MIN = dV3E__MIN,
129     dV3E_X = dV3E__AXES_MIN + dSA_X,
130     dV3E_Y = dV3E__AXES_MIN + dSA_Y,
131     dV3E_Z = dV3E__AXES_MIN + dSA_Z,
132     dV3E__AXES_MAX = dV3E__AXES_MIN + dSA__MAX,
133     dV3E_PAD = dV3E__AXES_MAX,
134     dV3E__MAX,
135     dV3E__AXES_COUNT = dV3E__AXES_MAX - dV3E__AXES_MIN,
136 }
137 
138 alias dVec4Element = int;
139 enum {
140     dV4E__MIN,
141     dV4E_X = dV4E__MIN + dSA_X,
142     dV4E_Y = dV4E__MIN + dSA_Y,
143     dV4E_Z = dV4E__MIN + dSA_Z,
144     dV4E_O = dV4E__MIN + dSA__MAX,
145     dV4E__MAX,
146 }
147 
148 alias dMat3Element = int;
149 enum {
150     dM3E__MIN,
151     dM3E__X_MIN = dM3E__MIN + dSA_X * dV3E__MAX,    
152     dM3E__X_AXES_MIN = dM3E__X_MIN + dV3E__AXES_MIN,
153     dM3E_XX = dM3E__X_MIN + dV3E_X,
154     dM3E_XY = dM3E__X_MIN + dV3E_Y,
155     dM3E_XZ = dM3E__X_MIN + dV3E_Z,
156     dM3E__X_AXES_MAX = dM3E__X_MIN + dV3E__AXES_MAX,
157     dM3E_XPAD = dM3E__X_MIN + dV3E_PAD,
158     dM3E__X_MAX = dM3E__X_MIN + dV3E__MAX,
159     dM3E__Y_MIN = dM3E__MIN + dSA_Y * dV3E__MAX,
160     dM3E__Y_AXES_MIN = dM3E__Y_MIN + dV3E__AXES_MIN,
161     dM3E_YX = dM3E__Y_MIN + dV3E_X,
162     dM3E_YY = dM3E__Y_MIN + dV3E_Y,
163     dM3E_YZ = dM3E__Y_MIN + dV3E_Z,
164     dM3E__Y_AXES_MAX = dM3E__Y_MIN + dV3E__AXES_MAX,
165     dM3E_YPAD = dM3E__Y_MIN + dV3E_PAD,
166     dM3E__Y_MAX = dM3E__Y_MIN + dV3E__MAX,
167     dM3E__Z_MIN = dM3E__MIN + dSA_Z * dV3E__MAX,
168     dM3E__Z_AXES_MIN = dM3E__Z_MIN + dV3E__AXES_MIN,
169     dM3E_ZX = dM3E__Z_MIN + dV3E_X,
170     dM3E_ZY = dM3E__Z_MIN + dV3E_Y,
171     dM3E_ZZ = dM3E__Z_MIN + dV3E_Z,
172     dM3E__Z_AXES_MAX = dM3E__Z_MIN + dV3E__AXES_MAX,
173     dM3E_ZPAD = dM3E__Z_MIN + dV3E_PAD,
174     dM3E__Z_MAX = dM3E__Z_MIN + dV3E__MAX,
175     dM3E__MAX = dM3E__MIN + dSA__MAX * dV3E__MAX,
176 }
177 
178 alias dMat4Element = int;
179 enum {
180     dM4E__MIN,
181     dM4E__X_MIN = dM4E__MIN + dV4E_X * dV4E__MAX,
182     dM4E_XX = dM4E__X_MIN + dV4E_X,
183     dM4E_XY = dM4E__X_MIN + dV4E_Y,
184     dM4E_XZ = dM4E__X_MIN + dV4E_Z,
185     dM4E_XO = dM4E__X_MIN + dV4E_O,
186     dM4E__X_MAX = dM4E__X_MIN + dV4E__MAX,
187     dM4E__Y_MIN = dM4E__MIN + dV4E_Y * dV4E__MAX,
188     dM4E_YX = dM4E__Y_MIN + dV4E_X,
189     dM4E_YY = dM4E__Y_MIN + dV4E_Y,
190     dM4E_YZ = dM4E__Y_MIN + dV4E_Z,
191     dM4E_YO = dM4E__Y_MIN + dV4E_O,
192     dM4E__Y_MAX = dM4E__Y_MIN + dV4E__MAX,
193     dM4E__Z_MIN = dM4E__MIN + dV4E_Z * dV4E__MAX,
194     dM4E_ZX = dM4E__Z_MIN + dV4E_X,
195     dM4E_ZY = dM4E__Z_MIN + dV4E_Y,
196     dM4E_ZZ = dM4E__Z_MIN + dV4E_Z,
197     dM4E_ZO = dM4E__Z_MIN + dV4E_O,
198     dM4E__Z_MAX = dM4E__Z_MIN + dV4E__MAX,
199     dM4E__O_MIN = dM4E__MIN + dV4E_O * dV4E__MAX,
200     dM4E_OX = dM4E__O_MIN + dV4E_X,
201     dM4E_OY = dM4E__O_MIN + dV4E_Y,
202     dM4E_OZ = dM4E__O_MIN + dV4E_Z,
203     dM4E_OO = dM4E__O_MIN + dV4E_O,
204     dM4E__O_MAX = dM4E__O_MIN + dV4E__MAX,
205     dM4E__MAX = dM4E__MIN + dV4E__MAX * dV4E__MAX,
206 }
207 
208 alias dQuatElement = int;
209 enum {
210     dQUE__MIN,
211     dQUE_R = dQUE__MIN,
212     dQUE__AXIS_MIN,
213     dQUE_I = dQUE__AXIS_MIN + dSA_X,
214     dQUE_J = dQUE__AXIS_MIN + dSA_Y,
215     dQUE_K = dQUE__AXIS_MIN + dSA_Z,
216     dQUE__AXIS_MAX = dQUE__AXIS_MIN + dSA__MAX,
217     dQUE__MAX = dQUE__AXIS_MAX,
218 }
219 
220 alias dVector3 = dReal[dV3E__MAX];
221 alias dVector4 = dReal[dV4E__MAX];
222 alias dMatrix3 = dReal[dM3E__MAX];
223 alias dMatrix4 = dReal[dM4E__MAX];
224 alias dMatrix6 = dReal[(dMD__MAX * dV3E__MAX) * (dMD__MAX * dSA__MAX)];
225 alias dQuaternion = dReal[dQUE__MAX];
226 
227 @nogc nothrow {
228     dReal dRecip(dReal x) {
229         return 1.0/x;
230     }
231 
232     dReal dRecipSqrt(dReal x) {
233         return 1.0/sqrt(x);
234     }
235 
236     dReal dFMod(dReal a, dReal b) {
237         real c;
238         return modf(a, c);
239     }
240 
241     dReal dMin(dReal x, dReal y) { return x <= y ? x : y; }
242     dReal dMax(dReal x, dReal y) { return x <= y ? y : x; }
243 }
244 
245 alias dSqrt = sqrt;
246 alias dSin = sin;
247 alias dCos = cos;
248 alias dFabs = fabs;
249 alias dAtan2 = atan2;
250 alias dAsin = asin;
251 alias dAcos = acos;
252 alias dFMod = fmod;
253 alias dFloor = floor;
254 alias dCeil = ceil;
255 alias dCopySign = copysign;
256 alias dNextAfter = nextafter;
257 alias dIsNan = isNaN;
258 
259 
260 
261 struct dxWorld;
262 struct dxSpace;
263 struct dxBody;
264 struct dxGeom;
265 struct dxJoint;
266 struct dxJointNode;
267 struct dxJointGroup;
268 struct dxWorldProcessThreadingManager;
269 
270 alias dWorldID = dxWorld*;
271 alias dSpaceID = dxSpace*;
272 alias dBodyID = dxBody*;
273 alias dGeomID = dxGeom*;
274 alias dJointID = dxJoint*;
275 alias dJointGroupID = dxJointGroup*;
276 alias dWorldStepThreadingManagerId = dxWorldProcessThreadingManager*;
277 
278 enum {
279     d_ERR_UNKNOWN = 0,
280     d_ERR_IASSERT,
281     d_ERR_UASSERT,
282     d_ERR_LCP
283 }
284 
285 alias dJointType = int;
286 enum {
287     dJointTypeNone = 0,
288     dJointTypeBall,
289     dJointTypeHinge,
290     dJointTypeSlider,
291     dJointTypeContact,
292     dJointTypeUniversal,
293     dJointTypeHinge2,
294     dJointTypeFixed,
295     dJointTypeNull,
296     dJointTypeAMotor,
297     dJointTypeLMotor,
298     dJointTypePlane2D,
299     dJointTypePR,
300     dJointTypePU,
301     dJointTypePiston,
302     dJointTypeDBall,
303     dJointTypeDHinge,
304     dJointTypeTransmission,
305 }
306 
307 enum {
308     dParamLoStop = 0,
309     dParamHiStop,
310     dParamVel,
311     dParamFMax,
312     dParamFudgeFactor,
313     dParamBounce,
314     dParamCFM,
315     dParamStopERP,
316     dParamStopCFM,
317     dParamSuspensionERP,
318     dParamSuspensionCFM,
319     dParamERP,
320     dParamsInGroup,
321     dParamLoStop1 = 0x000,
322     dParamHiStop1,
323     dParamVel1,
324     dParamFMax1,
325     dParamFudgeFactor1,
326     dParamBounce1,
327     dParamCFM1,
328     dParamStopERP1,
329     dParamStopCFM1,
330     dParamSuspensionERP1,
331     dParamSuspensionCFM1,
332     dParamERP1,
333     dParamLoStop2 = 0x100,
334     dParamHiStop2,
335     dParamVel2,
336     dParamFMax2,
337     dParamFudgeFactor2,
338     dParamBounce2,
339     dParamCFM2,
340     dParamStopERP2,
341     dParamStopCFM2,
342     dParamSuspensionERP2,
343     dParamSuspensionCFM2,
344     dParamERP2,
345     dParamLoStop3 = 0x200,
346     dParamHiStop3,
347     dParamVel3,
348     dParamFMax3,
349     dParamFudgeFactor3,
350     dParamBounce3,
351     dParamCFM3,
352     dParamStopERP3,
353     dParamStopCFM3,
354     dParamSuspensionERP3,
355     dParamSuspensionCFM3,
356     dParamERP3,
357     dParamGroup = 0x100
358 }
359 
360 enum {
361     dAMotorUser  = 0,
362     dAMotorEuler = 1,
363 }
364 
365 enum {
366     dTransmissionParallelAxes = 0,
367     dTransmissionIntersectingAxes = 1,
368     dTransmissionChainDrive = 2,
369 }
370 
371 struct dJointFeedback {
372     dVector3 f1;
373     dVector3 t1;
374     dVector3 f2;
375     dVector3 t2;
376 }
377 
378 // collision.h
379 enum {
380     dGeomCommonControlClass = 0,
381     dGeomColliderControlClass = 1
382 }
383 
384 enum {
385     dGeomCommonAnyControlCode = 0,
386 
387     dGeomColliderSetMergeSphereContactsControlCode = 1,
388     dGeomColliderGetMergeSphereContactsControlCode = 2
389 }
390 
391 enum {
392     dGeomColliderMergeContactsValue__Default = 0,
393     dGeomColliderMergeContactsValue_None = 1,
394     dGeomColliderMergeContactsValue_Normals = 2,
395     dGeomColliderMergeContactsValue_Full = 3
396 }
397 
398 enum {
399     CONTACTS_UNIMPORTANT = 0x80000000
400 }
401 
402 enum {
403     dMaxUserClasses = 4
404 }
405 
406 enum {
407     dSphereClass = 0,
408     dBoxClass,
409     dCapsuleClass,
410     dCylinderClass,
411     dPlaneClass,
412     dRayClass,
413     dConvexClass,
414     dGeomTransformClass,
415     dTriMeshClass,
416     dHeightFieldClass,
417     dFirstSpaceClass,
418     dSimpleSpaceClass = dFirstSpaceClass,
419     dHashSpaceClass,
420     dSweepAndPruneSpaceClass,
421     dQuadTreeClass,
422     dLastSpaceClass = dQuadTreeClass,
423     dFirstUserClass,
424     dLastUserClass = dFirstUserClass + dMaxUserClasses - 1,
425     dGeomNumClasses
426 }
427 
428 alias dCCylinderClass = dCapsuleClass;
429 
430 struct dxHeightfieldData;
431 alias dxHeightfieldData* dHeightfieldDataID;
432 
433 extern(C) nothrow {
434     alias dHeightfieldGetHeight = dReal function(void*, int, int);
435     alias dGetAABBFn = void function(dGeomID, ref dReal[6]);
436     alias dColliderFn = int function(dGeomID, dGeomID, int, dContactGeom*, int);
437     alias dGetColliderFnFn = dColliderFn function(int);
438     alias dGeomDtorFn = void function(dGeomID);
439     alias dAABBTestFn = int function(dGeomID, dGeomID, ref dReal[6]);
440 }
441 
442 
443 struct dGeomClass {
444     int bytes;
445     dGetColliderFnFn collider;
446     dGetAABBFn aabb;
447     dAABBTestFn aabb_test;
448     dGeomDtorFn dtor;
449 }
450 
451 // collision_space.h
452 extern(C) nothrow alias dNearCallback = void function(void*, dGeomID, dGeomID);
453 
454 enum {
455     dSAP_AXES_XYZ = ((0)|(1<<2)|(2<<4)),
456     dSAP_AXES_XZY = ((0)|(2<<2)|(1<<4)),
457     dSAP_AXES_YXZ = ((1)|(0<<2)|(2<<4)),
458     dSAP_AXES_YZX = ((1)|(2<<2)|(0<<4)),
459     dSAP_AXES_ZXY = ((2)|(0<<2)|(1<<4)),
460     dSAP_AXES_ZYX = ((2)|(1<<2)|(0<<4))
461 }
462 
463 // collision_trimesh.h
464 struct dxTriMeshData;
465 alias dxTriMeshData* dTriMeshDataID;
466 
467 alias dMeshTriangleVertex = int;
468 enum {
469     dMTV_MIN,
470     dMTV_FIRST = dMTV_MIN,
471     dMTV_SECOND,
472     dMTV_THIRD,
473     dMTV_MAX
474 }
475 
476 enum {
477     dTRIMESHDATA_MIN,
478     dTRIMESHDATA_FACE_NORMALS = dTRIMESHDATA_MIN,
479     dTRIMESHDATA_USE_FLAGS,
480     dTRIMESHDATA_MAX
481 }
482 alias TRIMESH_FACE_NORMALS = dTRIMESHDATA_FACE_NORMALS;
483 
484 enum 
485 {
486     dMESHDATAUSE_EDGE1      = 0x01,
487     dMESHDATAUSE_EDGE2      = 0x02,
488     dMESHDATAUSE_EDGE3      = 0x04,
489     dMESHDATAUSE_VERTEX1    = 0x08,
490     dMESHDATAUSE_VERTEX2    = 0x10,
491     dMESHDATAUSE_VERTEX3    = 0x20,
492 }
493 
494 extern(C) nothrow {
495     alias dTriCallback = int function(dGeomID, dGeomID, int);
496     alias dTriArrayCallback = void function(dGeomID, dGeomID, const(int)*, int);
497     alias dTriRayCallback = int function(dGeomID, dGeomID, int, dReal, dReal);
498     alias dTriTriMergeCallback = int function(dGeomID, int, int);
499 }
500 
501 // contact.h
502 enum {
503     dContactMu2 = 0x001,
504     dContactFDir1 = 0x002,
505     dContactBounce = 0x004,
506     dContactSoftERP = 0x008,
507     dContactSoftCFM = 0x010,
508     dContactMotion1 = 0x020,
509     dContactMotion2 = 0x040,
510     dContactMotionN = 0x080,
511     dContactSlip1 = 0x100,
512     dContactSlip2 = 0x200,
513     dContactRolling = 0x400,
514 
515     dContactApprox0 = 0x0000,
516     dContactApprox1_1 = 0x1000,
517     dContactApprox1_2 = 0x2000,
518     dContactApprox1_N = 0x4000,
519     dContactApprox1   = 0x7000,
520 }
521 
522 struct dSurfaceParameters {
523     int mode;
524     dReal mu;
525     dReal mu2;
526     dReal rho;
527     dReal rho2;
528     dReal rhoN;
529     dReal bounce;
530     dReal bounce_vel;
531     dReal soft_erp;
532     dReal soft_cfm;
533     dReal motion1, motion2, motionN;
534     dReal slip1, slip2;
535 }
536 
537 struct dContactGeom {
538     dVector3 pos;
539     dVector3 normal;
540     dReal depth;
541     dGeomID g1, g2;
542     int side1, side2;
543 }
544 
545 struct dContact {
546     dSurfaceParameters surface;
547     dContactGeom geom;
548     dVector3 fdir1;
549 }
550 
551 // error.h
552 extern(C) nothrow alias dMessageFunction = void function(int, const(char)*, va_list ap);
553 
554 // mass.h
555 struct dMass {
556     dReal mass;
557     dVector3 c;
558     dMatrix3 I;
559 }
560 
561 // memory.h
562 extern(C) nothrow {
563     alias dAllocFunction = void* function(size_t);
564     alias dReallocFunction = void* function(void*, size_t, size_t);
565     alias dFreeFunction = void function(void*, size_t);
566 }
567 
568 // objects.h
569 enum dWORLDSTEP_THREADCOUNT_UNLIMITED = 0U;
570 enum dWORLDSTEP_RESERVEFACTOR_DEFAULT = 1.2f;
571 enum dWORLDSTEP_RESERVESIZE_DEFAULT = 65536U;
572 
573 struct dWorldStepReserveInfo {
574     uint struct_size;
575 
576     float reserve_factor;
577     uint  reserve_minimum;
578 }
579 
580 struct dWorldStepMemoryFunctionsInfo {
581     uint struct_size;
582 
583     extern(C) nothrow {
584         void* function(size_t) alloc_block;
585         void* function(void*, size_t, size_t) shrink_block;
586         void  function(void*, size_t) free_block;
587     }
588 }
589 
590 // odeinit.h
591 enum : uint {
592     dInitFlagManualThreadCleanup = 0x00000001
593 }
594 
595 enum : uint {
596     dAllocateFlagsBasicData = 0,
597     dAllocateFlagsCollisionData = 0x00000001,
598     dAllocateMaskAll = ~0U,
599 }
600 
601 // odemath.h
602 @nogc nothrow {
603     auto dACCESS33(T)(T a, size_t i, size_t j) {
604         return a[i * 4 + j];
605     }
606 
607     bool dVALIDVEC3(T)(T v) {
608         return !(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]));
609     }
610 
611     bool dVALIDVEC4(T)(T v) {
612         return !(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3]));
613     }
614 
615     bool dVALIDMAT3(T)(T m) {
616         return !(
617             dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2])  || dIsNan(m[3]) ||
618             dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6])  || dIsNan(m[7]) ||
619             dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11])
620         );
621     }
622 
623     bool dVALIDMAT4(T)(T m) {
624         return !(
625             dIsNan(m[0])  || dIsNan(m[1])  || dIsNan(m[2])  || dIsNan(m[3])  ||
626             dIsNan(m[4])  || dIsNan(m[5])  || dIsNan(m[6])  || dIsNan(m[7])  ||
627             dIsNan(m[8])  || dIsNan(m[9])  || dIsNan(m[10]) || dIsNan(m[11]) ||
628             dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15])
629         );
630     }
631 
632     void dZeroVector3(ref dVector3 res) {
633         res[dV3E_X] = 0.0;
634         res[dV3E_Y] = 0.0;
635         res[dV3E_Z] = 0.0;
636     }
637 
638     void dZeroMatrix4(dMatrix4 res) {
639         res[dM4E_XX] = 0.0; res[dM4E_XY] = 0.0; res[dM4E_XZ] = 0.0; res[dM4E_XO] = 0.0;
640         res[dM4E_YX] = 0.0; res[dM4E_YY] = 0.0; res[dM4E_YZ] = 0.0; res[dM4E_YO] = 0.0;
641         res[dM4E_ZX] = 0.0; res[dM4E_ZY] = 0.0; res[dM4E_ZZ] = 0.0; res[dM4E_ZO] = 0.0;
642         res[dM4E_OX] = 0.0; res[dM4E_OY] = 0.0; res[dM4E_OZ] = 0.0; res[dM4E_OO] = 0.0;
643 }
644 
645     void dZeroMatrix3(ref dMatrix3 res) {
646         res[dM3E_XX] = 0.0; res[dM3E_XY] = 0.0; res[dM3E_XZ] = 0.0;
647         res[dM3E_YX] = 0.0; res[dM3E_YY] = 0.0; res[dM3E_YZ] = 0.0;
648         res[dM3E_ZX] = 0.0; res[dM3E_ZY] = 0.0; res[dM3E_ZZ] = 0.0;
649     }
650 
651     void dAssignVector3(ref dVector3 res, dReal x, dReal y, dReal z) {
652         res[dV3E_X] = x;
653         res[dV3E_Y] = y;
654         res[dV3E_Z] = z;
655     }
656 
657     void dAddVectors3(dReal* res, const(dReal)* a, const(dReal)* b) {
658         immutable res_0 = a[0] + b[0];
659         immutable res_1 = a[1] + b[1];
660         immutable res_2 = a[2] + b[2];
661 
662         res[0] = res_0; res[1] = res_1; res[2] = res_2;
663     }
664 
665     void dSubtractVectors3(dReal* res, const(dReal)* a, const(dReal)* b) {
666         immutable res_0 = a[0] - b[0];
667         immutable res_1 = a[1] - b[1];
668         immutable res_2 = a[2] - b[2];
669 
670         res[0] = res_0; res[1] = res_1; res[2] = res_2;
671     }
672 
673     void dAddVectorScaledVector3(dReal* res, const(dReal)* a, const(dReal)* b, dReal b_scale) {
674         immutable res_0 = a[0] + b_scale * b[0];
675         immutable res_1 = a[1] + b_scale * b[1];
676         immutable res_2 = a[2] + b_scale * b[2];
677         
678         res[0] = res_0; res[1] = res_1; res[2] = res_2;
679     }
680 
681     void dAddScaledVectors3(dReal* res, const(dReal)* a, const(dReal)* b, dReal a_scale, dReal b_scale) {
682         immutable res_0 = a_scale * a[0] + b_scale * b[0];
683         immutable res_1 = a_scale * a[1] + b_scale * b[1];
684         immutable res_2 = a_scale * a[2] + b_scale * b[2];
685 
686         res[0] = res_0; res[1] = res_1; res[2] = res_2;
687     }
688 
689     void dAddThreeScaledVectors3(dReal *res, const(dReal)*a, const(dReal)*b, const(dReal)*c, dReal a_scale, dReal b_scale, dReal c_scale)
690     {
691         immutable res_0 = a_scale * a[0] + b_scale * b[0] + c_scale * c[0];
692         immutable res_1 = a_scale * a[1] + b_scale * b[1] + c_scale * c[1];
693         immutable res_2 = a_scale * a[2] + b_scale * b[2] + c_scale * c[2];
694 
695         res[0] = res_0; res[1] = res_1; res[2] = res_2;
696     }
697 
698     void dScaleVector3(dReal* res, dReal nScale) {
699         res[0] *= nScale;
700         res[1] *= nScale;
701         res[2] *= nScale;
702     }
703 
704     void dNegateVector3(dReal* res) {
705         res[0] = -res[0];
706         res[1] = -res[1];
707         res[2] = -res[2];
708     }
709 
710     void dCopyVector3(dReal* res, const(dReal)* a) {
711         immutable res_0 = a[0];
712         immutable res_1 = a[1];
713         immutable res_2 = a[2];
714 
715         res[0] = res_0; res[1] = res_1; res[2] = res_2;
716     }
717 
718     void dCopyScaledVector3(dReal* res, const(dReal)* a, dReal nScale) {
719         immutable res_0 = a[0] * nScale;
720         immutable res_1 = a[1] * nScale;
721         immutable  res_2 = a[2] * nScale;
722 
723         res[0] = res_0; res[1] = res_1; res[2] = res_2;
724     }
725 
726     void dCopyNegatedVector3(dReal* res, const(dReal)* a) {
727         immutable res_0 = -a[0];
728         immutable res_1 = -a[1];
729         immutable res_2 = -a[2];
730 
731         res[0] = res_0; res[1] = res_1; res[2] = res_2;
732     }
733 
734     void dCopyVector4(dReal* res, const(dReal)* a) {
735         immutable res_0 = a[0];
736         immutable res_1 = a[1];
737         immutable res_2 = a[2];
738         immutable res_3 = a[3];
739 
740         res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3;
741     }
742 
743     void dCopyMatrix4x4(dReal* res, const(dReal)* a) {
744         dCopyVector4(res + 0, a + 0);
745         dCopyVector4(res + 4, a + 4);
746         dCopyVector4(res + 8, a + 8);
747     }
748 
749     void dCopyMatrix4x3(dReal* res, const(dReal)* a) {
750         dCopyVector3(res + 0, a + 0);
751         dCopyVector3(res + 4, a + 4);
752         dCopyVector3(res + 8, a + 8);
753     }
754 
755     void dGetMatrixColumn3(dReal* res, const(dReal)* a, uint n) {
756         immutable res_0 = a[n + 0];
757         immutable res_1 = a[n + 4];
758         immutable  res_2 = a[n + 8];
759 
760         res[0] = res_0; res[1] = res_1; res[2] = res_2;
761     }
762 
763     dReal dCalcVectorLength3(const(dReal)* a) {
764         return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
765     }
766 
767     dReal dCalcVectorLengthSquare3(const(dReal)* a) {
768         return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
769     }
770 
771     dReal dCalcPointDepth3(const(dReal)* test_p, const(dReal)* plane_p, const(dReal)* plane_n) {
772         return (plane_p[0] - test_p[0]) * plane_n[0] + (plane_p[1] - test_p[1]) * plane_n[1] + (plane_p[2] - test_p[2]) * plane_n[2];
773     }
774 
775     dReal _dCalcVectorDot3(const(dReal)* a, const(dReal)* b, uint step_a, uint step_b) {
776         return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b];
777     }
778 
779     dReal dCalcVectorDot3    (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,1,1); }
780     dReal dCalcVectorDot3_13 (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,1,3); }
781     dReal dCalcVectorDot3_31 (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,3,1); }
782     dReal dCalcVectorDot3_33 (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,3,3); }
783     dReal dCalcVectorDot3_14 (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,1,4); }
784     dReal dCalcVectorDot3_41 (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,4,1); }
785     dReal dCalcVectorDot3_44 (const(dReal)* a, const(dReal)* b) { return _dCalcVectorDot3(a,b,4,4); }
786 
787     void _dCalcVectorCross3(dReal* res, const(dReal)* a, const(dReal)* b, uint step_res, uint step_a, uint step_b) {
788         immutable res_0 = a[  step_a]*b[2*step_b] - a[2*step_a]*b[  step_b];
789         immutable res_1 = a[2*step_a]*b[       0] - a[       0]*b[2*step_b];
790         immutable res_2 = a[       0]*b[  step_b] - a[  step_a]*b[       0];
791 
792         res[         0] = res_0;
793         res[  step_res] = res_1;
794         res[2*step_res] = res_2;
795     }
796 
797     void dCalcVectorCross3    (dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); }
798     void dCalcVectorCross3_114(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); }
799     void dCalcVectorCross3_141(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); }
800     void dCalcVectorCross3_144(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); }
801     void dCalcVectorCross3_411(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); }
802     void dCalcVectorCross3_414(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); }
803     void dCalcVectorCross3_441(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); }
804     void dCalcVectorCross3_444(dReal* res, const(dReal)* a, const(dReal)* b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); }
805 
806     void dAddVectorCross3(dReal* res, const(dReal)* a, const(dReal)* b) {
807         dReal[3] tmp;
808         dCalcVectorCross3(tmp.ptr, a, b);
809         dAddVectors3(res, res, tmp.ptr);
810     }
811 
812     void dSubtractVectorCross3(dReal* res, const(dReal)* a, const(dReal)* b) {
813         dReal[3] tmp;
814         dCalcVectorCross3(tmp.ptr, a, b);
815         dSubtractVectors3(res, res, tmp.ptr);
816     }
817 
818     void dSetCrossMatrixPlus(dReal* res, const(dReal)* a, uint skip) {
819         immutable a_0 = a[0], a_1 = a[1], a_2 = a[2];
820         res[1] = -a_2;
821         res[2] = +a_1;
822         res[skip+0] = +a_2;
823         res[skip+2] = -a_0;
824         res[2*skip+0] = -a_1;
825         res[2*skip+1] = +a_0;
826     }
827 
828     void dSetCrossMatrixMinus(dReal* res, const(dReal)* a, uint skip) {
829         immutable  a_0 = a[0], a_1 = a[1], a_2 = a[2];
830         res[1] = +a_2;
831         res[2] = -a_1;
832         res[skip+0] = -a_2;
833         res[skip+2] = +a_0;
834         res[2*skip+0] = +a_1;
835         res[2*skip+1] = -a_0;
836     }
837 
838     dReal dCalcPointsDistance3(const(dReal)* a, const(dReal)* b) {
839         dReal res;
840         dReal[3] tmp;
841         dSubtractVectors3(tmp.ptr, a, b);
842         res = dCalcVectorLength3(tmp.ptr);
843         return res;
844     }
845 
846     void dMultiplyHelper0_331(dReal* res, const(dReal)* a, const(dReal)* b) {
847         immutable res_0 = dCalcVectorDot3(a, b);
848         immutable res_1 = dCalcVectorDot3(a + 4, b);
849         immutable res_2 = dCalcVectorDot3(a + 8, b);
850 
851         res[0] = res_0; res[1] = res_1; res[2] = res_2;
852     }
853 
854     void dMultiplyHelper1_331(dReal* res, const(dReal)* a, const(dReal)* b) {
855         immutable res_0 = dCalcVectorDot3_41(a, b);
856         immutable res_1 = dCalcVectorDot3_41(a + 1, b);
857         immutable res_2 = dCalcVectorDot3_41(a + 2, b);
858 
859         res[0] = res_0; res[1] = res_1; res[2] = res_2;
860     }
861 
862     void dMultiplyHelper0_133(dReal* res, const(dReal)* a, const(dReal)* b) {
863         dMultiplyHelper1_331(res, b, a);
864     }
865 
866     void dMultiplyHelper1_133(dReal* res, const(dReal)* a, const(dReal)* b) {
867         immutable res_0 = dCalcVectorDot3_44(a, b);
868         immutable res_1 = dCalcVectorDot3_44(a + 1, b);
869         immutable res_2 = dCalcVectorDot3_44(a + 2, b);
870 
871         res[0] = res_0; res[1] = res_1; res[2] = res_2;
872     }
873 
874     void dMultiply0_331(dReal* res, const(dReal)* a, const(dReal)* b) {
875         dMultiplyHelper0_331(res, a, b);
876     }
877 
878     void dMultiply1_331(dReal* res, const(dReal)* a, const(dReal)* b) {
879         dMultiplyHelper1_331(res, a, b);
880     }
881 
882     void dMultiply0_133(dReal* res, const(dReal)* a, const(dReal)* b) {
883         dMultiplyHelper0_133(res, a, b);
884     }
885 
886     void dMultiply0_333(dReal* res, const(dReal)* a, const(dReal)* b) {
887         dMultiplyHelper0_133(res + 0, a + 0, b);
888         dMultiplyHelper0_133(res + 4, a + 4, b);
889         dMultiplyHelper0_133(res + 8, a + 8, b);
890     }
891 
892     void dMultiply1_333(dReal* res, const(dReal)* a, const(dReal)* b) {
893         dMultiplyHelper1_133(res + 0, b, a + 0);
894         dMultiplyHelper1_133(res + 4, b, a + 1);
895         dMultiplyHelper1_133(res + 8, b, a + 2);
896     }
897 
898     void dMultiply2_333(dReal* res, const(dReal)* a, const(dReal)* b) {
899         dMultiplyHelper0_331(res + 0, b, a + 0);
900         dMultiplyHelper0_331(res + 4, b, a + 4);
901         dMultiplyHelper0_331(res + 8, b, a + 8);
902     }
903 
904     void dMultiplyAdd0_331(dReal* res, const(dReal)* a, const(dReal)* b) {
905         dReal[3] tmp;
906         dMultiplyHelper0_331(tmp.ptr, a, b);
907         dAddVectors3(res, res, tmp.ptr);
908     }
909 
910     void dMultiplyAdd1_331(dReal* res, const(dReal)* a, const(dReal)* b) {
911         dReal[3] tmp;
912         dMultiplyHelper1_331(tmp.ptr, a, b);
913         dAddVectors3(res, res, tmp.ptr);
914     }
915 
916     void dMultiplyAdd0_133(dReal* res, const(dReal)* a, const(dReal)* b) {
917         dReal[3] tmp;
918         dMultiplyHelper0_133(tmp.ptr, a, b);
919         dAddVectors3(res, res, tmp.ptr);
920     }
921 
922     void dMultiplyAdd0_333(dReal* res, const(dReal)* a, const(dReal)* b) {
923         dReal[3] tmp;
924         dMultiplyHelper0_133(tmp.ptr, a + 0, b);
925         dAddVectors3(res+ 0, res + 0, tmp.ptr);
926         dMultiplyHelper0_133(tmp.ptr, a + 4, b);
927         dAddVectors3(res + 4, res + 4, tmp.ptr);
928         dMultiplyHelper0_133(tmp.ptr, a + 8, b);
929         dAddVectors3(res + 8, res + 8, tmp.ptr);
930     }
931 
932     void dMultiplyAdd1_333(dReal* res, const(dReal)* a, const(dReal)* b) {
933         dReal[3] tmp;
934         dMultiplyHelper1_133(tmp.ptr, b, a + 0);
935         dAddVectors3(res + 0, res + 0, tmp.ptr);
936         dMultiplyHelper1_133(tmp.ptr, b, a + 1);
937         dAddVectors3(res + 4, res + 4, tmp.ptr);
938         dMultiplyHelper1_133(tmp.ptr, b, a + 2);
939         dAddVectors3(res + 8, res + 8, tmp.ptr);
940     }
941 
942     void dMultiplyAdd2_333(dReal* res, const(dReal)* a, const(dReal)* b) {
943         dReal[3] tmp;
944         dMultiplyHelper0_331(tmp.ptr, b, a + 0);
945         dAddVectors3(res + 0, res + 0, tmp.ptr);
946         dMultiplyHelper0_331(tmp.ptr, b, a + 4);
947         dAddVectors3(res + 4, res + 4, tmp.ptr);
948         dMultiplyHelper0_331(tmp.ptr, b, a + 8);
949         dAddVectors3(res + 8, res + 8, tmp.ptr);
950     }
951 
952     dReal dCalcMatrix3Det(const(dReal)* mat) {
953         dReal det;
954 
955         det = mat[0] * (mat[5]*mat[10] - mat[9]*mat[6])
956             - mat[1] * (mat[4]*mat[10] - mat[8]*mat[6])
957             + mat[2] * (mat[4]*mat[9]  - mat[8]*mat[5]);
958 
959         return det;
960     }
961 
962     dReal dInvertMatrix3(dReal* dst, const(dReal)* ma) {
963         dReal det;
964         dReal detRecip;
965 
966         det = dCalcMatrix3Det(ma);
967 
968         if(det == 0) {
969             return 0;
970         }
971 
972         detRecip = dRecip(det);
973 
974         dst[0] =  (ma[5]*ma[10] - ma[6]*ma[9] ) * detRecip;
975         dst[1] =  (ma[9]*ma[2]  - ma[1]*ma[10]) * detRecip;
976         dst[2] =  (ma[1]*ma[6]  - ma[5]*ma[2] ) * detRecip;
977 
978         dst[4] =  (ma[6]*ma[8]  - ma[4]*ma[10]) * detRecip;
979         dst[5] =  (ma[0]*ma[10] - ma[8]*ma[2] ) * detRecip;
980         dst[6] =  (ma[4]*ma[2]  - ma[0]*ma[6] ) * detRecip;
981 
982         dst[8] =  (ma[4]*ma[9]  - ma[8]*ma[5] ) * detRecip;
983         dst[9] =  (ma[8]*ma[1]  - ma[0]*ma[9] ) * detRecip;
984         dst[10] = (ma[0]*ma[5]  - ma[1]*ma[4] ) * detRecip;
985 
986         return det;
987     }
988 }
989 
990 // threading.h
991 struct dxThreadingImplementation;
992 alias dThreadingImplementationID = dxThreadingImplementation*;
993 
994 alias dmutexindex_t = uint;
995 struct dxMutexGroup;
996 alias dMutexGroupID = dxMutexGroup*;
997 
998 extern(C) nothrow {
999     alias dMutexGroupAllocFunction = dMutexGroupID function(dThreadingImplementationID,dmutexindex_t,const(char*)*);
1000     alias dMutexGroupFreeFunction = void function(dThreadingImplementationID,dMutexGroupID);
1001     alias dMutexGroupMutexLockFunction = void function(dThreadingImplementationID,dMutexGroupID,dmutexindex_t);
1002     alias dMutexGroupMutexUnlockFunction = void function(dThreadingImplementationID,dMutexGroupID,dmutexindex_t);
1003 }
1004 
1005 struct dxCallReleasee;
1006 alias dCallReleaseeID = dxCallReleasee*;
1007 
1008 struct dxCallWait;
1009 alias dCallWaitID = dxCallWait*;
1010 
1011 alias ddependencycount_t = size_t;
1012 alias ddependencychange_t = ptrdiff_t;
1013 alias dcallindex_t = size_t;
1014 
1015 struct dThreadedWaitTime {
1016     time_t wait_sec;
1017     c_ulong wait_nsec;
1018 }
1019 
1020 extern(C) nothrow {
1021     alias dThreadedCallFunction = int function(void*,dcallindex_t,dCallReleaseeID);
1022     alias dThreadedCallWaitAllocFunction = dCallWaitID function(dThreadingImplementationID);
1023     alias dThreadedCallWaitResetFunction = void function(dThreadingImplementationID,dCallWaitID);
1024     alias dThreadedCallWaitFreeFunction = void function(dThreadingImplementationID,dCallWaitID);
1025     alias dThreadedCallPostFunction = void function(dThreadingImplementationID,int*,dCallReleaseeID*,ddependencycount_t,dCallReleaseeID,dCallWaitID,dThreadedCallFunction*,void*,dcallindex_t,const(char)*);
1026     alias dThreadedCallDependenciesCountAlterFunction = void function(dThreadingImplementationID,dCallReleaseeID,ddependencychange_t);
1027     alias dThreadedCallWaitFunction = void function(dThreadingImplementationID,int*,dCallWaitID,const(dThreadedWaitTime)*,const(char)*);
1028     alias dThreadingImplThreadCountRetrieveFunction = uint function(dThreadingImplementationID);
1029     alias dThreadingImplResourcesForCallsPreallocateFunction = int function(dThreadingImplementationID,ddependencycount_t);
1030 }
1031 
1032 struct dThreadingFunctionsInfo {
1033     uint struct_size;
1034 
1035     dMutexGroupAllocFunction* alloc_mutex_group;
1036     dMutexGroupFreeFunction* free_mutex_group;
1037     dMutexGroupMutexLockFunction* lock_group_mutex;
1038     dMutexGroupMutexUnlockFunction* unlock_group_mutex;
1039 
1040     dThreadedCallWaitAllocFunction* alloc_call_wait;
1041     dThreadedCallWaitResetFunction* reset_call_wait;
1042     dThreadedCallWaitFreeFunction* free_call_wait;
1043 
1044     dThreadedCallPostFunction* post_call;
1045     dThreadedCallDependenciesCountAlterFunction* alter_call_dependencies_count;
1046     dThreadedCallWaitFunction* wait_call;
1047 
1048     dThreadingImplThreadCountRetrieveFunction* retrieve_thread_count;
1049     dThreadingImplResourcesForCallsPreallocateFunction* preallocate_resources_for_calls;
1050 }
1051 
1052 // timer.h
1053 struct dStopwatch {
1054     double time;
1055 	c_ulong[2] cc;
1056 }