I can implement the AABB method to detect collisions it is easy and cheap but I want to implement OBB for more accuracy so I create the bounding box with the model initialization it is consists of 8 bounding vertices and center, each frame I transform all the vertices with the transformation matrix to fit the Oriented Bounding Box but I can't understand the method for detecting the collision between two OBBs and I can't find a simplified and clear tutorial which explain the algorithm with the code view point not the math because I am not a mathematician.
if I have
struct Box {
glm::vec3 vertices[8];
Box() {
for (int i = 0; i < 8; i++) {
vertices[i] = glm::vec3(0);
}
}
glm::vec3 max;
glm::vec3 min;
glm::vec3 origin;
void reCompute() {
max = vertices[0];
min = vertices[0];
for (int i = 1; i < 8; i++) {
max.x = max.x > vertices[i].x ? max.x : vertices[i].x;
max.y = max.y > vertices[i].y ? max.y : vertices[i].y;
max.z = max.z > vertices[i].z ? max.z : vertices[i].z;
min.x = min.x < vertices[i].x ? min.x : vertices[i].x;
min.y = min.y < vertices[i].y ? min.y : vertices[i].y;
min.z = min.z < vertices[i].z ? min.z : vertices[i].z;
}
origin = glm::vec3((max.x + min.x) / 2.0f, (max.y + min.y) / 2.0f, (max.z + min.z) / 2.0f);
}
//AABB intersection
bool intersects(const Box &b) const {
return (min.x < b.max.x) && (max.x > b.min.x) && (min.y < b.max.y) && (max.y > b.min.y) && (min.z < b.max.z) && (max.z > b.min.z) && *this != b;
}
bool operator==(const Box& b) const {
return (max.x == b.max.x && max.y == b.max.y && max.z == b.max.z && min.x == b.min.x && min.y == b.min.y && min.z == b.min.z);
}
bool operator!=(const Box& b) const {
return (max.x != b.max.x) || (max.y != b.max.y) || (max.z != b.max.z) || (min.x != b.min.x) || (min.y != b.min.y) || (min.z != b.min.z);
}
};
on model initialization I create the box
box.vertices[0] = glm::vec3(meshMinX, meshMinY, meshMinZ);
box.vertices[1] = glm::vec3(meshMaxX, meshMinY, meshMinZ);
box.vertices[2] = glm::vec3(meshMinX, meshMaxY, meshMinZ);
box.vertices[3] = glm::vec3(meshMaxX, meshMaxY, meshMinZ);
box.vertices[4] = glm::vec3(meshMinX, meshMinY, meshMaxZ);
box.vertices[5] = glm::vec3(meshMaxX, meshMinY, meshMaxZ);
box.vertices[6] = glm::vec3(meshMinX, meshMaxY, meshMaxZ);
box.vertices[7] = glm::vec3(meshMaxX, meshMaxY, meshMaxZ);
and each frame I recompute the box with the transformation matrix of the model
for (int n = 0; n < 8; n++) {
boxs[j].vertices[n] = glm::vec3(matrix * glm::vec4(box.vertices[n], 1));
}
boxs[j].reCompute();
To know if two OBB collide you use SAT(separating axis theorem): you have to project all the points of the two shapes on every normal of the two shapes. Then you see if the projection of the two shapes overlap on each normals there is a collision. If there is at least one normal where there is no overlap then they do not collide. And that's all, to do that you will need a method to do orthogonal projection of a vector on another vector which returns a scalar, and a method to see if two intervals overlap.
I have some code in Java :
Orthagonal projection of U on V :
Overlapping of two interval :
With that your are able to do a method to test collision between two OBB :
And you will need that to get the min and max of the projection of the two shape projected on a vector:
I hope this helps you ;)