Blob contour to box2d b2EdgeChainDef

Hi,

I’m using the shape definition “b2EdgeChainDef” to recreate blobs contours in to a box2d world. All this works fine. The blobs can interact with other shapes in the box2d world [i.e. collision detection between blobs and circles].

Now I would like the blobs [b2EdgeChainDef] to be able to kick/throw away other shapes.
In fact, the same thing that happens when for example a moving b2CircleDef [with a mass] hit an other b2CircleDef [not moving].

Giving a mass/density to the b2EdgeChainDef does not seems to change anything.

Could this only be done with b2EdgeChainDef or should I recreate blobs contours using a chain of boxes ?

here is how I set the b2EdgeChainDef:

  
  
b2EdgeChainDef edgeDef;  
edgeDef.vertexCount = arraySize;  
edgeDef.vertices = verts;  
edgeDef.isALoop = true;  
edgeDef.density = 3.0f;  
edgeDef.restitution = 1.0f;  
body->CreateShape(&edgeDef);  
body->SetMassFromShapes();  
  

Thanks.

Hi

this is my example with openCv + Box2D

SORRY FOR MYENGLISH IS A FIRST TRY

http://vimeo.com/5830367

I Want To make better the reaction, like mouse evetns but with people anyone have idea how can i make this??

smallfly… I am looking at a similar problem right now.

I was wondering how you are updating your box2d blobs? Are you just like deleting it then rebuilding the whole thing? Or are you actually keeping the same box2d shape and updating its points and moving it?

I think if you wanted to be able to kick or push the shapes, using optical flow might be a better approach than using blob contours. Just an idea though.

There is also this: http://forum.openframeworks.cc/t/l/3435/0">http://www.box2d.org/forum/http://forum.openframeworks.cc/t/l/3435/0 about updating the points of a b2EdgeChainDef

Hi plong0,

Yep exactly. I delete and recreate every box2d blobs each cycle. Thinking about it, this is may be why I was not able to achieve what I was trying to do :).

I’m sure that using optical flow I would get the push action but not sure about the kick feeling though. The impact/collision between blob and box2d bodies would be missing.

Hugues.

have you considered a hybrid approach? I was thinking about something along the lines of doing what you are currently doing to get your blob into the box2d world (so it can collide with other box2d objects)… and then using optical flow to detect motions near your blobs and use that to generate the “push” force in the box2d world.

I am working on implementing something like that… I’m just having troubles getting my delaunay triangles into box2d properly. I implemented a delaunay triangulator add-on here and it seems to be doing its job pretty good.

The problem I am facing is that a lot of the points returned from the ofxCvContourFinder are too close together and some of the delaunay triangles are too small for box2d and when I try to create the polygon, I get errors like:

…/…/…/addons/ofxBox2d/scr/lib/Box2D/Source/Collision/Shapes/b2PolygonShape.cpp:224: failed assertion `d.x >= 0.0f’

I am wondering if you experienced any problems like this? I tried putting in a distance checker on my delaunay’s addPoint method, so points that are too close to pre-existing ones are not added. That reduces the number of triangles (so I only have larger ones), but doesn’t seem to solve the problem.

I saw your ofxDelauney addon and I’m going to try it soon ;).
I have already implemented a class to do voronoi, but I going for sure to have a look at your addon.
In fact, I was creating voronoi diagrams from blobs.

I never tried though to create box2d bodies from the voronoi ‘shapes’. But I never had this error when creating box2d bodies from blob countours.
I’m doing something quite similar to you. I’m smoothing the blobs contours in order to reduce the number of points before creating the box2d bodies.

@plong0

Yes box2d has some problems with polygons. You need to make sure that the area of the poly is large enough I think that it needs to be larger than 3px. If you are using a contour you should simplify the contour first then find triangles then do a inside poly test.

I have some code for this I will try and dig it up.

Another thing to check is to make sure that you are looping through the contour backwards when make a box2dLine. Box2d is not checking the other side of the line for collisions.

T

Hmm… thanks for the tips!

I just did some experimenting with simplifying the contours… basically I did a check to see if a point is a corner before I add it to the delaunay triangulator; and I also added a check in the delaunay triangulator’s addPoint method to make sure new points aren’t too close to existing points.

Results seem to be OK for some test images I made (haven’t tested with frame differencer contour yet).

Here is my code for adding the points to the triangulator:

  
  
			vector<ofPoint> points = blobs[i].pts;  
			int offSet = (points.size() > 10)?3:1;  
			ofPoint prevPoint, nextPoint;  
			for(int j=0; j < points.size(); j+=offSet){  
				prevPoint = (j > (offSet-1))?points[j-offSet]:points[points.size()-1];  
				nextPoint = (j < points.size()-offSet)?points[j+offSet]:points[0];  
				if(pointIsCorner(points[j], prevPoint, nextPoint))  
					triangulator.addPoint(points[j].x, points[j].y);  
			}  
			triangulator.triangulate();  
  

And here’s the corner-checking function:

  
bool testApp::pointIsCorner(ofPoint point, ofPoint prev, ofPoint next){  
	ofxVec2f v1, v2;  
	v1.set(point.x-prev.x, point.y-prev.y);  
	v2.set(point.x-next.x, point.y-next.y);  
	float angle = fabs(v1.angle(v2));  
//	cout << "angle:" << prev.x << "," << prev.y << "-" << point.x << "," << point.y << "-" << next.x << "," << next.y << ":" << angle << ":" << endl;  
	return (angle < 160.0);  
}  

Had to step over the points by 3 for the corner checking, otherwise the points from OpenCV’s contour almost always give an angle of 135… so comparing with a neighbour that isn’t directly adjacent seems to give better results.

It’s not a perfect solution, but it seems to work OK… I will post results when I test with contours from the frame differencer.

I am definitely open to any other approaches or ideas people have taken though!

If you are just trying to make the contour of a shape a box2d shape you dont even need to use triangulation. Just simplify the contour and make it a box2d line shape.

If you are using triangulation it gets tricky. polys can not have mass, they can not collide. they are hard coded a pit in ofxBox2dPoly(…) they will act simply as static shapes for things to bounce off.

I could be wrong but when ever trying to make a poly with a mass greater then 0.0 you get a assertion error (which i hate - dont use assert(…) )

I will post a demo of a contour box2d line… one sec


Here we go :slight_smile: box2d contours. It is using a little class ofxContourAnalysis which is really just a bunch of code from theo and triangle ++.

Here are the keys:

  
  
Threshold		      -- up key or down key  
Simple Amount	      -- left key or right key (how much to simplify the contour)  
DrawMode		      -- 1 key to toggle gray of color image  
Points Direction	      -- 2 key to toggle the direction of the points.  
Add some Balls	      -- space or b key to add big or small particles  
  

Download here:

http://toddvanderlin.com/OF/Box2dContour.zip

Oh! Yeah ! That’s looks a nice solution!

Awesome, thanks Vanerlin… that seems to be working nicely!

Next step for me is to try to combine optical flow with the frame difference-generated objects to get some “push” type interactions.

I’ll hopefully post an example soon.

Hey Todd

This looks really useful - was trying to do something very similiar at the start of the year and have just returned to the problem.

Unfortunately I can’t seem to compile your example - I get a slew of errors like:

Undefined symbols:
“ofxPoint3f::ofxPoint3f(float, float, float)”, referenced from:
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
poly_simplify(float, ofxPoint3f*, int, ofxPoint3f*)in testApp.o
ofxContourAnalysis::simplify(std::vector<ofPoint, std::allocator >&, std::vector<ofPoint, std::allocator >&, float)in testApp.o
ofxContourAnalysis::simplify(std::vector<ofPoint, std::allocator >&, std::vector<ofPoint, std::allocator >&, float)in testApp.o
“ofxVec3f::ofxVec3f(float, float, float)”, referenced from:
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
“ofxVec3f::operator=(ofPoint const&)”, referenced from:
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
“operator*(float, ofxVec3f const&)”, referenced from:
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
“ofxPoint3f::operator-(ofPoint const&) const”, referenced from:
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o
simplifyDP(float, ofxPoint3f*, int, int, int*)in testApp.o

Any pointers?

I’m on latest SVN 0.6 and a Mactel in Xcode…

Ok…not sure why but after copy pasting into a new project it all works fine! Great work :wink:

ya - i think that error was your ofxVectormath crapping out. I’m working off the svn the latest dumped the .cpp’s

T

Hi

i have a poblem, say something like “createBounds”

error: no matching function for call to `ofxBox2d::createBounds(int, int, int&, int&)’

exist a new version??

check my svn http://code.google.com/p/vanderlin/sour-…-s/ofxBox2d

Hi Vanderlin, thanks for your code…
I’m using yor box2d addon… is possible to upload your box2d contour to your google code account, your website reach the bandwidt limit :slight_smile:

sorry should be back up now :slight_smile:

hi - thanks heaps vanderlin for posting this awesome contour and box2d example! its exactly what i was looking for

it runs great but is throwing me a stream of errors (in OF 06 and 061) using the latest box2d from svn:

  
2010-02-11 11:23:28.286 openFrameworksDebug[2995:10b] GLUT Warning: GL error: invalid operation  

this seems to come from inside ofxBox2dCircle.setup() when called to create the particles somewhere in this code:

  
  
		body = world->CreateBody(&bodyDef);  
		body->SetLinearVelocity(b2Vec2(0.0, 0.0));  
		body->CreateShape(&circle);  
  

any clues as to how to resolve this? i have had no luck.
thanks in advance,
nay.