Skinning ofxBox2D objects

Sup OF geniuses!

I’m trying to texture the ofxBox2DRect object. I’ve seen posts on the forums asking for something similar, and people have suggested drawing an ofImage with the same coords and rotation as the box2d object. I’ve tried this and have run into some difficulty. There are big gaps between my objects and I can’t figure out why.

My coke cans are a simple extension of the ofxBox2dRect class:

  
  
class Can : public ofxBox2dRect {  
	  
public:  
      
	Can() {  
	}  
  
      
    ofColor color;  
    ofImage texture;  
      
	void draw() {  
		  
        glPushMatrix();  
        glTranslatef(getPosition().x, getPosition().y, 0);  
        glRotatef(getRotation(), 0, 0, 1);  
        ofSetColor(color.r, color.g, color.b);  
        ofFill();  
        ofEnableAlphaBlending();  
        texture.draw(0, 0, getWidth(), getHeight() );  
        glPopMatrix();  
		  
	}  
      
    void setup(b2World * b2dworld, float x, float y, float w, float h, ofImage _texture) {  
          
        ofxBox2dRect::setup(b2dworld, x, y, w, h);  
        texture = _texture;  
          
    }  
      
};  
  

The cans are being setup in a similar fashion to the other particles in the example:

  
  
    if(key == 'r') {  
        float w = 53;  
		float h = 100;  
		Can can;  
		can.setPhysics(3.0, 0.53, 0.1);  
		can.setup(box2d.getWorld(), mouseX, mouseY, w, h,tex);  
		cans.push_back(can);  
    }  
  
  

I’ve noticed that the ofBox2dRect class actually draws with an ofPath. Is it possible to fill an ofPath with an image? Any tips are much appreciated!

Cheers!

I should also mention that the can itself is the correct size as initialized and that the “ghost shell” is approximately double the dimensions of the can. The output of cout << getWidth() << “,” << getHeight() << endl gives me the right size.

Ok, I figured this out, but I thought I’d update this in case somebody has the same issue.

Key learnings:

  • Box2d figures its height and width with the registration point in the center. This means that any width or height you receive from box2d in needs to be multiplied by 2 if you wish to use a texture instead.

  • Since the registration point is in the middle, you might want to change the registration point of your texture to reflect this as well. Otherwise, your texture will be drawn in the wrong place.

New code:

  
class Can : public ofxBox2dRect {  
	  
public:  
      
	Can() {  
	}  
  
      
    ofColor color;  
    ofImage texture;  
      
	void draw() {  
		  
        glPushMatrix();  
        glTranslatef(getPosition().x, getPosition().y, 0);  
        glRotatef(getRotation(), 0, 0, 1);  
        ofSetColor(color.r, color.g, color.b);  
        ofFill();  
        ofEnableAlphaBlending();  
        texture.setAnchorPercent(0.50, 0.50);  
        texture.draw(0, 0, getWidth()*2, getHeight()*2 );  
        glPopMatrix();  
		  
	}  
      
    void setup(b2World * b2dworld, float x, float y, float w, float h, ofImage _texture) {  
          
        ofxBox2dRect::setup(b2dworld, x, y, w, h);  
        texture = _texture;  
          
    }  
      
};  
  

1 Like

Thanks for posting your results here, that’s great to see people filling out the knowledge on the forum a little more. I think this forum is an important resource and the more problems+solutions that there are on here, the better OF gets :slight_smile: