Anyone has an idea about how to dynamically change the internal meshes of an ofxAssimpLoader?
In particular I need to move some single vertices of the mesh every frame.
I saw that internally the type aiMesh is used and a mesh helper is used to wrap aiMesh for draw() but I have no idea how to tweak them without too much hassle.
Of course ofMeshes can be obtained by loader.getMesh(idx) or loader.getCurrentAnimatedMesh(idx), so I could directly access vertices of those “copies” and change them.
And after I could draw the meshes independently from the loader.
In a short pseudo code I’m trying this
BTW: I checked my file has only 1 mesh so for now I get only mesh(0).
ofMesh mesh;
ofxAssimpModelLoader loader;
ofCamera cam;
void setup()
{
loader.loadModel("modelFile.obj");
mesh = loader.getMesh(0);
}
void draw()
{
for(int i = 0; i < mesh.getNumVertices(); i++)
{
mesh.getVertex(i).x = someNewValue;
mesh.getVertex(i).y = someNewValue;
mesh.getVertex(i).z = someNewValue;
}
cam.begin();
mesh.drawFaces();
cam.end():
}
But it does not work, what I get is a blank window, even if I don’t touch vertices.
If I instead do
void draw()
{
cam.begin();
loader.drawFaces();
cam.end():
}
the model is shown correctly with colors and textures.
So I’m pretty sure I’m doing something wrong and/or I’m misunderstanding something.
Actually these are two questions, I will be happy if someone knows the answer for at least one…
UPDATE
If anyone is interested, i found that the only way to modify model’s meshes vertices is by adding a function to the addon, in ofxAssimpModelLoader.h file.
I added a public function to get an ofxAssimpMeshHelper pointer for the mesh I’d like to tweak, from a protected internal vector which holds all the model mesh helpers;
This way I can access:
- the cached model mesh, which holds the vertices set up by the loadModel() function
- the vbo which gets redrawn in drawFaces() and which needs to be updated after mesh tweaking
addons/ofxAssimpModelLoader/libs/assimp/src/ofxAssimpModelLoader.h
// add this somewhere before the "protected" statement
public:
ofxAssimpMeshHelper* getModelMeshHelper(int i) { return &modelMeshes[i]; }
protected:
.................
This is an example of how to use it.
It’s a modification of “3DModelLoaderExample” project in the examples folder.
The penguin model becomes “sparkling” by adding every frame a random value to all the vertices’ xyz coordinates
3DModelLoaderExample.cpp
void ofApp::draw()
{
// so the model isn't see through.
ofEnableDepthTest();
light.enable();
cam.begin();
if (bUsingMesh){
// draws the ply file loaded into the mesh is you pressed
meshNode.transformGL();
mesh.drawFaces();
meshNode.restoreTransformGL();
}
else
{
/////////////////////////////////////////////////////////////////////////////////
// modified part starts here
/////////////////////////////////////////////////////////////////////////////////
// the mesh helper: it exposes pointers to some internal data structs and variables
ofxAssimpMeshHelper* helper = model.getModelMeshHelper(0);
// pointer to an internal ofMesh exposed by the helper, which holds a copy
// of the model's vertices: it is used by ofxAssimpModelLoader drawing methods
ofMesh* cachedMesh = &helper->cachedMesh;
// model vertices loaded from the file are stored in an internal aiMesh struct,
// which is exposed by the helper; their xyz coordinates are copied
// to cachedMesh vertices but adding some random values
for (int i = 0; i < cachedMesh->getVertices().size(); i++)
{
cachedMesh->getVertices().at(i).x = helper->mesh->mVertices[i].x + ofRandom(-0.01, 0.01);
cachedMesh->getVertices().at(i).y = helper->mesh->mVertices[i].y + ofRandom(-0.01, 0.01);
cachedMesh->getVertices().at(i).z = helper->mesh->mVertices[i].z + ofRandom(-0.01, 0.01);
}
// update internal vbo before model drawing
helper->vbo.updateMesh(*cachedMesh);
/////////////////////////////////////////////////////////////////////////////////
// modified part ends here
/////////////////////////////////////////////////////////////////////////////////
model.drawFaces();
}
cam.end();
light.disable();
ofDisableDepthTest();
// display help text if it is enable
if(bHelpText) {
stringstream ss;
ss << "FPS: " << ofToString(ofGetFrameRate(),0) << endl << endl;
ss << "(1/2/3/4/5/6): load different file types"<<endl;
ss << "Current file info: " + curFileInfo <<endl;
if(bUsingMesh){
ss << "Use ofEasyCam mouse and key controls to navigate."<< endl <<endl;
}
ss <<"(h): Toggle help."<<endl;
ofDrawBitmapString(ss.str().c_str(), 20, 20);
}
}
1 Like
Thanks mate, super useful