joints question (newbie)

Official forum for the Chipmunk2D Physics Library.
Post Reply
rolando
Posts: 9
Joined: Thu Apr 23, 2009 1:28 pm
Contact:

joints question (newbie)

Post by rolando »

Hi all,
I'm trying to build a complex object, something like slembcke talks about here:

http://www.slembcke.net/forums/viewtopi ... 319&p=1476

The problem I'm facing right now is more about the purpose of the joints. So... I made a simpler version of the buggie, which is just a big box over a "chassis" and the wheels, something like this:

Image

I've connected the bix box to the "chassis" with a pin joint and the wheels to the chassis using a pivot joint. The problem is that apparently wheels are not rotating at all and the black box is not "glued" to the brown box... So, what would be the best way to join everything? Does the pin joint allows to rotate an object?
Here's the code I'm using: (ruby bindings, using cocos2d-iphone)

Code: Select all

cpvzero = CP::Vec2.new(0.0,0.0)
verts = [cpvzero, CP::Vec2.new(0.0,36.0), CP::Vec2.new(32.0,36.0), CP::Vec2.new(32.0,0.0)]
body1 = CP::Body.new(10, CP.moment_for_poly(10, verts, cpvzero))
shape1 = CP::Shape::Poly.new(body1, verts, cpvzero)
# the brown box
verts = [cpvzero, CP::Vec2.new(0.0,7.0), CP::Vec2.new(52.0,7.0), CP::Vec2.new(52.0,0.0)]
body2 = CP::Body.new(10, CP.moment_for_poly(10, verts, cpvzero))
shape2 = CP::Shape::Poly.new(body2, verts, cpvzero)
# the wheels
body_wheel1 = CP::Body.new(3, CP.moment_for_circle(3, 7, 0, cpvzero))
shape_wheel1 = CP::Shape::Circle.new(body_wheel1, 7, cpvzero)
body_wheel2 = CP::Body.new(3, CP.moment_for_circle(3, 7, 0, cpvzero))
shape_wheel2 = CP::Shape::Circle.new(body_wheel2, 7, cpvzero)
# position each body (@st_x and @st_y are 240, 160 respectively)
body1.p = CP::Vec2.new(@st_x - 0.0, @st_y - 0.0)
body2.p = CP::Vec2.new(@st_x - 0.0, @st_y - 21.5)
body_wheel1.p = CP::Vec2.new(@st_x - 25.0, @st_y - 21.5)
body_wheel2.p = CP::Vec2.new(@st_x + 25.0, @st_y - 21.5)
# create the joints
j1 = CP::Joint::Pin.new(body1, body2, cpvzero, cpvzero)
j2 = CP::Joint::Pivot.new(body2, body_wheel1, cpvzero)
j3 = CP::Joint::Pivot.new(body2, body_wheel2, cpvzero)
# add all bodies/shapes/joints to the space
[body1, body2, body_wheel1, body_wheel2].each { |b| $space.add_body(b) }
[shape1, shape2, shape_wheel1, shape_wheel2].each { |s| $space.add_shape(s) }
[j1, j2, j3].each { |j| $space.add_joint(j) }
# attach each body to the corresponding sprite
child_with_tag(1).attach_chipmunk_shape(shape1)
child_with_tag(2).attach_chipmunk_shape(shape2)
child_with_tag(3).attach_chipmunk_shape(shape_wheel1)
child_with_tag(4).attach_chipmunk_shape(shape_wheel2)
When running this, everything disconnects after hitting the floor...

http://www.youtube.com/watch?v=Bi_KGaGRBPA

... What could be the problem here? Should I use another type of joints?
thanks!
rolando./
rolando
Posts: 9
Joined: Thu Apr 23, 2009 1:28 pm
Contact:

Re: joints question (newbie)

Post by rolando »

OK... I read the documentation again, and it turns out that pivot joints are *not* what I want... So I tried groove joints and they're working:

http://www.youtube.com/watch?v=oaFPtLEpiug

except for the fact that the black box still detaches from the brown box and is somehow going below the floor... :(
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: joints question (newbie)

Post by slembcke »

A couple potential issues:
1: The center of gravity of your box shapes is at (0,0) which you are placing in one of the corners. Probably not what you meant.
2: You need to set your wheels and brown box shapes to the same collision group so that they don't generate collisions.
3: You probably did want pivot joints to attach the wheels, but your pivot point is most certainly not correct. The pivot is in world coordinates. (0,0) is pretty far from your chassis or any of your wheels.
4: Have you checked the winding? Try reversing the order of the vertices.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
rolando
Posts: 9
Joined: Thu Apr 23, 2009 1:28 pm
Contact:

Re: joints question (newbie)

Post by rolando »

Thanks for your reply!

3: If I specify the pivot point, then when moving the "car", do I have to update the joint?
4: What should be the winding? I read in the docs that it should be clockwise... is that correct? and what about the start point? can it be any point?

regards,
rolando./
rolando
Posts: 9
Joined: Thu Apr 23, 2009 1:28 pm
Contact:

Re: joints question (newbie)

Post by rolando »

slembcke wrote:A couple potential issues:
1: The center of gravity of your box shapes is at (0,0) which you are placing in one of the corners. Probably not what you meant.
One more thing... I think I'm totally lost between chipmunk coordinates and cocos2d coordinates...
When specifying the shape of the boxes, I used the shape of the sprite: a simple box width x height. Do I have to specify the border points thinking that the origin is in the middle of the box? Does it matter?
rolando
Posts: 9
Joined: Thu Apr 23, 2009 1:28 pm
Contact:

Re: joints question (newbie)

Post by rolando »

Ok... got it working :-)
What I did:

1: Changed the center of mass to the center of the object (changed the vertices)
2: Placed the wheels and the brown box in the same collision group
3: Used a Pin joint between the black and brown boxes
4: Used a Groove joint between the brown box and the wheels with a very small displacement.

Here's the working code:

Code: Select all

    cpvzero = CP::Vec2.new(0.0,0.0)
    # the black box
    verts = [[-16,18],[16,18],[16,-18],[-16,-18]].map{|p| CP::Vec2.new(p[0],p[1])}
    body1 = CP::Body.new(10, CP.moment_for_poly(10, verts, cpvzero))
    shape1 = CP::Shape::Poly.new(body1, verts, cpvzero)
    # the brown box
    verts = [[-26,3.5],[26,3.5],[26,-3,5],[-26,-3.5]].map{|p| CP::Vec2.new(p[0],p[1])}
    body2 = CP::Body.new(10, CP.moment_for_poly(10, verts, cpvzero))
    shape2 = CP::Shape::Poly.new(body2, verts, cpvzero)
    # the wheels
    body_wheel1 = CP::Body.new(3, CP.moment_for_circle(3, 7, 0, cpvzero))
    shape_wheel1 = CP::Shape::Circle.new(body_wheel1, 7, cpvzero)
    body_wheel2 = CP::Body.new(3, CP.moment_for_circle(3, 7, 0, cpvzero))
    shape_wheel2 = CP::Shape::Circle.new(body_wheel2, 7, cpvzero)
    # brown box and wheels in the same collision group
    shape_wheel2.group = shape_wheel1.group = shape2.group = 1
    # position each body
    body1.p = CP::Vec2.new(@st_x - 0.0, @st_y - 0.0)
    body2.p = CP::Vec2.new(@st_x - 0.0, @st_y - 21.5)
    body_wheel1.p = CP::Vec2.new(@st_x - 25.0, @st_y - 21.5)
    body_wheel2.p = CP::Vec2.new(@st_x + 25.0, @st_y - 21.5)
    # create the joints
    j1 = CP::Joint::Pin.new(body1, body2, cpvzero, cpvzero)
    j2 = CP::Joint::Groove.new(body_wheel1, body2, CP::Vec2.new(0.0,0.1), CP::Vec2.new(0.0,0.0), CP::Vec2.new(-25.0, 0))
    j3 = CP::Joint::Groove.new(body_wheel2, body2, CP::Vec2.new(0.0,0.1), CP::Vec2.new(0.0,0.0), CP::Vec2.new( 25.0, 0))
    # add all bodies/shapes/joints to the space
    [body1, body2, body_wheel1, body_wheel2].each { |b| $space.add_body(b) }
    (shapes = [shape1, shape2, shape_wheel1, shape_wheel2]).each { |s| $space.add_shape(s) }
    [j1, j2, j3].each { |j| $space.add_joint(j) }
    # attach each body to the corresponding sprite
    (0..3).each do |i|
      child_with_tag(i).tap do |c|
        c.attach_chipmunk_shape(shapes[i])
        #c.shape = shapes[i]
      end
    end
Also slembcke, have you considered removing CP::Vec2 from the ruby bindings and just using a ruby array? I'm currently writing the cocos2d-iphone ruby bindings and it's really much cheaper/faster to use ruby arrays and then convert them to a CGPoint/cpVect (which in cocos2d are equivalent).
If you need the math, maybe a module that could be included in the Array class might help, or even just extending particular objects:

Code: Select all

[].extend(CP::VectorMath)
something like that... Well, that's just a thought.

Thanks!
rolando./
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: joints question (newbie)

Post by slembcke »

Doing the vector math on a Ruby array would be much slower and require a lot more work to rewrite all the vector operations to convert back from Ruby arrays, check size etc. It doesn't seem like a clear win/win situation.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
rolando
Posts: 9
Joined: Thu Apr 23, 2009 1:28 pm
Contact:

Re: joints question (newbie)

Post by rolando »

I'm not saying to replace the vector math ruby ruby-arrays, just the conversion from the class Vec2 to just a plain ruby array. One should only need to modify rb_cpVect2.c... maybe I'll do it during the next days and make a comparison... benchmarks are far more useful than just works here :-)

cheers,
rolando./
Post Reply

Who is online

Users browsing this forum: No registered users and 20 guests