Edge Shapes for C++ (Merged!)

Here's the place to get help and discuss features. The focus is on the C++ version, but generic questions are welcome.
shaktool
Posts: 434
Joined: Sun Jan 20, 2008 7:52 pm
Contact:

Edge Shapes for C++ (Merged!)

Postby shaktool » Tue Oct 07, 2008 3:01 am

I have taken my Box2D branch down, because Edge Shapes are now merged into the main C++ Box2D branch. :)

Thanks to kne for the help with fixing bugs.

I have ported my line segment shapes from Flash to C++, and also updated the features, api, and robustness. :) As always, feedback and bug reports are welcome.

Example:

Code: Select all

// A concave square room:
float32 coords[] =
{
   -10.0f, -10.0f,
   -10.0f, 10.0f,
   10.0f, 10.0f,
   10.0f, -10.0f
};
b2Vec2 vertices[4];
for (int i = 0; i < 4; i++) {
   vertices[i].Set(coords[i*2], coords[i*2 + 1]);
}

b2BodyDef bd;
b2Body* body = m_world->CreateBody(&bd);

b2EdgeChainDef chain;
chain.isALoop = true; // connects the first and last vertices
chain.vertexCount = 4;
chain.vertices = vertices;
body->CreateShape(&chain);

Notes:
- The shapes are called b2EdgeShapes now. I dropped the word "Static" from the name because they're not forced to be static anymore.

- Edges Shapes have a "correct" side and a "wrong" side to collide with. Which is which depends on your coordinate system. If up is positive on the Y axis, floors go from right to left, and ceilings go from left to right. If up is negative, floors go from left to right and ceilings go from right to left. This is consistent with the vertex order of Polygons. If a shape touches the wrong side of an edge, it will be yanked to the correct side, after which it will collide with the correct side normally. However, there's no restriction on whether the edges form convex or concave geometry (which is really the whole point of these edges!).

- The definition object is called b2EdgeChainDef. Chain definitions are used to create adjacent b2EdgeShapes with shared vertices. Unlike b2PolygonDefs, you must allocate the memory for the arrays of vertices in the shape definition object on your own until you're done with the definition, and then you may deallocate the array. Also unlike b2Polygons, you're not limited to just eight vertices at a time. I added the word "chain" to the name of the definition files to emphasize that there is a one-to-many relationship between edge definitions and edge shapes. Technically, you can create one edge at a time by using chains with only two vertices, but that's less efficient and slightly less robust at continuous physics.

- You can attach the edge shapes to any body now, not just the ground body. b2Body::CreateShape() will create one b2EdgeShape for every pair of adjacent vertices in the definition file. It will return a reference to the first of these shapes. Each edge shape contains a reference to the next and previous edge shapes, so you can iterate over the edges after creating them if you want to tweak friction or restitution on them individually (be careful of infinite loops if the chain is a loop).

- Edge shapes can be dynamic. However, I don't really recommend it, aside from the novelty of it. They work fine if you turn on bullet mode for them, but they don't handle deep intersections very well, and they will only collide with polygons and circles. Edge shapes will never collide with each other. If you do decide to make dynamic edge shapes, don't forget to attach another shape to the same body, or maybe try messing around with b2MassData, since edge shapes always have zero mass and ignore the density property.

- There are three new TestBed examples, "StaticEdges", "PyramidStaticEdges", and "DynamicEdges".
Last edited by shaktool on Fri Nov 07, 2008 1:17 am, edited 5 times in total.

kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Thin Line Segment Shapes for C++ (beta)

Postby kne » Tue Oct 07, 2008 7:17 am

Great work!

Working well on Windows with a few modifications:

b2PolyAndEdgeContact.cpp:
Add these includes:

Code: Select all

#include "../../Collision/Shapes/b2EdgeShape.h"
#include "../../Collision/Shapes/b2PolygonShape.h"
b2Shape.cpp:
b2EdgeShape* edge has to be defined outside of the switch statement, so add this to the top of the function definition, so

Code: Select all

void b2Shape::Destroy(b2Shape* s, b2BlockAllocator* allocator)
{
   b2EdgeShape* edge;
...
   case e_edgeShape:
      edge = (b2EdgeShape*) s;
...
}

Minor inconvenience in the tests is that almost all of your numbers are set as doubles, so there are about 200+ warnings for double/float conversion. Fix attached.
Attachments
Tests.zip
StaticEdges.h/DynamicEdges.h doubles -> floats
(4.84 KiB) Downloaded 340 times

shaktool
Posts: 434
Joined: Sun Jan 20, 2008 7:52 pm
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby shaktool » Tue Oct 07, 2008 10:50 pm

Excellent, thank you! I am relatively inexperienced with both Windows and C++ (preferring Mac and Flash), so I'm glad to receive help here. It's especially important to get it right for C++ if there is to be any hope of keeping the edge shape up to date with the rest of Box2D, and maybe even getting it integrated into the main branch eventually.

I've updated the .zip at the top of my first post with your changes.

kne
Posts: 88
Joined: Mon Feb 18, 2008 12:30 am

Re: Thin Line Segment Shapes for C++ (beta)

Postby kne » Fri Oct 10, 2008 10:13 am

My apologies, it appears I had made one more change for it to compile that I didn't mention. Add to b2EdgeAndCircleContact.cpp:

Code: Select all

#include "../../Collision/Shapes/b2CircleShape.h"
Works in both MinGW and VC++ Express 2008 with v2.
Another thing I think you should do is set vertices to NULL in the b2EdgeChainDef constructor (just for good form).

Do you think you could put your code on source control so that we might be able to see the changes between your versions? It'll help a lot for someone like me who will want to merge the latest SVN versions of both the Box2D code and thin line segment code.

Also, I ported it to pybox2d this morning. For those interested, see here http://pybox2d.blogspot.com :)

mm2d
Posts: 31
Joined: Sat Sep 06, 2008 3:47 am
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby mm2d » Mon Oct 13, 2008 4:37 am

Works great, thanks a lot!
Some kind of patch would be good, instead of releasing the whole thing.

mm2d
Posts: 31
Joined: Sat Sep 06, 2008 3:47 am
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby mm2d » Tue Oct 14, 2008 1:01 pm

If a shape touches the wrong side of an edge, it will be yanked to the correct side,


I don't want this to happen. Nothing should happen if the collision happens from the wrong side. How can I do that?

shaktool
Posts: 434
Joined: Sun Jan 20, 2008 7:52 pm
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby shaktool » Tue Oct 14, 2008 1:57 pm

Determine, prior to contact, whether the object is above or below the edge, and set the contact filter accordingly, as demonstrated by Tinger:

http://www.huesforalice.com/resource/86

mm2d
Posts: 31
Joined: Sat Sep 06, 2008 3:47 am
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby mm2d » Thu Oct 16, 2008 9:57 am

Sounds complicated for something simple. I mean, isn't there just a code part in the edges code that does that shifting?

shaktool
Posts: 434
Joined: Sun Jan 20, 2008 7:52 pm
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby shaktool » Thu Oct 16, 2008 10:37 am

Well, yes. It's the same code that detects the collisions from the correct side. It can't tell the difference between approaching from the wrong side, and just having a really deep collision.

BorisTheBrave
Posts: 1911
Joined: Mon Jan 07, 2008 10:51 am
Contact:

Re: Thin Line Segment Shapes for C++ (beta)

Postby BorisTheBrave » Thu Oct 16, 2008 11:18 am

Before anyone else says it should be a simple thing, try to consider the case of a single one-way edge on it's own. How should it behave when you are near the ends of the edge? If anyone can answer that satisfactorily, they get a cookie. Or even if you disallow open edges, for that matter, you still get similar confusions near convex angles.


Return to “General Discussion”



Who is online

Users browsing this forum: No registered users and 2 guests