Physics bug with rectangle dynamic object

Hello. I’m developing physics based game and have problem with rectangular dynamic body.
 

[media]https://www.youtube.com/watch?v=AHK1hGw2FbI[/media]

Here I’m creating world objects

for i = 1, #layers do local layer = layers[i] if layer.type == "objectgroup" then for j = 1, #layer.objects do local object = layer.objects[j] if object.polygon then local backgrougdPointsLenght = #backgroundPoints local points = { } local isBig = true for k = 1, #object.polygon - 1 do isBig = isBig and Vector.len( object.polygon[k].x - object.polygon[k + 1].x, object.polygon[k].y - object.polygon[k + 1].y ) \> 5 end isBig = isBig and Vector.len( object.polygon[1].x - object.polygon[#object.polygon].x, object.polygon[1].y - object.polygon[#object.polygon].y ) \> 5 local clockwiseSum = 0 for k = 1, #object.polygon - 1 do clockwiseSum = clockwiseSum + (object.polygon[k + 1].x - object.polygon[k].x) \* (object.polygon[k + 1].y + object.polygon[k].x) end clockwiseSum = clockwiseSum + (object.polygon[1].x - object.polygon[#object.polygon].x) \* (object.polygon[1].y + object.polygon[#object.polygon].x) local minX = (object.polygon[1].x + object.x) \* mapScale local minY = (object.polygon[1].y + object.y) \* mapScale local maxX = (object.polygon[1].x + object.x) \* mapScale local maxY = (object.polygon[1].y + object.y) \* mapScale for k = 1, #object.polygon do local pointX, pointY = (object.polygon[k].x + object.x) \* mapScale, (object.polygon[k].y + object.y) \* mapScale if isBig then backgroundPoints[#backgroundPoints + 1] = Point(pointX, pointY) end points[2 \* k - 1] = pointX points[2 \* k] = pointY minX = mathMin( minX, pointX ) minY = mathMin( minY, pointY ) maxX = mathMax( maxX, pointX ) maxY = mathMax( maxY, pointY ) end -------------------------------- creating polygon static objects local polygonObject = display.newPolygon( map, (minX + maxX) \* .5, (minY + maxY) \* .5, points ) physics.addBody( polygonObject, "static", { density = 1, friction = 1 } ) ---------------------------------------------------------------------------- local polygon = Polygon(unpack(points)) local polygonTriangles = polygon:splitConvex() for k = 1, #polygonTriangles do local centerX, centerY = polygonTriangles[k]:getCenter() local trianglesLenght = #triangles for l = 1, #polygonTriangles[k].vertices - 1 do triangles[trianglesLenght + l] = Triangle(Point(polygonTriangles[k].vertices[l]:unpack()), Point(polygonTriangles[k].vertices[l + 1]:unpack()), Point(centerX, centerY)) triangles[trianglesLenght + l].p1.z = backgroundDepth() triangles[trianglesLenght + l].p2.z = backgroundDepth() triangles[trianglesLenght + l].p3.z = foregroundDepth() triangles[trianglesLenght + l].type = object.type end triangles[trianglesLenght + #polygonTriangles[k].vertices] = Triangle(Point(polygonTriangles[k].vertices[1]:unpack()), Point(polygonTriangles[k].vertices[#polygonTriangles[k].vertices]:unpack()), Point(centerX, centerY)) triangles[trianglesLenght + #polygonTriangles[k].vertices].p1.z = backgroundDepth() triangles[trianglesLenght + #polygonTriangles[k].vertices].p2.z = backgroundDepth() triangles[trianglesLenght + #polygonTriangles[k].vertices].p3.z = foregroundDepth() triangles[trianglesLenght + #polygonTriangles[k].vertices].type = object.type end elseif object.type == "piece" then if not gameManager.worlds[gameManager.choosedWorld].pieceCollected[pieceIndex] then pieceItems[#pieceItems + 1] = { x = object.x \* mapScale, y = object.y \* mapScale, index = pieceIndex } end pieceIndex = pieceIndex + 1 elseif object.type == "start" then playerStartX, playerStartY = object.x \* mapScale, object.y \* mapScale elseif object.type == "exit" then exitX, exitY = object.x \* mapScale, object.y \* mapScale end end end end

And creating player

player = display.newImageRect( map, gameManager.levelImageSheet, gameManager.levelSheetInfo:getFrameIndex( "heroes/cube/cube\_base" ), playerRadius, playerRadius ) gameManager.playerObject = player player.xScale = 4.5 player.yScale = 4.5 physics.addBody( player, "dynamic", { density = 1, friction = 1, bounce = 0, shape = { -playerRadius, -playerRadius, playerRadius, -playerRadius, playerRadius, playerRadius, -playerRadius, playerRadius } } )

 
I have no idea what I’m doing wrong
Interesting that player with circular shape works great without bugs

Have you enabled debug draw mode to inspect your bodies?

https://docs.coronalabs.com/api/library/physics/setDrawMode.html

also, it would be way eaiser for us to help with a project in hand.  Can you just share a zip of the project?  I know you might be reluctant, but that is a lot of code to read and guess at, especially since you didn’t remove that tabs and replace them wit spaces.

Tip:  When I paste code I,

  1. Paste it to notepad (or other simple text editor)

  2. Replace all tabs with 3 spaces.

  3. Copy that and paste it to forums.

roaminggamer

Thank you for your support.

I sent project zip to your private messages

I tried enabling debug mode, but I use scaled display group that contains physics objects. And in this case debug draw mode works incorrectly.

Before even looking, I have to say that using scaled groups with physics is generally a no-no and can cause no end of weird issues… 

Why are you scaling the groups?  

The proper way to handle scaling and physics is:

  • Determine needed scale factor (if any).
  • Scale objects as they are created.
  • Add bodies

Scaling the groups just hoses up the physics system.

it appears the use of scaling is a single master “camera” group.

if so, that type of scaling will work fine with physics  - though debug/hybrid draw will be useless, as described.

(otoh if you mix differently scaled/translated/rotated independent groups then yes, you will desync the view from the physics model - iow, the internal physics model will continue to function properly, but it won’t look like things are happening where they’re supposed to)

as for the original problem, i’d perhaps do some QA on this line:

local polygonTriangles = polygon:splitConvex()

are you 100% SURE that the returned triangles are all valid?

I see where you’re going with this scaling, but to help debug this, you may want to start off unscaled.

i.e. Skip the (beautiful) scaled out and transition to  starting position effect, and just start at full scale in the home position.

This should allow the debugMode() settings to draw the bodies in a representative fashion. 

PS - Nice looking game by the way.

Just for fun, I added some code to level.lua

starting at line 568

local tr = display.newPolygon( map, 0, 0, { triangles[i].p1.x, triangles[i].p1.y, triangles[i].p2.x, triangles[i].p2.y, triangles[i].p3.x, triangles[i].p3.y } ) local tmp = display.newLine( map, triangles[i].p1.x, triangles[i].p1.y, triangles[i].p2.x, triangles[i].p2.y, triangles[i].p3.x, triangles[i].p3.y ) tmp.strokeWidth = 1

This produced some surprisingly thick lines, which tells me you are scaling up the content.  I think this is the source of your troubles.

body_issues.jpg

Less important:

Another thing I noticed is you have a lot of overlapping shapes/bodies.  After you get past the current issue, you might try to reduce that complexity.

Note: I tried to reproduce the bug, but was unable to.  Can you reproduce it with this code in place and show us a video again?  I know it will be a bit hard, but I have this weird feeling we’ll be able to see what is causing it.  I’m wondering if there isn’t a gap or something we can’t see in the original video.

Update:

If you do add that code I provided to draw the polygon outlines, you can set the line thickness to 0.2 and when it gets scaled up, the lines will be thinner.

If that is a 1px stroke that is some crazy scaling!

I’m sorry for the delay.

I use scaling to make camera effect. I cannot find any other way make camera in corona.

All physics objects are in one group (map) and it shouldn’t cause any problems, as I know.

Thick lines appears because oulines cannot be smaller than 1 px. Scaling is too big and this 1px lines drawing as thick lines.

All physics bugs exists only with rectangle character. Circle player works perfectly.

I have the same bug (sphere works good, rect not)

https://www.youtube.com/watch?v=1JKBJJx8wLE&feature=youtu.be

As you can see box shape is big enough to collide normally, and I mean it’s big enough to make i.e. floating platform. Bad idea. Some collision precision option must be grown in settings. Screen resolution is HD 1280x720.

As you can see I have simple polygon here colliding with simple rect. In both cases height or radius are equal = 8

https://www.youtube.com/watch?v=KtzlqIoqpT4

Have you enabled debug draw mode to inspect your bodies?

https://docs.coronalabs.com/api/library/physics/setDrawMode.html

also, it would be way eaiser for us to help with a project in hand.  Can you just share a zip of the project?  I know you might be reluctant, but that is a lot of code to read and guess at, especially since you didn’t remove that tabs and replace them wit spaces.

Tip:  When I paste code I,

  1. Paste it to notepad (or other simple text editor)

  2. Replace all tabs with 3 spaces.

  3. Copy that and paste it to forums.

roaminggamer

Thank you for your support.

I sent project zip to your private messages

I tried enabling debug mode, but I use scaled display group that contains physics objects. And in this case debug draw mode works incorrectly.

Before even looking, I have to say that using scaled groups with physics is generally a no-no and can cause no end of weird issues… 

Why are you scaling the groups?  

The proper way to handle scaling and physics is:

  • Determine needed scale factor (if any).
  • Scale objects as they are created.
  • Add bodies

Scaling the groups just hoses up the physics system.

it appears the use of scaling is a single master “camera” group.

if so, that type of scaling will work fine with physics  - though debug/hybrid draw will be useless, as described.

(otoh if you mix differently scaled/translated/rotated independent groups then yes, you will desync the view from the physics model - iow, the internal physics model will continue to function properly, but it won’t look like things are happening where they’re supposed to)

as for the original problem, i’d perhaps do some QA on this line:

local polygonTriangles = polygon:splitConvex()

are you 100% SURE that the returned triangles are all valid?

I see where you’re going with this scaling, but to help debug this, you may want to start off unscaled.

i.e. Skip the (beautiful) scaled out and transition to  starting position effect, and just start at full scale in the home position.

This should allow the debugMode() settings to draw the bodies in a representative fashion. 

PS - Nice looking game by the way.

Just for fun, I added some code to level.lua

starting at line 568

local tr = display.newPolygon( map, 0, 0, { triangles[i].p1.x, triangles[i].p1.y, triangles[i].p2.x, triangles[i].p2.y, triangles[i].p3.x, triangles[i].p3.y } ) local tmp = display.newLine( map, triangles[i].p1.x, triangles[i].p1.y, triangles[i].p2.x, triangles[i].p2.y, triangles[i].p3.x, triangles[i].p3.y ) tmp.strokeWidth = 1

This produced some surprisingly thick lines, which tells me you are scaling up the content.  I think this is the source of your troubles.

body_issues.jpg

Less important:

Another thing I noticed is you have a lot of overlapping shapes/bodies.  After you get past the current issue, you might try to reduce that complexity.

Note: I tried to reproduce the bug, but was unable to.  Can you reproduce it with this code in place and show us a video again?  I know it will be a bit hard, but I have this weird feeling we’ll be able to see what is causing it.  I’m wondering if there isn’t a gap or something we can’t see in the original video.

Update:

If you do add that code I provided to draw the polygon outlines, you can set the line thickness to 0.2 and when it gets scaled up, the lines will be thinner.

If that is a 1px stroke that is some crazy scaling!