3
* ---------------------------------
4
* Copyright (c)2010 Daniel Fiser <danfis@danfis.cz>
7
* This file is part of libccd.
9
* Distributed under the OSI-approved BSD License (the "License");
10
* see accompanying file BDS-LICENSE for details or see
11
* <http://www.opensource.org/licenses/bsd-license.php>.
13
* This software is distributed WITHOUT ANY WARRANTY; without even the
14
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
* See the License for more information.
23
_ccd_inline void _ccdPtNearestUpdate(ccd_pt_t *pt, ccd_pt_el_t *el)
25
if (ccdEq(pt->nearest_dist, el->dist)){
26
if (el->type < pt->nearest_type){
28
pt->nearest_dist = el->dist;
29
pt->nearest_type = el->type;
31
}else if (el->dist < pt->nearest_dist){
33
pt->nearest_dist = el->dist;
34
pt->nearest_type = el->type;
38
static void _ccdPtNearestRenew(ccd_pt_t *pt)
44
pt->nearest_dist = CCD_REAL_MAX;
48
ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
49
_ccdPtNearestUpdate(pt, (ccd_pt_el_t *)v);
52
ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){
53
_ccdPtNearestUpdate(pt, (ccd_pt_el_t *)e);
56
ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){
57
_ccdPtNearestUpdate(pt, (ccd_pt_el_t *)f);
63
void ccdPtInit(ccd_pt_t *pt)
65
ccdListInit(&pt->vertices);
66
ccdListInit(&pt->edges);
67
ccdListInit(&pt->faces);
70
pt->nearest_dist = CCD_REAL_MAX;
74
void ccdPtDestroy(ccd_pt_t *pt)
76
ccd_pt_face_t *f, *f2;
77
ccd_pt_edge_t *e, *e2;
78
ccd_pt_vertex_t *v, *v2;
80
// first delete all faces
81
ccdListForEachEntrySafe(&pt->faces, f, ccd_pt_face_t, f2, ccd_pt_face_t, list){
86
ccdListForEachEntrySafe(&pt->edges, e, ccd_pt_edge_t, e2, ccd_pt_edge_t, list){
90
// delete all vertices
91
ccdListForEachEntrySafe(&pt->vertices, v, ccd_pt_vertex_t, v2, ccd_pt_vertex_t, list){
92
ccdPtDelVertex(pt, v);
97
ccd_pt_vertex_t *ccdPtAddVertex(ccd_pt_t *pt, const ccd_support_t *v)
99
ccd_pt_vertex_t *vert;
101
vert = CCD_ALLOC(ccd_pt_vertex_t);
105
vert->type = CCD_PT_VERTEX;
106
ccdSupportCopy(&vert->v, v);
108
vert->dist = ccdVec3Len2(&vert->v.v);
109
ccdVec3Copy(&vert->witness, &vert->v.v);
111
ccdListInit(&vert->edges);
113
// add vertex to list
114
ccdListAppend(&pt->vertices, &vert->list);
116
// update position in .nearest array
117
_ccdPtNearestUpdate(pt, (ccd_pt_el_t *)vert);
122
ccd_pt_edge_t *ccdPtAddEdge(ccd_pt_t *pt, ccd_pt_vertex_t *v1,
125
const ccd_vec3_t *a, *b;
128
if (v1 == NULL || v2 == NULL)
131
edge = CCD_ALLOC(ccd_pt_edge_t);
135
edge->type = CCD_PT_EDGE;
136
edge->vertex[0] = v1;
137
edge->vertex[1] = v2;
138
edge->faces[0] = edge->faces[1] = NULL;
140
a = &edge->vertex[0]->v.v;
141
b = &edge->vertex[1]->v.v;
142
edge->dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &edge->witness);
144
ccdListAppend(&edge->vertex[0]->edges, &edge->vertex_list[0]);
145
ccdListAppend(&edge->vertex[1]->edges, &edge->vertex_list[1]);
147
ccdListAppend(&pt->edges, &edge->list);
149
// update position in .nearest array
150
_ccdPtNearestUpdate(pt, (ccd_pt_el_t *)edge);
155
ccd_pt_face_t *ccdPtAddFace(ccd_pt_t *pt, ccd_pt_edge_t *e1,
159
const ccd_vec3_t *a, *b, *c;
164
if (e1 == NULL || e2 == NULL || e3 == NULL)
167
face = CCD_ALLOC(ccd_pt_face_t);
171
face->type = CCD_PT_FACE;
176
// obtain triplet of vertices
177
a = &face->edge[0]->vertex[0]->v.v;
178
b = &face->edge[0]->vertex[1]->v.v;
180
if (e->vertex[0] != face->edge[0]->vertex[0]
181
&& e->vertex[0] != face->edge[0]->vertex[1]){
182
c = &e->vertex[0]->v.v;
184
c = &e->vertex[1]->v.v;
186
face->dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &face->witness);
189
for (i = 0; i < 3; i++){
190
if (face->edge[i]->faces[0] == NULL){
191
face->edge[i]->faces[0] = face;
193
face->edge[i]->faces[1] = face;
197
ccdListAppend(&pt->faces, &face->list);
199
// update position in .nearest array
200
_ccdPtNearestUpdate(pt, (ccd_pt_el_t *)face);
206
void ccdPtRecomputeDistances(ccd_pt_t *pt)
211
const ccd_vec3_t *a, *b, *c;
214
ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
215
dist = ccdVec3Len2(&v->v.v);
217
ccdVec3Copy(&v->witness, &v->v.v);
220
ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){
221
a = &e->vertex[0]->v.v;
222
b = &e->vertex[1]->v.v;
223
dist = ccdVec3PointSegmentDist2(ccd_vec3_origin, a, b, &e->witness);
227
ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){
228
// obtain triplet of vertices
229
a = &f->edge[0]->vertex[0]->v.v;
230
b = &f->edge[0]->vertex[1]->v.v;
232
if (e->vertex[0] != f->edge[0]->vertex[0]
233
&& e->vertex[0] != f->edge[0]->vertex[1]){
234
c = &e->vertex[0]->v.v;
236
c = &e->vertex[1]->v.v;
239
dist = ccdVec3PointTriDist2(ccd_vec3_origin, a, b, c, &f->witness);
244
ccd_pt_el_t *ccdPtNearest(ccd_pt_t *pt)
247
_ccdPtNearestRenew(pt);
253
void ccdPtDumpSVT(ccd_pt_t *pt, const char *fn)
257
fout = fopen(fn, "a");
261
ccdPtDumpSVT2(pt, fout);
266
void ccdPtDumpSVT2(ccd_pt_t *pt, FILE *fout)
268
ccd_pt_vertex_t *v, *a, *b, *c;
273
fprintf(fout, "-----\n");
275
fprintf(fout, "Points:\n");
277
ccdListForEachEntry(&pt->vertices, v, ccd_pt_vertex_t, list){
279
fprintf(fout, "%lf %lf %lf\n",
280
ccdVec3X(&v->v.v), ccdVec3Y(&v->v.v), ccdVec3Z(&v->v.v));
283
fprintf(fout, "Edges:\n");
284
ccdListForEachEntry(&pt->edges, e, ccd_pt_edge_t, list){
285
fprintf(fout, "%d %d\n", e->vertex[0]->id, e->vertex[1]->id);
288
fprintf(fout, "Faces:\n");
289
ccdListForEachEntry(&pt->faces, f, ccd_pt_face_t, list){
290
a = f->edge[0]->vertex[0];
291
b = f->edge[0]->vertex[1];
292
c = f->edge[1]->vertex[0];
293
if (c == a || c == b){
294
c = f->edge[1]->vertex[1];
296
fprintf(fout, "%d %d %d\n", a->id, b->id, c->id);