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