Cannot display complex physics shape created in Physics editor

Ojnab,

I found the error and I do not understand why this does NOT work  -_-

I DID IT LIKE THIS

local data = physicsData:get("stoneGround6") physics.addBody( shape, data )

YOU DO IT LIKE THIS

physics.addBody( shape, physicsData:get("stoneGround6"))

My approach is required because I have few hundred shapes… so I need generic approach.

It should be the same?!

Can you please suggest a more generic solution?

Thanks!

Ivan

It is because the data is unpacked in the physics editor code.

If you do like this… your code will probably work:

local data = {physicsData:get("stoneGround6")} physics.addBody( shape, unpack(data) )

It does not work.

I get rectangle around the body as if I am not using shapes (like when you call add body by default).

You know what is interesting: my method works for simple shapes (rect, triangle and circle).
But for complex shape does not work.

I modified your code as I described. It does work for me.

local shapeDefinition = require "shapeDefinition" local get = shapeDefinition[1] local sh = get.what.physicsData() local data = {sh:get(get.nam)} -- modified here what = display.newImageRect(get.image\_sheet, get.wi, get.he) what.x = centerX what.y = centerY physics.addBody(what, "dynamic", unpack(data)) -- and modified here

It works!!
But only with curly brackets!
Thanks!

It is interesting how “simple” shapes work fine with my method, but not complex ones.

It is really not that strange. I will try to explain.

What you need to know is that “complex” physics shapes are created by putting together multiple “simple” physics shapes.

When Physics editor creates a nested table like the one in your attached example:

["stoneGround6"] = {         {         pe\_fixture\_id = "", density = 2, friction = 0.30000000000000004, bounce = 0.20000000000000001,          filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 },         shape = {   -96.5, -6  ,  -184.5, 44  ,  -180.5, -22  ,  -139.5, -44  }     },          {         pe\_fixture\_id = "", density = 2, friction = 0.30000000000000004, bounce = 0.20000000000000001,          filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 },         shape = {   174.5, -26  ,  178.5, 45  ,  80.5, -6  ,  139.5, -44  }      },     {         pe\_fixture\_id = "", density = 2, friction = 0.30000000000000004, bounce = 0.20000000000000001,          filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 },         shape = {   -184.5, 44  ,  -96.5, -6  ,  80.5, -6  ,  178.5, 45  }     }           }

Each nested table describes a simple physics shape. 

The reason your code didn’t work is that the physicsData:get(“stoneGround6”) call does not return a table - it returns an arbitrary number of tables, describing your “complex” shape from definitions of “simple” shapes.

And if you look in the docs for physics.addBody you will see it expects the multi-element bodies to be defined like this.

Not as one table but as an arbitrary number of tables:

physics.addBody( nebula, "dynamic",    { friction=0.2, bounce=0.4, shape=podT },     { friction=0.8, bounce=0.0, shape=podR },     { friction=0.8, bounce=0.0, shape=podB },     { friction=0.2, bounce=0.4, shape=podL } )

This is the reason Physics Editor returns the data this way.

In other words in your project this line of code was the problem: 

local data = physicsData:get("stoneGround6")

because only the first shape definition is assigned to the data variable. This is the reason you are seeing a simple shape instead of a complex one.

My proposed solution simply wraps the returned data in a table and unwraps it again when needed.

local data = {physicsData:get("stoneGround6")} physics.addBody( shape, unpack(data) )

Hope it makes sense to you now.

It makes perfect sense!

Thanks!  :smiley:

I have one last problem.

I am using custom collision filters.

So when I do:

local collFilter = {categoryBits = 1, maskBits = 2} physics.addBody( shape, unpack(data), {filter = collFilter})

I get one additional big rectangle around my shape!  :frowning:

How to incorporate collision filter to your solution?

You can define the collision filters in Physics Editor. Otherwise you will have to modify the shape definition files from Physics Editor.

But that will get messy if you update them along the way.

On a side note I would also like to mention that I think your attached code is overly complex :wink:

I suppose you are using TexturePacker + Physics Editor. The nice thing when using this combination is that you can load graphics and apply their physics shape definitions really easy. You just have to make sure that the images and their shape definitions have the same name.

Here is a quick example of how I do a generic level loader with graphics and physics. (written out of my head and not tested)

local level = 1 -- variable to make level loading generic -- imagesheet loaded from level directory local sheetInfo = require("level"..level..".sheet") local levelImageSheet = graphics.newImageSheet( "level"..level.."/sheet.png", sheetInfo:getSheet() ) -- Shape definitions local scaleFactor = 1.0 local physicsData = (require "level"..level..".shapedefs").physicsData(scaleFactor) -- Function for loading grapichs and applying physics local function loadObject(name)     local object = display.newImageRect( levelImageSheet , {frames={sheetInfo:getFrameIndex(name)}} )     physics.addBody( object, physicsData:get(name) ) end -- level object data. could be imported from json file local objectData = {     { name="stoneGround2", pos={x=200, y=200} },     { name="stoneGround3", pos={x=200, y=200} },     { name="stoneGround4", pos={x=200, y=200} },     -- etc... } -- Put objects on screen local levelObjects = {} for i=1, #objectData do     local object = loadObject(objectData[i].name)     object.x, object.y = objectData[i].x, objectData[i].y     levelObjects[#levelObjects+1] = object end

Uh… I am lost  :smiley:

You are master of LUA  :smiley:

I wil have to do a walk around because I have 7000 lines of code, and a lottttttt of simple shapes… no way I am changing everything!  :smiley:

I will try to do collision filters in PE or modify them on the fly for only few complex shapes  :smiley:

Thanks ojnab!

I owe you one!

I would not advise to, but if you really need to add custom collision filters in your code you would need to do something like this:

local data = {physicsData:get("stoneGround6")} local collFilter = {categoryBits = 1, maskBits = 2} for i=1, #data do      data[i].filter = collFilter end physics.addBody( shape, unpack(data) )

Aha… I understand, add for each shape! I have only two compex shapes so I will do that. Because I have over 300 simple shapes in my game due to fact I went to simple version because I did not know why Corona displays only first simple shape (now I know). Thanks a lot! My game should be live in 7-10 days, and I will post a link here.

Please do. Good luck!

Thanks ojnab!
You are a life saver! :slight_smile: