Model / Mesh Constructing OBB

| | August 4, 2015

Recently I started to implement simple bounding volumes in my Engine. So far I have implemented a Sphere and AABB, also I implemented simple ray-intersection methods for those two volumes. But I am STUCK on how to create a Oriented Bounding Box (OBB). Looking over the internet I find bits and pieces, mostly theory not actual straight-forward information. On one side somewhere I’ve read that the OBB should consist of extend / center and local orientation vectors, on other sources I saw some people talking about covariance matrices etc.

Also I should mention that I found this very simple and neat custom method, when I was looking for a OBB -> Ray Intersection.The code works fine, but I would like to have separate OBB generation rather than this. I will paste that here. Basically this method takes AABB (max,min) ModelMatrix and RayOrigin and RayDirection converts the AABB to OBB and does the intersection test. Note that the Scaling is separated and only applied on max,min. So I was trying to extrapolate only the conversion from AABB to OBB but the calculations involve the rays data. So I have done some refactoring of the code.

bool RayCast::RayBoxCollision(AABB *aabb, const ModelMatrices& BaseModelMatrix , float *intersection_distance){

const glm::vec3& aabb_min = vec3(BaseModelMatrix.Scaling * vec4(aabb->getMinBound(), 1.0f));
const glm::vec3& aabb_max = vec3(BaseModelMatrix.Scaling * vec4(aabb->getMaxBound(), 1.0f));
const glm::vec3& ray_origin = this->ray_start;
const glm::vec3& ray_direction = glm::normalize(this->ray_end - this->ray_start);
const glm::mat4& ModelMatrix = BaseModelMatrix.Transformation * BaseModelMatrix.Rotation;
float tMin = 0.0f;
float tMax = INFINITY;
glm::vec3 AABBposition_worldspace(ModelMatrix[3].x, ModelMatrix[3].y, ModelMatrix[3].z);
glm::vec3 delta = AABBposition_worldspace - ray_origin;
{
    glm::vec3 xaxis(ModelMatrix[0].x, ModelMatrix[0].y, ModelMatrix[0].z);
    float e = glm::dot(xaxis, delta);
    float f = glm::dot(ray_direction, xaxis);

    if (fabs(f) > 0.001f){

        float t1 = (e + aabb_min.x) / f; 
        float t2 = (e + aabb_max.x) / f; 

        if (t1>t2){
            float w = t1; t1 = t2; t2 = w;
        }
        if (t2 < tMax)
            tMax = t2;

        if (t1 > tMin)
            tMin = t1;

        if (tMax < tMin)
            return false;

    }
    else{ 
        if (-e + aabb_min.x > 0.0f || -e + aabb_max.x < 0.0f)
            return false;
    }
}

{
    glm::vec3 yaxis(ModelMatrix[1].x, ModelMatrix[1].y, ModelMatrix[1].z);
    float e = glm::dot(yaxis, delta);
    float f = glm::dot(ray_direction, yaxis);

    if (fabs(f) > 0.001f){

        float t1 = (e + aabb_min.y) / f;
        float t2 = (e + aabb_max.y) / f;

        if (t1>t2){ float w = t1; t1 = t2; t2 = w; }

        if (t2 < tMax)
            tMax = t2;
        if (t1 > tMin)
            tMin = t1;
        if (tMin > tMax)
            return false;

    }
    else{
        if (-e + aabb_min.y > 0.0f || -e + aabb_max.y < 0.0f)
            return false;
    }
}

{
    glm::vec3 zaxis(ModelMatrix[2].x, ModelMatrix[2].y, ModelMatrix[2].z);
    float e = glm::dot(zaxis, delta);
    float f = glm::dot(ray_direction, zaxis);

    if (fabs(f) > 0.001f){

        float t1 = (e + aabb_min.z) / f;
        float t2 = (e + aabb_max.z) / f;

        if (t1>t2){ float w = t1; t1 = t2; t2 = w; }

        if (t2 < tMax)
            tMax = t2;
        if (t1 > tMin)
            tMin = t1;
        if (tMin > tMax)
            return false;

    }
    else{
        if (-e + aabb_min.z > 0.0f || -e + aabb_max.z < 0.0f)
            return false;
    }
}

*intersection_distance = tMin;
return true;

}

Al in all my question is for a straightforward method or algorithm on how to create a OBB, also is it possible to generate one from a AABB?

Leave a Reply