[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]