├── README ├── c ├── collision.h ├── collision_space.h ├── collision_trimesh.h ├── common.h ├── compatibility.h ├── contact.h ├── error.h ├── export-dif.h ├── mass.h ├── matrix.h ├── memory.h ├── misc.h ├── objects.h ├── ode.h ├── odeconfig.h ├── odecpp.h ├── odecpp_collision.h ├── odeinit.h ├── odemath.h ├── odemath_legacy.h ├── rotation.h └── timer.h └── deimos └── ode ├── collision.d ├── collision_space.d ├── collision_trimesh.d ├── common.d ├── contact.d ├── error.d ├── exportdif.d ├── mass.d ├── matrix.d ├── memory.d ├── misc.d ├── objects.d ├── ode.d ├── odeconfig.d ├── odeinit.d ├── odemath.d ├── rotation.d └── timer.d /README: -------------------------------------------------------------------------------- 1 | ODE D bindings 2 | -------------- 3 | 4 | Version: 0.12 5 | 6 | The Open Dynamics Engine (ODE) is a physics engine in C/C++. Its two main 7 | components are a rigid body dynamics simulation engine and a collision 8 | detection engine. It is free software licensed both under the BSD 9 | license and the LGPL. 10 | 11 | ODE was started in 2001 and has already been used in many applications and 12 | games, such as BloodRayne 2, Call of Juarez, S.T.A.L.K.E.R, Titan Quest, 13 | World of Goo, X-Moto and OpenSimulator. 14 | 15 | License: dual licensed under the LGPL and BSD licenses: 16 | http://www.ode.org/ode-license.html 17 | 18 | Plain C header port by Daniel "q66" Kolesa . 19 | Original comments kept intact, sometimes with snippets of C code, 20 | possible DDoc conversion. 21 | 22 | C headers available in the c/ directory. 23 | -------------------------------------------------------------------------------- /c/collision_space.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * * 3 | * Open Dynamics Engine, Copyright (C) 2001-2003 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_COLLISION_SPACE_H_ 24 | #define _ODE_COLLISION_SPACE_H_ 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | struct dContactGeom; 33 | 34 | /** 35 | * @brief User callback for geom-geom collision testing. 36 | * 37 | * @param data The user data object, as passed to dSpaceCollide. 38 | * @param o1 The first geom being tested. 39 | * @param o2 The second geom being test. 40 | * 41 | * @remarks The callback function can call dCollide on o1 and o2 to generate 42 | * contact points between each pair. Then these contact points may be added 43 | * to the simulation as contact joints. The user's callback function can of 44 | * course chose not to call dCollide for any pair, e.g. if the user decides 45 | * that those pairs should not interact. 46 | * 47 | * @ingroup collide 48 | */ 49 | typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); 50 | 51 | 52 | ODE_API dSpaceID dSimpleSpaceCreate (dSpaceID space); 53 | ODE_API dSpaceID dHashSpaceCreate (dSpaceID space); 54 | ODE_API dSpaceID dQuadTreeSpaceCreate (dSpaceID space, const dVector3 Center, const dVector3 Extents, int Depth); 55 | 56 | 57 | // SAP 58 | // Order XZY or ZXY usually works best, if your Y is up. 59 | #define dSAP_AXES_XYZ ((0)|(1<<2)|(2<<4)) 60 | #define dSAP_AXES_XZY ((0)|(2<<2)|(1<<4)) 61 | #define dSAP_AXES_YXZ ((1)|(0<<2)|(2<<4)) 62 | #define dSAP_AXES_YZX ((1)|(2<<2)|(0<<4)) 63 | #define dSAP_AXES_ZXY ((2)|(0<<2)|(1<<4)) 64 | #define dSAP_AXES_ZYX ((2)|(1<<2)|(0<<4)) 65 | 66 | ODE_API dSpaceID dSweepAndPruneSpaceCreate( dSpaceID space, int axisorder ); 67 | 68 | 69 | 70 | ODE_API void dSpaceDestroy (dSpaceID); 71 | 72 | ODE_API void dHashSpaceSetLevels (dSpaceID space, int minlevel, int maxlevel); 73 | ODE_API void dHashSpaceGetLevels (dSpaceID space, int *minlevel, int *maxlevel); 74 | 75 | ODE_API void dSpaceSetCleanup (dSpaceID space, int mode); 76 | ODE_API int dSpaceGetCleanup (dSpaceID space); 77 | 78 | /** 79 | * @brief Sets sublevel value for a space. 80 | * 81 | * Sublevel affects how the space is handled in dSpaceCollide2 when it is collided 82 | * with another space. If sublevels of both spaces match, the function iterates 83 | * geometries of both spaces and collides them with each other. If sublevel of one 84 | * space is greater than the sublevel of another one, only the geometries of the 85 | * space with greater sublevel are iterated, another space is passed into 86 | * collision callback as a geometry itself. By default all the spaces are assigned 87 | * zero sublevel. 88 | * 89 | * @note 90 | * The space sublevel @e IS @e NOT automatically updated when one space is inserted 91 | * into another or removed from one. It is a client's responsibility to update sublevel 92 | * value if necessary. 93 | * 94 | * @param space the space to modify 95 | * @param sublevel the sublevel value to be assigned 96 | * @ingroup collide 97 | * @see dSpaceGetSublevel 98 | * @see dSpaceCollide2 99 | */ 100 | ODE_API void dSpaceSetSublevel (dSpaceID space, int sublevel); 101 | 102 | /** 103 | * @brief Gets sublevel value of a space. 104 | * 105 | * Sublevel affects how the space is handled in dSpaceCollide2 when it is collided 106 | * with another space. See @c dSpaceSetSublevel for more details. 107 | * 108 | * @param space the space to query 109 | * @returns the sublevel value of the space 110 | * @ingroup collide 111 | * @see dSpaceSetSublevel 112 | * @see dSpaceCollide2 113 | */ 114 | ODE_API int dSpaceGetSublevel (dSpaceID space); 115 | 116 | 117 | /** 118 | * @brief Sets manual cleanup flag for a space. 119 | * 120 | * Manual cleanup flag marks a space as eligible for manual thread data cleanup. 121 | * This function should be called for every space object right after creation in 122 | * case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag. 123 | * 124 | * Failure to set manual cleanup flag for a space may lead to some resources 125 | * remaining leaked until the program exit. 126 | * 127 | * @param space the space to modify 128 | * @param mode 1 for manual cleanup mode and 0 for default cleanup mode 129 | * @ingroup collide 130 | * @see dSpaceGetManualCleanup 131 | * @see dInitODE2 132 | */ 133 | ODE_API void dSpaceSetManualCleanup (dSpaceID space, int mode); 134 | 135 | /** 136 | * @brief Get manual cleanup flag of a space. 137 | * 138 | * Manual cleanup flag marks a space space as eligible for manual thread data cleanup. 139 | * See @c dSpaceSetManualCleanup for more details. 140 | * 141 | * @param space the space to query 142 | * @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space 143 | * @ingroup collide 144 | * @see dSpaceSetManualCleanup 145 | * @see dInitODE2 146 | */ 147 | ODE_API int dSpaceGetManualCleanup (dSpaceID space); 148 | 149 | ODE_API void dSpaceAdd (dSpaceID, dGeomID); 150 | ODE_API void dSpaceRemove (dSpaceID, dGeomID); 151 | ODE_API int dSpaceQuery (dSpaceID, dGeomID); 152 | ODE_API void dSpaceClean (dSpaceID); 153 | ODE_API int dSpaceGetNumGeoms (dSpaceID); 154 | ODE_API dGeomID dSpaceGetGeom (dSpaceID, int i); 155 | 156 | /** 157 | * @brief Given a space, this returns its class. 158 | * 159 | * The ODE classes are: 160 | * @li dSimpleSpaceClass 161 | * @li dHashSpaceClass 162 | * @li dSweepAndPruneSpaceClass 163 | * @li dQuadTreeSpaceClass 164 | * @li dFirstUserClass 165 | * @li dLastUserClass 166 | * 167 | * The class id not defined by the user should be between 168 | * dFirstSpaceClass and dLastSpaceClass. 169 | * 170 | * User-defined class will return their own number. 171 | * 172 | * @param space the space to query 173 | * @returns The space class ID. 174 | * @ingroup collide 175 | */ 176 | ODE_API int dSpaceGetClass(dSpaceID space); 177 | 178 | #ifdef __cplusplus 179 | } 180 | #endif 181 | 182 | #endif 183 | -------------------------------------------------------------------------------- /c/collision_trimesh.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * * 3 | * Open Dynamics Engine, Copyright (C) 2001-2003 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 | /* 24 | * TriMesh code by Erwin de Vries. 25 | * 26 | * Trimesh data. 27 | * This is where the actual vertexdata (pointers), and BV tree is stored. 28 | * Vertices should be single precision! 29 | * This should be more sophisticated, so that the user can easyly implement 30 | * another collision library, but this is a lot of work, and also costs some 31 | * performance because some data has to be copied. 32 | */ 33 | 34 | #ifndef _ODE_COLLISION_TRIMESH_H_ 35 | #define _ODE_COLLISION_TRIMESH_H_ 36 | 37 | #ifdef __cplusplus 38 | extern "C" { 39 | #endif 40 | 41 | /* 42 | * Data storage for triangle meshes. 43 | */ 44 | struct dxTriMeshData; 45 | typedef struct dxTriMeshData* dTriMeshDataID; 46 | 47 | /* 48 | * These dont make much sense now, but they will later when we add more 49 | * features. 50 | */ 51 | ODE_API dTriMeshDataID dGeomTriMeshDataCreate(void); 52 | ODE_API void dGeomTriMeshDataDestroy(dTriMeshDataID g); 53 | 54 | 55 | 56 | enum { TRIMESH_FACE_NORMALS }; 57 | ODE_API void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data); 58 | ODE_API void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); 59 | 60 | 61 | 62 | /** 63 | * We need to set the last transform after each time step for 64 | * accurate collision response. These functions get and set that transform. 65 | * It is stored per geom instance, rather than per dTriMeshDataID. 66 | */ 67 | ODE_API void dGeomTriMeshSetLastTransform( dGeomID g, dMatrix4 last_trans ); 68 | ODE_API dReal* dGeomTriMeshGetLastTransform( dGeomID g ); 69 | 70 | /* 71 | * Build a TriMesh data object with single precision vertex data. 72 | */ 73 | ODE_API void dGeomTriMeshDataBuildSingle(dTriMeshDataID g, 74 | const void* Vertices, int VertexStride, int VertexCount, 75 | const void* Indices, int IndexCount, int TriStride); 76 | /* same again with a normals array (used as trimesh-trimesh optimization) */ 77 | ODE_API void dGeomTriMeshDataBuildSingle1(dTriMeshDataID g, 78 | const void* Vertices, int VertexStride, int VertexCount, 79 | const void* Indices, int IndexCount, int TriStride, 80 | const void* Normals); 81 | /* 82 | * Build a TriMesh data object with double precision vertex data. 83 | */ 84 | ODE_API void dGeomTriMeshDataBuildDouble(dTriMeshDataID g, 85 | const void* Vertices, int VertexStride, int VertexCount, 86 | const void* Indices, int IndexCount, int TriStride); 87 | /* same again with a normals array (used as trimesh-trimesh optimization) */ 88 | ODE_API void dGeomTriMeshDataBuildDouble1(dTriMeshDataID g, 89 | const void* Vertices, int VertexStride, int VertexCount, 90 | const void* Indices, int IndexCount, int TriStride, 91 | const void* Normals); 92 | 93 | /* 94 | * Simple build. Single/double precision based on dSINGLE/dDOUBLE! 95 | */ 96 | ODE_API void dGeomTriMeshDataBuildSimple(dTriMeshDataID g, 97 | const dReal* Vertices, int VertexCount, 98 | const dTriIndex* Indices, int IndexCount); 99 | /* same again with a normals array (used as trimesh-trimesh optimization) */ 100 | ODE_API void dGeomTriMeshDataBuildSimple1(dTriMeshDataID g, 101 | const dReal* Vertices, int VertexCount, 102 | const dTriIndex* Indices, int IndexCount, 103 | const int* Normals); 104 | 105 | /* Preprocess the trimesh data to remove mark unnecessary edges and vertices */ 106 | ODE_API void dGeomTriMeshDataPreprocess(dTriMeshDataID g); 107 | /* Get and set the internal preprocessed trimesh data buffer, for loading and saving */ 108 | ODE_API void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, unsigned char** buf, int* bufLen); 109 | ODE_API void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, unsigned char* buf); 110 | 111 | 112 | /* 113 | * Per triangle callback. Allows the user to say if he wants a collision with 114 | * a particular triangle. 115 | */ 116 | typedef int dTriCallback(dGeomID TriMesh, dGeomID RefObject, int TriangleIndex); 117 | ODE_API void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); 118 | ODE_API dTriCallback* dGeomTriMeshGetCallback(dGeomID g); 119 | 120 | /* 121 | * Per object callback. Allows the user to get the list of triangles in 1 122 | * shot. Maybe we should remove this one. 123 | */ 124 | typedef void dTriArrayCallback(dGeomID TriMesh, dGeomID RefObject, const int* TriIndices, int TriCount); 125 | ODE_API void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback); 126 | ODE_API dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); 127 | 128 | /* 129 | * Ray callback. 130 | * Allows the user to say if a ray collides with a triangle on barycentric 131 | * coords. The user can for example sample a texture with alpha transparency 132 | * to determine if a collision should occur. 133 | */ 134 | typedef int dTriRayCallback(dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v); 135 | ODE_API void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback); 136 | ODE_API dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); 137 | 138 | /* 139 | * Triangle merging callback. 140 | * Allows the user to generate a fake triangle index for a new contact generated 141 | * from merging of two other contacts. That index could later be used by the 142 | * user to determine attributes of original triangles used as sources for a 143 | * merged contact. 144 | */ 145 | typedef int dTriTriMergeCallback(dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex); 146 | ODE_API void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback); 147 | ODE_API dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g); 148 | 149 | /* 150 | * Trimesh class 151 | * Construction. Callbacks are optional. 152 | */ 153 | ODE_API dGeomID dCreateTriMesh(dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback); 154 | 155 | ODE_API void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); 156 | ODE_API dTriMeshDataID dGeomTriMeshGetData(dGeomID g); 157 | 158 | 159 | // enable/disable/check temporal coherence 160 | ODE_API void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); 161 | ODE_API int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); 162 | 163 | /* 164 | * Clears the internal temporal coherence caches. When a geom has its 165 | * collision checked with a trimesh once, data is stored inside the trimesh. 166 | * With large worlds with lots of seperate objects this list could get huge. 167 | * We should be able to do this automagically. 168 | */ 169 | ODE_API void dGeomTriMeshClearTCCache(dGeomID g); 170 | 171 | 172 | /* 173 | * returns the TriMeshDataID 174 | */ 175 | ODE_API dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); 176 | 177 | /* 178 | * Gets a triangle. 179 | */ 180 | ODE_API void dGeomTriMeshGetTriangle(dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2); 181 | 182 | /* 183 | * Gets the point on the requested triangle and the given barycentric 184 | * coordinates. 185 | */ 186 | ODE_API void dGeomTriMeshGetPoint(dGeomID g, int Index, dReal u, dReal v, dVector3 Out); 187 | 188 | /* 189 | 190 | This is how the strided data works: 191 | 192 | struct StridedVertex{ 193 | dVector3 Vertex; 194 | // Userdata 195 | }; 196 | int VertexStride = sizeof(StridedVertex); 197 | 198 | struct StridedTri{ 199 | int Indices[3]; 200 | // Userdata 201 | }; 202 | int TriStride = sizeof(StridedTri); 203 | 204 | */ 205 | 206 | 207 | ODE_API int dGeomTriMeshGetTriangleCount (dGeomID g); 208 | 209 | ODE_API void dGeomTriMeshDataUpdate(dTriMeshDataID g); 210 | 211 | #ifdef __cplusplus 212 | } 213 | #endif 214 | 215 | #endif /* _ODE_COLLISION_TRIMESH_H_ */ 216 | 217 | -------------------------------------------------------------------------------- /c/common.h: -------------------------------------------------------------------------------- 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 | #include 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | 34 | #define PURE_INLINE static __inline 35 | 36 | 37 | /* configuration stuff */ 38 | 39 | /* constants */ 40 | 41 | /* pi and 1/sqrt(2) are defined here if necessary because they don't get 42 | * defined in on some platforms (like MS-Windows) 43 | */ 44 | 45 | #ifndef M_PI 46 | #define M_PI REAL(3.1415926535897932384626433832795029) 47 | #endif 48 | #ifndef M_SQRT1_2 49 | #define M_SQRT1_2 REAL(0.7071067811865475244008443621048490) 50 | #endif 51 | 52 | 53 | /* debugging: 54 | * IASSERT is an internal assertion, i.e. a consistency check. if it fails 55 | * we want to know where. 56 | * UASSERT is a user assertion, i.e. if it fails a nice error message 57 | * should be printed for the user. 58 | * AASSERT is an arguments assertion, i.e. if it fails "bad argument(s)" 59 | * is printed. 60 | * DEBUGMSG just prints out a message 61 | */ 62 | 63 | # if defined(__STDC__) && __STDC_VERSION__ >= 199901L 64 | # define __FUNCTION__ __func__ 65 | # endif 66 | #ifndef dNODEBUG 67 | # ifdef __GNUC__ 68 | # define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ 69 | "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); } } 70 | # define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \ 71 | msg " in %s()", __FUNCTION__); } } 72 | # define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \ 73 | msg " in %s() [%s:%u]", __FUNCTION__,__FILE__,__LINE__); } 74 | # else // not __GNUC__ 75 | # define dIASSERT(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ 76 | "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); } } 77 | # define dUASSERT(a,msg) { if (!(a)) { dDebug (d_ERR_UASSERT, \ 78 | msg " (%s:%u)", __FILE__,__LINE__); } } 79 | # define dDEBUGMSG(msg) { dMessage (d_ERR_UASSERT, \ 80 | msg " (%s:%u)", __FILE__,__LINE__); } 81 | # endif 82 | # define dIVERIFY(a) dIASSERT(a) 83 | #else 84 | # define dIASSERT(a) ((void)0) 85 | # define dUASSERT(a,msg) ((void)0) 86 | # define dDEBUGMSG(msg) ((void)0) 87 | # define dIVERIFY(a) ((void)(a)) 88 | #endif 89 | 90 | # ifdef __GNUC__ 91 | # define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ 92 | "assertion \"" #a "\" failed in %s() [%s:%u]",__FUNCTION__,__FILE__,__LINE__); *(int *)0 = 0; } } 93 | # else // not __GNUC__ 94 | # define dICHECK(a) { if (!(a)) { dDebug (d_ERR_IASSERT, \ 95 | "assertion \"" #a "\" failed in %s:%u",__FILE__,__LINE__); *(int *)0 = 0; } } 96 | # endif 97 | 98 | // Argument assert is a special case of user assert 99 | #define dAASSERT(a) dUASSERT(a,"Bad argument(s)") 100 | 101 | /* floating point data type, vector, matrix and quaternion types */ 102 | 103 | #if defined(dSINGLE) 104 | typedef float dReal; 105 | #ifdef dDOUBLE 106 | #error You can only #define dSINGLE or dDOUBLE, not both. 107 | #endif // dDOUBLE 108 | #elif defined(dDOUBLE) 109 | typedef double dReal; 110 | #else 111 | #error You must #define dSINGLE or dDOUBLE 112 | #endif 113 | 114 | // Detect if we've got both trimesh engines enabled. 115 | #if dTRIMESH_ENABLED 116 | #if dTRIMESH_OPCODE && dTRIMESH_GIMPACT 117 | #error You can only #define dTRIMESH_OPCODE or dTRIMESH_GIMPACT, not both. 118 | #endif 119 | #endif // dTRIMESH_ENABLED 120 | 121 | // Define a type for indices, either 16 or 32 bit, based on build option 122 | // TODO: Currently GIMPACT only supports 32 bit indices. 123 | #if dTRIMESH_16BIT_INDICES 124 | #if dTRIMESH_GIMPACT 125 | typedef uint32 dTriIndex; 126 | #else // dTRIMESH_GIMPACT 127 | typedef uint16 dTriIndex; 128 | #endif // dTRIMESH_GIMPACT 129 | #else // dTRIMESH_16BIT_INDICES 130 | typedef uint32 dTriIndex; 131 | #endif // dTRIMESH_16BIT_INDICES 132 | 133 | /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified 134 | * (used to compute matrix leading dimensions) 135 | */ 136 | #define dPAD(a) (((a) > 1) ? ((((a)-1)|3)+1) : (a)) 137 | 138 | /* these types are mainly just used in headers */ 139 | typedef dReal dVector3[4]; 140 | typedef dReal dVector4[4]; 141 | typedef dReal dMatrix3[4*3]; 142 | typedef dReal dMatrix4[4*4]; 143 | typedef dReal dMatrix6[8*6]; 144 | typedef dReal dQuaternion[4]; 145 | 146 | 147 | /* precision dependent scalar math functions */ 148 | 149 | #if defined(dSINGLE) 150 | 151 | #define REAL(x) (x ## f) /* form a constant */ 152 | #define dRecip(x) ((1.0f/(x))) /* reciprocal */ 153 | #define dSqrt(x) (sqrtf(x)) /* square root */ 154 | #define dRecipSqrt(x) ((1.0f/sqrtf(x))) /* reciprocal square root */ 155 | #define dSin(x) (sinf(x)) /* sine */ 156 | #define dCos(x) (cosf(x)) /* cosine */ 157 | #define dFabs(x) (fabsf(x)) /* absolute value */ 158 | #define dAtan2(y,x) (atan2f(y,x)) /* arc tangent with 2 args */ 159 | #define dFMod(a,b) (fmodf(a,b)) /* modulo */ 160 | #define dFloor(x) floorf(x) /* floor */ 161 | #define dCeil(x) ceilf(x) /* floor */ 162 | #define dCopySign(a,b) ((dReal)copysignf(a,b)) /* copy value sign */ 163 | #define dNextAfter(x, y) nextafterf(x, y) /* next value after */ 164 | 165 | #if defined(_ODE__NEXTAFTERF_REQUIRED) 166 | float _nextafterf(float x, float y); 167 | #endif 168 | 169 | #ifdef HAVE___ISNANF 170 | #define dIsNan(x) (__isnanf(x)) 171 | #elif defined(HAVE__ISNANF) 172 | #define dIsNan(x) (_isnanf(x)) 173 | #elif defined(HAVE_ISNANF) 174 | #define dIsNan(x) (isnanf(x)) 175 | #else 176 | /* 177 | fall back to _isnan which is the VC way, 178 | this may seem redundant since we already checked 179 | for _isnan before, but if isnan is detected by 180 | configure but is not found during compilation 181 | we should always make sure we check for __isnanf, 182 | _isnanf and isnanf in that order before falling 183 | back to a default 184 | */ 185 | #define dIsNan(x) (_isnan(x)) 186 | #endif 187 | 188 | #elif defined(dDOUBLE) 189 | 190 | #define REAL(x) (x) 191 | #define dRecip(x) (1.0/(x)) 192 | #define dSqrt(x) sqrt(x) 193 | #define dRecipSqrt(x) (1.0/sqrt(x)) 194 | #define dSin(x) sin(x) 195 | #define dCos(x) cos(x) 196 | #define dFabs(x) fabs(x) 197 | #define dAtan2(y,x) atan2((y),(x)) 198 | #define dFMod(a,b) (fmod((a),(b))) 199 | #define dFloor(x) floor(x) 200 | #define dCeil(x) ceil(x) 201 | #define dCopySign(a,b) (copysign((a),(b))) 202 | #define dNextAfter(x, y) nextafter(x, y) 203 | 204 | #undef _ODE__NEXTAFTERF_REQUIRED 205 | 206 | #ifdef HAVE___ISNAN 207 | #define dIsNan(x) (__isnan(x)) 208 | #elif defined(HAVE__ISNAN) 209 | #define dIsNan(x) (_isnan(x)) 210 | #elif defined(HAVE_ISNAN) 211 | #define dIsNan(x) (isnan(x)) 212 | #else 213 | #define dIsNan(x) (_isnan(x)) 214 | #endif 215 | 216 | #else 217 | #error You must #define dSINGLE or dDOUBLE 218 | #endif 219 | 220 | /* internal object types (all prefixed with `dx') */ 221 | 222 | struct dxWorld; /* dynamics world */ 223 | struct dxSpace; /* collision space */ 224 | struct dxBody; /* rigid body (dynamics object) */ 225 | struct dxGeom; /* geometry (collision object) */ 226 | struct dxJoint; 227 | struct dxJointNode; 228 | struct dxJointGroup; 229 | struct dxWorldProcessThreadingManager; 230 | 231 | typedef struct dxWorld *dWorldID; 232 | typedef struct dxSpace *dSpaceID; 233 | typedef struct dxBody *dBodyID; 234 | typedef struct dxGeom *dGeomID; 235 | typedef struct dxJoint *dJointID; 236 | typedef struct dxJointGroup *dJointGroupID; 237 | typedef struct dxWorldProcessThreadingManager *dWorldStepThreadingManagerID; 238 | 239 | /* error numbers */ 240 | 241 | enum { 242 | d_ERR_UNKNOWN = 0, /* unknown error */ 243 | d_ERR_IASSERT, /* internal assertion failed */ 244 | d_ERR_UASSERT, /* user assertion failed */ 245 | d_ERR_LCP /* user assertion failed */ 246 | }; 247 | 248 | 249 | /* joint type numbers */ 250 | 251 | typedef enum { 252 | dJointTypeNone = 0, /* or "unknown" */ 253 | dJointTypeBall, 254 | dJointTypeHinge, 255 | dJointTypeSlider, 256 | dJointTypeContact, 257 | dJointTypeUniversal, 258 | dJointTypeHinge2, 259 | dJointTypeFixed, 260 | dJointTypeNull, 261 | dJointTypeAMotor, 262 | dJointTypeLMotor, 263 | dJointTypePlane2D, 264 | dJointTypePR, 265 | dJointTypePU, 266 | dJointTypePiston 267 | } dJointType; 268 | 269 | 270 | /* an alternative way of setting joint parameters, using joint parameter 271 | * structures and member constants. we don't actually do this yet. 272 | */ 273 | 274 | /* 275 | typedef struct dLimot { 276 | int mode; 277 | dReal lostop, histop; 278 | dReal vel, fmax; 279 | dReal fudge_factor; 280 | dReal bounce, soft; 281 | dReal suspension_erp, suspension_cfm; 282 | } dLimot; 283 | 284 | enum { 285 | dLimotLoStop = 0x0001, 286 | dLimotHiStop = 0x0002, 287 | dLimotVel = 0x0004, 288 | dLimotFMax = 0x0008, 289 | dLimotFudgeFactor = 0x0010, 290 | dLimotBounce = 0x0020, 291 | dLimotSoft = 0x0040 292 | }; 293 | */ 294 | 295 | 296 | /* standard joint parameter names. why are these here? - because we don't want 297 | * to include all the joint function definitions in joint.cpp. hmmmm. 298 | * MSVC complains if we call D_ALL_PARAM_NAMES_X with a blank second argument, 299 | * which is why we have the D_ALL_PARAM_NAMES macro as well. please copy and 300 | * paste between these two. 301 | */ 302 | 303 | #define D_ALL_PARAM_NAMES(start) \ 304 | /* parameters for limits and motors */ \ 305 | dParamLoStop = start, \ 306 | dParamHiStop, \ 307 | dParamVel, \ 308 | dParamFMax, \ 309 | dParamFudgeFactor, \ 310 | dParamBounce, \ 311 | dParamCFM, \ 312 | dParamStopERP, \ 313 | dParamStopCFM, \ 314 | /* parameters for suspension */ \ 315 | dParamSuspensionERP, \ 316 | dParamSuspensionCFM, \ 317 | dParamERP, \ 318 | 319 | ////////////////////////////////////////////////////////////////////////////// 320 | /// \enum D_ALL_PARAM_NAMES_X 321 | /// 322 | /// \var dParamGroup This is the starting value of the different group 323 | /// (i.e. dParamGroup1, dParamGroup2, dParamGroup3) 324 | /// It also helps in the use of parameter 325 | /// (dParamGroup2 | dParamFMax) == dParamFMax2 326 | ////////////////////////////////////////////////////////////////////////////// 327 | #define D_ALL_PARAM_NAMES_X(start,x) \ 328 | dParamGroup ## x = start, \ 329 | /* parameters for limits and motors */ \ 330 | dParamLoStop ## x = start, \ 331 | dParamHiStop ## x, \ 332 | dParamVel ## x, \ 333 | dParamFMax ## x, \ 334 | dParamFudgeFactor ## x, \ 335 | dParamBounce ## x, \ 336 | dParamCFM ## x, \ 337 | dParamStopERP ## x, \ 338 | dParamStopCFM ## x, \ 339 | /* parameters for suspension */ \ 340 | dParamSuspensionERP ## x, \ 341 | dParamSuspensionCFM ## x, \ 342 | dParamERP ## x, 343 | 344 | enum { 345 | D_ALL_PARAM_NAMES(0) 346 | dParamsInGroup, ///< Number of parameter in a group 347 | D_ALL_PARAM_NAMES_X(0x000,1) 348 | D_ALL_PARAM_NAMES_X(0x100,2) 349 | D_ALL_PARAM_NAMES_X(0x200,3) 350 | 351 | /* add a multiple of this constant to the basic parameter numbers to get 352 | * the parameters for the second, third etc axes. 353 | */ 354 | dParamGroup=0x100 355 | }; 356 | 357 | 358 | /* angular motor mode numbers */ 359 | 360 | enum { 361 | dAMotorUser = 0, 362 | dAMotorEuler = 1 363 | }; 364 | 365 | 366 | /* joint force feedback information */ 367 | 368 | typedef struct dJointFeedback { 369 | dVector3 f1; /* force applied to body 1 */ 370 | dVector3 t1; /* torque applied to body 1 */ 371 | dVector3 f2; /* force applied to body 2 */ 372 | dVector3 t2; /* torque applied to body 2 */ 373 | } dJointFeedback; 374 | 375 | 376 | /* private functions that must be implemented by the collision library: 377 | * (1) indicate that a geom has moved, (2) get the next geom in a body list. 378 | * these functions are called whenever the position of geoms connected to a 379 | * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or 380 | * when the ODE step function updates the body state. 381 | */ 382 | 383 | void dGeomMoved (dGeomID); 384 | dGeomID dGeomGetBodyNext (dGeomID); 385 | 386 | /** 387 | * dGetConfiguration returns the specific ODE build configuration as 388 | * a string of tokens. The string can be parsed in a similar way to 389 | * the OpenGL extension mechanism, the naming convention should be 390 | * familiar too. The following extensions are reported: 391 | * 392 | * ODE 393 | * ODE_single_precision 394 | * ODE_double_precision 395 | * ODE_EXT_no_debug 396 | * ODE_EXT_trimesh 397 | * ODE_EXT_opcode 398 | * ODE_EXT_gimpact 399 | * ODE_EXT_malloc_not_alloca 400 | * ODE_EXT_gyroscopic 401 | * ODE_OPC_16bit_indices 402 | * ODE_OPC_new_collider 403 | */ 404 | ODE_API const char* dGetConfiguration (void); 405 | 406 | /** 407 | * Helper to check for a token in the ODE configuration string. 408 | * Caution, this function is case sensitive. 409 | * 410 | * @param token A configuration token, see dGetConfiguration for details 411 | * 412 | * @return 1 if exact token is present, 0 if not present 413 | */ 414 | ODE_API int dCheckConfiguration( const char* token ); 415 | 416 | #ifdef __cplusplus 417 | } 418 | #endif 419 | 420 | #endif 421 | -------------------------------------------------------------------------------- /c/compatibility.h: -------------------------------------------------------------------------------- 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_COMPATIBILITY_H_ 24 | #define _ODE_COMPATIBILITY_H_ 25 | 26 | /* 27 | * ODE's backward compatibility system ensures that as ODE's API 28 | * evolves, user code will not break. 29 | */ 30 | 31 | /* 32 | * These new rotation function names are more consistent with the 33 | * rest of the API. 34 | */ 35 | #define dQtoR(q,R) dRfromQ((R),(q)) 36 | #define dRtoQ(R,q) dQfromR((q),(R)) 37 | #define dWtoDQ(w,q,dq) dDQfromW((dq),(w),(q)) 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /c/contact.h: -------------------------------------------------------------------------------- 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_CONTACT_H_ 24 | #define _ODE_CONTACT_H_ 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | 33 | enum { 34 | dContactMu2 = 0x001, 35 | dContactFDir1 = 0x002, 36 | dContactBounce = 0x004, 37 | dContactSoftERP = 0x008, 38 | dContactSoftCFM = 0x010, 39 | dContactMotion1 = 0x020, 40 | dContactMotion2 = 0x040, 41 | dContactMotionN = 0x080, 42 | dContactSlip1 = 0x100, 43 | dContactSlip2 = 0x200, 44 | 45 | dContactApprox0 = 0x0000, 46 | dContactApprox1_1 = 0x1000, 47 | dContactApprox1_2 = 0x2000, 48 | dContactApprox1 = 0x3000 49 | }; 50 | 51 | 52 | typedef struct dSurfaceParameters { 53 | /* must always be defined */ 54 | int mode; 55 | dReal mu; 56 | 57 | /* only defined if the corresponding flag is set in mode */ 58 | dReal mu2; 59 | dReal bounce; 60 | dReal bounce_vel; 61 | dReal soft_erp; 62 | dReal soft_cfm; 63 | dReal motion1,motion2,motionN; 64 | dReal slip1,slip2; 65 | } dSurfaceParameters; 66 | 67 | 68 | /** 69 | * @brief Describe the contact point between two geoms. 70 | * 71 | * If two bodies touch, or if a body touches a static feature in its 72 | * environment, the contact is represented by one or more "contact 73 | * points", described by dContactGeom. 74 | * 75 | * The convention is that if body 1 is moved along the normal vector by 76 | * a distance depth (or equivalently if body 2 is moved the same distance 77 | * in the opposite direction) then the contact depth will be reduced to 78 | * zero. This means that the normal vector points "in" to body 1. 79 | * 80 | * @ingroup collide 81 | */ 82 | typedef struct dContactGeom { 83 | dVector3 pos; ///< contact position 84 | dVector3 normal; ///< normal vector 85 | dReal depth; ///< penetration depth 86 | dGeomID g1,g2; ///< the colliding geoms 87 | int side1,side2; ///< (to be documented) 88 | } dContactGeom; 89 | 90 | 91 | /* contact info used by contact joint */ 92 | 93 | typedef struct dContact { 94 | dSurfaceParameters surface; 95 | dContactGeom geom; 96 | dVector3 fdir1; 97 | } dContact; 98 | 99 | 100 | #ifdef __cplusplus 101 | } 102 | #endif 103 | 104 | #endif 105 | -------------------------------------------------------------------------------- /c/error.h: -------------------------------------------------------------------------------- 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 | /* this comes from the `reuse' library. copy any changes back to the source */ 24 | 25 | #ifndef _ODE_ERROR_H_ 26 | #define _ODE_ERROR_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* all user defined error functions have this type. error and debug functions 35 | * should not return. 36 | */ 37 | typedef void dMessageFunction (int errnum, const char *msg, va_list ap); 38 | 39 | /* set a new error, debug or warning handler. if fn is 0, the default handlers 40 | * are used. 41 | */ 42 | ODE_API void dSetErrorHandler (dMessageFunction *fn); 43 | ODE_API void dSetDebugHandler (dMessageFunction *fn); 44 | ODE_API void dSetMessageHandler (dMessageFunction *fn); 45 | 46 | /* return the current error, debug or warning handler. if the return value is 47 | * 0, the default handlers are in place. 48 | */ 49 | ODE_API dMessageFunction *dGetErrorHandler(void); 50 | ODE_API dMessageFunction *dGetDebugHandler(void); 51 | ODE_API dMessageFunction *dGetMessageHandler(void); 52 | 53 | /* generate a fatal error, debug trap or a message. */ 54 | ODE_API void dError (int num, const char *msg, ...); 55 | ODE_API void dDebug (int num, const char *msg, ...); 56 | ODE_API void dMessage (int num, const char *msg, ...); 57 | 58 | 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /c/export-dif.h: -------------------------------------------------------------------------------- 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_EXPORT_DIF_ 24 | #define _ODE_EXPORT_DIF_ 25 | 26 | #include 27 | 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | ODE_API void dWorldExportDIF (dWorldID w, FILE *file, const char *world_name); 34 | 35 | 36 | #ifdef __cplusplus 37 | } 38 | #endif 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /c/mass.h: -------------------------------------------------------------------------------- 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_MASS_H_ 24 | #define _ODE_MASS_H_ 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | struct dMass; 33 | typedef struct dMass dMass; 34 | 35 | /** 36 | * Check if a mass structure has valid value. 37 | * The function check if the mass and innertia matrix are positive definits 38 | * 39 | * @param m A mass structure to check 40 | * 41 | * @return 1 if both codition are met 42 | */ 43 | ODE_API int dMassCheck(const dMass *m); 44 | 45 | ODE_API void dMassSetZero (dMass *); 46 | 47 | ODE_API void dMassSetParameters (dMass *, dReal themass, 48 | dReal cgx, dReal cgy, dReal cgz, 49 | dReal I11, dReal I22, dReal I33, 50 | dReal I12, dReal I13, dReal I23); 51 | 52 | ODE_API void dMassSetSphere (dMass *, dReal density, dReal radius); 53 | ODE_API void dMassSetSphereTotal (dMass *, dReal total_mass, dReal radius); 54 | 55 | ODE_API void dMassSetCapsule (dMass *, dReal density, int direction, 56 | dReal radius, dReal length); 57 | ODE_API void dMassSetCapsuleTotal (dMass *, dReal total_mass, int direction, 58 | dReal radius, dReal length); 59 | 60 | ODE_API void dMassSetCylinder (dMass *, dReal density, int direction, 61 | dReal radius, dReal length); 62 | ODE_API void dMassSetCylinderTotal (dMass *, dReal total_mass, int direction, 63 | dReal radius, dReal length); 64 | 65 | ODE_API void dMassSetBox (dMass *, dReal density, 66 | dReal lx, dReal ly, dReal lz); 67 | ODE_API void dMassSetBoxTotal (dMass *, dReal total_mass, 68 | dReal lx, dReal ly, dReal lz); 69 | 70 | ODE_API void dMassSetTrimesh (dMass *, dReal density, dGeomID g); 71 | 72 | ODE_API void dMassSetTrimeshTotal (dMass *m, dReal total_mass, dGeomID g); 73 | 74 | ODE_API void dMassAdjust (dMass *, dReal newmass); 75 | 76 | ODE_API void dMassTranslate (dMass *, dReal x, dReal y, dReal z); 77 | 78 | ODE_API void dMassRotate (dMass *, const dMatrix3 R); 79 | 80 | ODE_API void dMassAdd (dMass *a, const dMass *b); 81 | 82 | 83 | // Backwards compatible API 84 | ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinder(dMass *a, dReal b, int c, dReal d, dReal e); 85 | ODE_API ODE_API_DEPRECATED void dMassSetCappedCylinderTotal(dMass *a, dReal b, int c, dReal d, dReal e); 86 | 87 | 88 | struct dMass { 89 | dReal mass; 90 | dVector3 c; 91 | dMatrix3 I; 92 | 93 | #ifdef __cplusplus 94 | dMass() 95 | { dMassSetZero (this); } 96 | void setZero() 97 | { dMassSetZero (this); } 98 | void setParameters (dReal themass, dReal cgx, dReal cgy, dReal cgz, 99 | dReal I11, dReal I22, dReal I33, 100 | dReal I12, dReal I13, dReal I23) 101 | { dMassSetParameters (this,themass,cgx,cgy,cgz,I11,I22,I33,I12,I13,I23); } 102 | 103 | void setSphere (dReal density, dReal radius) 104 | { dMassSetSphere (this,density,radius); } 105 | void setSphereTotal (dReal total, dReal radius) 106 | { dMassSetSphereTotal (this,total,radius); } 107 | 108 | void setCapsule (dReal density, int direction, dReal radius, dReal length) 109 | { dMassSetCapsule (this,density,direction,radius,length); } 110 | void setCapsuleTotal (dReal total, int direction, dReal radius, dReal length) 111 | { dMassSetCapsule (this,total,direction,radius,length); } 112 | 113 | void setCylinder(dReal density, int direction, dReal radius, dReal length) 114 | { dMassSetCylinder (this,density,direction,radius,length); } 115 | void setCylinderTotal(dReal total, int direction, dReal radius, dReal length) 116 | { dMassSetCylinderTotal (this,total,direction,radius,length); } 117 | 118 | void setBox (dReal density, dReal lx, dReal ly, dReal lz) 119 | { dMassSetBox (this,density,lx,ly,lz); } 120 | void setBoxTotal (dReal total, dReal lx, dReal ly, dReal lz) 121 | { dMassSetBoxTotal (this,total,lx,ly,lz); } 122 | 123 | void setTrimesh(dReal density, dGeomID g) 124 | { dMassSetTrimesh (this, density, g); } 125 | void setTrimeshTotal(dReal total, dGeomID g) 126 | { dMassSetTrimeshTotal (this, total, g); } 127 | 128 | void adjust (dReal newmass) 129 | { dMassAdjust (this,newmass); } 130 | void translate (dReal x, dReal y, dReal z) 131 | { dMassTranslate (this,x,y,z); } 132 | void rotate (const dMatrix3 R) 133 | { dMassRotate (this,R); } 134 | void add (const dMass *b) 135 | { dMassAdd (this,b); } 136 | #endif 137 | }; 138 | 139 | 140 | #ifdef __cplusplus 141 | } 142 | #endif 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /c/matrix.h: -------------------------------------------------------------------------------- 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 | /* optimized and unoptimized vector and matrix functions */ 24 | 25 | #ifndef _ODE_MATRIX_H_ 26 | #define _ODE_MATRIX_H_ 27 | 28 | #include 29 | 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | 36 | /* set a vector/matrix of size n to all zeros, or to a specific value. */ 37 | 38 | ODE_API void dSetZero (dReal *a, int n); 39 | ODE_API void dSetValue (dReal *a, int n, dReal value); 40 | 41 | 42 | /* get the dot product of two n*1 vectors. if n <= 0 then 43 | * zero will be returned (in which case a and b need not be valid). 44 | */ 45 | 46 | ODE_API dReal dDot (const dReal *a, const dReal *b, int n); 47 | 48 | 49 | /* get the dot products of (a0,b), (a1,b), etc and return them in outsum. 50 | * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case 51 | * the input vectors need not be valid). this function is somewhat faster 52 | * than calling dDot() for all of the combinations separately. 53 | */ 54 | 55 | /* NOT INCLUDED in the library for now. 56 | void dMultidot2 (const dReal *a0, const dReal *a1, 57 | const dReal *b, dReal *outsum, int n); 58 | */ 59 | 60 | 61 | /* matrix multiplication. all matrices are stored in standard row format. 62 | * the digit refers to the argument that is transposed: 63 | * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) 64 | * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) 65 | * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) 66 | * case 1,2 are equivalent to saying that the operation is A=B*C but 67 | * B or C are stored in standard column format. 68 | */ 69 | 70 | ODE_API void dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); 71 | ODE_API void dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); 72 | ODE_API void dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); 73 | 74 | 75 | /* do an in-place cholesky decomposition on the lower triangle of the n*n 76 | * symmetric matrix A (which is stored by rows). the resulting lower triangle 77 | * will be such that L*L'=A. return 1 on success and 0 on failure (on failure 78 | * the matrix is not positive definite). 79 | */ 80 | 81 | ODE_API int dFactorCholesky (dReal *A, int n); 82 | 83 | 84 | /* solve for x: L*L'*x = b, and put the result back into x. 85 | * L is size n*n, b is size n*1. only the lower triangle of L is considered. 86 | */ 87 | 88 | ODE_API void dSolveCholesky (const dReal *L, dReal *b, int n); 89 | 90 | 91 | /* compute the inverse of the n*n positive definite matrix A and put it in 92 | * Ainv. this is not especially fast. this returns 1 on success (A was 93 | * positive definite) or 0 on failure (not PD). 94 | */ 95 | 96 | ODE_API int dInvertPDMatrix (const dReal *A, dReal *Ainv, int n); 97 | 98 | 99 | /* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). 100 | * positive definite means that x'*A*x > 0 for any x. this performs a 101 | * cholesky decomposition of A. if the decomposition fails then the matrix 102 | * is not positive definite. A is stored by rows. A is not altered. 103 | */ 104 | 105 | ODE_API int dIsPositiveDefinite (const dReal *A, int n); 106 | 107 | 108 | /* factorize a matrix A into L*D*L', where L is lower triangular with ones on 109 | * the diagonal, and D is diagonal. 110 | * A is an n*n matrix stored by rows, with a leading dimension of n rounded 111 | * up to 4. L is written into the strict lower triangle of A (the ones are not 112 | * written) and the reciprocal of the diagonal elements of D are written into 113 | * d. 114 | */ 115 | ODE_API void dFactorLDLT (dReal *A, dReal *d, int n, int nskip); 116 | 117 | 118 | /* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, 119 | * and x,b are n*1. b is overwritten with x. 120 | * the leading dimension of L is `nskip'. 121 | */ 122 | ODE_API void dSolveL1 (const dReal *L, dReal *b, int n, int nskip); 123 | 124 | 125 | /* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, 126 | * and x,b are n*1. b is overwritten with x. 127 | * the leading dimension of L is `nskip'. 128 | */ 129 | ODE_API void dSolveL1T (const dReal *L, dReal *b, int n, int nskip); 130 | 131 | 132 | /* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */ 133 | 134 | ODE_API void dVectorScale (dReal *a, const dReal *d, int n); 135 | 136 | 137 | /* given `L', a n*n lower triangular matrix with ones on the diagonal, 138 | * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix 139 | * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. 140 | * the leading dimension of L is `nskip'. 141 | */ 142 | 143 | ODE_API void dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip); 144 | 145 | 146 | /* given an L*D*L' factorization of an n*n matrix A, return the updated 147 | * factorization L2*D2*L2' of A plus the following "top left" matrix: 148 | * 149 | * [ b a' ] <-- b is a[0] 150 | * [ a 0 ] <-- a is a[1..n-1] 151 | * 152 | * - L has size n*n, its leading dimension is nskip. L is lower triangular 153 | * with ones on the diagonal. only the lower triangle of L is referenced. 154 | * - d has size n. d contains the reciprocal diagonal elements of D. 155 | * - a has size n. 156 | * the result is written into L, except that the left column of L and d[0] 157 | * are not actually modified. see ldltaddTL.m for further comments. 158 | */ 159 | ODE_API void dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip); 160 | 161 | 162 | /* given an L*D*L' factorization of a permuted matrix A, produce a new 163 | * factorization for row and column `r' removed. 164 | * - A has size n1*n1, its leading dimension in nskip. A is symmetric and 165 | * positive definite. only the lower triangle of A is referenced. 166 | * A itself may actually be an array of row pointers. 167 | * - L has size n2*n2, its leading dimension in nskip. L is lower triangular 168 | * with ones on the diagonal. only the lower triangle of L is referenced. 169 | * - d has size n2. d contains the reciprocal diagonal elements of D. 170 | * - p is a permutation vector. it contains n2 indexes into A. each index 171 | * must be in the range 0..n1-1. 172 | * - r is the row/column of L to remove. 173 | * the new L will be written within the old L, i.e. will have the same leading 174 | * dimension. the last row and column of L, and the last element of d, are 175 | * undefined on exit. 176 | * 177 | * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. 178 | */ 179 | ODE_API void dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, 180 | int n1, int n2, int r, int nskip); 181 | 182 | 183 | /* given an n*n matrix A (with leading dimension nskip), remove the r'th row 184 | * and column by moving elements. the new matrix will have the same leading 185 | * dimension. the last row and column of A are untouched on exit. 186 | */ 187 | ODE_API void dRemoveRowCol (dReal *A, int n, int nskip, int r); 188 | 189 | 190 | #if defined(__ODE__) 191 | 192 | void _dSetZero (dReal *a, size_t n); 193 | void _dSetValue (dReal *a, size_t n, dReal value); 194 | dReal _dDot (const dReal *a, const dReal *b, int n); 195 | void _dMultiply0 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); 196 | void _dMultiply1 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); 197 | void _dMultiply2 (dReal *A, const dReal *B, const dReal *C, int p,int q,int r); 198 | int _dFactorCholesky (dReal *A, int n, void *tmpbuf); 199 | void _dSolveCholesky (const dReal *L, dReal *b, int n, void *tmpbuf); 200 | int _dInvertPDMatrix (const dReal *A, dReal *Ainv, int n, void *tmpbuf); 201 | int _dIsPositiveDefinite (const dReal *A, int n, void *tmpbuf); 202 | void _dFactorLDLT (dReal *A, dReal *d, int n, int nskip); 203 | void _dSolveL1 (const dReal *L, dReal *b, int n, int nskip); 204 | void _dSolveL1T (const dReal *L, dReal *b, int n, int nskip); 205 | void _dVectorScale (dReal *a, const dReal *d, int n); 206 | void _dSolveLDLT (const dReal *L, const dReal *d, dReal *b, int n, int nskip); 207 | void _dLDLTAddTL (dReal *L, dReal *d, const dReal *a, int n, int nskip, void *tmpbuf); 208 | void _dLDLTRemove (dReal **A, const int *p, dReal *L, dReal *d, int n1, int n2, int r, int nskip, void *tmpbuf); 209 | void _dRemoveRowCol (dReal *A, int n, int nskip, int r); 210 | 211 | PURE_INLINE size_t _dEstimateFactorCholeskyTmpbufSize(int n) 212 | { 213 | return dPAD(n) * sizeof(dReal); 214 | } 215 | 216 | PURE_INLINE size_t _dEstimateSolveCholeskyTmpbufSize(int n) 217 | { 218 | return dPAD(n) * sizeof(dReal); 219 | } 220 | 221 | PURE_INLINE size_t _dEstimateInvertPDMatrixTmpbufSize(int n) 222 | { 223 | size_t FactorCholesky_size = _dEstimateFactorCholeskyTmpbufSize(n); 224 | size_t SolveCholesky_size = _dEstimateSolveCholeskyTmpbufSize(n); 225 | size_t MaxCholesky_size = FactorCholesky_size > SolveCholesky_size ? FactorCholesky_size : SolveCholesky_size; 226 | return dPAD(n) * (n + 1) * sizeof(dReal) + MaxCholesky_size; 227 | } 228 | 229 | PURE_INLINE size_t _dEstimateIsPositiveDefiniteTmpbufSize(int n) 230 | { 231 | return dPAD(n) * n * sizeof(dReal) + _dEstimateFactorCholeskyTmpbufSize(n); 232 | } 233 | 234 | PURE_INLINE size_t _dEstimateLDLTAddTLTmpbufSize(int nskip) 235 | { 236 | return nskip * 2 * sizeof(dReal); 237 | } 238 | 239 | PURE_INLINE size_t _dEstimateLDLTRemoveTmpbufSize(int n2, int nskip) 240 | { 241 | return n2 * sizeof(dReal) + _dEstimateLDLTAddTLTmpbufSize(nskip); 242 | } 243 | 244 | // For internal use 245 | #define dSetZero(a, n) _dSetZero(a, n) 246 | #define dSetValue(a, n, value) _dSetValue(a, n, value) 247 | #define dDot(a, b, n) _dDot(a, b, n) 248 | #define dMultiply0(A, B, C, p, q, r) _dMultiply0(A, B, C, p, q, r) 249 | #define dMultiply1(A, B, C, p, q, r) _dMultiply1(A, B, C, p, q, r) 250 | #define dMultiply2(A, B, C, p, q, r) _dMultiply2(A, B, C, p, q, r) 251 | #define dFactorCholesky(A, n, tmpbuf) _dFactorCholesky(A, n, tmpbuf) 252 | #define dSolveCholesky(L, b, n, tmpbuf) _dSolveCholesky(L, b, n, tmpbuf) 253 | #define dInvertPDMatrix(A, Ainv, n, tmpbuf) _dInvertPDMatrix(A, Ainv, n, tmpbuf) 254 | #define dIsPositiveDefinite(A, n, tmpbuf) _dIsPositiveDefinite(A, n, tmpbuf) 255 | #define dFactorLDLT(A, d, n, nskip) _dFactorLDLT(A, d, n, nskip) 256 | #define dSolveL1(L, b, n, nskip) _dSolveL1(L, b, n, nskip) 257 | #define dSolveL1T(L, b, n, nskip) _dSolveL1T(L, b, n, nskip) 258 | #define dVectorScale(a, d, n) _dVectorScale(a, d, n) 259 | #define dSolveLDLT(L, d, b, n, nskip) _dSolveLDLT(L, d, b, n, nskip) 260 | #define dLDLTAddTL(L, d, a, n, nskip, tmpbuf) _dLDLTAddTL(L, d, a, n, nskip, tmpbuf) 261 | #define dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf) _dLDLTRemove(A, p, L, d, n1, n2, r, nskip, tmpbuf) 262 | #define dRemoveRowCol(A, n, nskip, r) _dRemoveRowCol(A, n, nskip, r) 263 | 264 | 265 | #define dEstimateFactorCholeskyTmpbufSize(n) _dEstimateFactorCholeskyTmpbufSize(n) 266 | #define dEstimateSolveCholeskyTmpbufSize(n) _dEstimateSolveCholeskyTmpbufSize(n) 267 | #define dEstimateInvertPDMatrixTmpbufSize(n) _dEstimateInvertPDMatrixTmpbufSize(n) 268 | #define dEstimateIsPositiveDefiniteTmpbufSize(n) _dEstimateIsPositiveDefiniteTmpbufSize(n) 269 | #define dEstimateLDLTAddTLTmpbufSize(nskip) _dEstimateLDLTAddTLTmpbufSize(nskip) 270 | #define dEstimateLDLTRemoveTmpbufSize(n2, nskip) _dEstimateLDLTRemoveTmpbufSize(n2, nskip) 271 | 272 | 273 | #endif // defined(__ODE__) 274 | 275 | 276 | #ifdef __cplusplus 277 | } 278 | #endif 279 | 280 | #endif 281 | -------------------------------------------------------------------------------- /c/memory.h: -------------------------------------------------------------------------------- 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 | /* this comes from the `reuse' library. copy any changes back to the source */ 24 | 25 | #ifndef _ODE_MEMORY_H_ 26 | #define _ODE_MEMORY_H_ 27 | 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | /* function types to allocate and free memory */ 35 | typedef void * dAllocFunction (size_t size); 36 | typedef void * dReallocFunction (void *ptr, size_t oldsize, size_t newsize); 37 | typedef void dFreeFunction (void *ptr, size_t size); 38 | 39 | /* set new memory management functions. if fn is 0, the default handlers are 40 | * used. */ 41 | ODE_API void dSetAllocHandler (dAllocFunction *fn); 42 | ODE_API void dSetReallocHandler (dReallocFunction *fn); 43 | ODE_API void dSetFreeHandler (dFreeFunction *fn); 44 | 45 | /* get current memory management functions */ 46 | ODE_API dAllocFunction *dGetAllocHandler (void); 47 | ODE_API dReallocFunction *dGetReallocHandler (void); 48 | ODE_API dFreeFunction *dGetFreeHandler (void); 49 | 50 | /* allocate and free memory. */ 51 | ODE_API void * dAlloc (size_t size); 52 | ODE_API void * dRealloc (void *ptr, size_t oldsize, size_t newsize); 53 | ODE_API void dFree (void *ptr, size_t size); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /c/misc.h: -------------------------------------------------------------------------------- 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 | /* miscellaneous math functions. these are mostly useful for testing */ 24 | 25 | #ifndef _ODE_MISC_H_ 26 | #define _ODE_MISC_H_ 27 | 28 | #include 29 | 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | 36 | /* return 1 if the random number generator is working. */ 37 | ODE_API int dTestRand(void); 38 | 39 | /* return next 32 bit random number. this uses a not-very-random linear 40 | * congruential method. 41 | */ 42 | ODE_API unsigned long dRand(void); 43 | 44 | /* get and set the current random number seed. */ 45 | ODE_API unsigned long dRandGetSeed(void); 46 | ODE_API void dRandSetSeed (unsigned long s); 47 | 48 | /* return a random integer between 0..n-1. the distribution will get worse 49 | * as n approaches 2^32. 50 | */ 51 | ODE_API int dRandInt (int n); 52 | 53 | /* return a random real number between 0..1 */ 54 | ODE_API dReal dRandReal(void); 55 | 56 | /* print out a matrix */ 57 | #ifdef __cplusplus 58 | ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt = "%10.4f ", 59 | FILE *f=stdout); 60 | #else 61 | ODE_API void dPrintMatrix (const dReal *A, int n, int m, char *fmt, FILE *f); 62 | #endif 63 | 64 | /* make a random vector with entries between +/- range. A has n elements. */ 65 | ODE_API void dMakeRandomVector (dReal *A, int n, dReal range); 66 | 67 | /* make a random matrix with entries between +/- range. A has size n*m. */ 68 | ODE_API void dMakeRandomMatrix (dReal *A, int n, int m, dReal range); 69 | 70 | /* clear the upper triangle of a square matrix */ 71 | ODE_API void dClearUpperTriangle (dReal *A, int n); 72 | 73 | /* return the maximum element difference between the two n*m matrices */ 74 | ODE_API dReal dMaxDifference (const dReal *A, const dReal *B, int n, int m); 75 | 76 | /* return the maximum element difference between the lower triangle of two 77 | * n*n matrices */ 78 | ODE_API dReal dMaxDifferenceLowerTriangle (const dReal *A, const dReal *B, int n); 79 | 80 | 81 | #ifdef __cplusplus 82 | } 83 | #endif 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /c/ode.h: -------------------------------------------------------------------------------- 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_ODE_H_ 24 | #define _ODE_ODE_H_ 25 | 26 | /* include *everything* here */ 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /c/odeconfig.h: -------------------------------------------------------------------------------- 1 | #ifndef ODECONFIG_H 2 | #define ODECONFIG_H 3 | 4 | /* Pull in the standard headers */ 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | #if defined(ODE_DLL) || defined(ODE_LIB) 16 | #define __ODE__ 17 | #endif 18 | 19 | /* Define a DLL export symbol for those platforms that need it */ 20 | #if defined(_MSC_VER) 21 | #if defined(ODE_DLL) 22 | #define ODE_API __declspec(dllexport) 23 | #elif !defined(ODE_LIB) 24 | #define ODE_DLL_API __declspec(dllimport) 25 | #endif 26 | #endif 27 | 28 | #if !defined(ODE_API) 29 | #define ODE_API 30 | #endif 31 | 32 | #if defined(_MSC_VER) 33 | # define ODE_API_DEPRECATED __declspec(deprecated) 34 | #elif defined (__GNUC__) && ( (__GNUC__ > 3) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)) ) 35 | # define ODE_API_DEPRECATED __attribute__((__deprecated__)) 36 | #else 37 | # define ODE_API_DEPRECATED 38 | #endif 39 | 40 | /* Well-defined common data types...need to define for 64 bit systems */ 41 | #if defined(_M_IA64) || defined(__ia64__) || defined(_M_AMD64) || defined(__x86_64__) 42 | #define X86_64_SYSTEM 1 43 | typedef int int32; 44 | typedef unsigned int uint32; 45 | typedef short int16; 46 | typedef unsigned short uint16; 47 | typedef signed char int8; 48 | typedef unsigned char uint8; 49 | #else 50 | typedef int int32; 51 | typedef unsigned int uint32; 52 | typedef short int16; 53 | typedef unsigned short uint16; 54 | typedef signed char int8; 55 | typedef unsigned char uint8; 56 | #endif 57 | 58 | /* Visual C does not define these functions */ 59 | #if defined(_MSC_VER) 60 | #define copysignf(x, y) ((float)_copysign(x, y)) 61 | #define copysign(x, y) _copysign(x, y) 62 | #define nextafterf(x, y) _nextafterf(x, y) 63 | #define nextafter(x, y) _nextafter(x, y) 64 | #if !defined(_WIN64) 65 | #define _ODE__NEXTAFTERF_REQUIRED 66 | #endif 67 | #endif 68 | 69 | 70 | 71 | /* Define the dInfinity macro */ 72 | #ifdef INFINITY 73 | #define dInfinity INFINITY 74 | #elif defined(HUGE_VAL) 75 | #ifdef dSINGLE 76 | #ifdef HUGE_VALF 77 | #define dInfinity HUGE_VALF 78 | #else 79 | #define dInfinity ((float)HUGE_VAL) 80 | #endif 81 | #else 82 | #define dInfinity HUGE_VAL 83 | #endif 84 | #else 85 | #ifdef dSINGLE 86 | #define dInfinity ((float)(1.0/0.0)) 87 | #else 88 | #define dInfinity (1.0/0.0) 89 | #endif 90 | #endif 91 | 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /c/odecpp_collision.h: -------------------------------------------------------------------------------- 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 | /* C++ interface for new collision API */ 24 | 25 | 26 | #ifndef _ODE_ODECPP_COLLISION_H_ 27 | #define _ODE_ODECPP_COLLISION_H_ 28 | #ifdef __cplusplus 29 | 30 | //#include 31 | 32 | //namespace ode { 33 | 34 | class dGeom { 35 | // intentionally undefined, don't use these 36 | dGeom (dGeom &); 37 | void operator= (dGeom &); 38 | 39 | protected: 40 | dGeomID _id; 41 | 42 | dGeom() 43 | { _id = 0; } 44 | public: 45 | ~dGeom() 46 | { if (_id) dGeomDestroy (_id); } 47 | 48 | dGeomID id() const 49 | { return _id; } 50 | operator dGeomID() const 51 | { return _id; } 52 | 53 | void destroy() { 54 | if (_id) dGeomDestroy (_id); 55 | _id = 0; 56 | } 57 | 58 | int getClass() const 59 | { return dGeomGetClass (_id); } 60 | 61 | dSpaceID getSpace() const 62 | { return dGeomGetSpace (_id); } 63 | 64 | void setData (void *data) 65 | { dGeomSetData (_id,data); } 66 | void *getData() const 67 | { return dGeomGetData (_id); } 68 | 69 | void setBody (dBodyID b) 70 | { dGeomSetBody (_id,b); } 71 | dBodyID getBody() const 72 | { return dGeomGetBody (_id); } 73 | 74 | void setPosition (dReal x, dReal y, dReal z) 75 | { dGeomSetPosition (_id,x,y,z); } 76 | const dReal * getPosition() const 77 | { return dGeomGetPosition (_id); } 78 | 79 | void setRotation (const dMatrix3 R) 80 | { dGeomSetRotation (_id,R); } 81 | const dReal * getRotation() const 82 | { return dGeomGetRotation (_id); } 83 | 84 | void setQuaternion (const dQuaternion quat) 85 | { dGeomSetQuaternion (_id,quat); } 86 | void getQuaternion (dQuaternion quat) const 87 | { dGeomGetQuaternion (_id,quat); } 88 | 89 | void getAABB (dReal aabb[6]) const 90 | { dGeomGetAABB (_id, aabb); } 91 | 92 | int isSpace() 93 | { return dGeomIsSpace (_id); } 94 | 95 | void setCategoryBits (unsigned long bits) 96 | { dGeomSetCategoryBits (_id, bits); } 97 | void setCollideBits (unsigned long bits) 98 | { dGeomSetCollideBits (_id, bits); } 99 | unsigned long getCategoryBits() 100 | { return dGeomGetCategoryBits (_id); } 101 | unsigned long getCollideBits() 102 | { return dGeomGetCollideBits (_id); } 103 | 104 | void enable() 105 | { dGeomEnable (_id); } 106 | void disable() 107 | { dGeomDisable (_id); } 108 | int isEnabled() 109 | { return dGeomIsEnabled (_id); } 110 | 111 | void getRelPointPos (dReal px, dReal py, dReal pz, dVector3 result) const 112 | { dGeomGetRelPointPos (_id, px, py, pz, result); } 113 | void getRelPointPos (const dVector3 p, dVector3 result) const 114 | { getRelPointPos (p[0], p[1], p[2], result); } 115 | 116 | void getPosRelPoint (dReal px, dReal py, dReal pz, dVector3 result) const 117 | { dGeomGetPosRelPoint (_id, px, py, pz, result); } 118 | void getPosRelPoint (const dVector3 p, dVector3 result) const 119 | { getPosRelPoint (p[0], p[1], p[2], result); } 120 | 121 | void vectorToWorld (dReal px, dReal py, dReal pz, dVector3 result) const 122 | { dGeomVectorToWorld (_id, px, py, pz, result); } 123 | void vectorToWorld (const dVector3 p, dVector3 result) const 124 | { vectorToWorld (p[0], p[1], p[2], result); } 125 | 126 | void vectorFromWorld (dReal px, dReal py, dReal pz, dVector3 result) const 127 | { dGeomVectorFromWorld (_id, px, py, pz, result); } 128 | void vectorFromWorld (const dVector3 p, dVector3 result) const 129 | { vectorFromWorld (p[0], p[1], p[2], result); } 130 | 131 | void collide2 (dGeomID g, void *data, dNearCallback *callback) 132 | { dSpaceCollide2 (_id,g,data,callback); } 133 | }; 134 | 135 | 136 | class dSpace : public dGeom { 137 | // intentionally undefined, don't use these 138 | dSpace (dSpace &); 139 | void operator= (dSpace &); 140 | 141 | protected: 142 | // the default constructor is protected so that you 143 | // can't instance this class. you must instance one 144 | // of its subclasses instead. 145 | dSpace () { _id = 0; } 146 | 147 | public: 148 | dSpaceID id() const 149 | { return (dSpaceID) _id; } 150 | operator dSpaceID() const 151 | { return (dSpaceID) _id; } 152 | 153 | void setCleanup (int mode) 154 | { dSpaceSetCleanup (id(), mode); } 155 | int getCleanup() 156 | { return dSpaceGetCleanup (id()); } 157 | 158 | void add (dGeomID x) 159 | { dSpaceAdd (id(), x); } 160 | void remove (dGeomID x) 161 | { dSpaceRemove (id(), x); } 162 | int query (dGeomID x) 163 | { return dSpaceQuery (id(),x); } 164 | 165 | int getNumGeoms() 166 | { return dSpaceGetNumGeoms (id()); } 167 | dGeomID getGeom (int i) 168 | { return dSpaceGetGeom (id(),i); } 169 | 170 | void collide (void *data, dNearCallback *callback) 171 | { dSpaceCollide (id(),data,callback); } 172 | }; 173 | 174 | 175 | class dSimpleSpace : public dSpace { 176 | // intentionally undefined, don't use these 177 | dSimpleSpace (dSimpleSpace &); 178 | void operator= (dSimpleSpace &); 179 | 180 | public: 181 | dSimpleSpace () 182 | { _id = (dGeomID) dSimpleSpaceCreate (0); } 183 | dSimpleSpace (dSpace &space) 184 | { _id = (dGeomID) dSimpleSpaceCreate (space.id()); } 185 | dSimpleSpace (dSpaceID space) 186 | { _id = (dGeomID) dSimpleSpaceCreate (space); } 187 | }; 188 | 189 | 190 | class dHashSpace : public dSpace { 191 | // intentionally undefined, don't use these 192 | dHashSpace (dHashSpace &); 193 | void operator= (dHashSpace &); 194 | 195 | public: 196 | dHashSpace () 197 | { _id = (dGeomID) dHashSpaceCreate (0); } 198 | dHashSpace (dSpace &space) 199 | { _id = (dGeomID) dHashSpaceCreate (space.id()); } 200 | dHashSpace (dSpaceID space) 201 | { _id = (dGeomID) dHashSpaceCreate (space); } 202 | 203 | void setLevels (int minlevel, int maxlevel) 204 | { dHashSpaceSetLevels (id(),minlevel,maxlevel); } 205 | }; 206 | 207 | 208 | class dQuadTreeSpace : public dSpace { 209 | // intentionally undefined, don't use these 210 | dQuadTreeSpace (dQuadTreeSpace &); 211 | void operator= (dQuadTreeSpace &); 212 | 213 | public: 214 | dQuadTreeSpace (const dVector3 center, const dVector3 extents, int depth) 215 | { _id = (dGeomID) dQuadTreeSpaceCreate (0,center,extents,depth); } 216 | dQuadTreeSpace (dSpace &space, const dVector3 center, const dVector3 extents, int depth) 217 | { _id = (dGeomID) dQuadTreeSpaceCreate (space.id(),center,extents,depth); } 218 | dQuadTreeSpace (dSpaceID space, const dVector3 center, const dVector3 extents, int depth) 219 | { _id = (dGeomID) dQuadTreeSpaceCreate (space,center,extents,depth); } 220 | }; 221 | 222 | 223 | class dSphere : public dGeom { 224 | // intentionally undefined, don't use these 225 | dSphere (dSphere &); 226 | void operator= (dSphere &); 227 | 228 | public: 229 | dSphere () { } 230 | dSphere (dReal radius) 231 | { _id = dCreateSphere (0, radius); } 232 | dSphere (dSpace &space, dReal radius) 233 | { _id = dCreateSphere (space.id(), radius); } 234 | dSphere (dSpaceID space, dReal radius) 235 | { _id = dCreateSphere (space, radius); } 236 | 237 | void create (dSpaceID space, dReal radius) { 238 | if (_id) dGeomDestroy (_id); 239 | _id = dCreateSphere (space, radius); 240 | } 241 | 242 | void setRadius (dReal radius) 243 | { dGeomSphereSetRadius (_id, radius); } 244 | dReal getRadius() const 245 | { return dGeomSphereGetRadius (_id); } 246 | }; 247 | 248 | 249 | class dBox : public dGeom { 250 | // intentionally undefined, don't use these 251 | dBox (dBox &); 252 | void operator= (dBox &); 253 | 254 | public: 255 | dBox () { } 256 | dBox (dReal lx, dReal ly, dReal lz) 257 | { _id = dCreateBox (0,lx,ly,lz); } 258 | dBox (dSpace &space, dReal lx, dReal ly, dReal lz) 259 | { _id = dCreateBox (space,lx,ly,lz); } 260 | dBox (dSpaceID space, dReal lx, dReal ly, dReal lz) 261 | { _id = dCreateBox (space,lx,ly,lz); } 262 | 263 | void create (dSpaceID space, dReal lx, dReal ly, dReal lz) { 264 | if (_id) dGeomDestroy (_id); 265 | _id = dCreateBox (space,lx,ly,lz); 266 | } 267 | 268 | void setLengths (dReal lx, dReal ly, dReal lz) 269 | { dGeomBoxSetLengths (_id, lx, ly, lz); } 270 | void getLengths (dVector3 result) const 271 | { dGeomBoxGetLengths (_id,result); } 272 | }; 273 | 274 | 275 | class dPlane : public dGeom { 276 | // intentionally undefined, don't use these 277 | dPlane (dPlane &); 278 | void operator= (dPlane &); 279 | 280 | public: 281 | dPlane() { } 282 | dPlane (dReal a, dReal b, dReal c, dReal d) 283 | { _id = dCreatePlane (0,a,b,c,d); } 284 | dPlane (dSpace &space, dReal a, dReal b, dReal c, dReal d) 285 | { _id = dCreatePlane (space.id(),a,b,c,d); } 286 | dPlane (dSpaceID space, dReal a, dReal b, dReal c, dReal d) 287 | { _id = dCreatePlane (space,a,b,c,d); } 288 | 289 | void create (dSpaceID space, dReal a, dReal b, dReal c, dReal d) { 290 | if (_id) dGeomDestroy (_id); 291 | _id = dCreatePlane (space,a,b,c,d); 292 | } 293 | 294 | void setParams (dReal a, dReal b, dReal c, dReal d) 295 | { dGeomPlaneSetParams (_id, a, b, c, d); } 296 | void getParams (dVector4 result) const 297 | { dGeomPlaneGetParams (_id,result); } 298 | }; 299 | 300 | 301 | class dCapsule : public dGeom { 302 | // intentionally undefined, don't use these 303 | dCapsule (dCapsule &); 304 | void operator= (dCapsule &); 305 | 306 | public: 307 | dCapsule() { } 308 | dCapsule (dReal radius, dReal length) 309 | { _id = dCreateCapsule (0,radius,length); } 310 | dCapsule (dSpace &space, dReal radius, dReal length) 311 | { _id = dCreateCapsule (space.id(),radius,length); } 312 | dCapsule (dSpaceID space, dReal radius, dReal length) 313 | { _id = dCreateCapsule (space,radius,length); } 314 | 315 | void create (dSpaceID space, dReal radius, dReal length) { 316 | if (_id) dGeomDestroy (_id); 317 | _id = dCreateCapsule (space,radius,length); 318 | } 319 | 320 | void setParams (dReal radius, dReal length) 321 | { dGeomCapsuleSetParams (_id, radius, length); } 322 | void getParams (dReal *radius, dReal *length) const 323 | { dGeomCapsuleGetParams (_id,radius,length); } 324 | }; 325 | 326 | 327 | class dCylinder : public dGeom { 328 | // intentionally undefined, don't use these 329 | dCylinder (dCylinder &); 330 | void operator= (dCylinder &); 331 | 332 | public: 333 | dCylinder() { } 334 | dCylinder (dReal radius, dReal length) 335 | { _id = dCreateCylinder (0,radius,length); } 336 | dCylinder (dSpace &space, dReal radius, dReal length) 337 | { _id = dCreateCylinder (space.id(),radius,length); } 338 | dCylinder (dSpaceID space, dReal radius, dReal length) 339 | { _id = dCreateCylinder (space,radius,length); } 340 | 341 | void create (dSpaceID space, dReal radius, dReal length) { 342 | if (_id) dGeomDestroy (_id); 343 | _id = dCreateCylinder (space,radius,length); 344 | } 345 | 346 | void setParams (dReal radius, dReal length) 347 | { dGeomCylinderSetParams (_id, radius, length); } 348 | void getParams (dReal *radius, dReal *length) const 349 | { dGeomCylinderGetParams (_id,radius,length); } 350 | }; 351 | 352 | 353 | class dRay : public dGeom { 354 | // intentionally undefined, don't use these 355 | dRay (dRay &); 356 | void operator= (dRay &); 357 | 358 | public: 359 | dRay() { } 360 | dRay (dReal length) 361 | { _id = dCreateRay (0,length); } 362 | dRay (dSpace &space, dReal length) 363 | { _id = dCreateRay (space.id(),length); } 364 | dRay (dSpaceID space, dReal length) 365 | { _id = dCreateRay (space,length); } 366 | 367 | void create (dSpaceID space, dReal length) { 368 | if (_id) dGeomDestroy (_id); 369 | _id = dCreateRay (space,length); 370 | } 371 | 372 | void setLength (dReal length) 373 | { dGeomRaySetLength (_id, length); } 374 | dReal getLength() 375 | { return dGeomRayGetLength (_id); } 376 | 377 | void set (dReal px, dReal py, dReal pz, dReal dx, dReal dy, dReal dz) 378 | { dGeomRaySet (_id, px, py, pz, dx, dy, dz); } 379 | void get (dVector3 start, dVector3 dir) 380 | { dGeomRayGet (_id, start, dir); } 381 | 382 | void setParams (int firstContact, int backfaceCull) 383 | { dGeomRaySetParams (_id, firstContact, backfaceCull); } 384 | void getParams (int *firstContact, int *backfaceCull) 385 | { dGeomRayGetParams (_id, firstContact, backfaceCull); } 386 | void setClosestHit (int closestHit) 387 | { dGeomRaySetClosestHit (_id, closestHit); } 388 | int getClosestHit() 389 | { return dGeomRayGetClosestHit (_id); } 390 | }; 391 | 392 | 393 | class dGeomTransform : public dGeom { 394 | // intentionally undefined, don't use these 395 | dGeomTransform (dGeomTransform &); 396 | void operator= (dGeomTransform &); 397 | 398 | public: 399 | dGeomTransform() { } 400 | dGeomTransform (dSpace &space) 401 | { _id = dCreateGeomTransform (space.id()); } 402 | dGeomTransform (dSpaceID space) 403 | { _id = dCreateGeomTransform (space); } 404 | 405 | void create (dSpaceID space=0) { 406 | if (_id) dGeomDestroy (_id); 407 | _id = dCreateGeomTransform (space); 408 | } 409 | 410 | void setGeom (dGeomID geom) 411 | { dGeomTransformSetGeom (_id, geom); } 412 | dGeomID getGeom() const 413 | { return dGeomTransformGetGeom (_id); } 414 | 415 | void setCleanup (int mode) 416 | { dGeomTransformSetCleanup (_id,mode); } 417 | int getCleanup () 418 | { return dGeomTransformGetCleanup (_id); } 419 | 420 | void setInfo (int mode) 421 | { dGeomTransformSetInfo (_id,mode); } 422 | int getInfo() 423 | { return dGeomTransformGetInfo (_id); } 424 | }; 425 | 426 | //} 427 | 428 | #endif 429 | #endif 430 | -------------------------------------------------------------------------------- /c/odeinit.h: -------------------------------------------------------------------------------- 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 | /* Library initialization/finalization functions. */ 24 | 25 | #ifndef _ODE_ODEINIT_H_ 26 | #define _ODE_ODEINIT_H_ 27 | 28 | #include 29 | 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | 36 | /* ************************************************************************ */ 37 | /* Library initialization */ 38 | 39 | /** 40 | * @defgroup init Library Initialization 41 | * 42 | * Library initialization functions prepare ODE internal data structures for use 43 | * and release allocated resources after ODE is not needed any more. 44 | */ 45 | 46 | 47 | /** 48 | * @brief Library initialization flags. 49 | * 50 | * These flags define ODE library initialization options. 51 | * 52 | * @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads 53 | * using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread. 54 | * If this flag is not specified the automatic resource tracking algorithm is used. 55 | * 56 | * With automatic resource tracking, On Windows, memory allocated for a thread may 57 | * remain not freed for some time after the thread exits. The resources may be 58 | * released when one of other threads calls @c dAllocateODEDataForThread. Ultimately, 59 | * the resources are released when library is closed with @c dCloseODE. On other 60 | * operating systems resources are always released by the thread itself on its exit 61 | * or on library closure with @c dCloseODE. 62 | * 63 | * With manual thread data cleanup mode every collision space object must be 64 | * explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup 65 | * after creation. See description of the function for more details. 66 | * 67 | * If @c dInitFlagManualThreadCleanup was not specified during initialization, 68 | * calls to @c dCleanupODEAllDataForThread are not allowed. 69 | * 70 | * @see dInitODE2 71 | * @see dAllocateODEDataForThread 72 | * @see dSpaceSetManualCleanup 73 | * @see dCloseODE 74 | * @ingroup init 75 | */ 76 | enum dInitODEFlags { 77 | dInitFlagManualThreadCleanup = 0x00000001 //@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call 78 | }; 79 | 80 | /** 81 | * @brief Initializes ODE library. 82 | * 83 | * @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization. 84 | * 85 | * A call to @c dInitODE is equal to the following initialization sequence 86 | * @code 87 | * dInitODE2(0); 88 | * dAllocateODEDataForThread(dAllocateMaskAll); 89 | * @endcode 90 | * 91 | * @see dInitODE2 92 | * @see dAllocateODEDataForThread 93 | * @ingroup init 94 | */ 95 | ODE_API void dInitODE(void); 96 | 97 | /** 98 | * @brief Initializes ODE library. 99 | * @param uiInitFlags Initialization options bitmask 100 | * @return A nonzero if initialization succeeded and zero otherwise. 101 | * 102 | * This function must be called to initialize ODE library before first use. If 103 | * initialization succeeds the function may not be called again until library is 104 | * closed with a call to @c dCloseODE. 105 | * 106 | * The @a uiInitFlags parameter specifies initialization options to be used. These 107 | * can be combination of zero or more @c dInitODEFlags flags. 108 | * 109 | * @note 110 | * If @c dInitFlagManualThreadCleanup flag is used for initialization, 111 | * @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every 112 | * space object right after creation. Failure to do so may lead to resource leaks. 113 | * 114 | * @see dInitODEFlags 115 | * @see dCloseODE 116 | * @see dSpaceSetManualCleanup 117 | * @ingroup init 118 | */ 119 | ODE_API int dInitODE2(unsigned int uiInitFlags/*=0*/); 120 | 121 | 122 | /** 123 | * @brief ODE data allocation flags. 124 | * 125 | * These flags are used to indicate which data is to be pre-allocated in call to 126 | * @c dAllocateODEDataForThread. 127 | * 128 | * @c dAllocateFlagBasicData tells to allocate the basic data set required for 129 | * normal library operation. This flag is equal to zero and is always implicitly 130 | * included. 131 | * 132 | * @c dAllocateFlagCollisionData tells that collision detection data is to be allocated. 133 | * Collision detection functions may not be called if the data has not be allocated 134 | * in advance. If collision detection is not going to be used, it is not necessary 135 | * to specify this flag. 136 | * 137 | * @c dAllocateMaskAll is a mask that can be used for for allocating all possible 138 | * data in cases when it is not known what exactly features of ODE will be used. 139 | * The mask may not be used in combination with other flags. It is guaranteed to 140 | * include all the current and future legal allocation flags. However, mature 141 | * applications should use explicit flags they need rather than allocating everything. 142 | * 143 | * @see dAllocateODEDataForThread 144 | * @ingroup init 145 | */ 146 | enum dAllocateODEDataFlags { 147 | dAllocateFlagBasicData = 0, //@< Allocate basic data required for library to operate 148 | 149 | dAllocateFlagCollisionData = 0x00000001, //@< Allocate data for collision detection 150 | 151 | dAllocateMaskAll = ~0U //@< Allocate all the possible data that is currently defined or will be defined in the future. 152 | }; 153 | 154 | /** 155 | * @brief Allocate thread local data to allow the thread calling ODE. 156 | * @param uiAllocateFlags Allocation options bitmask. 157 | * @return A nonzero if allocation succeeded and zero otherwise. 158 | * 159 | * The function is required to be called for every thread that is going to use 160 | * ODE. This function allocates the data that is required for accessing ODE from 161 | * current thread along with optional data required for particular ODE subsystems. 162 | * 163 | * @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags 164 | * enumerated type. Multiple calls with different allocation flags are allowed. 165 | * The flags that are already allocated are ignored in subsequent calls. If zero 166 | * is passed as the parameter, it means to only allocate the set of most important 167 | * data the library can not operate without. 168 | * 169 | * If the function returns failure status it means that none of the requested 170 | * data has been allocated. The client may retry allocation attempt with the same 171 | * flags when more system resources are available. 172 | * 173 | * @see dAllocateODEDataFlags 174 | * @see dCleanupODEAllDataForThread 175 | * @ingroup init 176 | */ 177 | ODE_API int dAllocateODEDataForThread(unsigned int uiAllocateFlags); 178 | 179 | /** 180 | * @brief Free thread local data that was allocated for current thread. 181 | * 182 | * If library was initialized with @c dInitFlagManualThreadCleanup flag the function 183 | * is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread. 184 | * Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining 185 | * not freed until program exit. The function may also be called when ODE is still 186 | * being used to release resources allocated for all the current subsystems and 187 | * possibly proceed with data pre-allocation for other subsystems. 188 | * 189 | * The function can safely be called several times in a row. The function can be 190 | * called without prior invocation of @c dAllocateODEDataForThread. The function 191 | * may not be called before ODE is initialized with @c dInitODE2 or after library 192 | * has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases 193 | * all the thread local resources that might be allocated for all the threads that 194 | * were using ODE. 195 | * 196 | * If library was initialized without @c dInitFlagManualThreadCleanup flag 197 | * @c dCleanupODEAllDataForThread must not be called. 198 | * 199 | * @see dAllocateODEDataForThread 200 | * @see dInitODE2 201 | * @see dCloseODE 202 | * @ingroup init 203 | */ 204 | ODE_API void dCleanupODEAllDataForThread(); 205 | 206 | 207 | /** 208 | * @brief Close ODE after it is not needed any more. 209 | * 210 | * The function is required to be called when program does not need ODE features any more. 211 | * The call to @c dCloseODE releases all the resources allocated for library 212 | * including all the thread local data that might be allocated for all the threads 213 | * that were using ODE. 214 | * 215 | * @c dCloseODE is a paired function for @c dInitODE2 and must only be called 216 | * after successful library initialization. 217 | * 218 | * @note Important! 219 | * Make sure that all the threads that were using ODE have already terminated 220 | * before calling @c dCloseODE. In particular it is not allowed to call 221 | * @c dCleanupODEAllDataForThread after @c dCloseODE. 222 | * 223 | * @see dInitODE2 224 | * @see dCleanupODEAllDataForThread 225 | * @ingroup init 226 | */ 227 | ODE_API void dCloseODE(void); 228 | 229 | 230 | 231 | #ifdef __cplusplus 232 | } // extern "C" 233 | #endif 234 | 235 | 236 | #endif // _ODE_ODEINIT_H_ 237 | -------------------------------------------------------------------------------- /c/odemath.h: -------------------------------------------------------------------------------- 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_ODEMATH_H_ 24 | #define _ODE_ODEMATH_H_ 25 | 26 | #include 27 | 28 | /* 29 | * macro to access elements i,j in an NxM matrix A, independent of the 30 | * matrix storage convention. 31 | */ 32 | #define dACCESS33(A,i,j) ((A)[(i)*4+(j)]) 33 | 34 | /* 35 | * Macro to test for valid floating point values 36 | */ 37 | #define dVALIDVEC3(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]))) 38 | #define dVALIDVEC4(v) (!(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3]))) 39 | #define dVALIDMAT3(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]))) 40 | #define dVALIDMAT4(m) (!(dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) )) 41 | 42 | 43 | 44 | // Some vector math 45 | PURE_INLINE void dAddVectors3(dReal *res, const dReal *a, const dReal *b) 46 | { 47 | dReal res_0, res_1, res_2; 48 | res_0 = a[0] + b[0]; 49 | res_1 = a[1] + b[1]; 50 | res_2 = a[2] + b[2]; 51 | // Only assign after all the calculations are over to avoid incurring memory aliasing 52 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 53 | } 54 | 55 | PURE_INLINE void dSubtractVectors3(dReal *res, const dReal *a, const dReal *b) 56 | { 57 | dReal res_0, res_1, res_2; 58 | res_0 = a[0] - b[0]; 59 | res_1 = a[1] - b[1]; 60 | res_2 = a[2] - b[2]; 61 | // Only assign after all the calculations are over to avoid incurring memory aliasing 62 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 63 | } 64 | 65 | PURE_INLINE void dAddScaledVectors3(dReal *res, const dReal *a, const dReal *b, dReal a_scale, dReal b_scale) 66 | { 67 | dReal res_0, res_1, res_2; 68 | res_0 = a_scale * a[0] + b_scale * b[0]; 69 | res_1 = a_scale * a[1] + b_scale * b[1]; 70 | res_2 = a_scale * a[2] + b_scale * b[2]; 71 | // Only assign after all the calculations are over to avoid incurring memory aliasing 72 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 73 | } 74 | 75 | PURE_INLINE void dScaleVector3(dReal *res, dReal nScale) 76 | { 77 | res[0] *= nScale ; 78 | res[1] *= nScale ; 79 | res[2] *= nScale ; 80 | } 81 | 82 | PURE_INLINE void dNegateVector3(dReal *res) 83 | { 84 | res[0] = -res[0]; 85 | res[1] = -res[1]; 86 | res[2] = -res[2]; 87 | } 88 | 89 | PURE_INLINE void dCopyVector3(dReal *res, const dReal *a) 90 | { 91 | dReal res_0, res_1, res_2; 92 | res_0 = a[0]; 93 | res_1 = a[1]; 94 | res_2 = a[2]; 95 | // Only assign after all the calculations are over to avoid incurring memory aliasing 96 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 97 | } 98 | 99 | PURE_INLINE void dCopyScaledVector3(dReal *res, const dReal *a, dReal nScale) 100 | { 101 | dReal res_0, res_1, res_2; 102 | res_0 = a[0] * nScale; 103 | res_1 = a[1] * nScale; 104 | res_2 = a[2] * nScale; 105 | // Only assign after all the calculations are over to avoid incurring memory aliasing 106 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 107 | } 108 | 109 | PURE_INLINE void dCopyNegatedVector3(dReal *res, const dReal *a) 110 | { 111 | dReal res_0, res_1, res_2; 112 | res_0 = -a[0]; 113 | res_1 = -a[1]; 114 | res_2 = -a[2]; 115 | // Only assign after all the calculations are over to avoid incurring memory aliasing 116 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 117 | } 118 | 119 | PURE_INLINE void dCopyVector4(dReal *res, const dReal *a) 120 | { 121 | dReal res_0, res_1, res_2, res_3; 122 | res_0 = a[0]; 123 | res_1 = a[1]; 124 | res_2 = a[2]; 125 | res_3 = a[3]; 126 | // Only assign after all the calculations are over to avoid incurring memory aliasing 127 | res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3; 128 | } 129 | 130 | PURE_INLINE void dCopyMatrix4x4(dReal *res, const dReal *a) 131 | { 132 | dCopyVector4(res + 0, a + 0); 133 | dCopyVector4(res + 4, a + 4); 134 | dCopyVector4(res + 8, a + 8); 135 | } 136 | 137 | PURE_INLINE void dCopyMatrix4x3(dReal *res, const dReal *a) 138 | { 139 | dCopyVector3(res + 0, a + 0); 140 | dCopyVector3(res + 4, a + 4); 141 | dCopyVector3(res + 8, a + 8); 142 | } 143 | 144 | PURE_INLINE void dGetMatrixColumn3(dReal *res, const dReal *a, unsigned n) 145 | { 146 | dReal res_0, res_1, res_2; 147 | res_0 = a[n + 0]; 148 | res_1 = a[n + 4]; 149 | res_2 = a[n + 8]; 150 | // Only assign after all the calculations are over to avoid incurring memory aliasing 151 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 152 | } 153 | 154 | PURE_INLINE dReal dCalcVectorLength3(const dReal *a) 155 | { 156 | return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); 157 | } 158 | 159 | PURE_INLINE dReal dCalcVectorLengthSquare3(const dReal *a) 160 | { 161 | return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); 162 | } 163 | 164 | PURE_INLINE dReal dCalcPointDepth3(const dReal *test_p, const dReal *plane_p, const dReal *plane_n) 165 | { 166 | 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]; 167 | } 168 | 169 | 170 | /* 171 | * 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced 172 | * step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311. 173 | */ 174 | 175 | PURE_INLINE dReal _dCalcVectorDot3(const dReal *a, const dReal *b, unsigned step_a, unsigned step_b) 176 | { 177 | return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b]; 178 | } 179 | 180 | 181 | PURE_INLINE dReal dCalcVectorDot3 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,1); } 182 | PURE_INLINE dReal dCalcVectorDot3_13 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,3); } 183 | PURE_INLINE dReal dCalcVectorDot3_31 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,1); } 184 | PURE_INLINE dReal dCalcVectorDot3_33 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,3,3); } 185 | PURE_INLINE dReal dCalcVectorDot3_14 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,1,4); } 186 | PURE_INLINE dReal dCalcVectorDot3_41 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,1); } 187 | PURE_INLINE dReal dCalcVectorDot3_44 (const dReal *a, const dReal *b) { return _dCalcVectorDot3(a,b,4,4); } 188 | 189 | 190 | /* 191 | * cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a' 192 | * and `b' are spaced step_res, step_a and step_b indexes apart respectively. 193 | * dCalcVectorCross3() means dCross3111. 194 | */ 195 | 196 | PURE_INLINE void _dCalcVectorCross3(dReal *res, const dReal *a, const dReal *b, unsigned step_res, unsigned step_a, unsigned step_b) 197 | { 198 | dReal res_0, res_1, res_2; 199 | res_0 = a[ step_a]*b[2*step_b] - a[2*step_a]*b[ step_b]; 200 | res_1 = a[2*step_a]*b[ 0] - a[ 0]*b[2*step_b]; 201 | res_2 = a[ 0]*b[ step_b] - a[ step_a]*b[ 0]; 202 | // Only assign after all the calculations are over to avoid incurring memory aliasing 203 | res[ 0] = res_0; 204 | res[ step_res] = res_1; 205 | res[2*step_res] = res_2; 206 | } 207 | 208 | PURE_INLINE void dCalcVectorCross3 (dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); } 209 | PURE_INLINE void dCalcVectorCross3_114(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); } 210 | PURE_INLINE void dCalcVectorCross3_141(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); } 211 | PURE_INLINE void dCalcVectorCross3_144(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); } 212 | PURE_INLINE void dCalcVectorCross3_411(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); } 213 | PURE_INLINE void dCalcVectorCross3_414(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); } 214 | PURE_INLINE void dCalcVectorCross3_441(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); } 215 | PURE_INLINE void dCalcVectorCross3_444(dReal *res, const dReal *a, const dReal *b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); } 216 | 217 | PURE_INLINE void dAddVectorCross3(dReal *res, const dReal *a, const dReal *b) 218 | { 219 | dReal tmp[3]; 220 | dCalcVectorCross3(tmp, a, b); 221 | dAddVectors3(res, res, tmp); 222 | } 223 | 224 | PURE_INLINE void dSubtractVectorCross3(dReal *res, const dReal *a, const dReal *b) 225 | { 226 | dReal tmp[3]; 227 | dCalcVectorCross3(tmp, a, b); 228 | dSubtractVectors3(res, res, tmp); 229 | } 230 | 231 | 232 | /* 233 | * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. 234 | * A is stored by rows, and has `skip' elements per row. the matrix is 235 | * assumed to be already zero, so this does not write zero elements! 236 | * if (plus,minus) is (+,-) then a positive version will be written. 237 | * if (plus,minus) is (-,+) then a negative version will be written. 238 | */ 239 | 240 | PURE_INLINE void dSetCrossMatrixPlus(dReal *res, const dReal *a, unsigned skip) 241 | { 242 | const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2]; 243 | res[1] = -a_2; 244 | res[2] = +a_1; 245 | res[skip+0] = +a_2; 246 | res[skip+2] = -a_0; 247 | res[2*skip+0] = -a_1; 248 | res[2*skip+1] = +a_0; 249 | } 250 | 251 | PURE_INLINE void dSetCrossMatrixMinus(dReal *res, const dReal *a, unsigned skip) 252 | { 253 | const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2]; 254 | res[1] = +a_2; 255 | res[2] = -a_1; 256 | res[skip+0] = -a_2; 257 | res[skip+2] = +a_0; 258 | res[2*skip+0] = +a_1; 259 | res[2*skip+1] = -a_0; 260 | } 261 | 262 | 263 | /* 264 | * compute the distance between two 3D-vectors 265 | */ 266 | 267 | PURE_INLINE dReal dCalcPointsDistance3(const dReal *a, const dReal *b) 268 | { 269 | dReal res; 270 | dReal tmp[3]; 271 | dSubtractVectors3(tmp, a, b); 272 | res = dCalcVectorLength3(tmp); 273 | return res; 274 | } 275 | 276 | /* 277 | * special case matrix multiplication, with operator selection 278 | */ 279 | 280 | PURE_INLINE void dMultiplyHelper0_331(dReal *res, const dReal *a, const dReal *b) 281 | { 282 | dReal res_0, res_1, res_2; 283 | res_0 = dCalcVectorDot3(a, b); 284 | res_1 = dCalcVectorDot3(a + 4, b); 285 | res_2 = dCalcVectorDot3(a + 8, b); 286 | // Only assign after all the calculations are over to avoid incurring memory aliasing 287 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 288 | } 289 | 290 | PURE_INLINE void dMultiplyHelper1_331(dReal *res, const dReal *a, const dReal *b) 291 | { 292 | dReal res_0, res_1, res_2; 293 | res_0 = dCalcVectorDot3_41(a, b); 294 | res_1 = dCalcVectorDot3_41(a + 1, b); 295 | res_2 = dCalcVectorDot3_41(a + 2, b); 296 | // Only assign after all the calculations are over to avoid incurring memory aliasing 297 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 298 | } 299 | 300 | PURE_INLINE void dMultiplyHelper0_133(dReal *res, const dReal *a, const dReal *b) 301 | { 302 | dMultiplyHelper1_331(res, b, a); 303 | } 304 | 305 | PURE_INLINE void dMultiplyHelper1_133(dReal *res, const dReal *a, const dReal *b) 306 | { 307 | dReal res_0, res_1, res_2; 308 | res_0 = dCalcVectorDot3_44(a, b); 309 | res_1 = dCalcVectorDot3_44(a + 1, b); 310 | res_2 = dCalcVectorDot3_44(a + 2, b); 311 | // Only assign after all the calculations are over to avoid incurring memory aliasing 312 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 313 | } 314 | 315 | /* 316 | Note: NEVER call any of these functions/macros with the same variable for A and C, 317 | it is not equivalent to A*=B. 318 | */ 319 | 320 | PURE_INLINE void dMultiply0_331(dReal *res, const dReal *a, const dReal *b) 321 | { 322 | dMultiplyHelper0_331(res, a, b); 323 | } 324 | 325 | PURE_INLINE void dMultiply1_331(dReal *res, const dReal *a, const dReal *b) 326 | { 327 | dMultiplyHelper1_331(res, a, b); 328 | } 329 | 330 | PURE_INLINE void dMultiply0_133(dReal *res, const dReal *a, const dReal *b) 331 | { 332 | dMultiplyHelper0_133(res, a, b); 333 | } 334 | 335 | PURE_INLINE void dMultiply0_333(dReal *res, const dReal *a, const dReal *b) 336 | { 337 | dMultiplyHelper0_133(res + 0, a + 0, b); 338 | dMultiplyHelper0_133(res + 4, a + 4, b); 339 | dMultiplyHelper0_133(res + 8, a + 8, b); 340 | } 341 | 342 | PURE_INLINE void dMultiply1_333(dReal *res, const dReal *a, const dReal *b) 343 | { 344 | dMultiplyHelper1_133(res + 0, b, a + 0); 345 | dMultiplyHelper1_133(res + 4, b, a + 1); 346 | dMultiplyHelper1_133(res + 8, b, a + 2); 347 | } 348 | 349 | PURE_INLINE void dMultiply2_333(dReal *res, const dReal *a, const dReal *b) 350 | { 351 | dMultiplyHelper0_331(res + 0, b, a + 0); 352 | dMultiplyHelper0_331(res + 4, b, a + 4); 353 | dMultiplyHelper0_331(res + 8, b, a + 8); 354 | } 355 | 356 | PURE_INLINE void dMultiplyAdd0_331(dReal *res, const dReal *a, const dReal *b) 357 | { 358 | dReal tmp[3]; 359 | dMultiplyHelper0_331(tmp, a, b); 360 | dAddVectors3(res, res, tmp); 361 | } 362 | 363 | PURE_INLINE void dMultiplyAdd1_331(dReal *res, const dReal *a, const dReal *b) 364 | { 365 | dReal tmp[3]; 366 | dMultiplyHelper1_331(tmp, a, b); 367 | dAddVectors3(res, res, tmp); 368 | } 369 | 370 | PURE_INLINE void dMultiplyAdd0_133(dReal *res, const dReal *a, const dReal *b) 371 | { 372 | dReal tmp[3]; 373 | dMultiplyHelper0_133(tmp, a, b); 374 | dAddVectors3(res, res, tmp); 375 | } 376 | 377 | PURE_INLINE void dMultiplyAdd0_333(dReal *res, const dReal *a, const dReal *b) 378 | { 379 | dReal tmp[3]; 380 | dMultiplyHelper0_133(tmp, a + 0, b); 381 | dAddVectors3(res+ 0, res + 0, tmp); 382 | dMultiplyHelper0_133(tmp, a + 4, b); 383 | dAddVectors3(res + 4, res + 4, tmp); 384 | dMultiplyHelper0_133(tmp, a + 8, b); 385 | dAddVectors3(res + 8, res + 8, tmp); 386 | } 387 | 388 | PURE_INLINE void dMultiplyAdd1_333(dReal *res, const dReal *a, const dReal *b) 389 | { 390 | dReal tmp[3]; 391 | dMultiplyHelper1_133(tmp, b, a + 0); 392 | dAddVectors3(res + 0, res + 0, tmp); 393 | dMultiplyHelper1_133(tmp, b, a + 1); 394 | dAddVectors3(res + 4, res + 4, tmp); 395 | dMultiplyHelper1_133(tmp, b, a + 2); 396 | dAddVectors3(res + 8, res + 8, tmp); 397 | } 398 | 399 | PURE_INLINE void dMultiplyAdd2_333(dReal *res, const dReal *a, const dReal *b) 400 | { 401 | dReal tmp[3]; 402 | dMultiplyHelper0_331(tmp, b, a + 0); 403 | dAddVectors3(res + 0, res + 0, tmp); 404 | dMultiplyHelper0_331(tmp, b, a + 4); 405 | dAddVectors3(res + 4, res + 4, tmp); 406 | dMultiplyHelper0_331(tmp, b, a + 8); 407 | dAddVectors3(res + 8, res + 8, tmp); 408 | } 409 | 410 | 411 | // Include legacy macros here 412 | #include 413 | 414 | 415 | #ifdef __cplusplus 416 | extern "C" { 417 | #endif 418 | 419 | /* 420 | * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) 421 | */ 422 | 423 | // For DLL export 424 | ODE_API int dSafeNormalize3 (dVector3 a); 425 | ODE_API int dSafeNormalize4 (dVector4 a); 426 | ODE_API void dNormalize3 (dVector3 a); // Potentially asserts on zero vec 427 | ODE_API void dNormalize4 (dVector4 a); // Potentially asserts on zero vec 428 | 429 | #if defined(__ODE__) 430 | 431 | int _dSafeNormalize3 (dVector3 a); 432 | int _dSafeNormalize4 (dVector4 a); 433 | 434 | PURE_INLINE void _dNormalize3(dVector3 a) 435 | { 436 | int bNormalizationResult = _dSafeNormalize3(a); 437 | dIVERIFY(bNormalizationResult); 438 | } 439 | 440 | PURE_INLINE void _dNormalize4(dVector4 a) 441 | { 442 | int bNormalizationResult = _dSafeNormalize4(a); 443 | dIVERIFY(bNormalizationResult); 444 | } 445 | 446 | // For internal use 447 | #define dSafeNormalize3(a) _dSafeNormalize3(a) 448 | #define dSafeNormalize4(a) _dSafeNormalize4(a) 449 | #define dNormalize3(a) _dNormalize3(a) 450 | #define dNormalize4(a) _dNormalize4(a) 451 | 452 | #endif // defined(__ODE__) 453 | 454 | /* 455 | * given a unit length "normal" vector n, generate vectors p and q vectors 456 | * that are an orthonormal basis for the plane space perpendicular to n. 457 | * i.e. this makes p,q such that n,p,q are all perpendicular to each other. 458 | * q will equal n x p. if n is not unit length then p will be unit length but 459 | * q wont be. 460 | */ 461 | 462 | ODE_API void dPlaneSpace (const dVector3 n, dVector3 p, dVector3 q); 463 | /* Makes sure the matrix is a proper rotation */ 464 | ODE_API void dOrthogonalizeR(dMatrix3 m); 465 | 466 | 467 | 468 | #ifdef __cplusplus 469 | } 470 | #endif 471 | 472 | 473 | #endif 474 | -------------------------------------------------------------------------------- /c/odemath_legacy.h: -------------------------------------------------------------------------------- 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_ODEMATH_LEGACY_H_ 24 | #define _ODE_ODEMATH_LEGACY_H_ 25 | 26 | 27 | /////////////////////////////////////////////////////////////////////////////// 28 | /////////////////////////////////////////////////////////////////////////////// 29 | /////////////////////////////////////////////////////////////////////////////// 30 | /////////////////////////////////////////////////////////////////////////////// 31 | /////////////////////////////////////////////////////////////////////////////// 32 | /* 33 | * These macros are not used any more inside of ODE 34 | * They are kept for backward compatibility with external code that 35 | * might still be using them. 36 | */ 37 | /////////////////////////////////////////////////////////////////////////////// 38 | /////////////////////////////////////////////////////////////////////////////// 39 | /////////////////////////////////////////////////////////////////////////////// 40 | /////////////////////////////////////////////////////////////////////////////// 41 | /////////////////////////////////////////////////////////////////////////////// 42 | 43 | /* 44 | * General purpose vector operations with other vectors or constants. 45 | */ 46 | 47 | #define dOP(a,op,b,c) do { \ 48 | (a)[0] = ((b)[0]) op ((c)[0]); \ 49 | (a)[1] = ((b)[1]) op ((c)[1]); \ 50 | (a)[2] = ((b)[2]) op ((c)[2]); \ 51 | } while (0) 52 | #define dOPC(a,op,b,c) do { \ 53 | (a)[0] = ((b)[0]) op (c); \ 54 | (a)[1] = ((b)[1]) op (c); \ 55 | (a)[2] = ((b)[2]) op (c); \ 56 | } while (0) 57 | #define dOPE(a,op,b) do {\ 58 | (a)[0] op ((b)[0]); \ 59 | (a)[1] op ((b)[1]); \ 60 | (a)[2] op ((b)[2]); \ 61 | } while (0) 62 | #define dOPEC(a,op,c) do { \ 63 | (a)[0] op (c); \ 64 | (a)[1] op (c); \ 65 | (a)[2] op (c); \ 66 | } while (0) 67 | 68 | /// Define an equation with operators 69 | /// For example this function can be used to replace 70 | ///
 71 | /// for (int i=0; i<3; ++i)
 72 | ///   a[i] += b[i] + c[i];
 73 | /// 
74 | #define dOPE2(a,op1,b,op2,c) do { \ 75 | (a)[0] op1 ((b)[0]) op2 ((c)[0]); \ 76 | (a)[1] op1 ((b)[1]) op2 ((c)[1]); \ 77 | (a)[2] op1 ((b)[2]) op2 ((c)[2]); \ 78 | } while (0) 79 | 80 | 81 | #define dLENGTHSQUARED(a) dCalcVectorLengthSquare3(a) 82 | #define dLENGTH(a) dCalcVectorLength3(a) 83 | #define dDISTANCE(a, b) dCalcPointsDistance3(a, b) 84 | 85 | 86 | #define dDOT(a, b) dCalcVectorDot3(a, b) 87 | #define dDOT13(a, b) dCalcVectorDot3_13(a, b) 88 | #define dDOT31(a, b) dCalcVectorDot3_31(a, b) 89 | #define dDOT33(a, b) dCalcVectorDot3_33(a, b) 90 | #define dDOT14(a, b) dCalcVectorDot3_14(a, b) 91 | #define dDOT41(a, b) dCalcVectorDot3_41(a, b) 92 | #define dDOT44(a, b) dCalcVectorDot3_44(a, b) 93 | 94 | 95 | /* 96 | * cross product, set a = b x c. dCROSSpqr means that elements of `a', `b' 97 | * and `c' are spaced p, q and r indexes apart respectively. 98 | * dCROSS() means dCROSS111. `op' is normally `=', but you can set it to 99 | * +=, -= etc to get other effects. 100 | */ 101 | 102 | #define dCROSS(a,op,b,c) \ 103 | do { \ 104 | (a)[0] op ((b)[1]*(c)[2] - (b)[2]*(c)[1]); \ 105 | (a)[1] op ((b)[2]*(c)[0] - (b)[0]*(c)[2]); \ 106 | (a)[2] op ((b)[0]*(c)[1] - (b)[1]*(c)[0]); \ 107 | } while(0) 108 | #define dCROSSpqr(a,op,b,c,p,q,r) \ 109 | do { \ 110 | (a)[ 0] op ((b)[ q]*(c)[2*r] - (b)[2*q]*(c)[ r]); \ 111 | (a)[ p] op ((b)[2*q]*(c)[ 0] - (b)[ 0]*(c)[2*r]); \ 112 | (a)[2*p] op ((b)[ 0]*(c)[ r] - (b)[ q]*(c)[ 0]); \ 113 | } while(0) 114 | #define dCROSS114(a,op,b,c) dCROSSpqr(a,op,b,c,1,1,4) 115 | #define dCROSS141(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,1) 116 | #define dCROSS144(a,op,b,c) dCROSSpqr(a,op,b,c,1,4,4) 117 | #define dCROSS411(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,1) 118 | #define dCROSS414(a,op,b,c) dCROSSpqr(a,op,b,c,4,1,4) 119 | #define dCROSS441(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,1) 120 | #define dCROSS444(a,op,b,c) dCROSSpqr(a,op,b,c,4,4,4) 121 | 122 | 123 | /* 124 | * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. 125 | * A is stored by rows, and has `skip' elements per row. the matrix is 126 | * assumed to be already zero, so this does not write zero elements! 127 | * if (plus,minus) is (+,-) then a positive version will be written. 128 | * if (plus,minus) is (-,+) then a negative version will be written. 129 | */ 130 | 131 | #define dCROSSMAT(A,a,skip,plus,minus) \ 132 | do { \ 133 | (A)[1] = minus (a)[2]; \ 134 | (A)[2] = plus (a)[1]; \ 135 | (A)[(skip)+0] = plus (a)[2]; \ 136 | (A)[(skip)+2] = minus (a)[0]; \ 137 | (A)[2*(skip)+0] = minus (a)[1]; \ 138 | (A)[2*(skip)+1] = plus (a)[0]; \ 139 | } while(0) 140 | 141 | 142 | 143 | 144 | /* 145 | Note: NEVER call any of these functions/macros with the same variable for A and C, 146 | it is not equivalent to A*=B. 147 | */ 148 | 149 | #define dMULTIPLY0_331(A, B, C) dMultiply0_331(A, B, C) 150 | #define dMULTIPLY1_331(A, B, C) dMultiply1_331(A, B, C) 151 | #define dMULTIPLY0_133(A, B, C) dMultiply0_133(A, B, C) 152 | #define dMULTIPLY0_333(A, B, C) dMultiply0_333(A, B, C) 153 | #define dMULTIPLY1_333(A, B, C) dMultiply1_333(A, B, C) 154 | #define dMULTIPLY2_333(A, B, C) dMultiply2_333(A, B, C) 155 | 156 | #define dMULTIPLYADD0_331(A, B, C) dMultiplyAdd0_331(A, B, C) 157 | #define dMULTIPLYADD1_331(A, B, C) dMultiplyAdd1_331(A, B, C) 158 | #define dMULTIPLYADD0_133(A, B, C) dMultiplyAdd0_133(A, B, C) 159 | #define dMULTIPLYADD0_333(A, B, C) dMultiplyAdd0_333(A, B, C) 160 | #define dMULTIPLYADD1_333(A, B, C) dMultiplyAdd1_333(A, B, C) 161 | #define dMULTIPLYADD2_333(A, B, C) dMultiplyAdd2_333(A, B, C) 162 | 163 | 164 | /////////////////////////////////////////////////////////////////////////////// 165 | /////////////////////////////////////////////////////////////////////////////// 166 | /////////////////////////////////////////////////////////////////////////////// 167 | /////////////////////////////////////////////////////////////////////////////// 168 | /////////////////////////////////////////////////////////////////////////////// 169 | /* 170 | * These macros are not used any more inside of ODE 171 | * They are kept for backward compatibility with external code that 172 | * might still be using them. 173 | */ 174 | /////////////////////////////////////////////////////////////////////////////// 175 | /////////////////////////////////////////////////////////////////////////////// 176 | /////////////////////////////////////////////////////////////////////////////// 177 | /////////////////////////////////////////////////////////////////////////////// 178 | /////////////////////////////////////////////////////////////////////////////// 179 | 180 | 181 | #endif // #ifndef _ODE_ODEMATH_LEGACY_H_ 182 | -------------------------------------------------------------------------------- /c/rotation.h: -------------------------------------------------------------------------------- 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_ROTATION_H_ 24 | #define _ODE_ROTATION_H_ 25 | 26 | #include 27 | #include 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | 34 | ODE_API void dRSetIdentity (dMatrix3 R); 35 | 36 | ODE_API void dRFromAxisAndAngle (dMatrix3 R, dReal ax, dReal ay, dReal az, 37 | dReal angle); 38 | 39 | ODE_API void dRFromEulerAngles (dMatrix3 R, dReal phi, dReal theta, dReal psi); 40 | 41 | ODE_API void dRFrom2Axes (dMatrix3 R, dReal ax, dReal ay, dReal az, 42 | dReal bx, dReal by, dReal bz); 43 | 44 | ODE_API void dRFromZAxis (dMatrix3 R, dReal ax, dReal ay, dReal az); 45 | 46 | ODE_API void dQSetIdentity (dQuaternion q); 47 | 48 | ODE_API void dQFromAxisAndAngle (dQuaternion q, dReal ax, dReal ay, dReal az, 49 | dReal angle); 50 | 51 | /* Quaternion multiplication, analogous to the matrix multiplication routines. */ 52 | /* qa = rotate by qc, then qb */ 53 | ODE_API void dQMultiply0 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); 54 | /* qa = rotate by qc, then by inverse of qb */ 55 | ODE_API void dQMultiply1 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); 56 | /* qa = rotate by inverse of qc, then by qb */ 57 | ODE_API void dQMultiply2 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); 58 | /* qa = rotate by inverse of qc, then by inverse of qb */ 59 | ODE_API void dQMultiply3 (dQuaternion qa, const dQuaternion qb, const dQuaternion qc); 60 | 61 | ODE_API void dRfromQ (dMatrix3 R, const dQuaternion q); 62 | ODE_API void dQfromR (dQuaternion q, const dMatrix3 R); 63 | ODE_API void dDQfromW (dReal dq[4], const dVector3 w, const dQuaternion q); 64 | 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /c/timer.h: -------------------------------------------------------------------------------- 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_TIMER_H_ 24 | #define _ODE_TIMER_H_ 25 | 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | 33 | /* stop watch objects */ 34 | 35 | typedef struct dStopwatch { 36 | double time; /* total clock count */ 37 | unsigned long cc[2]; /* clock count since last `start' */ 38 | } dStopwatch; 39 | 40 | ODE_API void dStopwatchReset (dStopwatch *); 41 | ODE_API void dStopwatchStart (dStopwatch *); 42 | ODE_API void dStopwatchStop (dStopwatch *); 43 | ODE_API double dStopwatchTime (dStopwatch *); /* returns total time in secs */ 44 | 45 | 46 | /* code timers */ 47 | 48 | ODE_API void dTimerStart (const char *description); /* pass a static string here */ 49 | ODE_API void dTimerNow (const char *description); /* pass a static string here */ 50 | ODE_API void dTimerEnd(void); 51 | 52 | /* print out a timer report. if `average' is nonzero, print out the average 53 | * time for each slot (this is only meaningful if the same start-now-end 54 | * calls are being made repeatedly. 55 | */ 56 | ODE_API void dTimerReport (FILE *fout, int average); 57 | 58 | 59 | /* resolution */ 60 | 61 | /* returns the timer ticks per second implied by the timing hardware or API. 62 | * the actual timer resolution may not be this great. 63 | */ 64 | ODE_API double dTimerTicksPerSecond(void); 65 | 66 | /* returns an estimate of the actual timer resolution, in seconds. this may 67 | * be greater than 1/ticks_per_second. 68 | */ 69 | ODE_API double dTimerResolution(void); 70 | 71 | 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /deimos/ode/collision_space.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.collision_space; 27 | 28 | private import deimos.ode.common; 29 | 30 | extern (C): 31 | nothrow: 32 | 33 | /** 34 | * @brief User callback for geom-geom collision testing. 35 | * 36 | * @param data The user data object, as passed to dSpaceCollide. 37 | * @param o1 The first geom being tested. 38 | * @param o2 The second geom being test. 39 | * 40 | * @remarks The callback function can call dCollide on o1 and o2 to generate 41 | * contact points between each pair. Then these contact points may be added 42 | * to the simulation as contact joints. The user's callback function can of 43 | * course chose not to call dCollide for any pair, e.g. if the user decides 44 | * that those pairs should not interact. 45 | * 46 | * @ingroup collide 47 | */ 48 | alias void function(void* data, dGeomID o1, dGeomID o2) dNearCallback; 49 | 50 | dSpaceID dSimpleSpaceCreate(dSpaceID space); 51 | dSpaceID dHashSpaceCreate(dSpaceID space); 52 | dSpaceID dQuadTreeSpaceCreate(dSpaceID space, in dVector3 Center, in dVector3 Extents, int Depth); 53 | 54 | 55 | // SAP 56 | // Order XZY or ZXY usually works best, if your Y is up. 57 | enum 58 | { 59 | dSAP_AXES_XYZ = ((0)|(1<<2)|(2<<4)), 60 | dSAP_AXES_XZY = ((0)|(2<<2)|(1<<4)), 61 | dSAP_AXES_YXZ = ((1)|(0<<2)|(2<<4)), 62 | dSAP_AXES_YZX = ((1)|(2<<2)|(0<<4)), 63 | dSAP_AXES_ZXY = ((2)|(0<<2)|(1<<4)), 64 | dSAP_AXES_ZYX = ((2)|(1<<2)|(0<<4)) 65 | } 66 | 67 | dSpaceID dSweepAndPruneSpaceCreate(dSpaceID space, int axisorder); 68 | 69 | void dSpaceDestroy(dSpaceID); 70 | 71 | void dHashSpaceSetLevels(dSpaceID space, int minlevel, int maxlevel); 72 | void dHashSpaceGetLevels(dSpaceID space, int* minlevel, int* maxlevel); 73 | 74 | void dSpaceSetCleanup(dSpaceID space, int mode); 75 | int dSpaceGetCleanup(dSpaceID space); 76 | 77 | /** 78 | * @brief Sets sublevel value for a space. 79 | * 80 | * Sublevel affects how the space is handled in dSpaceCollide2 when it is collided 81 | * with another space. If sublevels of both spaces match, the function iterates 82 | * geometries of both spaces and collides them with each other. If sublevel of one 83 | * space is greater than the sublevel of another one, only the geometries of the 84 | * space with greater sublevel are iterated, another space is passed into 85 | * collision callback as a geometry itself. By default all the spaces are assigned 86 | * zero sublevel. 87 | * 88 | * @note 89 | * The space sublevel @e IS @e NOT automatically updated when one space is inserted 90 | * into another or removed from one. It is a client's responsibility to update sublevel 91 | * value if necessary. 92 | * 93 | * @param space the space to modify 94 | * @param sublevel the sublevel value to be assigned 95 | * @ingroup collide 96 | * @see dSpaceGetSublevel 97 | * @see dSpaceCollide2 98 | */ 99 | void dSpaceSetSublevel(dSpaceID space, int sublevel); 100 | 101 | /** 102 | * @brief Gets sublevel value of a space. 103 | * 104 | * Sublevel affects how the space is handled in dSpaceCollide2 when it is collided 105 | * with another space. See @c dSpaceSetSublevel for more details. 106 | * 107 | * @param space the space to query 108 | * @returns the sublevel value of the space 109 | * @ingroup collide 110 | * @see dSpaceSetSublevel 111 | * @see dSpaceCollide2 112 | */ 113 | int dSpaceGetSublevel(dSpaceID space); 114 | 115 | 116 | /** 117 | * @brief Sets manual cleanup flag for a space. 118 | * 119 | * Manual cleanup flag marks a space as eligible for manual thread data cleanup. 120 | * This function should be called for every space object right after creation in 121 | * case if ODE has been initialized with @c dInitFlagManualThreadCleanup flag. 122 | * 123 | * Failure to set manual cleanup flag for a space may lead to some resources 124 | * remaining leaked until the program exit. 125 | * 126 | * @param space the space to modify 127 | * @param mode 1 for manual cleanup mode and 0 for default cleanup mode 128 | * @ingroup collide 129 | * @see dSpaceGetManualCleanup 130 | * @see dInitODE2 131 | */ 132 | void dSpaceSetManualCleanup(dSpaceID space, int mode); 133 | 134 | /** 135 | * @brief Get manual cleanup flag of a space. 136 | * 137 | * Manual cleanup flag marks a space space as eligible for manual thread data cleanup. 138 | * See @c dSpaceSetManualCleanup for more details. 139 | * 140 | * @param space the space to query 141 | * @returns 1 for manual cleanup mode and 0 for default cleanup mode of the space 142 | * @ingroup collide 143 | * @see dSpaceSetManualCleanup 144 | * @see dInitODE2 145 | */ 146 | int dSpaceGetManualCleanup(dSpaceID space); 147 | 148 | void dSpaceAdd(dSpaceID, dGeomID); 149 | void dSpaceRemove(dSpaceID, dGeomID); 150 | int dSpaceQuery(dSpaceID, dGeomID); 151 | void dSpaceClean(dSpaceID); 152 | int dSpaceGetNumGeoms(dSpaceID); 153 | dGeomID dSpaceGetGeom(dSpaceID, int i); 154 | 155 | /** 156 | * @brief Given a space, this returns its class. 157 | * 158 | * The ODE classes are: 159 | * @li dSimpleSpaceClass 160 | * @li dHashSpaceClass 161 | * @li dSweepAndPruneSpaceClass 162 | * @li dQuadTreeSpaceClass 163 | * @li dFirstUserClass 164 | * @li dLastUserClass 165 | * 166 | * The class id not defined by the user should be between 167 | * dFirstSpaceClass and dLastSpaceClass. 168 | * 169 | * User-defined class will return their own number. 170 | * 171 | * @param space the space to query 172 | * @returns The space class ID. 173 | * @ingroup collide 174 | */ 175 | int dSpaceGetClass(dSpaceID space); 176 | -------------------------------------------------------------------------------- /deimos/ode/collision_trimesh.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | /* 27 | * TriMesh code by Erwin de Vries. 28 | * 29 | * Trimesh data. 30 | * This is where the actual vertexdata (pointers), and BV tree is stored. 31 | * Vertices should be single precision! 32 | * This should be more sophisticated, so that the user can easyly implement 33 | * another collision library, but this is a lot of work, and also costs some 34 | * performance because some data has to be copied. 35 | */ 36 | 37 | module deimos.ode.collision_trimesh; 38 | 39 | private import deimos.ode.common; 40 | 41 | extern (C): 42 | nothrow: 43 | 44 | /* 45 | * Data storage for triangle meshes. 46 | */ 47 | struct dxTriMeshData; 48 | alias dxTriMeshData* dTriMeshDataID; 49 | 50 | /* 51 | * These dont make much sense now, but they will later when we add more 52 | * features. 53 | */ 54 | dTriMeshDataID dGeomTriMeshDataCreate(); 55 | void dGeomTriMeshDataDestroy(dTriMeshDataID g); 56 | 57 | 58 | 59 | enum { TRIMESH_FACE_NORMALS } 60 | void dGeomTriMeshDataSet(dTriMeshDataID g, int data_id, void* in_data); 61 | void* dGeomTriMeshDataGet(dTriMeshDataID g, int data_id); 62 | 63 | /** 64 | * We need to set the last transform after each time step for 65 | * accurate collision response. These functions get and set that transform. 66 | * It is stored per geom instance, rather than per dTriMeshDataID. 67 | */ 68 | void dGeomTriMeshSetLastTransform(dGeomID g, dMatrix4 last_trans); 69 | dReal* dGeomTriMeshGetLastTransform(dGeomID g); 70 | 71 | /* 72 | * Build a TriMesh data object with single precision vertex data. 73 | */ 74 | void dGeomTriMeshDataBuildSingle( 75 | dTriMeshDataID g, in void* Vertices, int VertexStride, int VertexCount, 76 | in void* Indices, int IndexCount, int TriStride 77 | ); 78 | /* same again with a normals array (used as trimesh-trimesh optimization) */ 79 | void dGeomTriMeshDataBuildSingle1( 80 | dTriMeshDataID g, in void* Vertices, int VertexStride, int VertexCount, 81 | in void* Indices, int IndexCount, int TriStride, in void* Normals 82 | ); 83 | /* 84 | * Build a TriMesh data object with double precision vertex data. 85 | */ 86 | void dGeomTriMeshDataBuildDouble( 87 | dTriMeshDataID g, in void* Vertices, int VertexStride, int VertexCount, 88 | in void* Indices, int IndexCount, int TriStride 89 | ); 90 | /* same again with a normals array (used as trimesh-trimesh optimization) */ 91 | void dGeomTriMeshDataBuildDouble1( 92 | dTriMeshDataID g, in void* Vertices, int VertexStride, 93 | int VertexCount, in void* Indices, int IndexCount, 94 | int TriStride, in void* Normals 95 | ); 96 | 97 | /* 98 | * Simple build. Single/double precision based on dSINGLE/dDOUBLE! 99 | */ 100 | void dGeomTriMeshDataBuildSimple( 101 | dTriMeshDataID g, in dReal* Vertices, int VertexCount, 102 | in dTriIndex* Indices, int IndexCount 103 | ); 104 | /* same again with a normals array (used as trimesh-trimesh optimization) */ 105 | void dGeomTriMeshDataBuildSimple1( 106 | dTriMeshDataID g, in dReal* Vertices, int VertexCount, 107 | in dTriIndex* Indices, int IndexCount, in int* Normals 108 | ); 109 | 110 | /* Preprocess the trimesh data to remove mark unnecessary edges and vertices */ 111 | void dGeomTriMeshDataPreprocess(dTriMeshDataID g); 112 | /* Get and set the internal preprocessed trimesh data buffer, for loading and saving */ 113 | void dGeomTriMeshDataGetBuffer(dTriMeshDataID g, ubyte** buf, int* bufLen); 114 | void dGeomTriMeshDataSetBuffer(dTriMeshDataID g, ubyte* buf); 115 | 116 | 117 | /* 118 | * Per triangle callback. Allows the user to say if he wants a collision with 119 | * a particular triangle. 120 | */ 121 | alias int function( 122 | dGeomID TriMesh, dGeomID RefObject, int TriangleIndex 123 | ) dTriCallback; 124 | void dGeomTriMeshSetCallback(dGeomID g, dTriCallback* Callback); 125 | dTriCallback* dGeomTriMeshGetCallback(dGeomID g); 126 | 127 | /* 128 | * Per object callback. Allows the user to get the list of triangles in 1 129 | * shot. Maybe we should remove this one. 130 | */ 131 | alias void function( 132 | dGeomID TriMesh, dGeomID RefObject, in int* TriIndicies, int TriCount 133 | ) dTriArrayCallback; 134 | void dGeomTriMeshSetArrayCallback(dGeomID g, dTriArrayCallback* ArrayCallback); 135 | dTriArrayCallback* dGeomTriMeshGetArrayCallback(dGeomID g); 136 | 137 | /* 138 | * Ray callback. 139 | * Allows the user to say if a ray collides with a triangle on barycentric 140 | * coords. The user can for example sample a texture with alpha transparency 141 | * to determine if a collision should occur. 142 | */ 143 | alias int function( 144 | dGeomID TriMesh, dGeomID Ray, int TriangleIndex, dReal u, dReal v 145 | ) dTriRayCallback; 146 | void dGeomTriMeshSetRayCallback(dGeomID g, dTriRayCallback* Callback); 147 | dTriRayCallback* dGeomTriMeshGetRayCallback(dGeomID g); 148 | 149 | /* 150 | * Triangle merging callback. 151 | * Allows the user to generate a fake triangle index for a new contact generated 152 | * from merging of two other contacts. That index could later be used by the 153 | * user to determine attributes of original triangles used as sources for a 154 | * merged contact. 155 | */ 156 | alias int function( 157 | dGeomID TriMesh, int FirstTriangleIndex, int SecondTriangleIndex 158 | ) dTriTriMergeCallback; 159 | void dGeomTriMeshSetTriMergeCallback(dGeomID g, dTriTriMergeCallback* Callback); 160 | dTriTriMergeCallback* dGeomTriMeshGetTriMergeCallback(dGeomID g); 161 | 162 | /* 163 | * Trimesh class 164 | * Construction. Callbacks are optional. 165 | */ 166 | dGeomID dCreateTriMesh( 167 | dSpaceID space, dTriMeshDataID Data, dTriCallback* Callback, 168 | dTriArrayCallback* ArrayCallback, dTriRayCallback* RayCallback 169 | ); 170 | 171 | void dGeomTriMeshSetData(dGeomID g, dTriMeshDataID Data); 172 | dTriMeshDataID dGeomTriMeshGetData(dGeomID g); 173 | 174 | 175 | // enable/disable/check temporal coherence 176 | void dGeomTriMeshEnableTC(dGeomID g, int geomClass, int enable); 177 | int dGeomTriMeshIsTCEnabled(dGeomID g, int geomClass); 178 | 179 | /* 180 | * Clears the internal temporal coherence caches. When a geom has its 181 | * collision checked with a trimesh once, data is stored inside the trimesh. 182 | * With large worlds with lots of seperate objects this list could get huge. 183 | * We should be able to do this automagically. 184 | */ 185 | void dGeomTriMeshClearTCCache(dGeomID g); 186 | 187 | 188 | /* 189 | * returns the TriMeshDataID 190 | */ 191 | dTriMeshDataID dGeomTriMeshGetTriMeshDataID(dGeomID g); 192 | 193 | /* 194 | * Gets a triangle. 195 | */ 196 | void dGeomTriMeshGetTriangle( 197 | dGeomID g, int Index, dVector3* v0, dVector3* v1, dVector3* v2 198 | ); 199 | 200 | /* 201 | * Gets the point on the requested triangle and the given barycentric 202 | * coordinates. 203 | */ 204 | void dGeomTriMeshGetPoint( 205 | dGeomID g, int Index, dReal u, dReal v, dVector3 Out 206 | ); 207 | 208 | /* 209 | 210 | This is how the strided data works: 211 | 212 | struct StridedVertex{ 213 | dVector3 Vertex; 214 | // Userdata 215 | }; 216 | int VertexStride = sizeof(StridedVertex); 217 | 218 | struct StridedTri{ 219 | int Indices[3]; 220 | // Userdata 221 | }; 222 | int TriStride = sizeof(StridedTri); 223 | 224 | */ 225 | 226 | 227 | int dGeomTriMeshGetTriangleCount(dGeomID g); 228 | 229 | void dGeomTriMeshDataUpdate(dTriMeshDataID g); 230 | -------------------------------------------------------------------------------- /deimos/ode/common.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.common; 27 | 28 | public import deimos.ode.odeconfig; 29 | public import deimos.ode.error; 30 | 31 | private import std.math; 32 | 33 | extern (C): 34 | nothrow: 35 | 36 | version(dSINGLE) 37 | alias float dReal; 38 | else 39 | alias double dReal; 40 | 41 | alias PI M_PI; 42 | alias SQRT1_2 M_SQRT1_2; 43 | 44 | version (dTRIMESH_16BIT_INDICIES) 45 | { 46 | version (dTRIMESH_GIMPACT) 47 | alias uint32 dTriIndex; 48 | else 49 | alias uint16 dTriIndex; 50 | } 51 | else 52 | alias uint32 dTriIndex; 53 | 54 | /* round an integer up to a multiple of 4, except that 0 and 1 are unmodified 55 | * (used to compute matrix leading dimensions) 56 | */ 57 | int dPAD(int a) 58 | { 59 | return (a > 1) ? (((a - 1)|3)+1) : a; 60 | } 61 | 62 | /* these types are mainly just used in headers */ 63 | alias dReal[4] dVector3; 64 | alias dReal[4] dVector4; 65 | alias dReal[4*3] dMatrix3; 66 | alias dReal[4*4] dMatrix4; 67 | alias dReal[8*6] dMatrix6; 68 | alias dReal[4] dQuaternion; 69 | 70 | dReal dRecip(dReal x) 71 | { 72 | return 1.0/x; 73 | } 74 | 75 | dReal dRecipSqrt(dReal x) 76 | { 77 | return 1.0/sqrt(x); 78 | } 79 | 80 | dReal dFMod(dReal a, dReal b) 81 | { 82 | real c; 83 | return modf(a, c); 84 | } 85 | 86 | alias sqrt dSqrt; 87 | alias sin dSin; 88 | alias cos dCos; 89 | alias fabs dFabs; 90 | alias atan2 dAtan2; 91 | alias isnan dIsNan; 92 | alias copysign dCopySign; 93 | alias floor dFloor; 94 | alias ceil dCeil; 95 | alias nextafter dNextAfter; 96 | 97 | /* internal object types (all prefixed with `dx') */ 98 | 99 | struct dxWorld; /* dynamics world */ 100 | struct dxSpace; /* collision space */ 101 | struct dxBody; /* rigid body (dynamics object) */ 102 | struct dxGeom; /* geometry (collision object) */ 103 | struct dxJoint; 104 | struct dxJointNode; 105 | struct dxJointGroup; 106 | struct dxWorldProcessThreadingManager; 107 | 108 | alias dxWorld* dWorldID; 109 | alias dxSpace* dSpaceID; 110 | alias dxBody* dBodyID; 111 | alias dxGeom* dGeomID; 112 | alias dxJoint* dJointID; 113 | alias dxJointGroup* dJointGroupID; 114 | alias dxWorldProcessThreadingManager* dWorldStepThreadingManagerId; 115 | 116 | /* error numbers */ 117 | 118 | enum 119 | { 120 | d_ERR_UNKNOWN = 0, /* unknown error */ 121 | d_ERR_IASSERT, /* internal assertion failed */ 122 | d_ERR_UASSERT, /* user assertion failed */ 123 | d_ERR_LCP /* user assertion failed */ 124 | } 125 | 126 | 127 | /* joint type numbers */ 128 | 129 | alias int dJointType; 130 | enum 131 | { 132 | dJointTypeNone = 0, /* or "unknown" */ 133 | dJointTypeBall, 134 | dJointTypeHinge, 135 | dJointTypeSlider, 136 | dJointTypeContact, 137 | dJointTypeUniversal, 138 | dJointTypeHinge2, 139 | dJointTypeFixed, 140 | dJointTypeNull, 141 | dJointTypeAMotor, 142 | dJointTypeLMotor, 143 | dJointTypePlane2D, 144 | dJointTypePR, 145 | dJointTypePU, 146 | dJointTypePiston, 147 | } 148 | 149 | /* an alternative way of setting joint parameters, using joint parameter 150 | * structures and member constants. we don't actually do this yet. 151 | */ 152 | 153 | /* 154 | typedef struct dLimot { 155 | int mode; 156 | dReal lostop, histop; 157 | dReal vel, fmax; 158 | dReal fudge_factor; 159 | dReal bounce, soft; 160 | dReal suspension_erp, suspension_cfm; 161 | } dLimot; 162 | 163 | enum { 164 | dLimotLoStop = 0x0001, 165 | dLimotHiStop = 0x0002, 166 | dLimotVel = 0x0004, 167 | dLimotFMax = 0x0008, 168 | dLimotFudgeFactor = 0x0010, 169 | dLimotBounce = 0x0020, 170 | dLimotSoft = 0x0040 171 | }; 172 | */ 173 | 174 | /* standard joint parameter names */ 175 | 176 | enum 177 | { 178 | /* parameters for limits and motors */ 179 | dParamLoStop = 0, 180 | dParamHiStop, 181 | dParamVel, 182 | dParamFMax, 183 | dParamFudgeFactor, 184 | dParamBounce, 185 | dParamCFM, 186 | dParamStopERP, 187 | dParamStopCFM, 188 | /* parameters for suspension */ 189 | dParamSuspensionERP, 190 | dParamSuspensionCFM, 191 | dParamERP, 192 | dParamsInGroup, 193 | /* parameters for limits and motors */ 194 | dParamLoStop1 = 0x000, 195 | dParamHiStop1, 196 | dParamVel1, 197 | dParamFMax1, 198 | dParamFudgeFactor1, 199 | dParamBounce1, 200 | dParamCFM1, 201 | dParamStopERP1, 202 | dParamStopCFM1, 203 | /* parameters for suspension */ 204 | dParamSuspensionERP1, 205 | dParamSuspensionCFM1, 206 | dParamERP1, 207 | /* parameters for limits and motors */ 208 | dParamLoStop2 = 0x100, 209 | dParamHiStop2, 210 | dParamVel2, 211 | dParamFMax2, 212 | dParamFudgeFactor2, 213 | dParamBounce2, 214 | dParamCFM2, 215 | dParamStopERP2, 216 | dParamStopCFM2, 217 | /* parameters for suspension */ 218 | dParamSuspensionERP2, 219 | dParamSuspensionCFM2, 220 | dParamERP2, 221 | /* parameters for limits and motors */ 222 | dParamLoStop3 = 0x200, 223 | dParamHiStop3, 224 | dParamVel3, 225 | dParamFMax3, 226 | dParamFudgeFactor3, 227 | dParamBounce3, 228 | dParamCFM3, 229 | dParamStopERP3, 230 | dParamStopCFM3, 231 | /* parameters for suspension */ 232 | dParamSuspensionERP3, 233 | dParamSuspensionCFM3, 234 | dParamERP3, 235 | dParamGroup = 0x100 236 | } 237 | 238 | /* angular motor mode numbers */ 239 | 240 | enum 241 | { 242 | dAMotorUser = 0, 243 | dAMotorEuler = 1, 244 | } 245 | 246 | /* joint force feedback information */ 247 | 248 | struct dJointFeedback 249 | { 250 | dVector3 f1; /* force applied to body 1 */ 251 | dVector3 t1; /* torque applied to body 1 */ 252 | dVector3 f2; /* force applied to body 2 */ 253 | dVector3 t2; /* torque applied to body 2 */ 254 | } 255 | 256 | /* private functions that must be implemented by the collision library: 257 | * (1) indicate that a geom has moved, (2) get the next geom in a body list. 258 | * these functions are called whenever the position of geoms connected to a 259 | * body have changed, e.g. with dBodySetPosition(), dBodySetRotation(), or 260 | * when the ODE step function updates the body state. 261 | */ 262 | 263 | void dGeomMoved (dGeomID); 264 | dGeomID dGeomGetBodyNext (dGeomID); 265 | 266 | /** 267 | * dGetConfiguration returns the specific ODE build configuration as 268 | * a string of tokens. The string can be parsed in a similar way to 269 | * the OpenGL extension mechanism, the naming convention should be 270 | * familiar too. The following extensions are reported: 271 | * 272 | * ODE 273 | * ODE_single_precision 274 | * ODE_double_precision 275 | * ODE_EXT_no_debug 276 | * ODE_EXT_trimesh 277 | * ODE_EXT_opcode 278 | * ODE_EXT_gimpact 279 | * ODE_EXT_malloc_not_alloca 280 | * ODE_EXT_gyroscopic 281 | * ODE_OPC_16bit_indices 282 | * ODE_OPC_new_collider 283 | */ 284 | const(char)* dGetConfiguration(); 285 | 286 | /** 287 | * Helper to check for a token in the ODE configuration string. 288 | * Caution, this function is case sensitive. 289 | * 290 | * @param token A configuration token, see dGetConfiguration for details 291 | * 292 | * @return 1 if exact token is present, 0 if not present 293 | */ 294 | int dCheckConfiguration(const(char)* token); 295 | -------------------------------------------------------------------------------- /deimos/ode/contact.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.contact; 27 | 28 | private import deimos.ode.common; 29 | 30 | extern (C): 31 | nothrow: 32 | 33 | enum 34 | { 35 | dContactMu2 = 0x001, 36 | dContactFDir1 = 0x002, 37 | dContactBounce = 0x004, 38 | dContactSoftERP = 0x008, 39 | dContactSoftCFM = 0x010, 40 | dContactMotion1 = 0x020, 41 | dContactMotion2 = 0x040, 42 | dContactMotionN = 0x080, 43 | dContactSlip1 = 0x100, 44 | dContactSlip2 = 0x200, 45 | 46 | dContactApprox0 = 0x0000, 47 | dContactApprox1_1 = 0x1000, 48 | dContactApprox1_2 = 0x2000, 49 | dContactApprox1 = 0x3000 50 | } 51 | 52 | struct dSurfaceParameters 53 | { 54 | /* must always be defined */ 55 | int mode; 56 | dReal mu; 57 | 58 | /* only defined if the corresponding flag is set in mode */ 59 | dReal mu2; 60 | dReal bounce; 61 | dReal bounce_vel; 62 | dReal soft_erp; 63 | dReal soft_cfm; 64 | dReal motion1, motion2, motionN; 65 | dReal slip1, slip2; 66 | } 67 | 68 | /** 69 | * @brief Describe the contact point between two geoms. 70 | * 71 | * If two bodies touch, or if a body touches a static feature in its 72 | * environment, the contact is represented by one or more "contact 73 | * points", described by dContactGeom. 74 | * 75 | * The convention is that if body 1 is moved along the normal vector by 76 | * a distance depth (or equivalently if body 2 is moved the same distance 77 | * in the opposite direction) then the contact depth will be reduced to 78 | * zero. This means that the normal vector points "in" to body 1. 79 | * 80 | * @ingroup collide 81 | */ 82 | struct dContactGeom 83 | { 84 | dVector3 pos; ///< contact position 85 | dVector3 normal; ///< normal vector 86 | dReal depth; ///< penetration depth 87 | dGeomID g1, g2; ///< the colliding geoms 88 | int side1, side2; ///< (to be documented) 89 | } 90 | 91 | /* contact info used by contact joint */ 92 | 93 | struct dContact 94 | { 95 | dSurfaceParameters surface; 96 | dContactGeom geom; 97 | dVector3 fdir1; 98 | } 99 | -------------------------------------------------------------------------------- /deimos/ode/error.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | /* this comes from the `reuse' library. copy any changes back to the source */ 27 | 28 | module deimos.ode.error; 29 | 30 | private import deimos.ode.odeconfig; 31 | private import core.vararg; 32 | 33 | extern (C): 34 | nothrow: 35 | 36 | /* all user defined error functions have this type. error and debug functions 37 | * should not return. 38 | */ 39 | alias void function(int errnum, const(char)* msg, va_list ap) dMessageFunction; 40 | 41 | /* set a new error, debug or warning handler. if fn is 0, the default handlers 42 | * are used. 43 | */ 44 | void dSetErrorHandler(dMessageFunction fn); 45 | void dSetDebugHandler(dMessageFunction fn); 46 | void dSetMessageHandler(dMessageFunction fn); 47 | 48 | /* return the current error, debug or warning handler. if the return value is 49 | * 0, the default handlers are in place. 50 | */ 51 | dMessageFunction dGetErrorHandler(); 52 | dMessageFunction dGetDebugHandler(); 53 | dMessageFunction dGetMessageHandler(); 54 | 55 | /* generate a fatal error, debug trap or a message. */ 56 | void dError (int num, const(char)* msg, ...); 57 | void dDebug (int num, const(char)* msg, ...); 58 | void dMessage(int num, const(char)* msg, ...); 59 | -------------------------------------------------------------------------------- /deimos/ode/exportdif.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.exportdif; 27 | 28 | private import deimos.ode.common; 29 | private import core.stdc.stdio: FILE; 30 | 31 | extern (C): 32 | nothrow: 33 | 34 | void dWorldExportDIF(dWorldID w, FILE* file, const(char)* world_name); 35 | -------------------------------------------------------------------------------- /deimos/ode/mass.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.mass; 27 | 28 | private import deimos.ode.common; 29 | 30 | extern (C): 31 | nothrow: 32 | 33 | /** 34 | * Check if a mass structure has valid value. 35 | * The function check if the mass and innertia matrix are positive definits 36 | * 37 | * @param m A mass structure to check 38 | * 39 | * @return 1 if both codition are met 40 | */ 41 | int dMassCheck(in dMass *m); 42 | 43 | void dMassSetZero(dMass*); 44 | 45 | void dMassSetParameters( 46 | dMass*, dReal themass, dReal cgx, dReal cgy, dReal cgz, dReal I11, 47 | dReal I22, dReal I33, dReal I12, dReal I13, dReal I23 48 | ); 49 | 50 | void dMassSetSphere(dMass*, dReal density, dReal radius); 51 | void dMassSetSphereTotal(dMass*, dReal total_mass, dReal radius); 52 | 53 | void dMassSetCapsule( 54 | dMass*, dReal density, int direction, dReal radius, dReal length 55 | ); 56 | void dMassSetCapsuleTotal( 57 | dMass*, dReal total_mass, int direction, dReal radius, dReal length 58 | ); 59 | 60 | void dMassSetCylinder( 61 | dMass*, dReal density, int direction, dReal radius, dReal length 62 | ); 63 | void dMassSetCylinderTotal( 64 | dMass*, dReal total_mass, int direction, dReal radius, dReal length 65 | ); 66 | 67 | void dMassSetBox(dMass*, dReal density, dReal lx, dReal ly, dReal lz); 68 | void dMassSetBoxTotal(dMass*, dReal total_mass, dReal lx, dReal ly, dReal lz); 69 | 70 | void dMassSetTrimesh(dMass*, dReal density, dGeomID g); 71 | 72 | void dMassSetTrimeshTotal(dMass* m, dReal total_mass, dGeomID g); 73 | 74 | void dMassAdjust(dMass*, dReal newmass); 75 | 76 | void dMassTranslate(dMass*, dReal x, dReal y, dReal z); 77 | 78 | void dMassRotate(dMass*, in dMatrix3 R); 79 | 80 | void dMassAdd(dMass* a, in dMass* b); 81 | 82 | struct dMass 83 | { 84 | dReal mass; 85 | dVector3 c; 86 | dMatrix3 I; 87 | } 88 | -------------------------------------------------------------------------------- /deimos/ode/matrix.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | /* optimized and unoptimized vector and matrix functions */ 27 | 28 | module deimos.ode.matrix; 29 | 30 | private import deimos.ode.common; 31 | 32 | extern (C): 33 | nothrow: 34 | 35 | /* set a vector/matrix of size n to all zeros, or to a specific value. */ 36 | 37 | void dSetZero(dReal* a, int n); 38 | void dSetValue(dReal* a, int n, dReal value); 39 | 40 | 41 | /* get the dot product of two n*1 vectors. if n <= 0 then 42 | * zero will be returned (in which case a and b need not be valid). 43 | */ 44 | 45 | dReal dDot(in dReal* a, in dReal* b, int n); 46 | 47 | 48 | /* get the dot products of (a0,b), (a1,b), etc and return them in outsum. 49 | * all vectors are n*1. if n <= 0 then zeroes will be returned (in which case 50 | * the input vectors need not be valid). this function is somewhat faster 51 | * than calling dDot() for all of the combinations separately. 52 | */ 53 | 54 | /* NOT INCLUDED in the library for now. 55 | void dMultidot2 (const dReal* a0, const dReal* a1, 56 | const dReal* b, dReal* outsum, int n); 57 | */ 58 | 59 | 60 | /* matrix multiplication. all matrices are stored in standard row format. 61 | * the digit refers to the argument that is transposed: 62 | * 0: A = B * C (sizes: A:p*r B:p*q C:q*r) 63 | * 1: A = B' * C (sizes: A:p*r B:q*p C:q*r) 64 | * 2: A = B * C' (sizes: A:p*r B:p*q C:r*q) 65 | * case 1,2 are equivalent to saying that the operation is A=B*C but 66 | * B or C are stored in standard column format. 67 | */ 68 | 69 | void dMultiply0(dReal* A, in dReal* B, in dReal* C, int p, int q, int r); 70 | void dMultiply1(dReal* A, in dReal* B, in dReal* C, int p, int q, int r); 71 | void dMultiply2(dReal* A, in dReal* B, in dReal* C, int p, int q, int r); 72 | 73 | 74 | /* do an in-place cholesky decomposition on the lower triangle of the n*n 75 | * symmetric matrix A (which is stored by rows). the resulting lower triangle 76 | * will be such that L*L'=A. return 1 on success and 0 on failure (on failure 77 | * the matrix is not positive definite). 78 | */ 79 | 80 | int dFactorCholesky(dReal* A, int n); 81 | 82 | 83 | /* solve for x: L*L'*x = b, and put the result back into x. 84 | * L is size n*n, b is size n*1. only the lower triangle of L is considered. 85 | */ 86 | 87 | void dSolveCholesky(in dReal* L, dReal* b, int n); 88 | 89 | 90 | /* compute the inverse of the n*n positive definite matrix A and put it in 91 | * Ainv. this is not especially fast. this returns 1 on success (A was 92 | * positive definite) or 0 on failure (not PD). 93 | */ 94 | 95 | int dInvertPDMatrix(in dReal* A, dReal* Ainv, int n); 96 | 97 | 98 | /* check whether an n*n matrix A is positive definite, return 1/0 (yes/no). 99 | * positive definite means that x'*A*x > 0 for any x. this performs a 100 | * cholesky decomposition of A. if the decomposition fails then the matrix 101 | * is not positive definite. A is stored by rows. A is not altered. 102 | */ 103 | 104 | int dIsPositiveDefinite(in dReal* A, int n); 105 | 106 | 107 | /* factorize a matrix A into L*D*L', where L is lower triangular with ones on 108 | * the diagonal, and D is diagonal. 109 | * A is an n*n matrix stored by rows, with a leading dimension of n rounded 110 | * up to 4. L is written into the strict lower triangle of A (the ones are not 111 | * written) and the reciprocal of the diagonal elements of D are written into 112 | * d. 113 | */ 114 | void dFactorLDLT(dReal* A, dReal* d, int n, int nskip); 115 | 116 | 117 | /* solve L*x=b, where L is n*n lower triangular with ones on the diagonal, 118 | * and x,b are n*1. b is overwritten with x. 119 | * the leading dimension of L is `nskip'. 120 | */ 121 | void dSolveL1(in dReal* L, dReal* b, int n, int nskip); 122 | 123 | 124 | /* solve L'*x=b, where L is n*n lower triangular with ones on the diagonal, 125 | * and x,b are n*1. b is overwritten with x. 126 | * the leading dimension of L is `nskip'. 127 | */ 128 | void dSolveL1T(in dReal* L, dReal* b, int n, int nskip); 129 | 130 | 131 | /* in matlab syntax: a(1:n) = a(1:n) .* d(1:n) */ 132 | 133 | void dVectorScale(dReal* a, in dReal* d, int n); 134 | 135 | 136 | /* given `L', a n*n lower triangular matrix with ones on the diagonal, 137 | * and `d', a n*1 vector of the reciprocal diagonal elements of an n*n matrix 138 | * D, solve L*D*L'*x=b where x,b are n*1. x overwrites b. 139 | * the leading dimension of L is `nskip'. 140 | */ 141 | 142 | void dSolveLDLT(in dReal* L, in dReal* d, dReal* b, int n, int nskip); 143 | 144 | 145 | /* given an L*D*L' factorization of an n*n matrix A, return the updated 146 | * factorization L2*D2*L2' of A plus the following "top left" matrix: 147 | * 148 | * [ b a' ] <-- b is a[0] 149 | * [ a 0 ] <-- a is a[1..n-1] 150 | * 151 | * - L has size n*n, its leading dimension is nskip. L is lower triangular 152 | * with ones on the diagonal. only the lower triangle of L is referenced. 153 | * - d has size n. d contains the reciprocal diagonal elements of D. 154 | * - a has size n. 155 | * the result is written into L, except that the left column of L and d[0] 156 | * are not actually modified. see ldltaddTL.m for further comments. 157 | */ 158 | void dLDLTAddTL(dReal* L, dReal* d, in dReal* a, int n, int nskip); 159 | 160 | 161 | /* given an L*D*L' factorization of a permuted matrix A, produce a new 162 | * factorization for row and column `r' removed. 163 | * - A has size n1*n1, its leading dimension in nskip. A is symmetric and 164 | * positive definite. only the lower triangle of A is referenced. 165 | * A itself may actually be an array of row pointers. 166 | * - L has size n2*n2, its leading dimension in nskip. L is lower triangular 167 | * with ones on the diagonal. only the lower triangle of L is referenced. 168 | * - d has size n2. d contains the reciprocal diagonal elements of D. 169 | * - p is a permutation vector. it contains n2 indexes into A. each index 170 | * must be in the range 0..n1-1. 171 | * - r is the row/column of L to remove. 172 | * the new L will be written within the old L, i.e. will have the same leading 173 | * dimension. the last row and column of L, and the last element of d, are 174 | * undefined on exit. 175 | * 176 | * a fast O(n^2) algorithm is used. see ldltremove.m for further comments. 177 | */ 178 | void dLDLTRemove( 179 | dReal** A, in int *p, dReal* L, dReal* d, int n1, int n2, int r, int nskip 180 | ); 181 | 182 | 183 | /* given an n*n matrix A (with leading dimension nskip), remove the r'th row 184 | * and column by moving elements. the new matrix will have the same leading 185 | * dimension. the last row and column of A are untouched on exit. 186 | */ 187 | void dRemoveRowCol(dReal* A, int n, int nskip, int r); 188 | -------------------------------------------------------------------------------- /deimos/ode/memory.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | /* this comes from the `reuse' library. copy any changes back to the source */ 27 | 28 | module deimos.ode.memory; 29 | 30 | private import deimos.ode.odeconfig; 31 | 32 | extern (C): 33 | nothrow: 34 | 35 | /* function types to allocate and free memory */ 36 | alias void* function(size_t size) dAllocFunction; 37 | alias void* function(void* ptr, size_t oldsz, size_t newsz) dReallocFunction; 38 | alias void function(void* ptr, size_t size) dFreeFunction; 39 | 40 | /* set new memory management functions. if fn is 0, the default handlers are 41 | * used. */ 42 | void dSetAllocHandler(dAllocFunction fn); 43 | void dSetReallocHandler(dReallocFunction fn); 44 | void dSetFreeHandler(dFreeFunction fn); 45 | 46 | /* get current memory management functions */ 47 | dAllocFunction dGetAllocHandler(); 48 | dReallocFunction dGetReallocHandler(); 49 | dFreeFunction dGetFreeHandler(); 50 | 51 | /* allocate and free memory. */ 52 | void* dAlloc(size_t size); 53 | void* dRealloc(void* ptr, size_t oldsize, size_t newsize); 54 | void dFree (void* ptr, size_t size); 55 | -------------------------------------------------------------------------------- /deimos/ode/misc.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | /* miscellaneous math functions. these are mostly useful for testing */ 27 | 28 | module deimos.ode.misc; 29 | 30 | private import deimos.ode.common; 31 | private import core.stdc.config; 32 | private import core.stdc.stdio: FILE; 33 | 34 | extern (C): 35 | nothrow: 36 | 37 | /* return 1 if the random number generator is working. */ 38 | int dTestRand(); 39 | 40 | /* return next 32 bit random number. this uses a not-very-random linear 41 | * congruential method. 42 | */ 43 | c_ulong dRand(); 44 | 45 | /* get and set the current random number seed. */ 46 | c_ulong dRandGetSeed(); 47 | void dRandSetSeed(c_ulong s); 48 | 49 | /* return a random integer between 0..n-1. the distribution will get worse 50 | * as n approaches 2^32. 51 | */ 52 | int dRandInt(int n); 53 | 54 | /* return a random real number between 0..1 */ 55 | dReal dRandReal(); 56 | 57 | /* print out a matrix */ 58 | void dPrintMatrix(in dReal* A, int n, int m, char* fmt, FILE* f); 59 | 60 | /* make a random vector with entries between +/- range. A has n elements. */ 61 | void dMakeRandomVector(dReal* A, int n, dReal range); 62 | 63 | /* make a random matrix with entries between +/- range. A has size n*m. */ 64 | void dMakeRandomMatrix(dReal* A, int n, int m, dReal range); 65 | 66 | /* clear the upper triangle of a square matrix */ 67 | void dClearUpperTriangle(dReal* A, int n); 68 | 69 | /* return the maximum element difference between the two n*m matrices */ 70 | dReal dMaxDifference(in dReal* A, in dReal* B, int n, int m); 71 | 72 | /* return the maximum element difference between the lower triangle of two 73 | * n*n matrices */ 74 | dReal dMaxDifferenceLowerTriangle(in dReal* A, in dReal* B, int n); 75 | -------------------------------------------------------------------------------- /deimos/ode/ode.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.ode; 27 | 28 | /* include *everything* here */ 29 | 30 | public 31 | { 32 | import deimos.ode.odeconfig; 33 | import deimos.ode.common; 34 | import deimos.ode.odeinit; 35 | import deimos.ode.contact; 36 | import deimos.ode.error; 37 | import deimos.ode.memory; 38 | import deimos.ode.odemath; 39 | import deimos.ode.matrix; 40 | import deimos.ode.timer; 41 | import deimos.ode.rotation; 42 | import deimos.ode.mass; 43 | import deimos.ode.misc; 44 | import deimos.ode.objects; 45 | import deimos.ode.collision_space; 46 | import deimos.ode.collision; 47 | import deimos.ode.exportdif; 48 | } 49 | -------------------------------------------------------------------------------- /deimos/ode/odeconfig.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.odeconfig; 27 | 28 | public import core.stdc.config; 29 | 30 | alias int int32; 31 | alias uint uint32; 32 | alias short int16; 33 | alias ushort uint16; 34 | alias byte int8; 35 | alias ubyte uint8; 36 | 37 | version(dSINGLE) 38 | enum dInfinity = float.infinity; 39 | else 40 | enum dInfinity = double.infinity; 41 | -------------------------------------------------------------------------------- /deimos/ode/odeinit.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | /* Library initialization/finalization functions. */ 27 | 28 | module deimos.ode.odeinit; 29 | 30 | private import deimos.ode.common; 31 | 32 | extern (C): 33 | nothrow: 34 | 35 | /* ************************************************************************ */ 36 | /* Library initialization */ 37 | 38 | /** 39 | * @defgroup init Library Initialization 40 | * 41 | * Library initialization functions prepare ODE internal data structures for use 42 | * and release allocated resources after ODE is not needed any more. 43 | */ 44 | 45 | 46 | /** 47 | * @brief Library initialization flags. 48 | * 49 | * These flags define ODE library initialization options. 50 | * 51 | * @c dInitFlagManualThreadCleanup indicates that resources allocated in TLS for threads 52 | * using ODE are to be cleared by library client with explicit call to @c dCleanupODEAllDataForThread. 53 | * If this flag is not specified the automatic resource tracking algorithm is used. 54 | * 55 | * With automatic resource tracking, On Windows, memory allocated for a thread may 56 | * remain not freed for some time after the thread exits. The resources may be 57 | * released when one of other threads calls @c dAllocateODEDataForThread. Ultimately, 58 | * the resources are released when library is closed with @c dCloseODE. On other 59 | * operating systems resources are always released by the thread itself on its exit 60 | * or on library closure with @c dCloseODE. 61 | * 62 | * With manual thread data cleanup mode every collision space object must be 63 | * explicitly switched to manual cleanup mode with @c dSpaceSetManualCleanup 64 | * after creation. See description of the function for more details. 65 | * 66 | * If @c dInitFlagManualThreadCleanup was not specified during initialization, 67 | * calls to @c dCleanupODEAllDataForThread are not allowed. 68 | * 69 | * @see dInitODE2 70 | * @see dAllocateODEDataForThread 71 | * @see dSpaceSetManualCleanup 72 | * @see dCloseODE 73 | * @ingroup init 74 | */ 75 | enum uint dInitFlagManualThreadCleanup = 0x00000001; //@< Thread local data is to be cleared explicitly on @c dCleanupODEAllDataForThread function call 76 | 77 | /** 78 | * @brief Initializes ODE library. 79 | * 80 | * @c dInitODE is obsolete. @c dInitODE2 is to be used for library initialization. 81 | * 82 | * A call to @c dInitODE is equal to the following initialization sequence 83 | * @code 84 | * dInitODE2(0); 85 | * dAllocateODEDataForThread(dAllocateMaskAll); 86 | * @endcode 87 | * 88 | * @see dInitODE2 89 | * @see dAllocateODEDataForThread 90 | * @ingroup init 91 | */ 92 | void dInitODE(); 93 | 94 | /** 95 | * @brief Initializes ODE library. 96 | * @param uiInitFlags Initialization options bitmask 97 | * @return A nonzero if initialization succeeded and zero otherwise. 98 | * 99 | * This function must be called to initialize ODE library before first use. If 100 | * initialization succeeds the function may not be called again until library is 101 | * closed with a call to @c dCloseODE. 102 | * 103 | * The @a uiInitFlags parameter specifies initialization options to be used. These 104 | * can be combination of zero or more @c dInitODEFlags flags. 105 | * 106 | * @note 107 | * If @c dInitFlagManualThreadCleanup flag is used for initialization, 108 | * @c dSpaceSetManualCleanup must be called to set manual cleanup mode for every 109 | * space object right after creation. Failure to do so may lead to resource leaks. 110 | * 111 | * @see dInitODEFlags 112 | * @see dCloseODE 113 | * @see dSpaceSetManualCleanup 114 | * @ingroup init 115 | */ 116 | int dInitODE2(uint uiInitFlags/*=0*/); 117 | 118 | /** 119 | * @brief ODE data allocation flags. 120 | * 121 | * These flags are used to indicate which data is to be pre-allocated in call to 122 | * @c dAllocateODEDataForThread. 123 | * 124 | * @c dAllocateFlagBasicData tells to allocate the basic data set required for 125 | * normal library operation. This flag is equal to zero and is always implicitly 126 | * included. 127 | * 128 | * @c dAllocateFlagCollisionData tells that collision detection data is to be allocated. 129 | * Collision detection functions may not be called if the data has not be allocated 130 | * in advance. If collision detection is not going to be used, it is not necessary 131 | * to specify this flag. 132 | * 133 | * @c dAllocateMaskAll is a mask that can be used for for allocating all possible 134 | * data in cases when it is not known what exactly features of ODE will be used. 135 | * The mask may not be used in combination with other flags. It is guaranteed to 136 | * include all the current and future legal allocation flags. However, mature 137 | * applications should use explicit flags they need rather than allocating everything. 138 | * 139 | * @see dAllocateODEDataForThread 140 | * @ingroup init 141 | */ 142 | enum : uint 143 | { 144 | dAllocateFlagsBasicData = 0, //@< Allocate basic data required for library to operate 145 | 146 | dAllocateFlagsCollisionData = 0x00000001, //@< Allocate data for collision detection 147 | 148 | //@< Allocate all the possible data that is currently defined or will be defined in the future. 149 | dAllocateMaskAll = ~0U, 150 | } 151 | 152 | /** 153 | * @brief Allocate thread local data to allow the thread calling ODE. 154 | * @param uiAllocateFlags Allocation options bitmask. 155 | * @return A nonzero if allocation succeeded and zero otherwise. 156 | * 157 | * The function is required to be called for every thread that is going to use 158 | * ODE. This function allocates the data that is required for accessing ODE from 159 | * current thread along with optional data required for particular ODE subsystems. 160 | * 161 | * @a uiAllocateFlags parameter can contain zero or more flags from @c dAllocateODEDataFlags 162 | * enumerated type. Multiple calls with different allocation flags are allowed. 163 | * The flags that are already allocated are ignored in subsequent calls. If zero 164 | * is passed as the parameter, it means to only allocate the set of most important 165 | * data the library can not operate without. 166 | * 167 | * If the function returns failure status it means that none of the requested 168 | * data has been allocated. The client may retry allocation attempt with the same 169 | * flags when more system resources are available. 170 | * 171 | * @see dAllocateODEDataFlags 172 | * @see dCleanupODEAllDataForThread 173 | * @ingroup init 174 | */ 175 | int dAllocateODEDataForThread(uint uiAllocateFlags); 176 | 177 | /** 178 | * @brief Free thread local data that was allocated for current thread. 179 | * 180 | * If library was initialized with @c dInitFlagManualThreadCleanup flag the function 181 | * is required to be called on exit of every thread that was calling @c dAllocateODEDataForThread. 182 | * Failure to call @c dCleanupODEAllDataForThread may result in some resources remaining 183 | * not freed until program exit. The function may also be called when ODE is still 184 | * being used to release resources allocated for all the current subsystems and 185 | * possibly proceed with data pre-allocation for other subsystems. 186 | * 187 | * The function can safely be called several times in a row. The function can be 188 | * called without prior invocation of @c dAllocateODEDataForThread. The function 189 | * may not be called before ODE is initialized with @c dInitODE2 or after library 190 | * has been closed with @c dCloseODE. A call to @c dCloseODE implicitly releases 191 | * all the thread local resources that might be allocated for all the threads that 192 | * were using ODE. 193 | * 194 | * If library was initialized without @c dInitFlagManualThreadCleanup flag 195 | * @c dCleanupODEAllDataForThread must not be called. 196 | * 197 | * @see dAllocateODEDataForThread 198 | * @see dInitODE2 199 | * @see dCloseODE 200 | * @ingroup init 201 | */ 202 | void dCleanupODEAllDataForThread(); 203 | 204 | /** 205 | * @brief Close ODE after it is not needed any more. 206 | * 207 | * The function is required to be called when program does not need ODE features any more. 208 | * The call to @c dCloseODE releases all the resources allocated for library 209 | * including all the thread local data that might be allocated for all the threads 210 | * that were using ODE. 211 | * 212 | * @c dCloseODE is a paired function for @c dInitODE2 and must only be called 213 | * after successful library initialization. 214 | * 215 | * @note Important! 216 | * Make sure that all the threads that were using ODE have already terminated 217 | * before calling @c dCloseODE. In particular it is not allowed to call 218 | * @c dCleanupODEAllDataForThread after @c dCloseODE. 219 | * 220 | * @see dInitODE2 221 | * @see dCleanupODEAllDataForThread 222 | * @ingroup init 223 | */ 224 | void dCloseODE(); 225 | -------------------------------------------------------------------------------- /deimos/ode/odemath.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.odemath; 27 | 28 | private import deimos.ode.common; 29 | 30 | /* 31 | * macro to access elements i,j in an NxM matrix A, independent of the 32 | * matrix storage convention. 33 | */ 34 | auto dACCESS33(T)(T a, size_t i, size_t j) 35 | { 36 | return a[i * 4 + j]; 37 | } 38 | 39 | /* 40 | * Macro to test for valid floating point values 41 | */ 42 | bool dVALIDVEC3(T)(T v) 43 | { 44 | return !(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2])); 45 | } 46 | 47 | bool dVALIDVEC4(T)(T v) 48 | { 49 | return !(dIsNan(v[0]) || dIsNan(v[1]) || dIsNan(v[2]) || dIsNan(v[3])); 50 | } 51 | 52 | bool dVALIDMAT3(T)(T m) 53 | { 54 | return !( 55 | dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || 56 | dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || 57 | dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) 58 | ); 59 | } 60 | 61 | bool dVALIDMAT4(T)(T m) 62 | { 63 | return !( 64 | dIsNan(m[0]) || dIsNan(m[1]) || dIsNan(m[2]) || dIsNan(m[3]) || 65 | dIsNan(m[4]) || dIsNan(m[5]) || dIsNan(m[6]) || dIsNan(m[7]) || 66 | dIsNan(m[8]) || dIsNan(m[9]) || dIsNan(m[10]) || dIsNan(m[11]) || 67 | dIsNan(m[12]) || dIsNan(m[13]) || dIsNan(m[14]) || dIsNan(m[15]) 68 | ); 69 | } 70 | 71 | // Some vector math 72 | void dAddVectors3(dReal* res, in dReal* a, in dReal* b) 73 | { 74 | dReal res_0, res_1, res_2; 75 | res_0 = a[0] + b[0]; 76 | res_1 = a[1] + b[1]; 77 | res_2 = a[2] + b[2]; 78 | 79 | // Only assign after all the calculations are over to avoid incurring memory aliasing 80 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 81 | } 82 | 83 | 84 | void dSubtractVectors3(dReal* res, in dReal* a, in dReal* b) 85 | { 86 | dReal res_0, res_1, res_2; 87 | res_0 = a[0] - b[0]; 88 | res_1 = a[1] - b[1]; 89 | res_2 = a[2] - b[2]; 90 | 91 | // Only assign after all the calculations are over to avoid incurring memory aliasing 92 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 93 | } 94 | 95 | void dAddScaledVectors3(dReal* res, in dReal* a, in dReal* b, dReal a_scale, dReal b_scale) 96 | { 97 | dReal res_0, res_1, res_2; 98 | res_0 = a_scale * a[0] + b_scale * b[0]; 99 | res_1 = a_scale * a[1] + b_scale * b[1]; 100 | res_2 = a_scale * a[2] + b_scale * b[2]; 101 | 102 | // Only assign after all the calculations are over to avoid incurring memory aliasing 103 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 104 | } 105 | 106 | void dScaleVector3(dReal* res, dReal nScale) 107 | { 108 | res[0] *= nScale; 109 | res[1] *= nScale; 110 | res[2] *= nScale; 111 | } 112 | 113 | void dNegateVector3(dReal* res) 114 | { 115 | res[0] = -res[0]; 116 | res[1] = -res[1]; 117 | res[2] = -res[2]; 118 | } 119 | 120 | void dCopyVector3(dReal* res, in dReal* a) 121 | { 122 | dReal res_0, res_1, res_2; 123 | res_0 = a[0]; 124 | res_1 = a[1]; 125 | res_2 = a[2]; 126 | 127 | // Only assign after all the calculations are over to avoid incurring memory aliasing 128 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 129 | } 130 | 131 | void dCopyScaledVector3(dReal* res, in dReal* a, dReal nScale) 132 | { 133 | dReal res_0, res_1, res_2; 134 | res_0 = a[0] * nScale; 135 | res_1 = a[1] * nScale; 136 | res_2 = a[2] * nScale; 137 | 138 | // Only assign after all the calculations are over to avoid incurring memory aliasing 139 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 140 | } 141 | 142 | void dCopyNegatedVector3(dReal* res, in dReal* a) 143 | { 144 | dReal res_0, res_1, res_2; 145 | res_0 = -a[0]; 146 | res_1 = -a[1]; 147 | res_2 = -a[2]; 148 | 149 | // Only assign after all the calculations are over to avoid incurring memory aliasing 150 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 151 | } 152 | 153 | void dCopyVector4(dReal* res, in dReal* a) 154 | { 155 | dReal res_0, res_1, res_2, res_3; 156 | res_0 = a[0]; 157 | res_1 = a[1]; 158 | res_2 = a[2]; 159 | res_3 = a[3]; 160 | 161 | // Only assign after all the calculations are over to avoid incurring memory aliasing 162 | res[0] = res_0; res[1] = res_1; res[2] = res_2; res[3] = res_3; 163 | } 164 | 165 | void dCopyMatrix4x4(dReal* res, in dReal* a) 166 | { 167 | dCopyVector4(res + 0, a + 0); 168 | dCopyVector4(res + 4, a + 4); 169 | dCopyVector4(res + 8, a + 8); 170 | } 171 | 172 | void dCopyMatrix4x3(dReal* res, in dReal* a) 173 | { 174 | dCopyVector3(res + 0, a + 0); 175 | dCopyVector3(res + 4, a + 4); 176 | dCopyVector3(res + 8, a + 8); 177 | } 178 | 179 | void dGetMatrixColumn3(dReal* res, in dReal* a, uint n) 180 | { 181 | dReal res_0, res_1, res_2; 182 | res_0 = a[n + 0]; 183 | res_1 = a[n + 4]; 184 | res_2 = a[n + 8]; 185 | 186 | // Only assign after all the calculations are over to avoid incurring memory aliasing 187 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 188 | } 189 | 190 | dReal dCalcVectorLength3(in dReal* a) 191 | { 192 | return dSqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); 193 | } 194 | 195 | dReal dCalcVectorLengthSquare3(in dReal* a) 196 | { 197 | return (a[0] * a[0] + a[1] * a[1] + a[2] * a[2]); 198 | } 199 | 200 | dReal dCalcPointDepth3(in dReal* test_p, in dReal* plane_p, in dReal* plane_n) 201 | { 202 | 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]; 203 | } 204 | 205 | /* 206 | * 3-way dot product. _dCalcVectorDot3 means that elements of `a' and `b' are spaced 207 | * step_a and step_b indexes apart respectively. dCalcVectorDot3() means dDot311. 208 | */ 209 | dReal _dCalcVectorDot3(in dReal* a, in dReal* b, uint step_a, uint step_b) 210 | { 211 | return a[0] * b[0] + a[step_a] * b[step_b] + a[2 * step_a] * b[2 * step_b]; 212 | } 213 | 214 | dReal dCalcVectorDot3 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,1,1); } 215 | dReal dCalcVectorDot3_13 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,1,3); } 216 | dReal dCalcVectorDot3_31 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,3,1); } 217 | dReal dCalcVectorDot3_33 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,3,3); } 218 | dReal dCalcVectorDot3_14 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,1,4); } 219 | dReal dCalcVectorDot3_41 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,4,1); } 220 | dReal dCalcVectorDot3_44 (in dReal* a, in dReal* b) { return _dCalcVectorDot3(a,b,4,4); } 221 | 222 | /* 223 | * cross product, set res = a x b. _dCalcVectorCross3 means that elements of `res', `a' 224 | * and `b' are spaced step_res, step_a and step_b indexes apart respectively. 225 | * dCalcVectorCross3() means dCross3111. 226 | */ 227 | void _dCalcVectorCross3(dReal* res, in dReal* a, in dReal* b, uint step_res, uint step_a, uint step_b) 228 | { 229 | dReal res_0, res_1, res_2; 230 | res_0 = a[ step_a]*b[2*step_b] - a[2*step_a]*b[ step_b]; 231 | res_1 = a[2*step_a]*b[ 0] - a[ 0]*b[2*step_b]; 232 | res_2 = a[ 0]*b[ step_b] - a[ step_a]*b[ 0]; 233 | 234 | res[ 0] = res_0; 235 | res[ step_res] = res_1; 236 | res[2*step_res] = res_2; 237 | } 238 | 239 | void dCalcVectorCross3 (dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 1, 1, 1); } 240 | void dCalcVectorCross3_114(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 1, 1, 4); } 241 | void dCalcVectorCross3_141(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 1, 4, 1); } 242 | void dCalcVectorCross3_144(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 1, 4, 4); } 243 | void dCalcVectorCross3_411(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 4, 1, 1); } 244 | void dCalcVectorCross3_414(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 4, 1, 4); } 245 | void dCalcVectorCross3_441(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 4, 4, 1); } 246 | void dCalcVectorCross3_444(dReal* res, in dReal* a, in dReal* b) { _dCalcVectorCross3(res, a, b, 4, 4, 4); } 247 | 248 | void dAddVectorCross3(dReal* res, in dReal* a, in dReal* b) 249 | { 250 | dReal tmp[3]; 251 | dCalcVectorCross3(tmp.ptr, a, b); 252 | dAddVectors3(res, res, tmp.ptr); 253 | } 254 | 255 | void dSubtractVectorCross3(dReal* res, in dReal* a, in dReal* b) 256 | { 257 | dReal tmp[3]; 258 | dCalcVectorCross3(tmp.ptr, a, b); 259 | dSubtractVectors3(res, res, tmp.ptr); 260 | } 261 | 262 | /* 263 | * set a 3x3 submatrix of A to a matrix such that submatrix(A)*b = a x b. 264 | * A is stored by rows, and has `skip' elements per row. the matrix is 265 | * assumed to be already zero, so this does not write zero elements! 266 | * if (plus,minus) is (+,-) then a positive version will be written. 267 | * if (plus,minus) is (-,+) then a negative version will be written. 268 | */ 269 | void dSetCrossMatrixPlus(dReal* res, in dReal* a, uint skip) 270 | { 271 | const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2]; 272 | res[1] = -a_2; 273 | res[2] = +a_1; 274 | res[skip+0] = +a_2; 275 | res[skip+2] = -a_0; 276 | res[2*skip+0] = -a_1; 277 | res[2*skip+1] = +a_0; 278 | } 279 | 280 | void dSetCrossMatrixMinus(dReal* res, in dReal* a, uint skip) 281 | { 282 | const dReal a_0 = a[0], a_1 = a[1], a_2 = a[2]; 283 | res[1] = +a_2; 284 | res[2] = -a_1; 285 | res[skip+0] = -a_2; 286 | res[skip+2] = +a_0; 287 | res[2*skip+0] = +a_1; 288 | res[2*skip+1] = -a_0; 289 | } 290 | 291 | /* 292 | * compute the distance between two 3D-vectors 293 | */ 294 | dReal dCalcPointsDistance3(in dReal* a, in dReal* b) 295 | { 296 | dReal res; 297 | dReal tmp[3]; 298 | dSubtractVectors3(tmp.ptr, a, b); 299 | res = dCalcVectorLength3(tmp.ptr); 300 | return res; 301 | } 302 | 303 | /* 304 | * special case matrix multiplication, with operator selection 305 | */ 306 | void dMultiplyHelper0_331(dReal* res, in dReal* a, in dReal* b) 307 | { 308 | dReal res_0, res_1, res_2; 309 | res_0 = dCalcVectorDot3(a, b); 310 | res_1 = dCalcVectorDot3(a + 4, b); 311 | res_2 = dCalcVectorDot3(a + 8, b); 312 | 313 | // Only assign after all the calculations are over to avoid incurring memory aliasing 314 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 315 | } 316 | 317 | void dMultiplyHelper1_331(dReal* res, in dReal* a, in dReal* b) 318 | { 319 | dReal res_0, res_1, res_2; 320 | res_0 = dCalcVectorDot3_41(a, b); 321 | res_1 = dCalcVectorDot3_41(a + 1, b); 322 | res_2 = dCalcVectorDot3_41(a + 2, b); 323 | 324 | // Only assign after all the calculations are over to avoid incurring memory aliasing 325 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 326 | } 327 | 328 | void dMultiplyHelper0_133(dReal* res, in dReal* a, in dReal* b) 329 | { 330 | dMultiplyHelper1_331(res, b, a); 331 | } 332 | 333 | void dMultiplyHelper1_133(dReal* res, in dReal* a, in dReal* b) 334 | { 335 | dReal res_0, res_1, res_2; 336 | res_0 = dCalcVectorDot3_44(a, b); 337 | res_1 = dCalcVectorDot3_44(a + 1, b); 338 | res_2 = dCalcVectorDot3_44(a + 2, b); 339 | 340 | // Only assign after all the calculations are over to avoid incurring memory aliasing 341 | res[0] = res_0; res[1] = res_1; res[2] = res_2; 342 | } 343 | 344 | /* 345 | Note: NEVER call any of these functions/macros with the same variable for A and C, 346 | it is not equivalent to A*=B. 347 | */ 348 | void dMultiply0_331(dReal* res, in dReal* a, in dReal* b) 349 | { 350 | dMultiplyHelper0_331(res, a, b); 351 | } 352 | 353 | void dMultiply1_331(dReal* res, in dReal* a, in dReal* b) 354 | { 355 | dMultiplyHelper1_331(res, a, b); 356 | } 357 | 358 | void dMultiply0_133(dReal* res, in dReal* a, in dReal* b) 359 | { 360 | dMultiplyHelper0_133(res, a, b); 361 | } 362 | 363 | void dMultiply0_333(dReal* res, in dReal* a, in dReal* b) 364 | { 365 | dMultiplyHelper0_133(res + 0, a + 0, b); 366 | dMultiplyHelper0_133(res + 4, a + 4, b); 367 | dMultiplyHelper0_133(res + 8, a + 8, b); 368 | } 369 | 370 | void dMultiply1_333(dReal* res, in dReal* a, in dReal* b) 371 | { 372 | dMultiplyHelper1_133(res + 0, b, a + 0); 373 | dMultiplyHelper1_133(res + 4, b, a + 1); 374 | dMultiplyHelper1_133(res + 8, b, a + 2); 375 | } 376 | 377 | void dMultiply2_333(dReal* res, in dReal* a, in dReal* b) 378 | { 379 | dMultiplyHelper0_331(res + 0, b, a + 0); 380 | dMultiplyHelper0_331(res + 4, b, a + 4); 381 | dMultiplyHelper0_331(res + 8, b, a + 8); 382 | } 383 | 384 | void dMultiplyAdd0_331(dReal* res, in dReal* a, in dReal* b) 385 | { 386 | dReal tmp[3]; 387 | dMultiplyHelper0_331(tmp.ptr, a, b); 388 | dAddVectors3(res, res, tmp.ptr); 389 | } 390 | 391 | void dMultiplyAdd1_331(dReal* res, in dReal* a, in dReal* b) 392 | { 393 | dReal tmp[3]; 394 | dMultiplyHelper1_331(tmp.ptr, a, b); 395 | dAddVectors3(res, res, tmp.ptr); 396 | } 397 | 398 | void dMultiplyAdd0_133(dReal* res, in dReal* a, in dReal* b) 399 | { 400 | dReal tmp[3]; 401 | dMultiplyHelper0_133(tmp.ptr, a, b); 402 | dAddVectors3(res, res, tmp.ptr); 403 | } 404 | 405 | void dMultiplyAdd0_333(dReal* res, in dReal* a, in dReal* b) 406 | { 407 | dReal tmp[3]; 408 | dMultiplyHelper0_133(tmp.ptr, a + 0, b); 409 | dAddVectors3(res+ 0, res + 0, tmp.ptr); 410 | dMultiplyHelper0_133(tmp.ptr, a + 4, b); 411 | dAddVectors3(res + 4, res + 4, tmp.ptr); 412 | dMultiplyHelper0_133(tmp.ptr, a + 8, b); 413 | dAddVectors3(res + 8, res + 8, tmp.ptr); 414 | } 415 | 416 | void dMultiplyAdd1_333(dReal* res, in dReal* a, in dReal* b) 417 | { 418 | dReal tmp[3]; 419 | dMultiplyHelper1_133(tmp.ptr, b, a + 0); 420 | dAddVectors3(res + 0, res + 0, tmp.ptr); 421 | dMultiplyHelper1_133(tmp.ptr, b, a + 1); 422 | dAddVectors3(res + 4, res + 4, tmp.ptr); 423 | dMultiplyHelper1_133(tmp.ptr, b, a + 2); 424 | dAddVectors3(res + 8, res + 8, tmp.ptr); 425 | } 426 | 427 | void dMultiplyAdd2_333(dReal* res, in dReal* a, in dReal* b) 428 | { 429 | dReal tmp[3]; 430 | dMultiplyHelper0_331(tmp.ptr, b, a + 0); 431 | dAddVectors3(res + 0, res + 0, tmp.ptr); 432 | dMultiplyHelper0_331(tmp.ptr, b, a + 4); 433 | dAddVectors3(res + 4, res + 4, tmp.ptr); 434 | dMultiplyHelper0_331(tmp.ptr, b, a + 8); 435 | dAddVectors3(res + 8, res + 8, tmp.ptr); 436 | } 437 | 438 | extern (C): 439 | nothrow: 440 | 441 | /* 442 | * normalize 3x1 and 4x1 vectors (i.e. scale them to unit length) 443 | */ 444 | 445 | // For DLL export 446 | int dSafeNormalize3(dVector3 a); 447 | int dSafeNormalize4(dVector4 a); 448 | void dNormalize3(dVector3 a); // Potentially asserts on zero vec 449 | void dNormalize4(dVector4 a); // Potentially asserts on zero vec 450 | 451 | /* 452 | * given a unit length "normal" vector n, generate vectors p and q vectors 453 | * that are an orthonormal basis for the plane space perpendicular to n. 454 | * i.e. this makes p,q such that n,p,q are all perpendicular to each other. 455 | * q will equal n x p. if n is not unit length then p will be unit length but 456 | * q wont be. 457 | */ 458 | 459 | void dPlaneSpace(in dVector3 n, dVector3 p, dVector3 q); 460 | /* Makes sure the matrix is a proper rotation */ 461 | void dOrthogonalizeR(dMatrix3 m); 462 | -------------------------------------------------------------------------------- /deimos/ode/rotation.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.rotation; 27 | 28 | private import deimos.ode.common; 29 | private import core.stdc.stdio: FILE; 30 | 31 | extern (C): 32 | nothrow: 33 | 34 | void dRSetIdentity(dMatrix3 R); 35 | 36 | void dRFromAxisAndAngle(dMatrix3 R, dReal ax, dReal ay, dReal az, dReal angle); 37 | 38 | void dRFromEulerAngles(dMatrix3 R, dReal phi, dReal theta, dReal psi); 39 | 40 | void dRFrom2Axes(dMatrix3 R, dReal ax, dReal ay, dReal az, dReal bx, dReal by, dReal bz); 41 | 42 | void dRFromZAxis(dMatrix3 R, dReal ax, dReal ay, dReal az); 43 | 44 | void dQSetIdentity(dQuaternion q); 45 | 46 | void dQFromAxisAndAngle(dQuaternion q, dReal ax, dReal ay, dReal az, dReal angle); 47 | 48 | /* Quaternion multiplication, analogous to the matrix multiplication routines. */ 49 | /* qa = rotate by qc, then qb */ 50 | void dQMultiply0(dQuaternion qa, in dQuaternion qb, in dQuaternion qc); 51 | /* qa = rotate by qc, then by inverse of qb */ 52 | void dQMultiply1(dQuaternion qa, in dQuaternion qb, in dQuaternion qc); 53 | /* qa = rotate by inverse of qc, then by qb */ 54 | void dQMultiply2(dQuaternion qa, in dQuaternion qb, in dQuaternion qc); 55 | /* qa = rotate by inverse of qc, then by inverse of qb */ 56 | void dQMultiply3(dQuaternion qa, in dQuaternion qb, in dQuaternion qc); 57 | 58 | void dRfromQ(dMatrix3 R, in dQuaternion q); 59 | void dQfromR(dQuaternion q, in dMatrix3 R); 60 | void dDQfromW(ref dReal[4] dq, in dVector3 w, in dQuaternion q); 61 | -------------------------------------------------------------------------------- /deimos/ode/timer.d: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * D bindings for ODE * 3 | * * 4 | * C header port by Daniel "q66" Kolesa * 5 | * * 6 | * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith. * 7 | * All rights reserved. Email: russ@q12.org Web: www.q12.org * 8 | * * 9 | * This library is free software; you can redistribute it and/or * 10 | * modify it under the terms of EITHER: * 11 | * (1) The GNU Lesser General Public License as published by the Free * 12 | * Software Foundation; either version 2.1 of the License, or (at * 13 | * your option) any later version. The text of the GNU Lesser * 14 | * General Public License is included with this library in the * 15 | * file LICENSE.TXT. * 16 | * (2) The BSD-style license that is included with this library in * 17 | * the file LICENSE-BSD.TXT. * 18 | * * 19 | * This library is distributed in the hope that it will be useful, * 20 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * 21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files * 22 | * LICENSE.TXT and LICENSE-BSD.TXT for more details. * 23 | * * 24 | *************************************************************************/ 25 | 26 | module deimos.ode.timer; 27 | 28 | private import deimos.ode.odeconfig; 29 | private import core.stdc.stdio: FILE; 30 | 31 | extern (C): 32 | nothrow: 33 | 34 | /* stop watch objects */ 35 | 36 | struct dStopwatch 37 | { 38 | double time; 39 | c_ulong cc[2]; 40 | } 41 | 42 | void dStopwatchReset (dStopwatch*); 43 | void dStopwatchStart (dStopwatch*); 44 | void dStopwatchStop (dStopwatch*); 45 | double dStopwatchTime(dStopwatch*); /* returns total time in secs */ 46 | 47 | 48 | /* code timers */ 49 | 50 | void dTimerStart(const(char)* description); /* pass a static string here */ 51 | void dTimerNow (const(char)* description); /* pass a static string here */ 52 | void dTimerEnd(); 53 | 54 | /* print out a timer report. if `average' is nonzero, print out the average 55 | * time for each slot (this is only meaningful if the same start-now-end 56 | * calls are being made repeatedly. 57 | */ 58 | void dTimerReport(FILE* fout, int average); 59 | 60 | 61 | /* resolution */ 62 | 63 | /* returns the timer ticks per second implied by the timing hardware or API. 64 | * the actual timer resolution may not be this great. 65 | */ 66 | double dTimerTicksPerSecond(); 67 | 68 | /* returns an estimate of the actual timer resolution, in seconds. this may 69 | * be greater than 1/ticks_per_second. 70 | */ 71 | double dTimerResolution(); 72 | --------------------------------------------------------------------------------