[ad_1]
I am trying to implement SAT and it works except for the fact that colliders extend infinitely along the Z axis and I can never get past them. I also have confirmed that vertices
values are correct. Seemingly everything checks out except for when it comes to actually calculating the overlap.
Minimal reproducible example
To move for 1 unit along the x and z axis simply type +x, -x, +z, -z. The bug can be observed in the example
My collision function:
void Body::CheckCollision(Body* other){
if(isStatic && other->isStatic){
return;
}
glm::vec3 axis;
//calculate the fucking normal 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, other, 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, other, 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, other, 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, other, 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;//Correct 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; // Simply for convenience so I dont have to deal with gravity for now
float Body::CalculateOverlap(float aMinProj, float aMaxProj, float bMinProj, float bMaxProj){
return std::min(bMaxProj, aMaxProj) - std::max(aMinProj, bMinProj);
}
OverlapInfo Body::CheckOverlap(Body* b1, Body* 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 Body::CheckOverlap(Body* b1, Body* 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]