Skip to content

Commit bb7ea96

Browse files
committed
slight GJK fix
1 parent 669e012 commit bb7ea96

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

‎src/include/sndx/collision/gjk.hpp‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,11 @@ namespace sndx::collision {
382382
size_t iterations = 0;
383383

384384
auto dir = glm::normalize(-support.out);
385-
while (true) {
385+
while (iterations < 1024) {
386386
support = detail::gjkMinkowski(supportA, supportB, dir);
387-
if (!detail::similarDir(support.out, dir)) {
387+
388+
// it is okay for the 2nd point to have a negative dot product.
389+
if (!detail::similarDir(support.out, dir) && iterations > 0) {
388390
return std::nullopt;
389391
}
390392

@@ -534,8 +536,6 @@ namespace sndx::collision {
534536
float sDistance = glm::dot(minNormal, support.out);
535537

536538
if (abs(sDistance - minDistance) > 0.0001f) {
537-
minDistance = FLT_MAX;
538-
539539
std::vector<std::pair<size_t, size_t>> uniqueEdges;
540540

541541
for (size_t i = 0; i < normals.size(); i++) {
@@ -557,6 +557,12 @@ namespace sndx::collision {
557557
}
558558
}
559559

560+
if (uniqueEdges.empty()) {
561+
// @TODO figure out why this happens
562+
return EpaResult{};
563+
}
564+
assert(uniqueEdges.size() > 0);
565+
560566
std::vector<size_t> newFaces;
561567
for (auto [edgeIndex1, edgeIndex2] : uniqueEdges) {
562568
newFaces.emplace_back(edgeIndex1);
@@ -582,6 +588,8 @@ namespace sndx::collision {
582588

583589
faces.insert(faces.end(), newFaces.begin(), newFaces.end());
584590
normals.insert(normals.end(), newNormals.begin(), newNormals.end());
591+
592+
minDistance = FLT_MAX;
585593
}
586594
}
587595

‎src/tests/collision/gjk.cpp‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,27 @@ TEST(GJK, circleAndTriangleCollide) {
9797
EXPECT_TRUE(result);
9898
}
9999

100+
TEST(GJK, circleAndTriangleCollide2) {
101+
Circle3D circle{ glm::vec3{4.41356277f, 3.2411015f, -2.31648755f}, 0.5f };
102+
const std::array<glm::vec3, 3> triangle{
103+
glm::vec3{1.0f, 1.0f, -1.0f},
104+
glm::vec3{-1.0f, 1.0f, -1.0f},
105+
glm::vec3{-1.0f, 1.0f, 1.0f},
106+
};
107+
108+
glm::mat4 transform = glm::translate(glm::mat4{ 1.0f }, glm::vec3(5.0, 1.5, 0.0));
109+
transform = glm::scale(transform, glm::vec3(2.0, 1.5, 5.0));
110+
auto inv = glm::inverse(transform);
111+
112+
auto ttri = transformSupportFn(getSupportFn(std::span{ triangle }), transform, inv);
113+
114+
auto result = gjk(getSupportFn(circle), ttri);
115+
EXPECT_TRUE(result);
116+
117+
result = gjk(ttri, getSupportFn(circle));
118+
EXPECT_TRUE(result);
119+
}
120+
100121
// because EXPECT_FLOAT_EQ is WAYYYYY too strict.
101122
bool floatEq(float a, float b) {
102123
return std::abs(a - b) <= 0.00005f;

0 commit comments

Comments
 (0)