I am trying to create a physics effect for characters similar to what is found in Left 4 Dead:
Characters have regular “hard” collisions with level geometry and enemy characters. My current setup handles this well. Characters are simply a sphere shape rigid body, and they collide with each other, blocking each others movement.
I want to have some additional behavior where characters that are friendly with each other will not exactly collide with each other and can pass through each other, but a force similar to same-pole magnets repelling will constantly be pushing them apart to try and maintain a certain amount of “private space” for each character.
The result is if one characters is running straight into other one, they can pass through. This prevents a character from standing in a doorway for example and impeding the progress of another. If the character pushed into the space of the other and stopped, the characters would push each other away to prevent occupying the same space.
I suppose I could track which characters are intersecting each other and calculate and apply forces manually, but figured I’d ask to see if anyone had a better idea of how to accomplish this.
There is nothing out-of-the-box which could provide such an effect.
I think you will have to compute things yourself. Even worse, computing forces is not enough, since characters are usually kinematic bodies, and kinematic bodies are not affected by forces. You will have to compute target displacements, and check if these target displacements are possible or if the lead to collisions (sweeping), then compute actual displacements from the target displacements. Maybe even iterate a few times per frame.
I recommend doing this in C++ for performance reasons. It’s not hard to write your own ‘contrib’ module for the Panda3D Bullet module. Even easier would be to modify the P3D Bullet module directly. Of course you could verify your ideas in Python first, and once you are satisfied with the result (except for performance) port the code to C++.
Actually we break convention here and use dynamic bodies for characters, so it is not such a big problem after-all.
I thought there might be something similar to ODE where I could tweak CFM/ERP to allow the contact joints a certain amount of flexibility for collision between a specific combination of bitmasks.
Ok, so you have dynamic bodies.
In this case you might have a look at these posts:
panda3d.org/forums/viewtopic … 9754#89754
We have added suppoprt for modifying contact data about 8 weeks ago. It is limited to the ‘contact added’ events, and the intention has been to modify friction.
I don’t see how this helps in your case, but tell me if you are successful or not.
My solution ended up as follows:
- Have both a rigid body and a ghost node for each character, with the ghost parented under the rigid body.
- Have a special collision mask for some characters which are supposed to block you and allow the rigid bodies of those characters to collide. Most character rigid bodies will not collide with each other.
- Character ghost nodes collide only with each other.
- Check the overlapping nodes of each ghost node, and manually modify the velocity of each rigid body to accelerate it away from other characters.
- The force increases exponentially the more the ghost nodes are penetrating each other.