Box2D attachments to spine characters

Hi!

I was wondering if anyone has any insight into how one would go about adding physics bodies to individual bones. I’ve tried a little but being new to both Corona and Spine I have had little luck. Has anyone tried this?

My goal is making a character where it is possible to detach arms and legs for example and then have them act independently in the world. 

local player = spine.Skeleton.new(skeletonData) local playerCol = display.newRect(80, 70, 64, 131) physics.addBody(playerCol, "dynamic") playerCol.alpha = 0 function update(e) if(player.x ~= playerCol.x) then player.x = playerCol.x end if(player.y ~= playerCol.y) then player.y = playerCol.y end end Runtime:addEventListener("enterFrame", update)

Above is how I add physics to my Spine skeletons. I would try adding a collision display.newImage() for each arm(just a static image for each arm) with alpha = 0 then have a boolean checking if they are detached from the body. If they are detached from the body then make the arm alpha = 1.

-Wesley

EDIT: remove parts of the code that were useless for my explaination

Alright, I managed to get something that works.

As far as I see the Corona spine runtime doesn’t offer an obvious way of accessing the image objects of a skeleton but it is there. A skeleton object actually contains an “images” field/table containing the images indexed by the slots of the skeleton; but only after updateWorldTransform has been called for the first time.

What I did was call skeleton:setToSetupPose() and skeleton:updateWorldTransform before adding physics bodies to the skeleton. Then looped through the slots of the skeleton with [lua] for i,slot in ipairs(skeleton.drawOrder) do physics.addBody(skeleton.images[slot], bodyOptions) end [/lua]

local player = spine.Skeleton.new(skeletonData) local playerCol = display.newRect(80, 70, 64, 131) physics.addBody(playerCol, "dynamic") playerCol.alpha = 0 function update(e) if(player.x ~= playerCol.x) then player.x = playerCol.x end if(player.y ~= playerCol.y) then player.y = playerCol.y end end Runtime:addEventListener("enterFrame", update)

Above is how I add physics to my Spine skeletons. I would try adding a collision display.newImage() for each arm(just a static image for each arm) with alpha = 0 then have a boolean checking if they are detached from the body. If they are detached from the body then make the arm alpha = 1.

-Wesley

EDIT: remove parts of the code that were useless for my explaination

Alright, I managed to get something that works.

As far as I see the Corona spine runtime doesn’t offer an obvious way of accessing the image objects of a skeleton but it is there. A skeleton object actually contains an “images” field/table containing the images indexed by the slots of the skeleton; but only after updateWorldTransform has been called for the first time.

What I did was call skeleton:setToSetupPose() and skeleton:updateWorldTransform before adding physics bodies to the skeleton. Then looped through the slots of the skeleton with [lua] for i,slot in ipairs(skeleton.drawOrder) do physics.addBody(skeleton.images[slot], bodyOptions) end [/lua]

@Reaver,

Does your way add to the whole character physics bodies for each images ?

Because I tried it but I don’t know exactly how to implement it, I try to put into the spine-corona/spine.lua where there is already something similiar than your code, but seems not working. 

How have you integrated the physics to your character, I got for few days trouble with Box2D and Spine, my shape and my physics bodie are going through everything,

I’m going to make a new Topic to explain better.

@Reaver,

Does your way add to the whole character physics bodies for each images ?

Because I tried it but I don’t know exactly how to implement it, I try to put into the spine-corona/spine.lua where there is already something similiar than your code, but seems not working. 

How have you integrated the physics to your character, I got for few days trouble with Box2D and Spine, my shape and my physics bodie are going through everything,

I’m going to make a new Topic to explain better.

You can also create a bounding box using the Spine editor and create a physics polygon using that data. You can access it like this. 

Enemy is an extension of the displayGroup returned by Spine with skeleton, bounds, and state rolled into it as well as methods for seeking targets, etc. You could use this same process to add physics to each of a models body parts, but that was unnecessary for our project. 

When assembling the model:  

local bounds = spine.SkeletonBounds.new() bounds:update(skeleton, false) --after assembly local bodyBounds = enemy.bounds:getPolygon(enemy.skeleton:getAttachment("bounds","bounds")) unpack(bodyBounds) for k = 1,  #bodyBounds do if k % 2 ~= 0 or k ~= 0 then bodyBounds[k] = -bodyBounds[k] end end physics.addBody(enemy, "dynamic" ,{density = 0.01, shape= bodyBounds,  bounce=0.0})

You invert points that are at indexes that are not divisible by zero, because Spine’s y-coordinate system is opposite of Corona’s. I hope this helps. 

You can also create a bounding box using the Spine editor and create a physics polygon using that data. You can access it like this. 

Enemy is an extension of the displayGroup returned by Spine with skeleton, bounds, and state rolled into it as well as methods for seeking targets, etc. You could use this same process to add physics to each of a models body parts, but that was unnecessary for our project. 

When assembling the model:  

local bounds = spine.SkeletonBounds.new() bounds:update(skeleton, false) --after assembly local bodyBounds = enemy.bounds:getPolygon(enemy.skeleton:getAttachment("bounds","bounds")) unpack(bodyBounds) for k = 1,  #bodyBounds do if k % 2 ~= 0 or k ~= 0 then bodyBounds[k] = -bodyBounds[k] end end physics.addBody(enemy, "dynamic" ,{density = 0.01, shape= bodyBounds,  bounce=0.0})

You invert points that are at indexes that are not divisible by zero, because Spine’s y-coordinate system is opposite of Corona’s. I hope this helps.