1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/***
* libccd
* ---------------------------------
* Copyright (c)2010,2011 Daniel Fiser <danfis@danfis.cz>
*
*
* This file is part of libccd.
*
* Distributed under the OSI-approved BSD License (the "License");
* see accompanying file BDS-LICENSE for details or see
* <http://www.opensource.org/licenses/bsd-license.php>.
*
* This software is distributed WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the License for more information.
*/
#ifndef __CCD_H__
#define __CCD_H__
#include <ccd/precision.h>
#include <ccd/vec3.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/**
* Type of *support* function that takes pointer to 3D object and direction
* and returns (via vec argument) furthest point from object in specified
* direction.
*/
typedef void (*ccd_support_fn)(const void *obj, const ccd_vec3_t *dir,
ccd_vec3_t *vec);
/**
* Returns (via dir argument) first direction vector that will be used in
* initialization of algorithm.
*/
typedef void (*ccd_first_dir_fn)(const void *obj1, const void *obj2,
ccd_vec3_t *dir);
/**
* Returns (via center argument) geometric center (some point near center)
* of given object.
*/
typedef void (*ccd_center_fn)(const void *obj1, ccd_vec3_t *center);
/**
* Main structure of CCD algorithm.
*/
struct _ccd_t {
ccd_first_dir_fn first_dir; /*!< Returns initial direction where first
!< support point will be searched*/
ccd_support_fn support1; /*!< Function that returns support point of
!< first object*/
ccd_support_fn support2; /*!< Function that returns support point of
!< second object*/
ccd_center_fn center1; /*!< Function that returns geometric center of
!< first object*/
ccd_center_fn center2; /*!< Function that returns geometric center of
!< second object*/
unsigned long max_iterations; /*!< Maximal number of iterations*/
ccd_real_t epa_tolerance;
ccd_real_t mpr_tolerance; /*!< Boundary tolerance for MPR algorithm*/
};
typedef struct _ccd_t ccd_t;
/**
* Default first direction.
*/
void ccdFirstDirDefault(const void *o1, const void *o2, ccd_vec3_t *dir);
#define CCD_INIT(ccd) \
do { \
(ccd)->first_dir = ccdFirstDirDefault; \
(ccd)->support1 = NULL; \
(ccd)->support2 = NULL; \
(ccd)->center1 = NULL; \
(ccd)->center2 = NULL; \
\
(ccd)->max_iterations = (unsigned long)-1; \
(ccd)->epa_tolerance = CCD_REAL(0.0001); \
(ccd)->mpr_tolerance = CCD_REAL(0.0001); \
} while(0)
/**
* Returns true if two given objects interest.
*/
int ccdGJKIntersect(const void *obj1, const void *obj2, const ccd_t *ccd);
/**
* This function computes separation vector of two objects. Separation
* vector is minimal translation of obj2 to get obj1 and obj2 speparated
* (without intersection).
* Returns 0 if obj1 and obj2 intersect and sep is filled with translation
* vector. If obj1 and obj2 don't intersect -1 is returned.
*/
int ccdGJKSeparate(const void *obj1, const void *obj2, const ccd_t *ccd,
ccd_vec3_t *sep);
/**
* Computes penetration of obj2 into obj1.
* Depth of penetration, direction and position is returned. It means that
* if obj2 is translated by distance depth in direction dir objects will
* have touching contact, pos should be position in global coordinates
* where force should take a place.
*
* CCD+EPA algorithm is used.
*
* Returns 0 if obj1 and obj2 intersect and depth, dir and pos are filled
* if given non-NULL pointers.
* If obj1 and obj2 don't intersect -1 is returned.
*/
int ccdGJKPenetration(const void *obj1, const void *obj2, const ccd_t *ccd,
ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
/**
* Returns true if two given objects intersect - MPR algorithm is used.
*/
int ccdMPRIntersect(const void *obj1, const void *obj2, const ccd_t *ccd);
/**
* Computes penetration of obj2 into obj1.
* Depth of penetration, direction and position is returned, i.e. if obj2
* is translated by computed depth in resulting direction obj1 and obj2
* would have touching contact. Position is point in global coordinates
* where force should be take a place.
*
* Minkowski Portal Refinement algorithm is used (MPR, a.k.a. XenoCollide,
* see Game Programming Gem 7).
*
* Returns 0 if obj1 and obj2 intersect, otherwise -1 is returned.
*/
int ccdMPRPenetration(const void *obj1, const void *obj2, const ccd_t *ccd,
ccd_real_t *depth, ccd_vec3_t *dir, ccd_vec3_t *pos);
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* __CCD_H__ */
|