ofMesh texture coordinates and ofxBox2d polygons

Hi!! im developing my first OF app, im Using Kinect and Box2d add ons. i have already make work the integration successfully, but now im trying to make a textured polygon using the example of the ofxBox2d addon, but with my own drawings, i have make a list of the vertices points of the texture but i can’t make it work. the polygon have the desired form but the texture is a mess…i can’t understand how texture coordenates work, im really beginner with this kind of development, here are my questions:

  1. Someone can explain how addTexCoord work if i have a custom imagen and a custom form or polygon?(exactly i want to make a box2d polygon with a turtle form and drawing).

  2. What its the best method for do the texturing for box2d texturing thinking in performance?

  3. someone know links or examples for do that?

here it my actual code

static ofPoint points[6] = {ofPoint(6.000,33.000),ofPoint(213.000,17.000),ofPoint(470.000,61.000),ofPoint(798.000,304.000),ofPoint(740.000,470.000),ofPoint(262.000,412.000)};

void setup(ofxBox2d &world, float cx, float cy, float r) {
    
    color.setHex(hexColors[(int)ofRandom(4)]);
    
    mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
    int   nPts  = 6;
    float scale = r / (float)texturePtr->getWidth();
    for (int i=0; i<nPts; i++) {
        float n = ofMap(i, 0, nPts-1, 0.0, TWO_PI);
        float x =points[i].x;
        float y = points[i].y;
        float d = ofRandom(-r/2, r/2);
        polyShape.addVertex(ofPoint(cx + (x * r + d), cy + (y * r + d)));
        mesh.addTexCoord(ofPoint(0, 0));
        mesh.addTexCoord(ofPoint(x * scale, y * scale));
    }
    
    polyShape.setPhysics(0.3, 0.5, 0.1);
	polyShape.create(world.getWorld());


}

void draw() {

    mesh.clearVertices();
    vector<ofPoint> &pts = polyShape.getPoints();
    ofPoint center       = polyShape.getCentroid2D();
    for (int i=0; i<pts.size(); i++) {
        mesh.addVertex(center);
        mesh.addVertex(pts[i]);
    }
    mesh.addVertex(center);
    mesh.addVertex(pts.front());
    
    ofSetColor(color);
    texturePtr->bind();
    mesh.draw();
    texturePtr->unbind();

}

thanks in advance

It’s a bit difficult to understand what you’re doing exactly because your mesh construction is a little convoluted. Here is a breakdown of how meshes are constructed in general terms.

Inside the mesh is just a list of different attributes: vertex, index, color, texCoord. Each point (VERTEX) in the mesh will have an INDEX that tells the mesh how it needs to be assembled according to the mesh mode (triangle strip in your case. You haven’t specified the indices so the mesh just sets the indices to the order you added them, 0, 1, 2, etc., then assembles it according to OF_PRIMITIVE_TRIANGLE_STRIP. The addColor() method sets the color per vertex. All this info is needed PER VERTEX.

A texCoord is how you tell the mesh how the texture is going to be laid out with respect to the vertices. Think of a layer of vertices underneath and a layer of texture on top. A texCoord would be like taking a pin and fixing a point in the image to a specific vertex. You need to drop a pin (texCoord) for each vertex so it knows what part of the image to attach to. The cool thing is you can attach the vertex anywhere on the texture you want and the mesh will stretch or shrink the texture to fit the triangle between the vertices.

The easiest way to do it is to attach the texcoord as soon as you add a vertex. Simplistically, as long as the pixel values of the vertex are within the dimensions of the image it should be fine. Some overly simplified pseudo code would be here:

ofPoint points[numPts] = {...}

ofMesh mesh;
for(int i = 0; i < numPts; i++){
    mesh.addVertex(points[i]);
    mesh.addTexCoord(points[i]);
}

Try to add them all at the same time in the beginning:

In for loop:
...
ofPoint p( cx + (x * r + d), cy + (y * r + d) );
polyShape.addVertex(p);
mesh.addVertex(p);
mesh.addTexCoord(p);

//Optional bit to also tint that vertex red :D
mesh.addColor( ofFloatColor( 1.0, 0.0, 0.0) ); 

That way the texCoords are set with respect to the vertices in the right places. THEN you can clearVertices(), which leaves the texCoords in tact and reset the vertices to where the polyshape points are. Again: this will work if the image you use for your texture is large enough pixel-wise to fit the maximum value of the point you’re attaching it to. If the texture is too small, use the following line (like you have above) with scale less than 1.0

mesh.addTexCoord(ofPoint(x * scale, y * scale));

Hope that helps.

Hi afernadez, thank you for take the time and make this clear explanation was very useful for me, i had doing all wrong, i had been confused because some examples were using the center of the polygon always I made a call of texcoord.

Im not get it work but am more close now:

  1. i try doing creating the mesh in setup, but the problem is it don’t move with the polyshape, the i change to draw and it move, but the polyshape have the desire form but the texture it cropped.

  2. if i put the mesh.clearvertices() after the loop don’t shows anything and if i puts after the loops works, but the texture still cropped.

  3. maybe something with the trangulation with the shape its affecting the texture coords, because the same vertices coords are used for the creations of both polyshape and mesh, but the mesh its totally mess.

  4. for some reason if i don’t use scale factor for the texcoords the texture despairs, the problems is the image its bigger and supposedly its have to fit with that coords, in fact i use a tool for game develop where i can draw the vertices over the image.

void setup(ofxBox2d &world, float cx, float cy, float r) {

    color.setHex(hexColors[(int)ofRandom(4)]);
    
    mesh.setMode(OF_PRIMITIVE_TRIANGLE_STRIP);
    int   nPts  = 6;

    for (int i=0; i<nPts; i++) {
         float x =pointsb[i].x;
         float y = pointsb[i].y;
     
        ofPoint p(x , y);
    polyShape.addVertex(p);

//            mesh.addVertex(p);
//            mesh.addTexCoord(p);
      //  mesh.addColor( ofFloatColor( 1.0, 0.0, 0.0) );
                     
     }
    polyShape.setPhysics(0.3, 0.5, 0.1);
	polyShape.create(world.getWorld());

}

void draw() {

    mesh.clearVertices();
    float scale = 1 / (float)texturePtr->getWidth();
    vector<ofPoint> &pts = polyShape.getPoints();
    for (int i=0; i<pts.size(); i++) {
        // mesh.addVertex(center);
        mesh.addVertex(pts[i]);
        mesh.addTexCoord(ofPoint(pts[i].x *scale,pts[i].y *scale));
        mesh.addColor( ofFloatColor( 1.0, 0.0, 0.0) );
    }

     ofSetColor(color);
    polyShape.draw();
    texturePtr->bind();
    mesh.draw();
    texturePtr->unbind();

}

here it how it working now

the top is how it working now image and the next is how is the imagen and the the desired vertex coords

if you see the polygon its flipped in the first imagen , i don know why this happen.

well i hope be more clear with this images, my english its very confuse i know.

thanks and best regards

I will give a longer reply later, if needed, but for now here are a few suggesions:

  1. Your polyshape seems to be assembled with all the points going in a clockwise loop. Try setting your mesh mode with:

mesh.setMode(OF_PRIMITIVE_LINE_LOOP);

  1. Instead of clearing the mesh vertices, try resetting them, like this:

for(int i = 0; i < mesh.getNumVertices(); i++){
mesh.setVertex( i, pts[i] );
}

  1. Do not touch the texCoords after the setup. Once you have set the texCoordinates, you should not need to touch them again. The anchor points for the image have been set and associated with the specific vertices in the mesh and more importantly, in the correct order as the vertices in the mesh. The reason it looks even weirder as you progress is that you keep adding more and more texCoords on TOP of the ones you set every loop before it ( clearVertices() doesn’t clear texCoords, just vertices).

Try that and let me know if that works.

Hi afernandez, thanks again. well i have made the changes and the resetting the vertices works, now i can make all in setup function, but when i change the mesh mode to line loop the app just render a counter line without any fill.

I have try with the others modes of the mesh and the OF_PRIMITIVE_TRIANGLE_FAN looks more close but still rendering deformed

up is with line loop and down with triangle fan

any suggestion ?..

thanks

Hey Nexonbird,

Yes, OF_PRIMITIVE_TRIANGLE_FAN works better. I forgot line_loop does not fill in the mesh.

I think you might be overcomplicating it a little bit. This should be all the code you need in your update():

mesh.clearVertices();
vector<ofPoint> &pts = polyShape.getPoints();
for (int i=0; i<pts.size(); i++) {
    mesh.addVertex(pts[i]);
}

or

vector<ofPoint> &pts = polyShape.getPoints();
for (int i=0; i<pts.size(); i++) {
    mesh.setVertex( i, pts[i] );
}

They’re both the same (but the first is probably faster)

Workflow: Clear out the mesh, and add new points in the same order as usual from the polyShape points vector. The texcoords should only be added in setup and never touched again. No need to add the center point or anything else. The mesh does not need the center to interpolate the image between the edge points.