static int refinePortal(const void *obj1, const void *obj2, const ccd_t *ccd, ccd_simplex_t *portal) { ccd_vec3_t dir; ccd_support_t v4; while (1) { /* compute direction outside the portal (from v0 throught v1,v2,v3*/ /* face)*/ portalDir(portal, &dir); /* test if origin is inside the portal*/ if (portalEncapsulesOrigin(portal, &dir)) return 0; /* get next support point*/ __ccdSupport(obj1, obj2, &dir, ccd, &v4); /* test if v4 can expand portal to contain origin and if portal*/ /* expanding doesn't reach given tolerance*/ if (!portalCanEncapsuleOrigin(portal, &v4, &dir) || portalReachTolerance(portal, &v4, &dir, ccd)) { return -1; } /* v1-v2-v3 triangle must be rearranged to face outside Minkowski*/ /* difference (direction from v0).*/ expandPortal(portal, &v4); } return -1; }
static void findPenetr(const void *obj1, const void *obj2, const ccd_t *ccd, ccd_simplex_t *portal, ccd_real_t *depth, ccd_vec3_t *pdir, ccd_vec3_t *pos) { ccd_vec3_t dir; ccd_support_t v4; while (1){ // compute portal direction and obtain next support point portalDir(portal, &dir); __ccdSupport(obj1, obj2, &dir, ccd, &v4); // reached tolerance -> find penetration info if (portalReachTolerance(portal, &v4, &dir, ccd)){ *depth = ccdVec3PointTriDist2(ccd_vec3_origin, &ccdSimplexPoint(portal, 1)->v, &ccdSimplexPoint(portal, 2)->v, &ccdSimplexPoint(portal, 3)->v, pdir); *depth = CCD_SQRT(*depth); ccdVec3Normalize(pdir); // barycentric coordinates: findPos(obj1, obj2, ccd, portal, pos); return; } expandPortal(portal, &v4); } }