Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- float Body::CalculateOverlap(float aMinProj, float aMaxProj, float bMinProj, float bMaxProj){
- return std::min(bMaxProj, aMaxProj) - std::max(aMinProj, bMinProj);
- }
- //ALL COLLIDERS ARE BOXES
- //vertices is simply a glm::vec3 array
- 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;
- //surface relative to box1
- 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;
- //surface relative to box2
- 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;
- }
- //surface relative to cross products of boxes 1 and 2
- 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;
- }
- //another surface relative to cross products of boxes 1 and 2
- 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){
- //get the minimal distance and direction to travel to resolve the collision
- overlap = overlapInfo.overlap;
- mtvAxis = axis;
- }
- }
- //Some weird floating point weirdness, this fixed it
- mtvAxis.x = static_cast<float>(static_cast<int>(mtvAxis.x * 10)) / 10;
- mtvAxis.y = static_cast<float>(static_cast<int>(mtvAxis.y * 10)) / 10;
- mtvAxis.z = static_cast<float>(static_cast<int>(mtvAxis.z * 10)) / 10;
- //Resolving collision
- pos -= mtvAxis * overlap;
- vel.y = 0;
- }
- 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;
- }
Add Comment
Please, Sign In to add comment