• Runtimes
  • [Corona]How to make a bone follow a physics bounding Box

Related Discussions
...

Hi,

I have a bounding box attached to a bone and I drew a box around the bounding box so I could attach physics to it (dynamic body). I've read in other posts that I can manipulate a bone by stopping the animation but how do I make the bone follow the physics bounding box while it's falling?

I've tried to change the bone's worldX and worldY so that it follows the physics bounding box but nothing happens, I think it's because it's a read-only parameter and cannot be changed. I can change the bone's x and y positions but those are relative to its parent bone, so I wonder How can I make a specific bone to follow it's respective bounding box that has physics applied to it?

My idea is that once I stop the animation, all the pieces that make a skeleton fall to the floor per gravity. Currently the bounding boxes fall to the floor but the images of the skeleton remain in their place once I stop the animation

Thanks in advance
Hector

Usually you would just stop the animation, let the physics take over and not care that the skeleton no longer matches the physics. Probably you want to update the skeleton because you are using it for drawing?

The bone world coordinates are computed from the local coordinates, so you'd need to translate the world position into a local position for the bone. You'd then set bone.x and bone.y. To do that you need have a 3x3 matrix that is the bone's world transform, then you multiple the world position by the inverse of the matrix to get local coordinates.

Does Corona have a Matrix3 class? You could write the code you need yourself. You can see how a matrix is computed here, it is just an array with 9 elements:
https://github.com/EsotericSoftware/spi ... .java#L201
The Bone class in spine-corona gives you the m* variables and worldX/Y. To inverse the matrix:
https://github.com/libgdx/libgdx/blob/m ... .java#L256
To multiple a vector (which is just an x and y value) by the matrix:
https://github.com/libgdx/libgdx/blob/m ... .java#L258
The resulting values are your local coordinates, taking into consideration the position, rotation and scale of all parent bones.

Thanks Nate, yes I want to update the skeleton because I used it for drawing a bounding box that I applied physics to.

Your approach sounds good to me, in the sense that I would have to translate the world position of the bone into a local position so I can manipulate it. In my case, the world position of the bone would be the x, y and rotation that my physics bounding box gets while falling with gravity, then I can make the bone follow the bounding box position as it falls.

Corona doesn't have a Matrix3 class, but your links should help me to make one. It's been at least 20 years since the Iast time I worked math with a matrix, so let's see how it goes.

So I can better understand, What do all these matrix's values mean? I imagine they relate to the x,y and rotation but not sure which one is which

val[M00] = m00;
val[M01] = m01;
val[M10] = m10;
val[M11] = m11;
val[M02] = worldX;
val[M12] = worldY;
val[M20] = 0;
val[M21] = 0;
val[M22] = 1;

Regards
Hector

The m* variables and worldX/Y come from the bone. You don't really have to worry about how matrices work if you just copy the code. 🙂

Thanks Nate, I think your code is in Java and Corona uses Lua, so I don't think I can copy it directly. I'm not familiar with Java so let me dig into your code and see how can I convert it to Lua

Regards
Hector

@hsanchezp - I just posted here re whether anyone has worked out the code to create a Ragdoll viewtopic.php?f=7&t=2545

Was wondering is this effectively what you're trying to do? If yes I guess I'm interested in how you went?

Note if you were drawing based on your physics bodies (rather than the skeleton) then driving the physics bodies with the animation, to get rag doll you could just stop updating the physics bodies with the animation.

hi Nate - hey would you be able to expand on this? I really want to understand your point but I'm not quite following. e.g.

  • "if you were drawing based on your physics bodies (rather than the skeleton)" - not sure what you mean here. I'm just using Spine in the basic Corona sense per the examples?
  • "you could just stop updating the physics bodies with the animation" - are you hinting at there is a way for Spine to automatically create physics bodies (corona speak) to the character? that would be great, but not sure if this is what you meant?

Overall I'm just after the simplest way for say the spine-boy character to hit a wall / fall off a cliff and go into a Physics Ragdoll type effects as he flails around & bounces etc

My post was to the OP. He is drawing his skeleton and updating the physics bodies to match. Now he wants ragdoll, so if he stops updating the physics bodies they will fall but the skeleton won't follow, so he needs to update the bones to match the physics bodies. He could instead use the physics bodies to draw. When the animation moves the physics bodies the skeleton animates, when the animation doesn't the skeleton falls.

OK. So a bit of a different situation. I'd love your feedback on my post here in that case: viewtopic.php?f=7&t=2545 to get me on the best/easiest track

Hi Nate, I'm getting closer to a solution, I found a really cool class in Github that does all kind of calculations with matrices in Lua, I did a quick test and it works great to calculate the determinant and inverse the matrix. You can find it here https://github.com/davidm/lua-matrix

I studied the matrices in your code and I see that m20, m21 and m22 are constant values (0 and 1), and m02 and m12 are the worldX and worldY of the bone which I can get from the Corona's bone class. Based on this structure for the matrix and the Matrix Lua Class, I was able to inverse the matrix (the determinant always gives me one, not sure if that is correct).
 Loading Image

So with the matrix inversed all I have to do now is to multiply the vector to get the local x and y positions. This is the piece of your code that I need to translate into Lua

public Vector2 mul (Matrix3 mat) {
float x = this.x * mat.val[0] + this.y * mat.val[3] + mat.val[6];
float y = this.x * mat.val[1] + this.y * mat.val[4] + mat.val[7];
this.x = x;
this.y = y;
return this;
}

Couple of questions:
1) Which varaibles from the matrix correspond to the mat.val values in your Java function. I'm pretty sure mat.val[0] corresponds to m00, but not sure about the rest
2) Should I be using the bone I'm trying to move or its parent's m* variables and worldX/Y?
3) I imagine that "this.x" in my case would be the worldX and worldY values of the bone I'm trying to move, as I'm trying to get local x and y values, am I right?

@mixedup Nate is correct in what I'm trying to make. If I'm successful, I will not only be able to position the bone based on gravity but also implement dragging like in a ragdoll. Reason I'm doing this via bounding boxes > polygons > physical bodies is because I'm using a Texture Packer SpriteSheet and not individial images, and I think with SpriteSheets and Corona is not so easy to apply phisics to Spritesheet indexes, at least that's been my personal experience.

Regards
Hector

@Hector - I think I'm getting excited with what you're doing 🙂 So I'm not exactly sure when you mention phrases such as "position the bone based on gravity" and "implement dragging", but is this it:

  • be able to create the character via Spine API and have it automatically position itself overall via physics
  • animation of the character would still be normal (individual bones not affected by gravity as such)
  • re the Corona physics body that would trigger gravity: not sure if you're implying this would be one specific bone, or multiple?
  • re ragdoll & dragging: not sure what you mean by dragging but do you effectively at the time of a crash "create the corona physics joints etc"?
  • using spritesheets for the images (which is good)

So from my part I'm quite happy with the character that gets created by spine, but I am (in the current game) positioning manually, as I only then rely on physics after a crash when I want the ragdoll effect. So do you think what you're doing would cover off what I'm after? So what I'm after in addition to spine is:

a) create a Ragdoll effect on crash (e.g. physics bodies for each of the main character elements & joints)

b) use of spritesheets would be nice for performance, if the workflow was not more difficult. Ideally really would just want to use the Spine created atlas as full resolution then manually scale down for our Corona project no? Just wondering if using Texture Packer for this makes things more difficult? I'm guessing you've got an approach in mind in terms of how you create the images, package int a spritesheet using texture packer, export for the corona project & export for the Spine application, such that everything ties in correctly re positioning?

c) dynamic image selection (e.g. @2x, @3x etc) - i.e. an approach for this as Spine runtime doesn't have this yet.

hsanchezp wrote

1) Which varaibles from the matrix correspond to the mat.val values in your Java function. I'm pretty sure mat.val[0] corresponds to m00, but not sure about the rest
2) Should I be using the bone I'm trying to move or its parent's m* variables and worldX/Y?
3) I imagine that "this.x" in my case would be the worldX and worldY values of the bone I'm trying to move, as I'm trying to get local x and y values, am I right?

1) See the top of the Matrix3 class for M* constants that show you which indices are which.
2) I believe you should use the bone's matrix, not its parent. If not, try the parent. 🙂
3) Yep.

c) dynamic image selection (e.g. @2x, @3x etc) - i.e. an approach for this as Spine runtime doesn't have this yet.

The runtimes support scaling. You need to choose the images yourself though.

@[obrisani korisnik]
I've tried using the bone's matrix not the parent's but in java libGDX and it didn't work. so I used its parent and that worked for me. just a tip, idk how it is in Corona.

@jos_fzr, Yes you are correct, it works using the bone's inverted parents' matrix and it looks great!. That Matrix class I found in Github was essential to invert the parent bone's matrix

Here is how I assigned all the variables on the matrix :

    local m00 = bone.m00
    local m01 = bone.m01
    local m02 = bone.worldX 

bone.worldX
local m10 = bone.m10
local m11 = bone.m11
local m12 = bone.worldY


bone.worldY
local m20 = 0
local m21 = 0
local m22 = 1

And here is how I got the localX and localY values

    local xLocal =  ((calculatedX * mi[1][1]) + (calculatedY * mi[1][2]) + mi[01][03])
    local yLocal =  ((calculatedX * mi[2][1]) + (calculatedY * mi[2][2]) + mi[02][03])

For calculatedX and calculatedY, I mean the Bounding Box real world X/Y minus the skeleton's group X/Y

Thanks everybody for all your help

Regards
Hector

Hi Hector - Not sure if you're interested in sharing but I'm quite interested in what you've done with Spine for Corona? In particular the points just in terms of the points I raised in my earlier post...(mainly the "create a Ragdoll effect on crash" type function)....

@hsanchezp, Hello again, I have a question: are you applying rotations from physics to the bone? if you are, could you possibly tell me how you did do it?
Thanks

You can just subtract the bone's world rotation from the physics rotation, this gives you the bones local rotation that when set makes the bone point to the physics rotation.

@Nate, Hello, I'm sorry, I didn't get the "subject the bone's world rotation part". English just isn't my primary language, could you please explain?
Thanks

Edit: I did this: (box2dBodyRotation * radiansToDeg) - bone.getParent().getWorldRotation()
It works fine but I don't know if it's the right way.