Objects constantly overlap and jump around the screen

Official forum for the Chipmunk2D Physics Library.
Post Reply
mordrax
Posts: 8
Joined: Sun Mar 06, 2011 8:59 am
Contact:

Objects constantly overlap and jump around the screen

Post by mordrax »

I have a player and several monster objects defined like this:

Code: Select all

    def __init__(self, image, position, world, mass=1):
        self.mass = mass
        self.radius = 16
        self.inertia = pymunk.moment_for_circle(self.mass, 0, self.radius)
        self.body = pymunk.Body(self.mass, self.inertia)
        self.body.position = self.position[0], self.position[1]
        self.shape = pymunk.Circle(self.body, self.radius)
        self.world.space.add(self.body, self.shape)
        self.controlBody = pymunk.Body(pymunk.inf, pymunk.inf)
        self.joint = pymunk.PivotJoint(self.body, self.controlBody, (0,0), (0,0))
        self.joint.max_force = 10000
        self.joint.bias_coef = 0
        world.space.add(self.joint)
on every game update, i move these objects with this code:

Code: Select all

    def Move(self, velocity):
        self.body.apply_impulse((velocity[0], velocity[1]))
        self.position = [self.body.position.x, self.body.position.y]
        self.rect.topleft = (int(self.position[0]), int(self.position[1]))
the velocity is a unit vector.

What i've noticed is that on collision the player and monsters always overlaps. When i move the player into the monster on purpose, they can overlap up to 90% but otherwise they always overlap around 25%.
Also, when the player and monsters clump together (currently the monsters are programmed to follow the player) and i move the player around, monsters frequently "jump" backwards, sometimes quite far and they slowly proceed to move towards the player again.

If I understand it properly, because collision is calculated after the move, the impulse makes the monsters constantly overlap the player and walls and other monsters.
I'm not after perfect circle to circle collision detection but how can i reduce these overlaps to say under 5% of the circle surface?

UPDATE:
I was able to setup some crude collision callback which stopped the monster on contact with the player. However this feels really unnatural because i'm manually creating a callback handler for something which i want the physics engine to deal with. I don't want to be manually positioning the monster whenever i detect an overlap with another object. Or am I thinking about this the wrong way?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Objects constantly overlap and jump around the screen

Post by slembcke »

If you are using the control body/constraint method for top down control, you should be setting the velocity to the control body and not the real body. Then the constraint will pass on the velocity while respecting the max force amount you set.

The problem you are having is that by setting the velocity every frame, you are completely undoing all the work that the collision solver did to stop it from moving. The max force on the constraint will cause the velocity to be applied a little at a time, leading to a smoother result.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
mordrax
Posts: 8
Joined: Sun Mar 06, 2011 8:59 am
Contact:

Re: Objects constantly overlap and jump around the screen

Post by mordrax »

when i set the apply_impulse to the controlBody then the objects do not move at all. Should the control body be set to inf mass/inertia? how can i push the body if the controlBody is inert?
mordrax
Posts: 8
Joined: Sun Mar 06, 2011 8:59 am
Contact:

Re: Objects constantly overlap and jump around the screen

Post by mordrax »

I've done what you suggested so instead of apply_impulse on the body, i've set the velocity on the controlBody. This looks alot more natural, i'm actually getting circle edge collision! :D

Just curious though, what's the difference between applying an impulse and setting the velocity because if i apply an impulse to the control body then i get no movement, but if i set the velocity then i do.
I just had an idea, is this because applying an impulse to a object of infinite mass would not physically move it whereas setting the velocity would move it?
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Objects constantly overlap and jump around the screen

Post by slembcke »

Impulses are very large, but very short lived forces. An example of an impulse in real life would be hitting a baseball with a bat. The ball and bat are only in contact for maybe 1/1000th of a second. Because their duration is such a fixed small number are usually expressed in units of velocity*mass (the same as momentum).

To get back to your original question, applying an impulse to a body works like velocity += impulse/mass. So applying an impulse to an object with infinite mass doesn't do anything. Setting the velocity explicitly gets around that.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
mordrax
Posts: 8
Joined: Sun Mar 06, 2011 8:59 am
Contact:

Re: Objects constantly overlap and jump around the screen

Post by mordrax »

What you said makes sense, but then it feels like impulse and velocity are neither what i'm looking for.

For an object to start moving by itself, it has some sort of internal force (in this case the internal force is the feet pushing against the ground to propel it forward).
If i set the velocity explicitly (as i'm doing now), when this object is against a wall, it overlaps because the velocity is set against the laws of physics, then gets corrected because it is overlapping, then moves into it again, causing a jittering motion on collision.

If i set an impulse, then sometimes the force being pretty big, push other objects back beyond what seems 'natural' for the context. To counteract this, you suggest setting a max force, however with max force, does it mean that if i have a massive object charging at high velocity, that the force it exerts would be capped to lessen the effects of it's charge?

so what i'm looking for is for a player to move on user input, stop when the user stops input (unless there is something else pushing against the player) and stops when it hits a wall or other objects which has much larger mass than itself.
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: Objects constantly overlap and jump around the screen

Post by slembcke »

The force of friction between the feet and the ground is exactly what the pivot joint is configured to do. It's not obvious how, but it does work. By disabling the joint correction by setting the biasCoef or maxBias to 0, the joint won't try to push the joint anchors together. Instead, it only tries to match the velocity of the control and slave bodies and is limited by the joint's maxForce property. You can change the velocity of the control body to whatever you want, whenever you want and the physics handles the rest.

Massive objects will still have a lot of momentum. Consider pushing a heavy car around by hand. While it will be hard to get it moving fast, if it hits something it will do a lot more damage than you could do by hand. The amount of kinetic energy an object can store isn't limited by the force pushing it. Ion propulsion engines used on space probes like Deep Space One produce less thrust than if you were to blow on it. Do that continuously for a 2 years though and you don't want to stand in the way.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: No registered users and 7 guests