1 /*************************************************************************
2  *                                                                       *
3  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
4  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
5  *                                                                       *
6  * This library is free software; you can redistribute it and/or         *
7  * modify it under the terms of EITHER:                                  *
8  *   (1) The GNU Lesser General Public License as published by the Free  *
9  *       Software Foundation; either version 2.1 of the License, or (at  *
10  *       your option) any later version. The text of the GNU Lesser      *
11  *       General Public License is included with this library in the     *
12  *       file LICENSE.TXT.                                               *
13  *   (2) The BSD-style license that is included with this library in     *
14  *       the file LICENSE-BSD.TXT.                                       *
15  *                                                                       *
16  * This library is distributed in the hope that it will be useful,       *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
19  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
20  *                                                                       *
21  *************************************************************************/
22 
23 #ifndef _ODE_COMMON_H_
24 #define _ODE_COMMON_H_
25 
26 #include <ode/odeconfig.h>
27 #include <ode/error.h>
28 
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 
35 /* configuration stuff */
36 
37 /* constants */
38 
39 /* pi and 1/sqrt(2) are defined here if necessary because they don't get
40  * defined in <math.h> on some platforms (like MS-Windows)
41  */
42 
43 #ifndef M_PI
44 #define M_PI REAL(3.1415926535897932384626433832795029)
45 #endif
46 #ifndef M_PI_2
47 #define M_PI_2 REAL(1.5707963267948966192313216916398)
48 #endif
49 #ifndef M_SQRT1_2
50 #define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
51 #endif
52 
53 
54 /* floating point data type, vector, matrix and quaternion types */
55 
56 #if defined(dSINGLE)
57 typedef float dReal;
58 #ifdef dDOUBLE
59 #error You can only #define dSINGLE or dDOUBLE, not both.
60 #endif /* dDOUBLE */
61 #elif defined(dDOUBLE)
62 typedef double dReal;
63 #else
64 #error You must #define dSINGLE or dDOUBLE
65 #endif
66 
67 /* Detect if we've got both trimesh engines enabled. */
68 #if dTRIMESH_ENABLED
69 #if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
70 #error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
71 #endif
72 #endif /* dTRIMESH_ENABLED */
73 
74 /*
75  * Define a type for indices, either 16 or 32 bit, based on build option
76  * TODO: Currently GIMPACT only supports 32 bit indices.
77  */
78 #if dTRIMESH_16BIT_INDICES
79 #if dTRIMESH_GIMPACT
80 typedef duint32 dTriIndex;
81 #else /* dTRIMESH_GIMPACT */
82 typedef duint16 dTriIndex;
83 #endif /* dTRIMESH_GIMPACT */
84 #else /* dTRIMESH_16BIT_INDICES */
85 typedef duint32 dTriIndex;
86 #endif /* dTRIMESH_16BIT_INDICES */
87 
88 /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
89  * (used to compute matrix leading dimensions)
90  */
91 #define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
92 
93 /* these types are mainly just used in headers */
94 typedef dReal dVector3[4];
95 typedef dReal dVector4[4];
96 typedef dReal dMatrix3[4*3];
97 typedef dReal dMatrix4[4*4];
98 typedef dReal dMatrix6[8*6];
99 typedef dReal dQuaternion[4];
100 
101 
102 /* precision dependent scalar math functions */
103 
104 #if defined(dSINGLE)
105 
106 #define REAL(x) (x##f)					/* form a constant */
107 #define dRecip(x) ((1.0f/(x)))				/* reciprocal */
108 #define dSqrt(x) (sqrtf(x))			/* square root */
109 #define dRecipSqrt(x) ((1.0f/sqrtf(x)))		/* reciprocal square root */
110 #define dSin(x) (sinf(x))				/* sine */
111 #define dCos(x) (cosf(x))				/* cosine */
112 #define dFabs(x) (fabsf(x))			/* absolute value */
113 #define dAtan2(y,x) (atan2f(y,x))		/* arc tangent with 2 args */
114 #define dAcos(x) (acosf(x))
115 #define dFMod(a,b) (fmodf(a,b))		/* modulo */
116 #define dFloor(x) floorf(x)			/* floor */
117 #define dCeil(x) ceilf(x)			/* ceil */
118 #define dCopySign(a,b) _ode_copysignf(a, b) /* copy value sign */
119 #define dNextAfter(x, y) _ode_nextafterf(x, y) /* next value after */
120 
121 #ifdef HAVE___ISNANF
122 #define dIsNan(x) (__isnanf(x))
123 #elif defined(HAVE__ISNANF)
124 #define dIsNan(x) (_isnanf(x))
125 #elif defined(HAVE_ISNANF)
126 #define dIsNan(x) (isnanf(x))
127 #else
128   /*
129      fall back to _isnan which is the VC way,
130      this may seem redundant since we already checked
131      for _isnan before, but if isnan is detected by
132      configure but is not found during compilation
133      we should always make sure we check for __isnanf,
134      _isnanf and isnanf in that order before falling
135      back to a default
136   */
137 #define dIsNan(x) (_isnan(x))
138 #endif
139 
140 #elif defined(dDOUBLE)
141 
142 #define REAL(x) (x)
143 #define dRecip(x) (1.0/(x))
144 #define dSqrt(x) sqrt(x)
145 #define dRecipSqrt(x) (1.0/sqrt(x))
146 #define dSin(x) sin(x)
147 #define dCos(x) cos(x)
148 #define dFabs(x) fabs(x)
149 #define dAtan2(y,x) atan2((y),(x))
150 #define dAcos(x) acos(x)
151 #define dFMod(a,b) (fmod((a),(b)))
152 #define dFloor(x) floor(x)
153 #define dCeil(x) ceil(x)
154 #define dCopySign(a,b) _ode_copysign(a, b)
155 #define dNextAfter(x, y) _ode_nextafter(x, y)
156 
157 #ifdef HAVE___ISNAN
158 #define dIsNan(x) (__isnan(x))
159 #elif defined(HAVE__ISNAN)
160 #define dIsNan(x) (_isnan(x))
161 #elif defined(HAVE_ISNAN)
162 #define dIsNan(x) (isnan(x))
163 #else
164 #define dIsNan(x) (_isnan(x))
165 #endif
166 
167 #else
168 #error You must #define dSINGLE or dDOUBLE
169 #endif
170 
171 
172 /* internal object types (all prefixed with `dx') */
173 
174 struct dxWorld;		/* dynamics world */
175 struct dxSpace;		/* collision space */
176 struct dxBody;		/* rigid body (dynamics object) */
177 struct dxGeom;		/* geometry (collision object) */
178 struct dxJoint;
179 struct dxJointNode;
180 struct dxJointGroup;
181 struct dxWorldProcessThreadingManager;
182 
183 typedef struct dxWorld *dWorldID;
184 typedef struct dxSpace *dSpaceID;
185 typedef struct dxBody *dBodyID;
186 typedef struct dxGeom *dGeomID;
187 typedef struct dxJoint *dJointID;
188 typedef struct dxJointGroup *dJointGroupID;
189 typedef struct dxWorldProcessThreadingManager *dWorldStepThreadingManagerID;
190 
191 /* error numbers */
192 
193 enum {
194   d_ERR_UNKNOWN = 0,		/* unknown error */
195   d_ERR_IASSERT,		/* internal assertion failed */
196   d_ERR_UASSERT,		/* user assertion failed */
197   d_ERR_LCP			/* user assertion failed */
198 };
199 
200 
201 /* joint type numbers */
202 
203 typedef enum {
204   dJointTypeNone = 0,		/* or "unknown" */
205   dJointTypeBall,
206   dJointTypeHinge,
207   dJointTypeSlider,
208   dJointTypeContact,
209   dJointTypeUniversal,
210   dJointTypeHinge2,
211   dJointTypeFixed,
212   dJointTypeNull,
213   dJointTypeAMotor,
214   dJointTypeLMotor,
215   dJointTypePlane2D,
216   dJointTypePR,
217   dJointTypePU,
218   dJointTypePiston,
219   dJointTypeDBall,
220   dJointTypeDHinge,
221   dJointTypeTransmission,
222 } dJointType;
223 
224 
225 /* an alternative way of setting joint parameters, using joint parameter
226  * structures and member constants. we don't actually do this yet.
227  */
228 
229 /*
230 typedef struct dLimot {
231   int mode;
232   dReal lostop, histop;
233   dReal vel, fmax;
234   dReal fudge_factor;
235   dReal bounce, soft;
236   dReal suspension_erp, suspension_cfm;
237 } dLimot;
238 
239 enum {
240   dLimotLoStop		= 0x0001,
241   dLimotHiStop		= 0x0002,
242   dLimotVel		= 0x0004,
243   dLimotFMax		= 0x0008,
244   dLimotFudgeFactor	= 0x0010,
245   dLimotBounce		= 0x0020,
246   dLimotSoft		= 0x0040
247 };
248 */
249 
250 
251 /* standard joint parameter names. why are these here? - because we don't want
252  * to include all the joint function definitions in joint.cpp. hmmmm.
253  * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
254  * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
255  * paste between these two.
256  */
257 
258 #define D_ALL_PARAM_NAMES(start) \
259   /* parameters for limits and motors */ \
260   dParamLoStop = start, \
261   dParamHiStop, \
262   dParamVel, \
263   dParamLoVel, \
264   dParamHiVel, \
265   dParamFMax, \
266   dParamFudgeFactor, \
267   dParamBounce, \
268   dParamCFM, \
269   dParamStopERP, \
270   dParamStopCFM, \
271   /* parameters for suspension */ \
272   dParamSuspensionERP, \
273   dParamSuspensionCFM, \
274   dParamERP, \
275 
276   /*
277    * \enum  D_ALL_PARAM_NAMES_X
278    *
279    * \var dParamGroup This is the starting value of the different group
280    *                  (i.e. dParamGroup1, dParamGroup2, dParamGroup3)
281    *                  It also helps in the use of parameter
282    *                  (dParamGroup2 | dParamFMax) == dParamFMax2
283    */
284 #define D_ALL_PARAM_NAMES_X(start,x) \
285   dParamGroup ## x = start, \
286   /* parameters for limits and motors */ \
287   dParamLoStop ## x = start, \
288   dParamHiStop ## x, \
289   dParamVel ## x, \
290   dParamLoVel ## x, \
291   dParamHiVel ## x, \
292   dParamFMax ## x, \
293   dParamFudgeFactor ## x, \
294   dParamBounce ## x, \
295   dParamCFM ## x, \
296   dParamStopERP ## x, \
297   dParamStopCFM ## x, \
298   /* parameters for suspension */ \
299   dParamSuspensionERP ## x, \
300   dParamSuspensionCFM ## x, \
301   dParamERP ## x,
302 
303 enum {
304   D_ALL_PARAM_NAMES(0)
305   dParamsInGroup,     /* < Number of parameter in a group */
306   D_ALL_PARAM_NAMES_X(0x000,1)
307   D_ALL_PARAM_NAMES_X(0x100,2)
308   D_ALL_PARAM_NAMES_X(0x200,3)
309 
310   /* add a multiple of this constant to the basic parameter numbers to get
311    * the parameters for the second, third etc axes.
312    */
313   dParamGroup=0x100
314 };
315 
316 
317 /* angular motor mode numbers */
318 
319 enum {
320   dAMotorUser = 0,
321   dAMotorEuler = 1
322 };
323 
324 /* transmission joint mode numbers */
325 
326 enum {
327   dTransmissionParallelAxes = 0,
328   dTransmissionIntersectingAxes = 1,
329   dTransmissionChainDrive = 2
330 };
331 
332 
333 /* joint force feedback information */
334 
335 typedef struct dJointFeedback {
336   dVector3 f1;		/* force applied to body 1 */
337   dVector3 t1;		/* torque applied to body 1 */
338   dVector3 f2;		/* force applied to body 2 */
339   dVector3 t2;		/* torque applied to body 2 */
340 } dJointFeedback;
341 
342 
343 /* private functions that must be implemented by the collision library:
344  * (1) indicate that a geom has moved, (2) get the next geom in a body list.
345  * these functions are called whenever the position of geoms connected to a
346  * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
347  * when the ODE step function updates the body state.
348  */
349 
350 void dGeomMoved (dGeomID);
351 dGeomID dGeomGetBodyNext (dGeomID);
352 
353 /**
354  * dGetConfiguration returns the specific ODE build configuration as
355  * a string of tokens. The string can be parsed in a similar way to
356  * the OpenGL extension mechanism, the naming convention should be
357  * familiar too. The following extensions are reported:
358  *
359  * ODE
360  * ODE_single_precision
361  * ODE_double_precision
362  * ODE_EXT_no_debug
363  * ODE_EXT_trimesh
364  * ODE_EXT_opcode
365  * ODE_EXT_gimpact
366  * ODE_EXT_malloc_not_alloca
367  * ODE_EXT_gyroscopic
368  * ODE_OPC_16bit_indices
369  * ODE_OPC_new_collider
370 */
371 ODE_API const char* dGetConfiguration (void);
372 
373 /**
374  * Helper to check for a token in the ODE configuration string.
375  * Caution, this function is case sensitive.
376  *
377  * @param token A configuration token, see dGetConfiguration for details
378  *
379  * @return 1 if exact token is present, 0 if not present
380  */
381 ODE_API int dCheckConfiguration( const char* token );
382 
383 #ifdef __cplusplus
384 }
385 #endif
386 
387 #endif
388