1
\$\begingroup\$

I have the animated bounding boxes for the individual bones of an object which comes from a pre-computation of the bone's bounding boxes multiplied with the bone matrix. In this question I'm referring to the surrounding aka overall BB for the model. I get it by looping through the precomputed bounding boxes of the bones.

I'm able to get an OBB but not an AABB or circular volume because I can't get into the correct "space" for the center of the volume. I thought that getting an AABB would be very easy, but since I have the min/max points in bone space (?) I need to do some operation to disable rotation. All I can get is OBB :(

enter image description here

I figure that the aabbV4 vector is in "bone space". So, I have to take the inverse of that space somehow, but since I have the combined value of each bone, I need the AABB / circular volumes to follow tutorials on collision detection and not just OBB that I have now.

So, each object has multiple bones which have a bounding box which animate each frame according to a bone matrix. Then, the mvpGet() function creates the MVP matrix which moves / rotates / scales the whole thing.

I render the OBB / surrounding volume of the bones like this:

for (auto &i : myAbj.allObj)
{
    if (i->bb->val_b && i->anim->val_b)
    {
        i->aabbV4.clear();

        for (auto &j : i->bbSkelAll)
        {
            for (auto &k : i->aiGbones)
            {
                if (k.name == j.name)
                {
                    i->obbMVP = glm::transpose(k.animatedXform) * j.obbMVP; // precomputed obbMVP

                    //AABB - STEP 1 - GATHER / STORE
                    glm::vec4 bbSkelXformMin = glm::transpose(k.animatedXform) * glm::vec4(j.min, 1.f);
                    glm::vec4 bbSkelXformMax = glm::transpose(k.animatedXform) * glm::vec4(j.max, 1.f);
                    i->aabbV4.push_back(bbSkelXformMin);
                    i->aabbV4.push_back(bbSkelXformMax);

                    break;
                }
            }

            i->mvpGet();
            i->render();
        }
    }
}

 //AABB - STEP 2 - MIN / MAX
for (auto &i : myAbj.allObj)
{
    if (i->bb->val_b && i->anim->val_b)
    {
        glm::vec4 aabbMin = (i->aabbV4.empty()) ? glm::vec4(0.f) : i->aabbV4[0];
        glm::vec4 aabbMax = (i->aabbV4.empty()) ? glm::vec4(0.f) : i->aabbV4[0];

        for (uint j = 0; j < i->aabbV4.size(); ++j)
        {
            aabbMin = glm::min(i->aabbV4[j], aabbMin);
            aabbMax = glm::max(i->aabbV4[j], aabbMax);
        }

        glm::vec3 aabbSize = aabbMax - aabbMin;
        glm::vec3 aabbCenter = .5f * (aabbMin + aabbMax);
        i->aabbMVP = glm::translate(glm::mat4(), aabbCenter) * glm::scale(glm::mat4(), aabbSize);

        i->aabbTgl = 1;
        i->mvpGet();
        i->render();
        i->aabbTgl = 0;

        cout << "aabbCenter = " << glm::to_string(aabbCenter) << endl;
    }
}
\$\endgroup\$
0
\$\begingroup\$

Maybe I am misunderstanding your question, but it seems like you have oriented bounding boxes and you want to get an axis aligned bounding box that contains all the OBBs.

The easiest way to get an AABB containing an OBB is to gather the min and max (x,y,z) coordinates of the corners of the OBB. When you have the min and max corners, that defines an AABB. That is the AABB which contains your OBB. If you want to contain more OBBs, just gather the min and max from every OBB's corners.

You can get a corner of an OBB by transforming a unit cube's corner by the OBB's World matrix.

There are probably more efficient methods though, but you could implement the simplest first and optimize when you find it too slow for your needs.

Good luck!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.