5 #define REAL_infinity 1.0e30
6 #define REAL_EQUAL(a,b) (((a < b + EPSILON) && (a > b - EPSILON)) ? true : false)
13 return u.dot(v.cross(w));
34 T _w[4];
if (!w) w = _w;
39 if ((*n).normSquared() < 1e-6)
41 *n = (*n).normalize();
42 T h = (x - y0).
dot(*n);
43 T b0 =
STP(y1 - x, y2 - x, *n),
44 b1 =
STP(y2 - x, y0 - x, *n),
45 b2 =
STP(y0 - x, y1 - x, *n);
47 w[1] = -b0 / (b0 + b1 + b2);
48 w[2] = -b1 / (b0 + b1 + b2);
49 w[3] = -b2 / (b0 + b1 + b2);
61 T _w[4];
if (!w) w = _w;
67 if ((*n).normSquared() < 1e-6)
70 *n = (*n).normalize();
71 T h = (x0 - y0).
dot(*n);
72 T a0 =
STP(y1 - x1, y0 - x1, *n);
73 T a1 =
STP(y0 - x0, y1 - x0, *n);
74 T b0 =
STP(x0 - y1, x1 - y1, *n);
75 T b1 =
STP(x1 - y0, x0 - y0, *n);
76 w[0] = a0 / (a0 + a1);
77 w[1] = a1 / (a0 + a1);
78 w[2] = -b0 / (b0 + b1);
79 w[3] = -b1 / (b0 + b1);
86 return a.cross(b).dot(c);
96 DYN_FUNC
int sgn(
T x) {
return x < 0 ? -1 : 1; }
101 T d = b * b - 4 * a * c;
106 T q = -(b +
sgn(b) * glm::sqrt(d)) / 2;
108 if (glm::abs(a) > 1e-12 * glm::abs(q))
110 if (glm::abs(q) > 1e-12 * glm::abs(c))
112 if (i == 2 && x[0] > x[1])
122 T y0 = d + x0 * (c + x0 * (b + x0 * a)),
123 ddy0 = 2 * b + x0 * (6 * a);
124 x0 += init_dir * glm::sqrt(glm::abs(2 * y0 / ddy0));
126 for (
int iter = 0; iter < 100; iter++) {
127 T y = d + x0 * (c + x0 * (b + x0 * a));
128 T dy = c + x0 * (2 * b + x0 * 3 * a);
132 if (glm::abs(x0 - x1) < 1e-6)
149 else if (ncrit == 1) {
153 T yc[2] = { d + xc[0] * (c + xc[0] * (b + xc[0] * a)),
154 d + xc[1] * (c + xc[1] * (b + xc[1] * a)) };
158 if (yc[0] * yc[1] <= 0) {
159 int closer =
abs(yc[0]) <
abs(yc[1]) ? 0 : 1;
160 x[i++] =
NewtonsMethod(a, b, c, d, xc[closer], closer == 0 ? 1 : -1);
172 T& time,
const int isVF)
174 T a0 =
STP(x1, x2, x3);
175 T a1 =
STP(v1, x2, x3) +
STP(x1, v2, x3) +
STP(x1, x2, v3);
176 T a2 =
STP(x1, v2, v3) +
STP(v1, x2, v3) +
STP(v1, v2, x3);
177 T a3 =
STP(v1, v2, v3);
188 for (
int i = 0; i < nsol; i++) {
189 if (t[i] < 0 || t[i] > 1)
204 inside = (fmin(-w[1], fmin(-w[2], -w[3])) >= -1e-6);
208 inside = (fmin(fmin(w[0], w[1]), fmin(-w[2], -w[3])) >= -1e-6);
211 if (fabs(d) < 1e-6 && inside)
215 time = t[i] < time ? t[i] : time;
237 return CollisionTest(x0, x1, x2, x3, v0, v1, v2, v3, time, 0);
255 return CollisionTest(a0, p1, p2, p3, v0, v1, v2, v3, time, 1);
270 Real invL = 1 / lmax;
273 p[0] = invL * s0.
v[0];
274 p[1] = invL * s0.
v[1];
275 p[2] = invL * s0.
v[2];
278 pp[0] = invL * s1.
v[0];
279 pp[1] = invL * s1.
v[1];
280 pp[2] = invL * s1.
v[2];
283 q[0] = invL * t0.
v[0];
284 q[1] = invL * t0.
v[1];
285 q[2] = invL * t0.
v[2];
288 qq[0] = invL * t1.
v[0];
289 qq[1] = invL * t1.
v[1];
290 qq[2] = invL * t1.
v[2];
295 for (
int st = 0; st < 3; st++)
299 p[st], q[0], q[1], q[2],
300 pp[st], qq[0], qq[1], qq[2],
303 toi = collided ?
minimum(t, toi) : toi;
308 for (
int st = 0; st < 3; st++)
312 qq[st], pp[0], pp[1], pp[2],
314 toi = collided ?
minimum(t, toi) : toi;
319 for (
int st = 0; st < 3; st++)
322 int ind1 = (st + 1) % 3;
323 for (
int ss = 0; ss < 3; ss++)
326 int ind3 = (ss + 1) % 3;
330 p[ind0], p[ind1], q[ind2], q[ind3],
331 pp[ind0], pp[ind1], qq[ind2], qq[ind3],
334 toi = collided ?
minimum(t, toi) : toi;
DYN_FUNC Real maximumEdgeLength() const
static DYN_FUNC bool EdgeEdgeCCD(const Vector< T, 3 > &a0, const Vector< T, 3 > &b0, const Vector< T, 3 > &c0, const Vector< T, 3 > &d0, const Vector< T, 3 > &a1, const Vector< T, 3 > &b1, const Vector< T, 3 > &c1, const Vector< T, 3 > &d1, T &time)
Do a continuous collision detection between two edges.
static DYN_FUNC bool VertexFaceCCD(const Vector< T, 3 > &p0, const Vector< T, 3 > &a0, const Vector< T, 3 > &b0, const Vector< T, 3 > &c0, const Vector< T, 3 > &p1, const Vector< T, 3 > &a1, const Vector< T, 3 > &b1, const Vector< T, 3 > &c1, T &time)
Do a continuous collision detection between a vertex and a triangle.
static DYN_FUNC bool TriangleCCD(TTriangle3D< Real > &s0, TTriangle3D< Real > &s1, TTriangle3D< Real > &t0, TTriangle3D< Real > &t1, Real &toi)
Do a continuous collision detection between two triangles.
This is an implementation of AdditiveCCD based on peridyno.
DYN_FUNC Vector< T, 3 > xvpos(Vector< T, 3 > x, Vector< T, 3 > v, T t)
DYN_FUNC T dot(Vector< T, 2 > const &U, Vector< T, 2 > const &V)
DYN_FUNC T abs(const T &v)
DYN_FUNC T SignedDistanceVF(const Vector< T, 3 > &x, const Vector< T, 3 > &y0, const Vector< T, 3 > &y1, const Vector< T, 3 > &y2, Vector< T, 3 > *n, T *w)
DYN_FUNC T triProduct(Vector< T, 3 > &a, Vector< T, 3 > &b, Vector< T, 3 > &c)
DYN_FUNC int SolveQuadratic(T a, T b, T c, T x[2])
DYN_FUNC T minimum(const T &v0, const T &v1)
DYN_FUNC int SolveCubic(T a, T b, T c, T d, T x[3])
constexpr Real REAL_EPSILON
DYN_FUNC T SignedDistanceEE(const Vector< T, 3 > &x0, const Vector< T, 3 > &x1, const Vector< T, 3 > &y0, const Vector< T, 3 > &y1, Vector< T, 3 > *n, Real *w)
DYN_FUNC T STP(const Vector< T, 3 > &u, const Vector< T, 3 > &v, const Vector< T, 3 > &w)
DYN_FUNC void fswap(T &a, T &b)
DYN_FUNC T NewtonsMethod(T a, T b, T c, T d, T x0, int init_dir)
DYN_FUNC T maximum(const T &v0, const T &v1)
DYN_FUNC bool CollisionTest(const Vector< T, 3 > &x0, const Vector< T, 3 > &x1, const Vector< T, 3 > &x2, const Vector< T, 3 > &x3, const Vector< T, 3 > &v0, const Vector< T, 3 > &v1, const Vector< T, 3 > &v2, const Vector< T, 3 > &v3, T &time, const int isVF)