[SOLVED] Clipping through floor and framerate drop

Hi, I’m pretty sure I am doing something wrong, as my physic behave horribly.

I made a prototype using modified Fancy Car code as reference and Terrain Fractal grid.

I tried to made a all terrain vehicle with the frame higher than the wheel.

I am observing several problem:

  • vehicle wheels tend to clip trough the floor and get stuck “below” ground
  • player character control capsule will do the same and fall through world if I push against vehicle
  • if player character jump on vehicle, the wheel sink in the floor and the framerate drop to a crawl
  • if I add about 20 Rigid body control with a capsule shape, the framerate drop to 10-20

Is this limitation of the engine, or am I doing something wrong?

here is a jar if you want to experience the first 3 points, you just need to add JME3-testdata.jar in the libs

WASD+space, E to climb in vehicle.

Here is how I do the physic for the terrain, all the rest is pretty much cut n paste from jmeTest code
[java]
public void AddToPhysicSpace(final PhysicsSpace phys) {
RigidBodyControl landscape = new RigidBodyControl(0);
terrain.addControl(landscape);
phys.add(landscape);

    terrain.addListener(new TerrainGridListener() {

        public void gridMoved(Vector3f newCenter) {
        }

        public void tileAttached(Vector3f cell, TerrainQuad quad) {
            while(quad.getControl(RigidBodyControl.class)!=null){
                quad.removeControl(RigidBodyControl.class);
            }
            quad.addControl(new RigidBodyControl(new HeightfieldCollisionShape(quad.getHeightMap(), getTerrain().getLocalScale()), 0));
            phys.add(quad);
        }

        public void tileDetached(Vector3f cell, TerrainQuad quad) {
            phys.remove(quad);
            quad.removeControl(RigidBodyControl.class);
        }

    });
}[/java]

1-3 might be as simple as the suspension of the car can’t handle the weight so you need to trim the values for the suspension. More information here (PDF): http://blender3d.org.ua/forum/game/iwe/upload/Vehicle_Simulation_With_Bullet.pdf

The bullet ray cast vehicle is a “simple” hack in bullet to approximate a vehicle for some use cases (e.g. racing car game) and might not work very well in other use cases. I’ve had lots of trouble with bullet ray cast vehicle behaving strange, it is easy to make them tunnel (http://hub.jmonkeyengine.org/forum/topic/jme3-beta1-vehicle-tunneling-through-terrain-what-to-try-next/) if you go “off road”.

Ok so if I understand correctly, the wheel sinking in ground can be handled via suspension settings (most likely), but bullet as a whole is not particulary suited for off road vehicle?

My MaxSuspension is already quite high tho…
[java]
float stiffness = 50.0f;//200=f1 car
float compValue = 0.2f; //(lower than damp!)
float dampValue = 0.3f;
final float mass = 800;

    //Create a vehicle control
    vehicleControl = new VehicleControl(carHull, mass);

    //Setting default values for wheels
    vehicleControl.setSuspensionCompression(compValue * 2.0f * FastMath.sqrt(stiffness));
    vehicleControl.setSuspensionDamping(dampValue * 2.0f * FastMath.sqrt(stiffness));
    vehicleControl.setSuspensionStiffness(stiffness);
    vehicleControl.setMaxSuspensionForce(20000);

[/java]

I’ll try to tweak value and get back with result, see if point 2 framerate portion also get fixed when wheel don’t sink.

What would be the best approach to have something to similar to Halo Warthog (agile, fast yet feel heavy, doesn’t roll too easily, can go pretty much everywhere)?

What would be the best approach to have something to similar to Halo Warthog (agile, fast yet feel heavy, doesn’t roll too easily, can go pretty much everywhere)?

I don’t know, I’ve been hacking on and off for a year on a hover craft control and still haven’t found a “fun” and playable feeling so I shouldn’t give advice :slight_smile: But in general, if you can tweak the values and get it to work I think the vehicle control is the least painful way.
You shouldn’t be afraid of faking stuff, Halo, for example, has a nice “vehicle sinks a bit when a character is boarding”-animation but I really don’t think they use physics for that. The roads in halo are pretty damn flat also, as soon as you run into a few rocks the vehicle doesn’t feel that natural. So I don’t think you actually can go “everywhere” but with a good level design it feels like you can.
Other examples might be to not use a 1 ton car but make it 100 kg so the forces aren’'t to high when airborne. In my experience it’s mostly try stuff out until it feels good.

I suggest using a different approach, (at least tahts what i doing now)

Do traces (3 or 4 whatever you prefer) downwards diagonal relative to the own rotation., then apply force upwards at the point. Eg if front left is only 10 cm away from ground apply at front left a upwards force of 1k if its 30 cm away apply only 0,25k ect. Togheter with a angular dampening this leads to quite some stabilized behaviour.

<cite>@jmaasing said:</cite> [...] if you can tweak the values and get it to work I think the vehicle control is the least painful way. You shouldn't be afraid of faking stuff, [...] not use a 1 ton car but make it 100 kg so the forces aren''t to high when airborne

good tips, i’ll keep that in mind

<cite>@Empire Phoenix said:</cite> I suggest using a different approach, (at least tahts what i doing now)

Do traces (3 or 4 whatever you prefer) downwards diagonal relative to the own rotation., then apply force upwards at the point. Eg if front left is only 10 cm away from ground apply at front left a upwards force of 1k if its 30 cm away apply only 0,25k ect. Togheter with a angular dampening this leads to quite some stabilized behaviour.

That sound like a very good idea, but i’m not sure if I understand correctly. You are sugesting I keep using vehicleControl like I do now, but in addition to that have each wheel detect how close its to the ground using a couple of diagonal raycast based on center of wheel and aligned to vehicle world rotation, then apply more force on the wheel the closer it is to ground (and even more if it collide with it?) on each of those direction?

Depending on the amount of vehicles(and their precision) i would even go with a dirty hack, like just using a box with no friction or similar. After all what looks good enough works ^^ Nobody realy cares if it is actually simulated that way.

So basically after that you have a box that tries to hover a few cm above ground, so kinda similar to a vehicle.^^

If you also want wheels to go with that you’d have to calculate the wheel position but since you already cast rays you know where they intersect the ground. Then you basically have the same as the bullet ray cast vehicle :slight_smile: The two main differences is that the bullet vehicle is executing in native code and it has problems with the wheels getting stuck on the wrong side of planes.
But what @EmpirePhoenix says is true, there are many ways to simulate a vehicle depending on what you want. Another way is to use a kinematic rigid body + some ray casting and then just position the vehicle where you think it should be - not obeying the laws of bullet physics but rather your own simplified physics. It has the drawback that you have to handle collision behavior yourself. That is the feeling I get when playing Halo. Vehicles do not collide like rigid body billiard balls, they mostly just stop when colliding with something.

Hey all, thanks for the suggestions. I haven’t got around to implement them, but I think I’ll go with control attached to each wheel checking floor distance and applying necessary force. I’ll post it here once I do.

As for player/vehicle interaction causing issue, I think I’ve found the solution, at least the theory, but I’m not exactly sure how to implement that. Its my understanding it would use collision group but I’m not familiar with those yet.

Here is the theory: have a static rigid body follow the vehicle node and have the player interact with it instead. That way the player won’t interact with the active vehicle physic, just the immobile object at the same place. This should get rid of framerate issue when player try to push the vehicle toward the ground and fall in void issue when vehicle push the player in the ground.

Now, I just need to figure out how to tell physic who interact with who.

After many hours of trial and errors, here is what I got. There is a lot less case of stuck wheel, but its still not perfect. Anyway you see how it could be improved?

[java]
@Override
protected void controlUpdate(float tpf) {
VehicleControl phys = spatial.getControl(VehicleControl.class);
if (phys != null) {
int numWheel = phys.getNumWheels();
float maxImpulse = (phys.getMass() / numWheel);
float impulse = maxImpulse * Math.min(tpf, 0.1f);
for (int i = 0; i < numWheel; i++) {
CollisionResults resultsDown = new CollisionResults();
VehicleWheel wheel = phys.getWheel(i);
Quaternion rotation = phys.getPhysicsRotation();
Vector3f wheelTop = rotation.mult(wheel.getLocation().add(0, wheel.getRadius(), 0));
Vector3f rayStart = wheelTop.add(phys.getPhysicsLocation());

            Ray rayDown = new Ray(rayStart, rotation.mult(NEGATIVE_Y));
            terrainNode.collideWith(rayDown, resultsDown);
            if (resultsDown != null &amp;&amp; resultsDown.size() &gt; 0) {
                float wheelDiameter = wheel.getRadius() * 2;
                float dist = resultsDown.getClosestCollision().getDistance();
                if (dist &lt;= wheel.getRadius()) {
                    //panic!
                    phys.applyImpulse(rotation.mult(new Vector3f(0,maxImpulse,0)), wheel.getLocation());
                } else {
                    phys.applyImpulse(rotation.mult(new Vector3f(0,(wheelDiameter/dist)*(impulse),0)), wheel.getLocation());
                }
            }
        }
    }
}

[/java]

One poossible bughack would be to determine if there is something between the middle of the car and the wheel (by doing aoccasional additional ray) if it is, then the whell is probably on the wrong side and you should apply a bit of force to push it back to the right one.

Also another possible solution would be to use real cylinders as wheels and use a constraint that allows rotating.

Well, after a few tweaking of the stabilizerControl shown above, as some other tweaking, including reducing suspension stiffness and suspension max length, I got a very setup. I still suffer from the occasional “wheel gone on the wrong side of the plan” framerate drop but its good enought for now, so I’ll mark this as closed.

thanks everyone for the suggestion :slight_smile:

Hi everyone, I wanted to add to this because I found the “real” solution to my issue, and its MUCH more simpler and MUCH more efficient than adding control.

Found this important detail in JME2 jbullet PhysicsVehicleNode google code page:

The rays should originate inside the vehicle chassis's CollisionShape. Otherwise, the wheel can be projected through world geometry.

So simply using a compound collision shape and adding a box where the axels should be solved all my wheel sinking issue :slight_smile:

3 Likes

OMG to think of all the time I spent with this and not finding the solution, must try this out on my own code :slight_smile:

Excellent advice, thank you. Now I can get a little car to leap to a decent height and land with a satisfying bounce, rather than getting stuck in the track, thanks to a CompoundCollisionShape which adds a BoxCollisionShape dedicated to guarding the points where the suspension “joins” the vehicle.