1# libccd [![Build Status](https://travis-ci.org/danfis/libccd.svg?branch=master)](https://travis-ci.org/danfis/libccd) 2 3***libccd*** is library for a collision detection between two convex shapes. 4libccd implements variation on Gilbert–Johnson–Keerthi algorithm plus Expand 5Polytope Algorithm (EPA) and also implements algorithm Minkowski Portal 6Refinement (MPR, a.k.a. XenoCollide) as described in Game Programming Gems 7. 7 8libccd is the only available open source library of my knowledge that include 9MPR algorithm working in 3-D space. However, there is a library called 10[mpr2d](http://code.google.com/p/mpr2d/), implemented in D programming 11language, that works in 2-D space. 12 13libccd is currently part of: 14 151. [ODE](http://www.ode.org/) library (see ODE's *./configure --help* how to enable it), 162. [FCL](http://www.ros.org/wiki/fcl) library from [Willow Garage](http://www.willowgarage.com/), 173. [Bullet3](http://bulletphysics.org/) library (https://github.com/bulletphysics/bullet3). 18 19For implementation details on GJK algorithm, see 20http://www.win.tue.nl/~gino/solid/jgt98convex.pdf. 21 22 23## Dependencies 24 25This library is currently based only on standard libraries. 26The only exception are testsuites that are built on top of CU 27(https://github.com/danfis/cu) library licensed under LGPL, however only 28testing depends on it and libccd library itself can be distributed without it. 29 30 31## License 32 33libccd is licensed under OSI-approved 3-clause BSD License, text of license 34is distributed along with source code in BSD-LICENSE file. 35Each file should include license notice, the rest should be considered as 36licensed under 3-clause BSD License. 37 38 39## Compile And Install 40 41libccd contains several mechanisms for compiling and installing. Using a simple Makefile, using autotools, and using CMake. 42 43### 1. Using Makefile 44 45Directory src/ contains Makefile that should contain everything needed for compilation and installation: 46```sh 47 $ cd src/ 48 $ make 49 $ make install 50``` 51 52Library libccd is by default compiled in double precision of floating point numbers - you can change this by options *USE_SINGLE/USE_DOUBLE*, i.e.: 53```sh 54 $ make USE_SINGLE=yes 55``` 56will compile library in single precision. 57 58Installation directory can be changed by options PREFIX, INCLUDEDIR and LIBDIR. 59For more info type 'make help'. 60 61### 2. Using Autotools 62 63libccd also contains support for autotools: 64Generate configure script etc.: 65```sh 66 $ ./bootstrap 67``` 68 69Create new build/ directory: 70```sh 71 $ mkdir build && cd build 72``` 73 74Run configure script: 75```sh 76 $ ../configure 77``` 78 79Run make and make install: 80```sh 81 $ make && make install 82``` 83 84configure script can change the way libccd is compiled and installed, most significant option is *--enable-double-precision* which enables double precision (single is default in this case). 85 86### 3. Using CMake 87 88To build using `make`: 89```sh 90 $ mkdir build && cd build 91 $ cmake -G "Unix Makefiles" .. 92 $ make && make install 93``` 94 95To build using `ninja`: 96```sh 97 $ mkdir build && cd build 98 $ cmake -G Ninja .. 99 $ ninja && ninja install 100``` 101 102Other build tools may be using by specifying a different generator. For example: 103```sh 104 $ cmake -G Xcode .. 105``` 106 107```bat 108 > cmake -G "Visual Studio 14 2015" .. 109``` 110 111To compile using double precision, set the `ENABLE_DOUBLE_PRECISION` option: 112```sh 113 $ mkdir build && cd build 114 $ cmake -G "Unix Makefiles" -DENABLE_DOUBLE_PRECISION=ON .. 115 $ make && make install 116``` 117 118To build libccd as a shared library, set the `BUILD_SHARED_LIBS` option: 119```sh 120 $ mkdir build && cd build 121 $ cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=ON .. 122 $ make && make install 123``` 124 125To build the test suite, set the `BUILD_TESTING` option: 126```sh 127 $ mkdir build && cd build 128 $ cmake -G "Unix Makefiles" -DBUILD_TESTING=ON .. 129 $ make && make test 130``` 131 132The installation directory may be changed using the `CMAKE_INSTALL_PREFIX` variable: 133```sh 134 $ mkdir build && cd build 135 $ cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/path/to/install .. 136 $ make && make install 137``` 138 139## GJK - Intersection Test 140 141This section describes how to use libccd for testing if two convex objects intersects (i.e., 'yes/no' test) using Gilbert-Johnson-Keerthi (GJK) algorithm. 142 143Procedure is very simple (and is similar for usages of library): 144 1451. Include *<ccd/ccd.h>* file. 1462. Implement support function for specific shapes. Support function is function that returns furthest point from object (shape) in specified direction. 1473. Set up *ccd_t* structure. 1484. Run ccdGJKIntersect() function on desired objects. 149 150Here is skeleton of simple program: 151```cpp 152 #include <ccd/ccd.h> 153 #include <ccd/quat.h> // for work with quaternions 154 155 /** Support function for box */ 156 void support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec) 157 { 158 // assume that obj_t is user-defined structure that holds info about 159 // object (in this case box: x, y, z, pos, quat - dimensions of box, 160 // position and rotation) 161 obj_t *obj = (obj_t *)_obj; 162 ccd_vec3_t dir; 163 ccd_quat_t qinv; 164 165 // apply rotation on direction vector 166 ccdVec3Copy(&dir, _dir); 167 ccdQuatInvert2(&qinv, &obj->quat); 168 ccdQuatRotVec(&dir, &qinv); 169 170 // compute support point in specified direction 171 ccdVec3Set(v, ccdSign(ccdVec3X(&dir)) * box->x * CCD_REAL(0.5), 172 ccdSign(ccdVec3Y(&dir)) * box->y * CCD_REAL(0.5), 173 ccdSign(ccdVec3Z(&dir)) * box->z * CCD_REAL(0.5)); 174 175 // transform support point according to position and rotation of object 176 ccdQuatRotVec(v, &obj->quat); 177 ccdVec3Add(v, &obj->pos); 178 } 179 180 int main(int argc, char *argv[]) 181 { 182 ... 183 184 ccd_t ccd; 185 CCD_INIT(&ccd); // initialize ccd_t struct 186 187 // set up ccd_t struct 188 ccd.support1 = support; // support function for first object 189 ccd.support2 = support; // support function for second object 190 ccd.max_iterations = 100; // maximal number of iterations 191 192 int intersect = ccdGJKIntersect(obj1, obj2, &ccd); 193 // now intersect holds true if obj1 and obj2 intersect, false otherwise 194 } 195``` 196 197## GJK + EPA - Penetration Of Two Objects 198 199If you want to obtain also penetration info about two intersection objects ccdGJKPenetration() function can be used. 200 201Procedure is almost same as for previous case: 202```cpp 203 #include <ccd/ccd.h> 204 #include <ccd/quat.h> // for work with quaternions 205 206 /** Support function is same as in previous case */ 207 208 int main(int argc, char *argv[]) 209 { 210 ... 211 ccd_t ccd; 212 CCD_INIT(&ccd); // initialize ccd_t struct 213 214 // set up ccd_t struct 215 ccd.support1 = support; // support function for first object 216 ccd.support2 = support; // support function for second object 217 ccd.max_iterations = 100; // maximal number of iterations 218 ccd.epa_tolerance = 0.0001; // maximal tolerance fro EPA part 219 220 ccd_real_t depth; 221 ccd_vec3_t dir, pos; 222 int intersect = ccdGJKPenetration(obj1, obj2, &ccd, &depth, &dir, &pos); 223 // now intersect holds 0 if obj1 and obj2 intersect, -1 otherwise 224 // in depth, dir and pos is stored penetration depth, direction of 225 // separation vector and position in global coordinate system 226 } 227``` 228 229## MPR - Intersection Test 230 231libccd also provides MPR - Minkowski Portal Refinement algorithm that can be used for testing if two objects intersects. 232 233Procedure is similar to the one used for GJK algorithm. Support function is same but also function that returns center (or any point near center) of given object must be implemented: 234```cpp 235 #include <ccd/ccd.h> 236 #include <ccd/quat.h> // for work with quaternions 237 238 /** Support function is same as in previous case */ 239 240 /** Center function - returns center of object */ 241 void center(const void *_obj, ccd_vec3_t *center) 242 { 243 obj_t *obj = (obj_t *)_obj; 244 ccdVec3Copy(center, &obj->pos); 245 } 246 247 int main(int argc, char *argv[]) 248 { 249 ... 250 ccd_t ccd; 251 CCD_INIT(&ccd); // initialize ccd_t struct 252 253 // set up ccd_t struct 254 ccd.support1 = support; // support function for first object 255 ccd.support2 = support; // support function for second object 256 ccd.center1 = center; // center function for first object 257 ccd.center2 = center; // center function for second object 258 ccd.mpr_tolerance = 0.0001; // maximal tolerance 259 260 int intersect = ccdMPRIntersect(obj1, obj2, &ccd); 261 // now intersect holds true if obj1 and obj2 intersect, false otherwise 262 } 263``` 264 265 266## MPR - Penetration Of Two Objects 267 268Using MPR algorithm for obtaining penetration info about two intersection objects is equally easy as in previous case instead ccdMPRPenetration() function is used: 269```cpp 270 #include <ccd/ccd.h> 271 #include <ccd/quat.h> // for work with quaternions 272 273 /** Support function is same as in previous case */ 274 /** Center function is same as in prevous case */ 275 276 int main(int argc, char *argv[]) 277 { 278 ... 279 ccd_t ccd; 280 CCD_INIT(&ccd); // initialize ccd_t struct 281 282 // set up ccd_t struct 283 ccd.support1 = support; // support function for first object 284 ccd.support2 = support; // support function for second object 285 ccd.center1 = center; // center function for first object 286 ccd.center2 = center; // center function for second object 287 ccd.mpr_tolerance = 0.0001; // maximal tolerance 288 289 ccd_real_t depth; 290 ccd_vec3_t dir, pos; 291 int intersect = ccdMPRPenetration(obj1, obj2, &ccd, &depth, &dir, &pos); 292 // now intersect holds 0 if obj1 and obj2 intersect, -1 otherwise 293 // in depth, dir and pos is stored penetration depth, direction of 294 // separation vector and position in global coordinate system 295 } 296``` 297