Box 2d tutorials

Hi OFers
I’m still relatively new to OF (shifting up from Processing) and am finding my way for basic things but there are issues with syntax particularly around implementing Box 2D that I can’t seem to get. I’m a musician not a code head so while I am prepared to work at coding it would be great if I could have access to tutorials that explain code like:
circles.back().get()->setPhysics(6.0, 0.93, 0.1);

This is part of an example for ofBox2d. I’ve read Shiffman’s tutorials on Box2d looked at the Box 2d Manual and can’t find a reference to setPhysics. Nor can I get my head around how ofPtr is used in these examples. I’ve gone through the tutorials on references and pointers but a explanation of their specific use in Box 2d would save me days of head scratching and chin stroking. Are there any tutorials that might help me out?

Hi there, I’m new to OF too but I’ve spent some quality time with C/C++; it sounds like the issue you’re having is programming related rather than OF-specific. I suggest looking up some tutorials on accessors in C++ (like the dot and arrow operators) to understand what’s going on in code like this.

I can tell you about this specific line though, it’s basically a bunch of chained function calls:

circles.back().get()->setPhysics(6.0, 0.93, 0.1);

“circles” is some kind of collection, probably a vector, which holds a bunch of “Circles.” back() is a function that is called on the circles vector, it returns a reference to the last element in the vector. get() is a function called on that last element, which from how it looks, returns a pointer to a single Circle. Finally setPhysics() is called on the pointer to the last Circle referenced in the vector, so now that Circle object’s internal data will have been modified based on whatever that function does.

The ‘dot’ and ‘arrow’ operators are very similar, the difference is that the arrow is used to call functions on a pointer to an object, where the dot is for objects directly (again, you should look up some info on how that works).

If you’re ever unsure of what a function does, you can usually look it up; just type the object type and the function name into google and usually there’ll be a description somewhere of the function. If the source code you’re working with is well-commented, functions should have descriptions above their declarations in the code files as well (you can normally command-leftclick to see the function info, if you’re using an IDE). Hope that helps some!

1 Like

So the setPhysics function just sets the density, bounce and friction (in that order) of the object (in your case, the circle).

The density is used in conjuction with other objects to figure out how the mass should be distributed in a parent body.
Bounce is exactly what it sounds like: it tells the object how much to bounce when it hits another object.
Friction is used to determine how much two objects slow down when they’re sliding against each other.

Keep in mind that Box2d is not an openFrameworks specific system. It’s a physics engine that has been adapted into openFrameworks, so to understand the concepts behind it, read some of the more general documentation (I know you’ve already seen the manual, but for others who happen upon this thread later, it’s here: http://www.box2d.org/manual.html) and tutorials (this is a good intro, although it’s meant for processing: http://natureofcode.com/book/chapter-5-physics-libraries/).

For OF addon specific syntax, look at the source code to get a good idea, either by right clicking a function/variable of the addon and going to its definition, or by looking here: https://github.com/vanderlin/ofxBox2d/tree/master/src. It’s very well written and uses really self-explanatory function and variable names. If you spend a half hour looking at various parts of it, you can get a pretty good general sense of how it works, especially if you’ve read the non-OF specific stuff already.

As an example, if I were wondering about setPhysics, I would look at the ofxBox2dBaseShape.cpp file (since all shapes use it) and look for the function there. When I find it, I see it takes three arguments, and all it does is set the class member variables to those arguments. Then, if that wasn’t enough and I wanted to know more about what those three things do, I would look them up in the manual.

Honestly though, I find it most helpful to experiment! Get two circles, change their physics values and throw them against each other in various ways to see what happens.

Also, Jag is right, that to understand pointers and such things, you should look beyond Box2D and at C++ in general.

Hope that helps!

1 Like

Thanks jag and tabularasa1992 for your detailed responses. All helpful stuff and the suggestions about looking up definitions inside the addon code is useful. My question really is about knowing the extent to which ofBox2D differs from the manual and explanations like Shiffman’s. For example a thing in box 2d (according to Shiffman and this is documented in the box 2d manual) has a body and a shape which is attached via a fixture. Where is fixture in ofBox2d? Or body? Fixtures have the bounce (restitution in the manual), density etc parameters but it seems in ofBox 2D this is in the shape. Bodies (in Shiffman’s tutorials and the manual) can be dynamic, static, of kinematic but where are these attributes in ofBox2D? These differences are significant and for me it calls into question what I already know about box2d and how box2d it is structured at the higher levels in OF.

Heres some further questions arising from experiments with ofBox2D. I just tried to alter the code example “Simple” where I changed:
if(key == ‘c’) {
float r = ofRandom(20, 60);
circles.push_back(ofPtr(new ofxBox2dCircle));
circles.back().get()->setPhysics(6.0, 0.93, 0.1);
circles.back().get()->setup(box2d.getWorld(), mouseX, mouseY, r);
}

to

if(key == 'c') {
	float r = ofRandom(20, 60);
	circles.push_back(ofPtr<ofxBox2dCircle>(new ofxBox2dCircle));
	circles.back().get()->setPhysics(6.0, 0.93, 0.1);
    circles.back().get()->setVelocity(ofRandom(-30, 30), ofRandom(-30, 30));
	circles.back().get()->setup(box2d.getWorld(), mouseX, mouseY, r);
	
}

I looked up the definition of setPhysics (as you suggested tabularasa1992) and setPhysics in is in ofxBox2dBaseShape. I noticed that setVelocity is also part of ofxBox2dBaseShape. So I wanted to see if I could get a body to move by adding velocity and as it is in ofxBox2dBaseShape it seems logical enough to add velocity in the same way that physics parameters are added. But nothing happens - neither does addForce do anything. So where to go from here? Short of learning about references and pointers in great detail I don’t know. Even if I do understand pointers and references better there is no information about adding velocities to bodies. There is an example where you can add velocity to a custom body but is this the only way it can be done? How can I find this kind of thing out?

Lucky for you, it has nothing to do with pointers. Neither of those functions (and as far as I know, this is true for most of the things you can do to a body) will work before calling setup. Move setVelocity below setup and it will work just fine.

What you’re basically doing here is trying to tell it to move a certain way before it knows it’s part of the world. When the setup function gets called, the body gets assigned to a fixture in the box2d world and initializes itself. The values provided by setPhysics are used in the setup function and applied to the created fixture, but the values from setVelocity are not, so they get lost when you call setup.

Sometimes it takes a couple of class jumps, but if you keep following the declarations, you’ll get to the bottom of it eventually.

Also, to answer your earlier question, I haven’t read Shiffman’s tutorials, but: I believe ofxBox2d bodies can only be static or dynamic. I don’t see anything about a third category from a quick glance (I could be wrong). Fixture is in b2Fixture.h (in the libraries folder). Similarly, body is in b2Body.h.

tabularasa1992 thanks for your comments. I feel that interrogating the code of ofBox2D is beyond my abilities at present.