Getting real vertex positions from an ofxAssimpModelLoader

I’m trying to get bounding boxes for all 3d models of a project. I have 2 types of model: “ofMesh” for models that i create “manually” and “ofxAssimpModelLoader” for loaded models.

for the ofMesh that i create “manually”, i use this method to find 2 opposite corners of my bounding box:

void Renderer::getBoundingBox(const ofMesh& aMesh, glm::vec3& cornerMin, glm::vec3& cornerMax) {
    const vector<glm::vec3> vertices = aMesh.getVertices();
    if (vertices.size() > 0) {
        cornerMin = vertices[0];
        cornerMax = vertices[0];
    }
    for (int i = 0; i < vertices.size(); i++) {
        cornerMin.x = MIN(cornerMin.x, vertices[i].x);
        cornerMin.y = MIN(cornerMin.y, vertices[i].y);
        cornerMin.z = MIN(cornerMin.z, vertices[i].z);
        cornerMax.x = MAX(cornerMax.x, vertices[i].x);
        cornerMax.y = MAX(cornerMax.y, vertices[i].y);
        cornerMax.z = MAX(cornerMax.z, vertices[i].z);
    }
}

It works and gives me the real position of my vertices in my 3d scene. For the imported meshes, i use this method:

void Renderer::getBoundingBox(const ofxAssimpModelLoader& mesh, glm::vec3& cornerMin, glm::vec3& cornerMax) {
    vector<glm::vec3> vertices;   

    for (int i = 0; i < teapot.getNumMeshes(); ++i) {
        vector<glm::vec3> currentMeshVertices = teapot.getMesh(i).getVertices();

        vertices.insert(vertices.end(), currentMeshVertices.begin(), currentMeshVertices.end());
    }

    if (vertices.size() > 0) {
        cornerMin = vertices[0];
        cornerMax = vertices[0];
    }

    for (int i = 0; i < vertices.size(); i++) {
        cornerMin.x = MIN(cornerMin.x, vertices[i].x);
        cornerMin.y = MIN(cornerMin.y, vertices[i].y);
        cornerMin.z = MIN(cornerMin.z, vertices[i].z);
        cornerMax.x = MAX(cornerMax.x, vertices[i].x);
        cornerMax.y = MAX(cornerMax.y, vertices[i].y);
        cornerMax.z = MAX(cornerMax.z, vertices[i].z);
    }
}

What i get are very small coordinates. Furthermore, even if my model is moving around, the vertex positions remain constant. It seems that i’m getting the coordinates i would find in a “obj” file instead of the real positions of the vertices in my scene. Is there a way to convert those coordinates to get the real positions of the vertices in my 3d scene?

Hi,

I might be wrong, but I’ve encountered a similar problem recently.

3D Models gets rescaled automatically when loaded with the ofxAssimpModelLoader due to normalization , which explains the small coordinates versus the size of your model.

Either disable the Normalization with “your3dmodel.setScaleNormalization(false);”

Or find the Model scale factor and multiply it on your bounding box dimensions.
This works “float norm = your3dmodel.getNormalizedScale();”

Hope this helps !

without the normalization, the model looks like a small dot. It’s to be expected since all vertices of the mesh are in positions that vary in range from like -1 to 1. But it’s not just the scaling, all vertices always show up at the same position as well, even when the object is moving around. Furthermore, there are some negative positions. There must surely be a way to get that info. Knowing the position of a model and it’s bounding box does seem important for many applications. Like for example, if you are building an fps engine, how would you know where your hit boxes are if you cant find your model’s mesh position…

Not sure if it works but I would try to:
multiply your output coordinates by assimpModelLoader getScale()
and sum with .getPosition()
if you don’t need bounding box for rotated objects.

the position returned is always at (0,0,0), no matter where the model really is.
The scale matches the value i set with “setScale”, but there seems to be another scale applied as well.

Our teacher suggested us to use this framework for our project. That was the biggest mistake i made. Everything is overly complicated, and some basic functionality are way harder to find than they should. I mean, it seems logic that users of a mesh or a model would want to get the real scene positions of the vertices at some point. Why is it so hard to find?

The multi windows functionality and the listener systems are both the worst i’ve ever used as well. And there is almost 0 comments in the code, 3/4 of the features are undocumented, and the documentation almost always only give a list of constructors when available. sry, i had to vent :slight_smile: I wasted so much time with this framework.

I’ve finally found the solution. The code i’ll show here is to convert the min and max vertices of the model (aka if you want to do a bounding box). But it will work for any vertex of your ofAssimpLoader model.

void Renderer::getBoundingBox(ofxAssimpModelLoader& model, glm::vec4& cornerMin, glm::vec4& cornerMax) {
    mat4 modelMatrix = ofMatrix4x4::getTransposedOf(m_model.getModelMatrix());
    glm::vec3 min = m_model.getSceneMin();
    glm::vec3 max = m_model.getSceneMax();

    cornerMax.x = max.x;
    cornerMax.y = max.y;
    cornerMax.z = max.z;
    cornerMax.w = 1;
    cornerMax = cornerMax * modelMatrix;

    cornerMin.x = min.x;
    cornerMin.y = min.y;
    cornerMin.z = min.z;
    cornerMin.w = 1;
    cornerMin = cornerMin * modelMatrix;
}

One thing thats very confusing:

Here: ofMatrix4x4 | openFrameworks they say:

oF uses row-vector style by default, meaning that when transforming a vector by multiplying with a matrix, you should put the vector on the left side and the matrix (or matrices) to its right. When multiplying by multiple matrices, the order of application of the transforms is left-to-right. This means that the standard order of manipulation operations is vector * scale * rotate * translate.

But as you can see in my method, i’m transposing the matrix, but i still have to put the vector on the left side of the multiplication. It’s the only way i was able to get the real vertex positions correctly.

1 Like

Hey @Thormind , I’m glad you got this working! I know that oF can be a challenging and I understand the desire to vent frustrations in the forum. However, I’m not sure that venting is constructive in any way. oF is developed by a community of users. It has adapted over the years to the many changes in c++. If you see some things that can be done better, or things that could be added, you’re welcome to join the ongoing effort. In the meantime, the forum is a great place to search for previous posts on topics and also ask questions. You should find that people are helpful and thoughtful, both now and in the past. And be patient with the learning curve. Like anything else in life, oF takes some time to learn and understand. Have fun!