Chain - doesn't rotate

Hey guys,
I’m trying to use dynamic Edge Shape (Chain) Body - by drawing a line on the screen, then translate it to physic obj.
And while gravity works on it fine - the object is not rotateable. Even if I draw a line - it just stuck at the same orientation.

Did I forget to change something?

This kind of question is a perfect candidate for a mini-demo that you upload so we can download it, look at it, and run it. Just a main.lua file with the minimum set of code is enough.

In fact, you could probably demonstrate this in about 50 lines of code or less and then just paste it here between two sets of three-ticks

```
pasted code here
```

will produce this:

pasted code here

Sure. Easy.

W=display.contentWidth;
H=display.contentHeight;
local physics=require("physics");
physics.setDrawMode("hybrid");
physics.start();

function newGroup(parent)
	local mc = display.newGroup();
	parent:insert(mc);
	return mc
end

local bg=display.newRect(W/2,H/2,W*2,H*2);
bg:setFillColor(113/255/2, 170/255/2, 157/255/2);

local game = display.newGroup();
local face = display.newGroup();

local linemc;
local touchStarX, touchStarY;
bg:addEventListener("touch",function ( e )
	if(e.phase == "began")then
        linemc = display.newGroup();
        game:insert(linemc)
        touchStarX, touchStarY = e.x, e.y;
    elseif(e.phase == "moved")then
		local r = 4;
		local rr = r*r;
		local prev = linemc[linemc.numChildren];
		if(prev)then
			local dx, dy = prev.x - e.x, prev.y - e.y;
			local dd = dx*dx + dy*dy;
			if(dd<rr)then
				return
			end
		end
		local b = display.newCircle(linemc, e.x, e.y, 3);
		b:setFillColor(8/10);
    else
		if linemc.numChildren > 1 then
			local a1 = linemc[1];
			local b = newGroup(game);
			b.x, b.y = a1.x, a1.y;
			local chain = {};
			for i=1,linemc.numChildren do
				local p = linemc[i];
				table.insert(chain, p.x-b.x);
				table.insert(chain, p.y-b.y);
			end
			for i=linemc.numChildren, 1, -1 do
               local p = linemc[i];
               b:insert(p);
               p:translate(-b.x, -b.y)
			end
			physics.addBody(b, "dynamic",
				{
					chain = chain,
					connectFirstAndLastChainVertex = false,
					density = 1, friction = 0.1, bounce = 0.1
				}
			)
		end
    end
end);

for i=1,10 do
	local b = display.newRect(game, 100+100*i, H-100, 50, 50);
	physics.addBody(b, "static");
end

Now sure how it will help =)

It helps because I generally find I can’t be sure the descriptions folks give correctly describe that goal(s) people have and the problem they are encountering. Communicating is hard. We always think we’re being clear, but then the folks reading what we say may interpret what we mean differently.

It is always better to have a run-able example demonstrating the issue. This is why I almost always provide a downloadable micro-project when talking about issues and examples.

Also, by forcing yourself to make such a demo one will often find the problem. i.e. By simplifying the issue and being forced to demonstrate it you get a second look at the problem that is often illuminating.

I’ll dump the code you pasted into a file and run it, then I’ll re-read your post and see if I can work out what isn’t working and if there is a solution. It will be a bit before I get to do this.

You did not forget anything. This is one of the limitations of Box2D chain shapes.

(Bear with me. Long answer, but I promise to get to where you need to go eventually.

Please note, Corona SDK/Solar 2D has not always supported chain shapes. We have had them for a long time, but not from the start. That said, I believe the docs may be a little bit light with regards to this body type and its limitations. (https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#edge-shape-chain-body)

Originally (I believe) Box2D introduced the chain shape to allow users to make complex static shapes that have the ability to be collided with by other simple dynamic objects. These are often used for terrains and such, but have been used in many other clever cases. Note: The shape now supports all body types as you know.

These shapes may violate the ‘no concave’ shapes rule and thus have no definable inside or outside. Instead, collisions with these bodies are determined based on line versus shape collision calculations where the line is the nearby segment(s) of the chain shape.

If you’re familiar with collision detection calculations, you will know that handling arbitrary shapes can become immensely costly. This is probably the reason that the author(s) of Box2D placed some limitations on the shape. Those limitations are:

  • Body cannot rotate - You discovered this. Allowing it to rotate would require the Box2D code to calculate an an arbitrarily long sequence of line-segments ‘bodies’ every frame.
  • Chains don’t collide with other Chains - You may not have noticed this, but chains can’t register collisions with eachother.
  • Chains are best used for static bodies - While you can make them dynamic or kinematic, it is far better to use them as static ones.

So, how do you get a line-like shape that can also rotate?
You only have one option I can think of. Create a sequence of thin polygonal bodies attached to each other with joints. This is not a super solution as it can quickly get out of hand in terms of complexity and cost. It is also hard to make it look nice.

You may just have to suffer the ‘no rotation’ limitation and continue.

Shape Complexity Reduction - An optimization tip
Whether you go with joint-connected polygons or stick with chain shapes, you should probably consider reducing the number of verticies in your ‘line’. You can do this by converting to a spline and then using that list of vertices to draw you line.

I have code for that optimization here:

Here is a working example, but you will notice I draw the line wrong (offset) for shapes like a W or V.
https://github.com/roaminggamer/RG_FreeStuff/raw/master/AskEd/2018/11/draw_physics_line.zip