Hi, I’m having a little problem with physics (I’m using Minie).
A rigid body made of a cylinder collision shape with gravity and angle factor set to 0.
The object is moved by setting a linear velocity.
There’s also an obstacle made of a static rigid body slightly taller than the base of the cylinder.
When the cylinder bumps against the obstacle it will sometimes bounce back and other times move up over the obstacle depending on the speed.
I don’t understand exactly what makes the pushing up happen but I would like to avoid it (e.g. if I’m moving horizontally I don’t want a step to alter the height of the body).
I guess jbullet detects the bodies overlapping and moves the dynamic one to the shortest non overlapping position but I’d prefer if it moved it against the velocity vector.
When this scenario happens in my game it feels very inconsistent, players can overcome some obstacles if they move fast and makes level design very difficult because there is not clear max steps height.
For simulating characters, Minie provides a PhysicsCharacter collision object with a configurable step height. You could use that in place of the PhysicsRigidBody with rotation disabled.
Thanks for the suggestions, I avoided using PhysicsCharacter (or BetterCharacterControl) because I wanted to customize the movement to my needs and those implementations didn’t work well for me. So I decided to made my own.
I need to experiment but I’m not sure if the PhysicsCharacter will be free of this particular problem, if that’s true I would try to port the solution to my code.
Increasing accuracy certainly helps in this example, I might end up doing that, although I want to avoid it as I don’t want my game to be too cpu demanding. At the end I only care for the user character to have tight and predictable controls, the NPCs and other objects don’t need to be precise.
I remember I was having a problem similar to this, and the simulation was better when the number of the colloiding triangles increases (I guess the level of detail parameter or you could control it through the Geometry API).
This is a different case, I think since he describes having an actual ‘lip’.
Essentially, questions like these (and they are common to games) boil down to:
“My physics is acting too real, how do I stop it?”
If you have a real cylinder slide along the floor and hit a small lip, it’s going to have a chaotically bad time. Need something rounded on the bottom if you want to minimize that.
Thanks for the suggestion, I understand a common practice is to use capsules for this and that’s how I did it before.
But for my taste the capsule makes everything worse as it adds this bottom area of weirdness where if I go fast against a step the body jumps unpredictable and breaks the speed built up so far.
Also with bullet when crossing seams between coplanar triangles there are random jumps (I think this might be what Pavl mentions, no sure but I’ve seen it being asked in the forums).
So my implementation is to use a floating cylinder, using racasts to keep it at a fixed distance above the floor. This way (except for the case in the example) the steps do not affect at all the speed of the player and the player moves up by exactly the distance as the step height, zero jumping.
So far it’s been working great to my taste, consider I try to make my game movement feel like quake’s which is very fast and precise.
Absolutely, I would ditch the “realistic” physics simulation anytime if Minie weren’t so convenient.
Overall Minie gets me 90% there, it’s just the player’s physics I override to make it more “mechanical” than “natural”.
Anyway I made a simple proof of concept that fixes this case nicely. I haven’t adapted it to my game yet but I think it should work.
I throw a raycast in the forward direction and clip the velocity vector so it doesn’t go inside the obstacle:
private void clipVelocity(PhysicsRigidBody player, float tpf) {
var location = player.getPhysicsLocation().add(0.25f, -0.5f, 0);
var results = space.rayTest(location, location.add(1, 0, 0));
for (var result : results) {
var delta = player.getLinearVelocity().x * tpf;
var dist = result.getHitFraction();
if (delta > dist) {
player.setLinearVelocity(new Vector3f(dist / tpf, 0, 0));
}
}
}
Just for future reference (if some future monkey reads this) I wanted to share this short article. I found it interesting since it explains how Source engine handles physics.
In short it runs two physics simulations: the simpler quake one and the more advanced havok. For some game objects (player, enemies, elevators) quake is dominant and for others (barrels, vehicles) havok is dominant.