@@ -81,8 +81,9 @@ static mjtNum attachFace(Polytope* pt, int v1, int v2, int v3, int adj1, int adj
81
81
// status must have initial tetrahedrons
82
82
static int gjkIntersect (mjCCDStatus * status , mjCCDObj * obj1 , mjCCDObj * obj2 );
83
83
84
- // return the penetration depth of two convex objects; witness points are in status->{x1, x2}
85
- static mjtNum epa (mjCCDStatus * status , Polytope * pt , mjCCDObj * obj1 , mjCCDObj * obj2 );
84
+ // return a face of the expanded polytope that best approximates the pentration depth
85
+ // witness points are in status->{x1, x2}
86
+ static Face * epa (mjCCDStatus * status , Polytope * pt , mjCCDObj * obj1 , mjCCDObj * obj2 );
86
87
87
88
// -------------------------------- inlined 3D vector utils --------------------------------------
88
89
@@ -145,7 +146,7 @@ static int discreteGeoms(mjCCDObj* obj1, mjCCDObj* obj2) {
145
146
146
147
147
148
// GJK algorithm
148
- static mjtNum gjk (mjCCDStatus * status , mjCCDObj * obj1 , mjCCDObj * obj2 ) {
149
+ static void gjk (mjCCDStatus * status , mjCCDObj * obj1 , mjCCDObj * obj2 ) {
149
150
int get_dist = status -> dist_cutoff > 0 ; // need to recover geom distances if not in contact
150
151
int backup_gjk = !get_dist ; // use gjkIntersect if no geom distances needed
151
152
mjtNum * simplex1 = status -> simplex1 ; // simplex for obj1
@@ -192,7 +193,7 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
192
193
status -> nsimplex = 0 ;
193
194
status -> nx = 0 ;
194
195
status -> dist = mjMAXVAL ;
195
- return status -> dist ;
196
+ return ;
196
197
}
197
198
} else if (status -> dist_cutoff < mjMAXVAL ) {
198
199
mjtNum vs = mju_dot3 (x_k , s_k ), vv = mju_dot3 (x_k , x_k );
@@ -201,7 +202,7 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
201
202
status -> nsimplex = 0 ;
202
203
status -> nx = 0 ;
203
204
status -> dist = mjMAXVAL ;
204
- return status -> dist ;
205
+ return ;
205
206
}
206
207
}
207
208
@@ -213,7 +214,7 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
213
214
if (ret != -1 ) {
214
215
status -> nx = 0 ;
215
216
status -> dist = ret > 0 ? 0 : mjMAXVAL ;
216
- return status -> dist ;
217
+ return ;
217
218
}
218
219
k = status -> gjk_iterations ;
219
220
backup_gjk = 0 ;
@@ -259,7 +260,6 @@ static mjtNum gjk(mjCCDStatus* status, mjCCDObj* obj1, mjCCDObj* obj2) {
259
260
status -> gjk_iterations = k ;
260
261
status -> nsimplex = n ;
261
262
status -> dist = mju_norm3 (x_k );
262
- return status -> dist ;
263
263
}
264
264
265
265
@@ -1294,8 +1294,9 @@ static void epaWitness(const Polytope* pt, const Face* face, mjtNum x1[3], mjtNu
1294
1294
1295
1295
1296
1296
1297
- // return the penetration depth of two convex objects; witness points are in status->{x1, x2}
1298
- static mjtNum epa (mjCCDStatus * status , Polytope * pt , mjCCDObj * obj1 , mjCCDObj * obj2 ) {
1297
+ // return a face of the expanded polytope that best approximates the pentration depth
1298
+ // witness points are in status->{x1, x2}
1299
+ static Face * epa (mjCCDStatus * status , Polytope * pt , mjCCDObj * obj1 , mjCCDObj * obj2 ) {
1299
1300
mjtNum tolerance = status -> tolerance , lower , upper = FLT_MAX ;
1300
1301
int k , kmax = status -> max_iterations ;
1301
1302
mjData * d = (mjData * ) obj1 -> data ;
@@ -1368,7 +1369,8 @@ static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* o
1368
1369
mj_freeStack (d );
1369
1370
status -> epa_iterations = k ;
1370
1371
status -> nx = 0 ;
1371
- return 0 ;
1372
+ status -> dist = 0 ;
1373
+ return NULL ;
1372
1374
}
1373
1375
1374
1376
// store face in map
@@ -1395,7 +1397,8 @@ static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* o
1395
1397
mj_freeStack (d );
1396
1398
status -> epa_iterations = k ;
1397
1399
status -> nx = 0 ;
1398
- return 0 ;
1400
+ status -> dist = 0 ;
1401
+ return NULL ;
1399
1402
}
1400
1403
1401
1404
// store face in map
@@ -1417,7 +1420,8 @@ static mjtNum epa(mjCCDStatus* status, Polytope* pt, mjCCDObj* obj1, mjCCDObj* o
1417
1420
epaWitness (pt , face , status -> x1 , status -> x2 );
1418
1421
status -> epa_iterations = k ;
1419
1422
status -> nx = 1 ;
1420
- return face -> dist ;
1423
+ status -> dist = - face -> dist ;
1424
+ return face ;
1421
1425
}
1422
1426
1423
1427
@@ -1444,8 +1448,7 @@ static inline void inflate(mjCCDStatus* status, mjtNum margin1, mjtNum margin2)
1444
1448
1445
1449
// general convex collision detection
1446
1450
mjtNum mjc_ccd (const mjCCDConfig * config , mjCCDStatus * status , mjCCDObj * obj1 , mjCCDObj * obj2 ) {
1447
- // set up
1448
- mjtNum dist ;
1451
+ // setup
1449
1452
obj1 -> center (status -> x1 , obj1 );
1450
1453
obj2 -> center (status -> x2 , obj2 );
1451
1454
status -> gjk_iterations = 0 ;
@@ -1488,11 +1491,11 @@ mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, m
1488
1491
}
1489
1492
1490
1493
status -> dist_cutoff += margin1 + margin2 ;
1491
- dist = gjk (status , obj1 , obj2 );
1494
+ gjk (status , obj1 , obj2 );
1492
1495
status -> dist_cutoff = config -> dist_cutoff ;
1493
1496
1494
1497
// shallow penetration, inflate contact
1495
- if (dist > 0 ) {
1498
+ if (status -> dist > 0 ) {
1496
1499
inflate (status , margin1 , margin2 );
1497
1500
if (status -> dist > status -> dist_cutoff ) {
1498
1501
status -> dist = mjMAXVAL ;
@@ -1515,14 +1518,15 @@ mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, m
1515
1518
obj2 -> center (status -> x2 , obj2 );
1516
1519
}
1517
1520
1518
- dist = gjk (status , obj1 , obj2 );
1521
+ gjk (status , obj1 , obj2 );
1519
1522
1520
1523
// penetration recovery for contacts not needed
1521
1524
if (!config -> max_contacts ) {
1522
- return dist ;
1525
+ return status -> dist ;
1523
1526
}
1524
1527
1525
- if (dist <= config -> tolerance && status -> nsimplex > 1 ) {
1528
+ if (status -> dist <= config -> tolerance && status -> nsimplex > 1 ) {
1529
+ status -> dist = 0 ; // assume touching
1526
1530
int N = status -> max_iterations ;
1527
1531
mjData * d = (mjData * ) obj1 -> data ;
1528
1532
mj_markStack ((mjData * ) obj1 -> data );
@@ -1561,11 +1565,9 @@ mjtNum mjc_ccd(const mjCCDConfig* config, mjCCDStatus* status, mjCCDObj* obj1, m
1561
1565
1562
1566
// simplex not on boundary (objects are penetrating)
1563
1567
if (!ret ) {
1564
- dist = - epa (status , & pt , obj1 , obj2 );
1565
- } else {
1566
- dist = 0 ;
1568
+ epa (status , & pt , obj1 , obj2 );
1567
1569
}
1568
1570
mj_freeStack (d );
1569
1571
}
1570
- return dist ;
1572
+ return status -> dist ;
1571
1573
}
0 commit comments