getMesh() from ofxAssimpModelLoader

Hi all,

I’m trying to figure out how to get a mesh from a model loaded using ofxAssimpModelLoader.
The aim is to manipulate this mesh using camera input like in the meshFromCamera example, but instead of displacing a plane, I’d like to displace a model (.obj)

Where do I start?

Check the assimpExample in ofApp.h is declared

 ofxAssimpModelLoader model;
 ...
 ofMesh mesh;

Then later in update
mesh = model.getCurrentAnimatedMesh(0);

Then again you can use de model.getMesh(parameter) where parameter is the index of the mesh contained in the model, o the name in form of string.

Thanks, I’ll try that.
I tried the model.getMesh(parameter) but must’ve done something wrong before, it kept giving the ‘no matching member function…’ error.
A nights rest and your tip that it’s actually the index of the mesh did wonders. I was trying to reference the name of the assimpModelLoader instance. :relaxed:

Ok, that works.
Using the image from the camera is not working though. The entire mesh is textured in a single (changing) color.
Probably this is only the 1st pixel of the camera image…

[edit] The problem is that all tutorials/posts/… I find are for meshes generated vertex by vertex, or simple planes. I want to wrap a texture around the mesh which comes from a model; nothing special, in a crude wrap-it-around way is good (the model has no UV coords or .mtl or whatever), but I’m having trouble understanding how to generate the texture coordinates…

I just figured this out! Sorry about a year late for you.

Also, this solution is only for using texture coordinates generated from a modeling program, which are then imported into oF using ofxAssimpModelLoader. (Actually, I’m only testing with OBJ files so this may not hold true for all model file formats).

In any case, if you load a model with texture coordinates through ofxAssimpModelLoader, the coordinates are then easily accessed by:

ofxAssimpModelLoader model;
model.loadModel("myModel.obj");
ofMesh mesh = model.getMesh(0); // replace 0 with the index of the mesh you want, if you have more than one mesh in the model
cout << "tex coords count: " << mesh.getNumTexCoords() << " : " << endl;
const vector <ofVec2f> texCoords = mesh.getTexCoords();
for (int i=0; i<texCoords.size(); i++){
    cout << texCoords[i] << endl;
}
cout << "end tex coords" << endl;

If you print the texCoords to the console, you’ll see that they are all ofVec2f values between 0 and 1. In this case, (0,0) corresponds to the top left of the texture, and (1,1) corresponds to the bottom right of the texture.

The issue is that openFrameworks defaults instead to use arbitrary texture coordinates - meaning it reads the texture coordinates as pixel coordinates rather than as percentages of the texture dimensions (floats between 0 and 1 - which is what the OBJ file gives you).

To solve this you simply need to call ofDisableArbTex(); in setup (or before you bind the texture).

Here’s the code:

class ofApp : public ofBaseApp {
public:
  // void setup(); etc...
  ofxAssimpModelLoader model;
  ofMesh mesh;
  ofImage tex;
}
void ofApp::setup(){
  tex.load("myTexture.jpg"); // custom texture
  model.loadModel("myModel.obj); // model containing texture coords
  mesh = model.getMesh(0); // replace 0 with index of desired mesh if more than one
  ofDisableArbTex(); // use normalized texture coordinates!!!
  ofEnableDepthTest(); // draw in order of depth to screen
}
void ofApp::draw(){
  tex.bind();
  mesh.drawFaces();
  tex.unbind();
}
1 Like