Open Dynamics Engine

common.h

00001 /*************************************************************************
00002  *                                                                       *
00003  * Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.       *
00004  * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
00005  *                                                                       *
00006  * This library is free software; you can redistribute it and/or         *
00007  * modify it under the terms of EITHER:                                  *
00008  *   (1) The GNU Lesser General Public License as published by the Free  *
00009  *       Software Foundation; either version 2.1 of the License, or (at  *
00010  *       your option) any later version. The text of the GNU Lesser      *
00011  *       General Public License is included with this library in the     *
00012  *       file LICENSE.TXT.                                               *
00013  *   (2) The BSD-style license that is included with this library in     *
00014  *       the file LICENSE-BSD.TXT.                                       *
00015  *                                                                       *
00016  * This library is distributed in the hope that it will be useful,       *
00017  * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00019  * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
00020  *                                                                       *
00021  *************************************************************************/
00022 
00023 #ifndef _ODE_COMMON_H_
00024 #define _ODE_COMMON_H_
00025 #include <ode/odeconfig.h>
00026 #include <ode/error.h>
00027 #include <math.h>
00028 
00029 #ifdef __cplusplus
00030 extern "C" {
00031 #endif
00032 
00033 
00034 #define PURE_INLINE static __inline
00035 
00036 
00037 /* configuration stuff */
00038 
00039 /* constants */
00040 
00041 /* pi and 1/sqrt(2) are defined here if necessary because they don't get
00042  * defined in <math.h> on some platforms (like MS-Windows)
00043  */
00044 
00045 #ifndef M_PI
00046 #define M_PI REAL(3.1415926535897932384626433832795029)
00047 #endif
00048 #ifndef M_SQRT1_2
00049 #define M_SQRT1_2 REAL(0.7071067811865475244008443621048490)
00050 #endif
00051 
00052 
00053 /* debugging:
00054  *   IASSERT  is an internal assertion, i.e. a consistency check. if it fails
00055  *            we want to know where.
00056  *   UASSERT  is a user assertion, i.e. if it fails a nice error message
00057  *            should be printed for the user.
00058  *   AASSERT  is an arguments assertion, i.e. if it fails "bad argument(s)"
00059  *            is printed.
00060  *   DEBUGMSG just prints out a message
00061  */
00062 
00063 #  if defined(__STDC__) && __STDC_VERSION__ >= 199901L
00064 #    define __FUNCTION__ __func__
00065 #  endif
00066 #ifndef dNODEBUG
00067 #  ifdef __GNUC__
00068 #    define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
00069       "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); } }
00070 #    define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \
00071       msg " in %s()", __FUNCTION__); } }
00072 #    define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT,          \
00073   msg " in %s() [%s:%u]", __FUNCTION__,__FILE__,__LINE__); }
00074 #  else // not __GNUC__
00075 #    define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
00076       "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); } }
00077 #    define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \
00078       msg " (%s:%u)", __FILE__,__LINE__); } }
00079 #    define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \
00080       msg " (%s:%u)", __FILE__,__LINE__); }
00081 #  endif
00082 #  define dIVERIFY(a) dIASSERT(a)
00083 #else
00084 #  define dIASSERT(a) ((void)0)
00085 #  define dUASSERT(a,msg) ((void)0)
00086 #  define dDEBUGMSG(msg) ((void)0)
00087 #  define dIVERIFY(a) ((void)(a))
00088 #endif
00089 
00090 #  ifdef __GNUC__
00091 #    define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
00092       "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); *(int *)0 = 0; } }
00093 #  else // not __GNUC__
00094 #    define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \
00095       "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); *(int *)0 = 0; } }
00096 #  endif
00097 
00098 // Argument assert is a special case of user assert
00099 #define dAASSERT(a) dUASSERT(a,"Bad argument(s)")
00100 
00101 /* floating point data type, vector, matrix and quaternion types */
00102 
00103 #if defined(dSINGLE)
00104 typedef float dReal;
00105 #ifdef dDOUBLE
00106 #error You can only #define dSINGLE or dDOUBLE, not both.
00107 #endif // dDOUBLE
00108 #elif defined(dDOUBLE)
00109 typedef double dReal;
00110 #else
00111 #error You must #define dSINGLE or dDOUBLE
00112 #endif
00113 
00114 // Detect if we've got both trimesh engines enabled.
00115 #if dTRIMESH_ENABLED
00116 #if dTRIMESH_OPCODE && dTRIMESH_GIMPACT
00117 #error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both.
00118 #endif
00119 #endif // dTRIMESH_ENABLED
00120 
00121 // Define a type for indices, either 16 or 32 bit, based on build option
00122 // TODO: Currently GIMPACT only supports 32 bit indices.
00123 #if dTRIMESH_16BIT_INDICES
00124 #if dTRIMESH_GIMPACT
00125 typedef uint32 dTriIndex;
00126 #else // dTRIMESH_GIMPACT
00127 typedef uint16 dTriIndex;
00128 #endif // dTRIMESH_GIMPACT
00129 #else // dTRIMESH_16BIT_INDICES
00130 typedef uint32 dTriIndex;
00131 #endif // dTRIMESH_16BIT_INDICES
00132 
00133 /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified
00134  * (used to compute matrix leading dimensions)
00135  */
00136 #define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a))
00137 
00138 /* these types are mainly just used in headers */
00139 typedef dReal dVector3[4];
00140 typedef dReal dVector4[4];
00141 typedef dReal dMatrix3[4*3];
00142 typedef dReal dMatrix4[4*4];
00143 typedef dReal dMatrix6[8*6];
00144 typedef dReal dQuaternion[4];
00145 
00146 
00147 /* precision dependent scalar math functions */
00148 
00149 #if defined(dSINGLE)
00150 
00151 #define REAL(x) (x ## f)               /* form a constant */
00152 #define dRecip(x) ((1.0f/(x)))            /* reciprocal */
00153 #define dSqrt(x) (sqrtf(x))         /* square root */
00154 #define dRecipSqrt(x) ((1.0f/sqrtf(x)))      /* reciprocal square root */
00155 #define dSin(x) (sinf(x))           /* sine */
00156 #define dCos(x) (cosf(x))           /* cosine */
00157 #define dFabs(x) (fabsf(x))         /* absolute value */
00158 #define dAtan2(y,x) (atan2f(y,x))      /* arc tangent with 2 args */
00159 #define dFMod(a,b) (fmodf(a,b))     /* modulo */
00160 #define dFloor(x) floorf(x)         /* floor */
00161 #define dCeil(x) ceilf(x)        /* floor */
00162 #define dCopySign(a,b) ((dReal)copysignf(a,b)) /* copy value sign */
00163 #define dNextAfter(x, y) nextafterf(x, y) /* next value after */
00164 
00165 #if defined(_ODE__NEXTAFTERF_REQUIRED)
00166 float _nextafterf(float x, float y);
00167 #endif
00168 
00169 #ifdef HAVE___ISNANF
00170 #define dIsNan(x) (__isnanf(x))
00171 #elif defined(HAVE__ISNANF)
00172 #define dIsNan(x) (_isnanf(x))
00173 #elif defined(HAVE_ISNANF)
00174 #define dIsNan(x) (isnanf(x))
00175 #else
00176   /*
00177      fall back to _isnan which is the VC way,
00178      this may seem redundant since we already checked
00179      for _isnan before, but if isnan is detected by
00180      configure but is not found during compilation
00181      we should always make sure we check for __isnanf,
00182      _isnanf and isnanf in that order before falling
00183      back to a default
00184   */
00185 #define dIsNan(x) (_isnan(x))
00186 #endif
00187 
00188 #elif defined(dDOUBLE)
00189 
00190 #define REAL(x) (x)
00191 #define dRecip(x) (1.0/(x))
00192 #define dSqrt(x) sqrt(x)
00193 #define dRecipSqrt(x) (1.0/sqrt(x))
00194 #define dSin(x) sin(x)
00195 #define dCos(x) cos(x)
00196 #define dFabs(x) fabs(x)
00197 #define dAtan2(y,x) atan2((y),(x))
00198 #define dFMod(a,b) (fmod((a),(b)))
00199 #define dFloor(x) floor(x)
00200 #define dCeil(x) ceil(x)
00201 #define dCopySign(a,b) (copysign((a),(b)))
00202 #define dNextAfter(x, y) nextafter(x, y)
00203 
00204 #undef _ODE__NEXTAFTERF_REQUIRED
00205 
00206 #ifdef HAVE___ISNAN
00207 #define dIsNan(x) (__isnan(x))
00208 #elif defined(HAVE__ISNAN)
00209 #define dIsNan(x) (_isnan(x))
00210 #elif defined(HAVE_ISNAN)
00211 #define dIsNan(x) (isnan(x))
00212 #else
00213 #define dIsNan(x) (_isnan(x))
00214 #endif
00215 
00216 #else
00217 #error You must #define dSINGLE or dDOUBLE
00218 #endif
00219 
00220 /* internal object types (all prefixed with `dx') */
00221 
00222 struct dxWorld;      /* dynamics world */
00223 struct dxSpace;      /* collision space */
00224 struct dxBody;    /* rigid body (dynamics object) */
00225 struct dxGeom;    /* geometry (collision object) */
00226 struct dxJoint;
00227 struct dxJointNode;
00228 struct dxJointGroup;
00229 struct dxWorldProcessThreadingManager;
00230 
00231 typedef struct dxWorld *dWorldID;
00232 typedef struct dxSpace *dSpaceID;
00233 typedef struct dxBody *dBodyID;
00234 typedef struct dxGeom *dGeomID;
00235 typedef struct dxJoint *dJointID;
00236 typedef struct dxJointGroup *dJointGroupID;
00237 typedef struct dxWorldProcessThreadingManager *dWorldStepThreadingManagerID;
00238 
00239 /* error numbers */
00240 
00241 enum {
00242   d_ERR_UNKNOWN = 0,    /* unknown error */
00243   d_ERR_IASSERT,     /* internal assertion failed */
00244   d_ERR_UASSERT,     /* user assertion failed */
00245   d_ERR_LCP       /* user assertion failed */
00246 };
00247 
00248 
00249 /* joint type numbers */
00250 
00251 typedef enum {
00252   dJointTypeNone = 0,      /* or "unknown" */
00253   dJointTypeBall,
00254   dJointTypeHinge,
00255   dJointTypeSlider,
00256   dJointTypeContact,
00257   dJointTypeUniversal,
00258   dJointTypeHinge2,
00259   dJointTypeFixed,
00260   dJointTypeNull,
00261   dJointTypeAMotor,
00262   dJointTypeLMotor,
00263   dJointTypePlane2D,
00264   dJointTypePR,
00265   dJointTypePU,
00266   dJointTypePiston
00267 } dJointType;
00268 
00269 
00270 /* an alternative way of setting joint parameters, using joint parameter
00271  * structures and member constants. we don't actually do this yet.
00272  */
00273 
00274 /*
00275 typedef struct dLimot {
00276   int mode;
00277   dReal lostop, histop;
00278   dReal vel, fmax;
00279   dReal fudge_factor;
00280   dReal bounce, soft;
00281   dReal suspension_erp, suspension_cfm;
00282 } dLimot;
00283 
00284 enum {
00285   dLimotLoStop    = 0x0001,
00286   dLimotHiStop    = 0x0002,
00287   dLimotVel    = 0x0004,
00288   dLimotFMax      = 0x0008,
00289   dLimotFudgeFactor  = 0x0010,
00290   dLimotBounce    = 0x0020,
00291   dLimotSoft      = 0x0040
00292 };
00293 */
00294 
00295 
00296 /* standard joint parameter names. why are these here? - because we don't want
00297  * to include all the joint function definitions in joint.cpp. hmmmm.
00298  * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument,
00299  * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and
00300  * paste between these two.
00301  */
00302 
00303 #define D_ALL_PARAM_NAMES(start) \
00304   /* parameters for limits and motors */ \
00305   dParamLoStop = start, \
00306   dParamHiStop, \
00307   dParamVel, \
00308   dParamFMax, \
00309   dParamFudgeFactor, \
00310   dParamBounce, \
00311   dParamCFM, \
00312   dParamStopERP, \
00313   dParamStopCFM, \
00314   /* parameters for suspension */ \
00315   dParamSuspensionERP, \
00316   dParamSuspensionCFM, \
00317   dParamERP, \
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 
00327 #define D_ALL_PARAM_NAMES_X(start,x) \
00328   dParamGroup ## x = start, \
00329   /* parameters for limits and motors */ \
00330   dParamLoStop ## x = start, \
00331   dParamHiStop ## x, \
00332   dParamVel ## x, \
00333   dParamFMax ## x, \
00334   dParamFudgeFactor ## x, \
00335   dParamBounce ## x, \
00336   dParamCFM ## x, \
00337   dParamStopERP ## x, \
00338   dParamStopCFM ## x, \
00339   /* parameters for suspension */ \
00340   dParamSuspensionERP ## x, \
00341   dParamSuspensionCFM ## x, \
00342   dParamERP ## x,
00343 
00344 enum {
00345   D_ALL_PARAM_NAMES(0)
00346   dParamsInGroup,     
00347   D_ALL_PARAM_NAMES_X(0x000,1)
00348   D_ALL_PARAM_NAMES_X(0x100,2)
00349   D_ALL_PARAM_NAMES_X(0x200,3)
00350 
00351   /* add a multiple of this constant to the basic parameter numbers to get
00352    * the parameters for the second, third etc axes.
00353    */
00354   dParamGroup=0x100
00355 };
00356 
00357 
00358 /* angular motor mode numbers */
00359 
00360 enum {
00361   dAMotorUser = 0,
00362   dAMotorEuler = 1
00363 };
00364 
00365 
00366 /* joint force feedback information */
00367 
00368 typedef struct dJointFeedback {
00369   dVector3 f1;    /* force applied to body 1 */
00370   dVector3 t1;    /* torque applied to body 1 */
00371   dVector3 f2;    /* force applied to body 2 */
00372   dVector3 t2;    /* torque applied to body 2 */
00373 } dJointFeedback;
00374 
00375 
00376 /* private functions that must be implemented by the collision library:
00377  * (1) indicate that a geom has moved, (2) get the next geom in a body list.
00378  * these functions are called whenever the position of geoms connected to a
00379  * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or
00380  * when the ODE step function updates the body state.
00381  */
00382 
00383 void dGeomMoved (dGeomID);
00384 dGeomID dGeomGetBodyNext (dGeomID);
00385 
00404 ODE_API const char* dGetConfiguration (void);
00405 
00414 ODE_API int dCheckConfiguration( const char* token );
00415 
00416 #ifdef __cplusplus
00417 }
00418 #endif
00419 
00420 #endif