Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Cannot display complex physics shape created in Physics editor
Started by ivan888 Jan 25 2017 02:39 PM

- - - - -
16 replies to this topic
shape complex physics

Best Answer ojnab , 27 January 2017 - 07:09 AM

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

[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

Hi guys,

Can you please check is there any problems in displaying complex physics shape`s ?

Mr. Andreas from CodeAndWeb also concluded that Corona physics engine can not display anything more complex then circle and/or rectangle, created with help of Physics editor.

In attached case 2 triangles + 1 rectangle is displayed as only 1 triangle (1 triangle and 1 rect is missing ! ).

Many thanks!
Ivan

Attached Thumbnails

  • Screen Shot 2017-01-22 at   10.12.37.png

Attached Files



[TOPIC: post.html]
#2

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

Hi guys,

 

I apologize for not providing complete plug n play zip example.

 

You can find attached, and can give it a try.

 

Insead of 3 shapes (created by Physics editor) only 1 is displayed by Corona.

 

 

I noticed circle, triangle and rectangle (i.e. simple shapes) are always displayed correctly by Corona.

 

 

Ivan

Attached Files



[TOPIC: post.html]
#3

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

Something is wrong with the code you wrote.

I just tried importing the shapes as instructed in the data file generated by physics editor and it works fine.

 

try replacing your main.lua with below code and you will see:

display.setStatusBar(display.HiddenStatusBar)

-- most commonly used screen coordinates
local centerX = display.contentCenterX
local centerY = display.contentCenterY
local screenLeft = display.screenOriginX
local screenWidth = display.viewableContentWidth - screenLeft * 2
local screenRight = screenLeft + screenWidth
local screenTop = display.screenOriginY
local screenHeight = display.viewableContentHeight - screenTop * 2
local screenBottom = screenTop + screenHeight

local physics = require "physics"
physics.start()
physics.setDrawMode( "hybrid" )
physics.setGravity( 0, 0 )

local scaleFactor = 1.0
local physicsData = (require "stoneGround6shape").physicsData(scaleFactor)
local shape = display.newImage("images/stoneGround6.png")
shape.x, shape.y = centerX, centerY
physics.addBody( shape, physicsData:get("stoneGround6") )


[TOPIC: post.html]
#4

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

Thanks ojnab!

 

I do not know where I messed up, I will think it over!



[TOPIC: post.html]
#5

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

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


Edited by ivan888, 27 January 2017 - 03:36 AM.


[TOPIC: post.html]
#6

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

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) )


[TOPIC: post.html]
#7

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

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.

[TOPIC: post.html]
#8

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

  Best Answer

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


[TOPIC: post.html]
#9

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

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

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

[TOPIC: post.html]
#10

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

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.

 

 



[TOPIC: post.html]
#11

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

It makes perfect sense!

Thanks!  :D

 

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!  :(

 

 

How to incorporate collision filter to your solution?



[TOPIC: post.html]
#12

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

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 ;)

 

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


[TOPIC: post.html]
#13

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

Uh.... I am lost  :D

You are master of LUA  :D

 

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!  :D

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

 

 

Thanks ojnab!

I owe you one!



[TOPIC: post.html]
#14

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

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) )


[TOPIC: post.html]
#15

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

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.

[TOPIC: post.html]
#16

ojnab

[GLOBAL: userInfoPane.html]
ojnab
  • Contributor

  • 614 posts
  • Corona SDK

Please do. Good luck!



[TOPIC: post.html]
#17

ivan888

[GLOBAL: userInfoPane.html]
ivan888
  • Contributor

  • 397 posts
  • Corona SDK

Thanks ojnab!
You are a life saver! :)


[topic_controls]
[/topic_controls]