2

I'm trying to do what the title says. I have a character with a gun constrained to its hand, and I'm trying to get the gun to point at the cursor. I figured that a DampedRotarySpring would be a nice way to do it, but it turns out not to be as simple as that. The gun is a dynamic body with a Segment shape, and for the cursor I create a static body whose position I set to the mouse location with pygame each step.

When I run the program, the gun simply does not move at all except for the effect of gravity or collisions.

Here is the relevant code:

# add crosshairs at the location of the mouse
pointer_body = pymunk.Body()
pointer_shape1 = pymunk.Segment(pointer_body, (0,CROSSHAIRS_SIZE), (0,-CROSSHAIRS_SIZE), 1) # vertical segment
pointer_shape2 = pymunk.Segment(pointer_body, (-CROSSHAIRS_SIZE,0), (CROSSHAIRS_SIZE,0), 1) # horizontal segment

# add a spring that will angle the gun toward the mouse
spring = pymunk.DampedRotarySpring(me.gun.body, pointer_body, 0, 0.01, 1)

space.add(pointer_shape1, pointer_shape2, spring)

while True:
    # handle event queue
    for event in pygame.event.get():
        if event.type == pygame.MOUSEMOTION:
            from math import atan2
            # update location of pointer
            pointer_body.position = flipy(pygame.mouse.get_pos())
            pointer_body.angle = atan2( (pointer_body.position.y - me.gun.body.position.y), (pointer_body.position.x - me.gun.body.position.x) )

Edit:

Here is a Gist repository of all my code: https://gist.github.com/4470807. The main loop is in ragdoll.py.

desophos
  • 207
  • 1
  • 9

2 Answers2

2

The problem with the code in the gist is that you have attached the gun to the hand with two joints to keep them in the same place and same rotation. However, the the hand is a rouge body and wont rotate. Therefor the gun wont rotate when its pulled by the spring between it and the cursor, because that other joint is stronger.

Im not sure exactly how you want the setup, but you can see that it all works if you remove the RotaryLimitJoint from the gun-hand.

Take a look at a fixed fork of the code for the exact details: https://gist.github.com/4505219

Some tips for future troubleshooting that I did to find the problem:

  1. Make everything 10x bigger so its easy to see what happens. I know pymunk only draws in one size, but it was easy to just add a 0 on the end of all sizes in the code.
  2. Make the hand not move so its easier to see how it rotates (removed all stuff in the update_hand_position method)
  3. Disable collisions between all shapes in the scene so that the rotating gun is not hindered by some body part. (did a simple loop of space.shapes and ran shape.group=1)
viblo
  • 4,159
  • 4
  • 20
  • 28
  • I tried removing the RotaryLimitJoint and it still didn't work. I tried all of what you recommended and I couldn't see any difference. I understand what you're saying and it makes sense to me, but for some reason it's not working. – desophos Jan 09 '13 at 22:14
  • 1
    I edited the post with a link to the working code that I hope will help. – viblo Jan 15 '13 at 18:05
  • When I remove the angular_velocity_limit from the gun, the gun moves up as the angle increases and down as the angle decreases. The gun's angle still does not change. What could possibly be happening? – desophos Jan 17 '13 at 00:31
  • 1
    If I print the angle of the gun (print me.gun.body.angle in the main loop) it changes as expected? – viblo Jan 20 '13 at 16:53
  • 1
    I'm printing the angle of the gun and it still only changes by miniscule amounts (on the order of e-16). The angle changed the same amount with the angular_velocity_limit in place. However, the gun now moves vertically as the cursor moves. I have no clue why. I'm also printing the angle of the right_hand and that doesn't change either. – desophos Jan 20 '13 at 20:42
  • 1
    Its hard to give a better answer when it works just fine for me (as long as the angular_velocity_limit is a reasonable value or not set at all). – viblo Jan 20 '13 at 21:27
  • 1
    I never figured this out. The gun moves vertically but the angle doesn't change, and my code looks exactly like yours. I'm marking your answer as a solution, though, because it *should* work. – desophos Feb 06 '13 at 20:46
  • 1
    I changed my DampedRotarySpring to a RotaryLimitJoint between the gun and the pointer, and now it works fine. I'm definitely seeing the problem with the rotation between positive and negative pi, though. Any way to fix that? – desophos Feb 26 '13 at 23:00
  • 1
    I havent spent much thought about it, and I dont have a ready made solution. But you might want to take a look at the thread I made at chipmunk with some insights into what can be done: http://chipmunk-physics.net/forum/viewtopic.php?f=1&t=2503 – viblo Mar 04 '13 at 18:38
0

Maybe your problem is with the spring parameters? The stiffness and damping looks very low unless the gun is extremely light.

Check out this code example I added to pymunk yesterday: http://code.google.com/p/pymunk/source/browse/trunk/examples/damped_rotary_spring_pointer.py

(There is one thing going on with the rotation when it flip over between positive and negative pi that I will look at)

viblo
  • 4,159
  • 4
  • 20
  • 28
  • My code now almost exactly matches yours and it still doesn't work for some reason. It must be some small error that I've overlooked. I've posted a link to a Gist of all my code in my original post. – desophos Jan 06 '13 at 22:44