Roadster vehicle dynamics

Just another one of those videos to inspire others on this forum.

Does it actually inspire others? I wonder.

Side friction stiffness settings:
front: 0.8f
rear: 0.04f


Nice .
I guess it’s a Chibii racers retro car.

Yes, that’s correct. I bought several art packs from 3drt and noticed you were using the retro set as well. I gotta say, it’s nice to work with something of a quality, unlike my pickup truck that I made in my offroad repo.

oh, wait. The name of the person that made the android racer started with ‘E’ and I thought it was you, but it’s extobias.

That’s really nice. I’m trying to get the same effects, unsuccessfully, for a couple of weeks. The thing is I would to have several height’s on the track but the car is flying in the curves with heights.

What do you mean by added heights, something like a ramp, speed bump, or gradual height elevation on the road?

Like in gradual height elevation. The front wheels start to bumping, even applying a down force.
I’ve playing with sideFrictionStiffness, but the problem occurs when the car takes the curve with height.

OK, I understand what you mean. One thing that can help force the vehicle to stay on the ground is to apply a downward force. In the original 19_VehicleDemo, there’s this block:

    // Apply downforce proportional to velocity
    Vector3 localVelocity = hullRot.Inverse() * hullBody_->GetLinearVelocity();
    hullBody_->ApplyForce(hullRot * Vector3::DOWN * Abs(localVelocity.z_) * DOWN_FORCE);

I do something similar but apply force only when one of the wheel is not touching:

void Vehicle::ApplyDownwardForce()
    // apply downward force when some wheels are grounded
    if (numWheelContacts_ != numWheels_ )
        // small arbitrary multiplier
        const float velocityMultiplyer = 1.00f;
        Vector3 downNormal = node_->GetUp() * -1.0f;
        float velocityMag = hullBody_->GetLinearVelocity().LengthSquared() * velocityMultiplyer;
        velocityMag = Clamp(velocityMag, MIN_DOWN_FORCE, MAX_DOWN_FORCE);
        hullBody_->ApplyForce(velocityMag * downNormal);

The velocityMultiplyer is a tweakable value, which I haven’t touched yet. And the MIN_DOWN_FORCE and MAX_DOWN_FORCE are set to 10.0f and 1e4f, respectively. The MAX value is pretty high, but I tend to have my vehicles travel at much faster speed than normal.

edit: You should also consider raising your sidewalls, though.

How did you make the tire tracks? :grinning:

Welcome to the forum noskopo. You can find the skid track code here,


I think you could try to play with:

  1. vehicle center of mass and your collision shape. In some cases one can make car which
    can’t flip at all.
  2. If you’re using raycast vehicle, try to increase spring stiffness.
  3. If you’re using raycast vehicle, try also decreasing roll influence.
    Also I find it amusing to use 2 downforces - one when all wheels touch ground and another which
    whorks when at least one wheel touches ground. This makes vehicle hard to go flying for no reason.
    Also try to learn yourself a bit about real vehicle physics parameters to make sure the behavior is not too
    unrealistic and makes sense at least a tiny bit. Articles like and
    help a lot with understanding mechanics. Also, try some common games like Tux Racer, GTA3/VC/SA and try to feel the difference and what you really like and dislike.
    Hope that helps.
1 Like

Also Bullet term for “I use convex hull and my vehicle behaves strange, I did everything abouc center of mass and still can’t make it behave, Havok fixes it easily with inertia shape” is Inertia Tensor. Just for records.

Well, your track is too flat, a little curve for it and slight elevation of some parts would make it much more interesting…
About side friction - how do you implement it? The problem about original btRaycastVehicle in addition to wheel rotation is absence of control of side to side slide. Probably this also should depend on track surface somehow, but I did not go that far yet. (Urho3D component fixes wheel rotation, but not side-side sliding).

That won’t happen until the level design/creation phase. I still have a couple of dynamics to work out first before I get to that point.

You reviewed the “offroad repo” a long time ago – it’s the changes to the btRaycastVehicle side.

I just tested this bit for auto correct pitch roll: //ref from Constraint Class working on derived class

void Vehicle::AutoCorrectPitchRoll()
    // auto correct pitch and roll while air borne
    if (numWheelContacts_ == 0)
        // ref from
        const float stability = 0.3f;
        const float speed = 1.5f;
        Vector3 predictedUp = Quaternion(hullBody_->GetAngularVelocity().Length() * M_DEGTORAD * stability / speed,
                                         hullBody_->GetAngularVelocity()) * node_->GetUp();
        Vector3 torqueVector = predictedUp.CrossProduct(Vector3::UP);
        torqueVector *= speed * speed * m_fVehicleMass;

The predictedUp calculation is clever and it works a lot better.

edit: I added this to the repo minutes ago.


21 AI vehicles pathing on a spline. Tested on my Android phone and it ran very smooth.


Your phone is tough.
Mine can handle up to 5 btRaycastVehicles, so I have to LOD and run distant ones without physics.

I mean without Bullet as I do very simple fake physics manually. I think it depends on terrain
and various other aspects like my phone is Meizu M5 note.

I’m not usually up this early, but went to bed early and just got up for no good reason. Anyway, my phone is Android 4.1.2, API 16, a duo-core arm, and yours is Android 6.0 with an octa-core cpu, a more powerful phone. It’s hard to believe that you can only have 5 raycast vehicles in your scene. It must be the terrain. I don’t have it in my scene nor did I have it testing on my phone.

Well, I did play with raycast schedule pipeline, and it does have potential. so maybe I will be able to run more than 5 vehicles as I come to this, I just need to write another subsystem for this.

btw, my terrain is 240x240 grid (procedural, but nothing fancy), distance between vertices is 1 unit. So one have to be careful about raycasts to survive.