libccd

repository·master·Indexed 20 days ago

https://github.com/danfis/libccd

A C library for collision detection between two convex shapes. It implements the Gilbert-Johnson-Keerthi (GJK) algorithm with the Expand Polytope Algorithm (EPA) and the Minkowski Portal Refinement (MPR) algorithm for intersection testing and penetration depth, direction, and position calculations.

Tokens
4.2K
Snippets
17
Records
17
Agent score
69%

What's inside libccd

  1. How MPR intersection and penetration testing works

    master

    The Minkowski Portal Refinement (MPR) algorithm can be used for both intersection testing and penetration information.

    Unlike GJK, MPR requires two additional functions for each object:

    1. A support function (same as GJK).
    2. A center function that returns the center (or any point near the center) of the object.

    To use MPR:

    • For intersection only: Use ccdMPRIntersect().
    • For penetration info: Use ccdMPRPenetration().
    • Set ccd.mpr_tolerance in the ccd_t structure.
    #include <ccd/ccd.h>
    
    // Support function
    void support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec) { /* ... */ }
    
    // Center function
    void center(const void *_obj, ccd_vec3_t *center) {
        obj_t *obj = (obj_t *)_obj;
        ccdVec3Copy(center, &obj->pos);
    }
    
    int main() {
        ccd_t ccd;
        CCD_INIT(&ccd);
        ccd.support1 = support;
        ccd.support2 = support;
        ccd.center1 = center;
        ccd.center2 = center;
        ccd.mpr_tolerance = 0.0001;
    
        // Intersection test
        int intersect = ccdMPRIntersect(obj1, obj2, &ccd);
    
        // Penetration test
        ccd_real_t depth;
        ccd_vec3_t dir, pos;
        int res = ccdMPRPenetration(obj1, obj2, &ccd, &depth, &dir, &pos);
    }
  2. How GJK + EPA penetration testing works

    master

    If you need to know the details of an intersection (penetration depth, direction, and position), use the GJK + Expand Polytope Algorithm (EPA) via ccdGJKPenetration().

    This requires the same setup as GJK, but you should also set ccd.epa_tolerance to define the maximal tolerance for the EPA phase.

    #include <ccd/ccd.h>
    
    int main() {
        ccd_t ccd;
        CCD_INIT(&ccd);
        ccd.support1 = support;
        ccd.support2 = support;
        ccd.max_iterations = 100;
        ccd.epa_tolerance = 0.0001;
    
        ccd_real_t depth;
        ccd_vec3_t dir, pos;
        // Returns 0 if objects intersect, -1 otherwise
        int intersect = ccdGJKPenetration(obj1, obj2, &ccd, &depth, &dir, &pos);
        // depth: penetration depth
        // dir: direction of separation vector
        // pos: position in global coordinate system
    }
  3. How GJK intersection testing works

    master

    The Gilbert-Johnson-Keerthi (GJK) algorithm is used to test if two convex objects intersect (a boolean 'yes/no' test).

    To use GJK, you must:

    1. Include <ccd/ccd.h>.
    2. Implement a support function for your specific shapes. This function must return the furthest point from the object in a specified direction.
    3. Initialize a ccd_t structure using the CCD_INIT(&ccd) macro.
    4. Assign your support functions to ccd.support1 and ccd.support2.
    5. Call ccdGJKIntersect(obj1, obj2, &ccd).
    #include <ccd/ccd.h>
    
    // User-defined support function
    void support(const void *obj, const ccd_vec3_t *dir, ccd_vec3_t *vec) {
        // ... implementation ...
    }
    
    int main() {
        ccd_t ccd;
        CCD_INIT(&ccd);
        ccd.support1 = support;
        ccd.support2 = support;
        ccd.max_iterations = 100;
    
        int intersect = ccdGJKIntersect(obj1, obj2, &ccd);
        // intersect is true if objects intersect
    }
  4. Calculate penetration depth and direction using GJK + EPA

    master

    If two objects intersect and you need to know how much they are penetrating, use the ccdGJKPenetration() function. This combines GJK with the Expanding Polytope Algorithm (EPA).

    In addition to the support functions required for GJK, you should configure epa_tolerance in the ccd_t structure to control the precision of the EPA phase.

    ccdGJKPenetration returns:

    • An integer indicating if an intersection exists.
    • depth: The penetration depth.
    • dir: The direction of the separation vector.
    • pos: The position in the global coordinate system.
    #include <ccd/ccd.h>
    
    int main(int argc, char *argv[])
    {
        // ... setup objects ...
    
        ccd_t ccd;
        CCD_INIT(&ccd); // initialize ccd_t struct
    
        ccd.support1       = support; 
        ccd.support2       = support; 
        ccd.max_iterations = 100;     
        ccd.epa_tolerance  = 0.0001;  // maximal tolerance for EPA part
    
        ccd_real_t depth;
        ccd_vec3_t dir, pos;
        int intersect = ccdGJKPenetration(obj1, obj2, &ccd, &depth, &dir, &pos);
        // intersect holds true if obj1 and obj2 intersect
        // depth, dir, and pos store penetration depth, separation direction, and global position
    }
  5. Install libccd using Autotools

    master

    To build using Autotools, first generate the configure script with ./bootstrap. Create a build/ directory, navigate into it, and run the configure script.

    Use the --enable-double-precision flag to enable double precision (single precision is the default when using this method).

    $ ./bootstrap
    $ mkdir build && cd build
    $ ../configure --enable-double-precision
    $ make && make install
  6. Calculate penetration depth and direction using MPR

    master

    Use the ccdMPRPenetration() function to obtain penetration information using the MPR algorithm.

    Similar to the intersection test, you must provide support functions and center functions for both objects. You should also set mpr_tolerance in the ccd_t structure.

    ccdMPRPenetration returns:

    • An integer indicating if an intersection exists.
    • depth: The penetration depth.
    • dir: The direction of the separation vector.
    • pos: The position in the global coordinate system.
    #include <ccd/ccd.h>
    
    int main(int argc, char *argv[])
    {
        // ... setup objects ...
    
        ccd_t ccd;
        CCD_INIT(&ccd); // initialize ccd_t struct
    
        ccd.support1       = support; 
        ccd.support2       = support; 
        ccd.center1        = center; 
        ccd.center2        = center; 
        ccd.mpr_tolerance  = 0.0001; 
    
        ccd_real_t depth;
        ccd_vec3_t dir, pos;
        int intersect = ccdMPRPenetration(obj1, obj2, &ccd, &depth, &dir, &pos);
        // intersect holds true if obj1 and obj2 intersect
        // depth, dir, and pos store penetration depth, separation direction, and global position
    }
  7. Compile and install libccd using CMake

    master

    CMake is a supported build system for libccd. You can generate build files for various generators like Unix Makefiles, Ninja, Xcode, or Visual Studio. It is recommended to perform an out-of-source build by creating a build/ directory.

    # Using Unix Makefiles
    $ mkdir build && cd build
    $ cmake -G "Unix Makefiles" ..
    $ make && make install
    
    # Using Ninja
    $ mkdir build && cd build
    $ cmake -G Ninja ..
    $ ninja && ninja install
  8. Install libccd using Makefile

    master

    To compile and install libccd using a Makefile, navigate to the src/ directory and run make followed by make install.

    By default, the library is compiled with double-precision floating point numbers. To compile with single precision, use the USE_SINGLE=yes option. You can customize the installation path using PREFIX, INCLUDEDIR, and LIBDIR.

    $ cd src/
    $ make
    $ make install
    
    # For single precision:
    $ make USE_SINGLE=yes
  9. Perform intersection tests using MPR

    master

    The Minkowski Portal Refinement (MPR) algorithm can be used as an alternative to GJK for intersection testing.

    To use MPR, you must implement two types of functions for each object:

    1. A support function (same as GJK).
    2. A center function that returns a point near the center of the object.

    Configure the ccd_t structure with support1, support2, center1, center2, and mpr_tolerance. Then call ccdMPRIntersect(obj1, obj2, &ccd).

    #include <ccd/ccd.h>
    
    /** Center function - returns center of object */
    void center(const void *_obj, ccd_vec3_t *center)
    {
        obj_t *obj = (obj_t *)_obj;
        ccdVec3Copy(center, &obj->pos);
    }
    
    int main(int argc, char *argv[])
    {
        // ... setup objects ...
    
        ccd_t ccd;
        CCD_INIT(&ccd); // initialize ccd_t struct
    
        ccd.support1       = support; 
        ccd.support2       = support; 
        ccd.center1        = center;  // center function for first object
        ccd.center2        = center;  // center function for second object
        ccd.mpr_tolerance  = 0.0001;  // maximal tolerance
    
        int intersect = ccdMPRIntersect(obj1, obj2, &ccd);
        // intersect holds true if obj1 and obj2 intersect
    }
  10. Install libccd using CMake

    master

    libccd supports CMake for various build systems (Unix Makefiles, Ninja, Xcode, Visual Studio).

    Key configuration options:

    • ENABLE_DOUBLE_PRECISION=ON: Enables double precision.
    • BUILD_SHARED_LIBS=ON: Builds the library as a shared library.
    • BUILD_TESTING=ON: Builds the test suite.
    • CMAKE_INSTALL_PREFIX=/path/to/install: Sets the installation directory.
    # Using Unix Makefiles
    $ mkdir build && cd build
    $ cmake -G "Unix Makefiles" -DENABLE_DOUBLE_PRECISION=ON ..
    $ make && make install
    
    # Using Ninja
    $ mkdir build && cd build
    $ cmake -G Ninja ..
    $ ninja && ninja install
  11. Perform intersection tests using GJK

    master

    Use the Gilbert-Johnson-Keerthi (GJK) algorithm to perform a boolean 'yes/no' intersection test between two convex objects.

    To use GJK, you must:

    1. Include <ccd/ccd.h>.
    2. Implement a support function for each shape. This function takes an object and a direction vector, and returns the furthest point from the object in that direction.
    3. Initialize a ccd_t structure using CCD_INIT(&ccd).
    4. Configure the ccd_t structure with your support functions and max_iterations.
    5. Call ccdGJKIntersect(obj1, obj2, &ccd).
    #include <ccd/ccd.h>
    
    // ... implement support function ...
    
    int main(int argc, char *argv[])
    {
        // ... setup objects ...
    
        ccd_t ccd;
        CCD_INIT(&ccd); // initialize ccd_t struct
    
        // set up ccd_t struct
        ccd.support1       = support; // support function for first object
        ccd.support2       = support; // support function for second object
        ccd.max_iterations = 100;     // maximal number of iterations
    
        int intersect = ccdGJKIntersect(obj1, obj2, &ccd);
        // intersect holds true if obj1 and obj2 intersect, false otherwise
    }
  12. Compile and install libccd using Autotools

    master

    To build using Autotools, you must first generate the configuration scripts, then use the standard configure/make workflow. Note that when using Autotools, single precision is the default, so you must explicitly enable double precision if required.

    $ ./bootstrap
    $ mkdir build && cd build
    $ ../configure
    $ make && make install