Trouble with separating axis theorem C++

人盡茶涼 提交于 2020-12-26 12:45:58

问题


I am trying to perform separating axis theorem on two triangles to test for collisions between them however it is not working.

My relevant code is:

glm::vec3 CalcSurfaceNormal(glm::vec3 tri1, glm::vec3 tri2, glm::vec3 tri3)
{
    //Get surface normal of a triangle
    glm::vec3 u = tri2 - tri1;
    glm::vec3 v = tri3 - tri1;

    glm::vec3 nrmcross = glm::cross(u, v);
    nrmcross = glm::normalize(nrmcross);
    return nrmcross;
}

bool SATTriangleCheck(glm::vec3 axis, glm::vec3 tri1vert1, glm::vec3 tri1vert2, glm::vec3 tri1vert3, glm::vec3 tri2vert1, glm::vec3 tri2vert2, glm::vec3 tri2vert3)
{

    //Dot each vertex with the axis and get the min and max
    int t1v1 = glm::dot(axis, tri1vert1);
    int t1v2 = glm::dot(axis, tri1vert2);
    int t1v3 = glm::dot(axis, tri1vert3);
    int t2v1 = glm::dot(axis, tri2vert1);
    int t2v2 = glm::dot(axis, tri2vert2);
    int t2v3 = glm::dot(axis, tri2vert3);

    int t1min = glm::min(t1v1, glm::min(t1v2, t1v3));
    int t1max = glm::min(t1v1, glm::min(t1v2, t1v3));
    int t2min = glm::min(t2v1, glm::min(t2v2, t2v3));
    int t2max = glm::min(t2v1, glm::min(t2v2, t2v3));

    //Test for overlaps
    if ((t1min < t2max && t1min > t2min) || (t1max < t2max && t1max > t2min) || (t2min < t1max && t2min > t1min) || (t2max < t1max && t2max > t1min))
        return true;

    return false;
}

bool CollisionHelper::isTriangleIntersectingTriangle(glm::vec3 tri1, glm::vec3 tri2, glm::vec3 tri3, glm::vec3 otherTri1, glm::vec3 otherTri2, glm::vec3 otherTri3)
{
    //Triangle surface normals, 2 axes to test
    glm::vec3 tri1FaceNrml = CalcSurfaceNormal(tri1, tri2, tri3);
    glm::vec3 tri2FaceNrml = CalcSurfaceNormal(otherTri1, otherTri2, otherTri3);

    //Calculate edges
    glm::vec3 tri1Edge1 = tri2 - tri1;
    glm::vec3 tri1Edge2 = tri3 - tri1;
    glm::vec3 tri1Edge3 = tri3 - tri2;
    glm::vec3 tri2Edge1 = otherTri2 - otherTri1;
    glm::vec3 tri2Edge2 = otherTri3 - otherTri1;
    glm::vec3 tri2Edge3 = otherTri3 - otherTri2;

    //Calculate all axes
    glm::vec3 axis1 = tri1FaceNrml;
    glm::vec3 axis2 = tri2FaceNrml;
    glm::vec3 axis3 = glm::normalize(glm::cross(tri1Edge1, tri2Edge1));
    glm::vec3 axis4 = glm::normalize(glm::cross(tri1Edge1, tri2Edge2));
    glm::vec3 axis5 = glm::normalize(glm::cross(tri1Edge1, tri2Edge3));
    glm::vec3 axis6 = glm::normalize(glm::cross(tri1Edge2, tri2Edge1));
    glm::vec3 axis7 = glm::normalize(glm::cross(tri1Edge2, tri2Edge2));
    glm::vec3 axis8 = glm::normalize(glm::cross(tri1Edge2, tri2Edge3));
    glm::vec3 axis9 = glm::normalize(glm::cross(tri1Edge3, tri2Edge1));
    glm::vec3 axis10 = glm::normalize(glm::cross(tri1Edge3, tri2Edge2));
    glm::vec3 axis11 = glm::normalize(glm::cross(tri1Edge3, tri2Edge3));

    //Perform SAT
    if (SATTriangleCheck(axis1, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis2, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis3, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis4, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis5, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis6, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis7, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis8, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis9, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis10, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;
    if (SATTriangleCheck(axis11, tri1, tri2, tri3, otherTri1, otherTri2, otherTri3)) return true;

    return false;
}

The code that calls and verifies these functions is in a main game loop every frame that passes in the x y and z coords of both triangles:

if (CollisionHelper::isTriangleIntersectingTriangle(glm::vec3(tri11.x, tri11.y, tri11.z), glm::vec3(tri22.x, tri22.y, tri22.z), glm::vec3(tri33.x, tri33.y, tri33.z), glm::vec3(othertri11.x, othertri11.y, othertri11.z), glm::vec3(othertri22.x, othertri22.y, othertri22.z), glm::vec3(othertri33.x, othertri33.y, othertri33.z)))
{
    std::cout << "Triangle intersection\n";
}

I never get anything printed to the console. One of the triangles is rotated 90 degrees from the other

来源:https://stackoverflow.com/questions/63943600/trouble-with-separating-axis-theorem-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!