c++ – Separating axis theorem implementation ends in limitless extending colliders alongside the Z axis

c++ – Separating axis theorem implementation ends in limitless extending colliders alongside the Z axis

[ad_1]

I’m attempting to implement SAT and it really works apart from the truth that colliders prolong infinitely alongside the Z axis and I can by no means get previous them. I even have confirmed that vertices values are right. Seemingly the whole lot checks out apart from in the case of really calculating the overlap.

Minimal reproducible instance
To maneuver for 1 unit alongside the x and z axis merely sort +x, -x, +z, -z. The bug will be noticed within the instance

My collision operate:

void Physique::CheckCollision(Physique* different){

    if(isStatic && other->isStatic){
        return;
    }

    glm::vec3 axis;

    //calculate the fucking regular axis:

    glm::vec3 mtvAxis;
    float overlap = std::numeric_limits<float>::infinity();

    for(uint32_t i = 0; i < COLLIDER_VERTEX_COUNT; i++){
        glm::vec3 curr = vertices[i];
        glm::vec3 edges[2];

        edges[0] = vertices[(i + 1) % COLLIDER_VERTEX_COUNT]- curr;
        edges[1] = vertices[(i + 2) % COLLIDER_VERTEX_COUNT]- curr;

        axis = glm::normalize(glm::cross(edges[1], edges[0]));

        OverlapInfo overlapInfo = CheckOverlap(this, different, axis);
        if(!overlapInfo.isOverlapping){
            return;
        }
        if(overlapInfo.overlap < overlap){
            overlap = overlapInfo.overlap;
            mtvAxis = axis;
        }

        curr = other->vertices[i];
        edges[0] = other->vertices[(i + 1) % COLLIDER_VERTEX_COUNT]- curr;
        edges[1] = other->vertices[(i + 2) % COLLIDER_VERTEX_COUNT]- curr;

        axis = glm::normalize(glm::cross(edges[1], edges[0]));

        overlapInfo = CheckOverlap(this, different, axis);
        if(!overlapInfo.isOverlapping){
            return;
        }
        if(overlapInfo.overlap < overlap){
            overlap = overlapInfo.overlap;
            mtvAxis = axis;
        }

        axis = glm::normalize(glm::cross(vertices[(i + 1) % COLLIDER_VERTEX_COUNT] - curr,
        other->vertices[(i + 1) % COLLIDER_VERTEX_COUNT] - other->vertices[i]));

        overlapInfo = CheckOverlap(this, different, axis);
        if(!overlapInfo.isOverlapping){
            return;
        }
        if(overlapInfo.overlap < overlap){
            overlap = overlapInfo.overlap;
            mtvAxis = axis;
        }

        axis = glm::normalize(glm::cross(vertices[(i + 2) % COLLIDER_VERTEX_COUNT] - curr,
        other->vertices[(i + 2) % COLLIDER_VERTEX_COUNT] - other->vertices[i]));
        
        overlapInfo = CheckOverlap(this, different, axis);
        if(!overlapInfo.isOverlapping){
            return;
        }
        
        if(overlapInfo.overlap < overlap){
            overlap = overlapInfo.overlap;
            mtvAxis = axis;
        }

    }


    mtvAxis.x = static_cast<float>(static_cast<int>(mtvAxis.x * 10)) / 10;//Right some float precision errors
    mtvAxis.y = static_cast<float>(static_cast<int>(mtvAxis.y * 10)) / 10;
    mtvAxis.z = static_cast<float>(static_cast<int>(mtvAxis.z * 10)) / 10;


    pos -= mtvAxis * overlap;

    vel.y = 0; // Merely for comfort so I dont should take care of gravity for now
    

float Physique::CalculateOverlap(float aMinProj, float aMaxProj, float bMinProj, float bMaxProj){
    return std::min(bMaxProj, aMaxProj) - std::max(aMinProj, bMinProj); 
}

OverlapInfo Physique::CheckOverlap(Physique* b1, Physique* b2, glm::vec3 axis){


    OverlapInfo overlapInfo;

    float aMaxProj = -std::numeric_limits<float>::infinity();
    float aMinProj = std::numeric_limits<float>::infinity();

    float bMaxProj = -std::numeric_limits<float>::infinity();
    float bMinProj = std::numeric_limits<float>::infinity();
    

    for(glm::vec3 p : b1->vertices){
        float proj = glm::dot(axis, p);

        if(proj < aMinProj){
            aMinProj = proj;
        }
        if(proj > aMaxProj){
            aMaxProj = proj;
        }
    }

    for(glm::vec3 p : b2->vertices){
        float proj = glm::dot(axis, p);

        if(proj < bMinProj){
            bMinProj = proj;
        }
        if(proj > bMaxProj){
            bMaxProj = proj;
        }
    }
   OverlapInfo Physique::CheckOverlap(Physique* b1, Physique* b2, glm::vec3 axis){


    OverlapInfo overlapInfo;

    float aMaxProj = -std::numeric_limits<float>::infinity();
    float aMinProj = std::numeric_limits<float>::infinity();

    float bMaxProj = -std::numeric_limits<float>::infinity();
    float bMinProj = std::numeric_limits<float>::infinity();
    

    for(glm::vec3 p : b1->vertices){
        float proj = glm::dot(axis, p);

        if(proj < aMinProj){
            aMinProj = proj;
        }
        if(proj > aMaxProj){
            aMaxProj = proj;
        }
    }

    for(glm::vec3 p : b2->vertices){
        float proj = glm::dot(axis, p);

        if(proj < bMinProj){
            bMinProj = proj;
        }
        if(proj > bMaxProj){
            bMaxProj = proj;
        }
    }
    if(aMaxProj < bMinProj || bMaxProj < aMinProj){
        overlapInfo.isOverlapping = false;
        overlapInfo.overlap = std::numeric_limits<float>::infinity();
        return overlapInfo;
    }

    overlapInfo.isOverlapping = true;
    overlapInfo.overlap = CalculateOverlap(aMinProj, aMaxProj, bMinProj, bMaxProj);
    return overlapInfo;
}
overlapInfo.isOverlapping = true;
    overlapInfo.overlap = CalculateOverlap(aMinProj, aMaxProj, bMinProj, bMaxProj);
    return overlapInfo;
}

[ad_2]

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply