Search code examples
box2dgame-physicsliquidfun

Box2D Ring shape


What would be the best way to create a ring shape in Box2D (by ring I mean a dynamic circle with empty space inside, so that other dynamic objects can fit in it).

Thank you for your tips.


Solution

  • "Best" is of course is a matter of opinion, but here are some ways I can think of. Please tell us (like in the comment section) what you decide on going with. I'll be curious to know!

    For Static Ring

    If the ring shape only needs to be static, then building the ring out of the chain shape is the way to go. If the ring needs to be dynamic however, which is what it sounds like you're saying, then read on.

    For Dynamic Ring Without Inner Ring Friction/Restitution

    If you don't care about friction or restitution of objects against the inner ring, you could set the physics up by using the circle shape as the outer diameter of the ring and using the rope joint to constrain anything you want inside the ring (so longer as the collide connected setting of the joint is false). You'd just need to set the joint's max length to a distance that's less than the radius of the circle. This would allow the ring to roll naturally (since its outside is a circle) but wouldn't give you friction nor restitution effects within the ring against its conceptual inside.

    For Dynamic Ring With Fully Simulated Inner Ring Physics

    If the objects inside the ring need to be able to interact with the ring like any other surface that has friction and restitution, then the way I'd suggest making it (short of changing the Box2D code itself) would be out of a bunch of polygon shapes. These would all need to be positioned & sized to make the ring and affixed to a single body.

    You'll have to make decisions like how many polygons to make the ring out of and how to butt them together. The smaller and more numerous the polygons the closer of course the result will estimate a circular ring. Assuming you want as little jaggedness to the polygon overlapping as possible, you may want to set the body mass by hand to avoid the over-calculation from the overlap.

    Your ring will require a minimum thickness (including its "skin") of at least 2 * b2_polygonRadius. Beyond that it's up to you to size one of the polygon dimensions to match the thickness of the ring that you want.

    You'll probably want to write yourself a function which determines the points of the polygons that you'll need to match the location size and angular orientation relative to the body for the job. I could see making the ring out of 3-sided polygons or 4-sided ones. Using 4-sided polygons could create more butting issues (than using 3-sided ones) unless you spaced the inner points less (to match the diameter difference), however successive 4-sided polygons wouldn't need to be flip-flopped like for triangular ones.

    For Dynamic Ring By Modifying Box2D

    If you're willing/interested in changing the Box2D code you could either:

    1. Extend the mass calculation code and collision code to handle collisions with edge shapes and chain shapes. Or...
    2. Create your own ring shape type.

    Given that I've derived a Physics engine/library from Box2D which supports a dynamic ring shape using the chain shape (see PlayRho), I have some experience with solving this; albeit outside of Box2D. Based on this experience, if you do want to modify the Box2D code to solve the problem, I believe starting with the first choice (option #1) would at least be the way to begin. You'll wind up benefiting from the experience that will give you which I think you'd need anyway if you're going to do the second option.

    Note that the broad phase will require a composition of rectangles (AABBs actually) anyway for the ring. So making the ring out of a composition of polygons while seemingly less memory efficient than other ways I can think of doing this, may win out in terms of computational efficiency. YMMV. Testing will be the only way to know for sure.

    Or Maybe...

    It's possible someone has already made a ring shape for Box2D and provided sources for it but the only shape extensions I'm aware of is a capsule shape.