Archive 17/01/2023.

Raycast vehicle

slapin

Hi, all!

For some time I was making city sandbox and got some progress.

Doing a car (AI and controlled by player) I was using Urho example
from vehicle demo and now I find that it doesn’t fit what I make due to following reasons:

  1. It is very difficult to control, car is getting stuck quickly and in general it is very hard
    to make it work in complicated environment. One ends-up hacking-up all behavior,
    so while using physics is great, working-around physics is not, and it seems that Bullet
    physics is not advance enough to make reliable vehicles. Not mentioning wheels stuck in terrain :frowning:

  2. LODding the vehicle behaviors (i.e. path motion/physics motion with collision) and spawning does have
    too much side effects.

So after fighting things for several months I think it is better to move on and go for raycast vehicle.
I’ve been reading Internet for quite some time on subject but it looks like I don’t have some basic knowledge
pros know, so I still can’t understand the concept.

So what I really ask for is to put me into right direction - are there any good theory links to read about
these? I want GTA3 level of car physics. I know it is hard work, I don’t have problem with it I just need to know
where to begin.

Modanung

Starting with the sample, adding some suspension to the vehicle would help a lot when it comes to both realism and control.

slapin

Sorry for being so dumb, but - what do you mean by “adding suspension”?

johnnycable

A counter-force impulse when the car bump into something, like the bump cars in playing parks… you know that, don’t you?
Just a little spin, not too strong… a little recoil…
then measure the “medium stuck force” of your simulation and set the bump to go over that…
just messin :wink:

Modanung

What I guess I’m saying is… flinstone mobile ain’t got these: :wink:
Car suspension

Tires not shown in image :stuck_out_tongue_winking_eye: also add some bounciness in real life making for longer contact with the road on take off. But this squeezing could probably be neglected after adding suspension. Tire friction does vary with pressure (both from air and suspension).

johnnycable

Exactly what I had in mind, I swear :grin:

Modanung

slapin

I see you guys having fun, I like it.

Well, I found the simplest case.

  1. I now understand what spring force is. The idea is that I do raycast from some point to ground and notice its length.
    then I find the compression value comp = raycast_distance / raycast_length. And then I can find my force by

Vector3 spring = Vector3(0.0f, 1.0f, 0.0f) * k * comp where k is multiplier value.

  1. The problem is what to do with the result. If I do body.AddForce(spring) either nothing happens, or
    everything explodes. Any ideas on what to do next?
slapin

Also original example with 5 rigid bodies and constraints puts too much strain to CPU,
which puts even i7 2500K to crawling position with 10 vehicles. I expect raycast car to be less intense…

lezak

Have You seen offroad vehicle made by @Lumak?

Modanung

In most cases you’ll want to multiply your force with the timeStep.

Lumak

He’s already admitted that that is too complicated for him.

Edit: just realized that he said:

deleted my suggestion.

slapin

@Lumak It appears that I said not really what I intended to say.

I just mean that full physical vehicle with rigidbody for everything done in Urho3D
Bullet integration does not allow to implement reliable vehicles. By this I mean vehicle based on example.
The main problem is torque transform from RigidBody to actual motion - it is very hard (probably impossible)
to get proper (controllable, predictable) behavior due to too many side effects. I never intended to say it is not possible to implement the required thing using Bullet directly as it exports enough hooks. But I’m really not ready for Bullet.
It is too complicated to set up and too little documentation for me to understand. So I’d prefer to stick to some simple
things for now. And yes, your RaycastVehicle demo is great, but it is too complicated for me to understand at my current level.

suncaller

The Rocket League team implemented their own “fake physics” for similar reasons to what you suggest. I’ve read various discussions online about this simplified physics on reddit, GDC talks by the devs, etc. It might help to look into this game. Bullet physics likely won’t do the job here if you want to simulate some serious, complex vehicles.

Lumak

Ah, ok. What I was going to suggest was this, btRaycastVehicle example
A simple demonstration of btRaycastVehicle dynamics.

But after reading what you said, or at least what I thought you meant, it would’ve been pointless to even suggest it. But most raycast vehicle dynamics are about the same, you typically code the dynamics you’re looking for.

johnnycable

Why not add checks for physics values into the update cycles? It’s easy to give infinite power impulse to a body, especially if you drag them around by changing their position with setPositionSomething…
this is evil :smiling_imp: you get teleport… :fearful:
you need a good way of number crunching to fine tune physics…
if you take for instance @Modanung “bumping car” physics example above, you see you could easily “sample” the impulse the car is being applied, then reverse it someway…

slapin

Well, it looks like it is not possible to implement raycast vehicle in Urho, as AddForce to RigidBody consumes extreme amount of CPU and FPS drops to about 12 fps for 10 cars on i7 2600K.
For single vehicle and no other processing that is probably OK, but for several vehicles this doesn’t work at all.

Is there any other ideas? I think I can just do ray/spherecast and move wheels up/down to prevent
terrain penetration and use distances for proper hull positioning. Is there anything else I can do?

Thanks!

void update(float timeStep)
{
    float comp = 0.0f;
    float spring = 21000.0f;
    PhysicsRaycastResult result = sc.physicsWorld.RaycastSingle(
        Ray(wheel.parent.worldRotation *
               position + wheel.parent.worldPosition,
            wheel.parent.worldRotation * Vector3(0.0f, -1.0f, 0.0f)),
        length,
        STATIC_LAYER|VEHICLE_LAYER|CHARACTER_LAYER);
    float distance;
    if (result.body !is null) {
        comp = 1.0f - result.distance / length;
        distance = result.distance;
    } else
        distance = length;
    float springv = (distance - prevdistance) / timeStep;
    float springf = spring * (length - distance);
    float damperf = damping * springv;
    float force = springf - damperf;
    RigidBody@ body = wheel.parent.GetComponent("RigidBody");
    body.ApplyForce(wheel.worldRotation * Vector3(0.0f, 1.0f, 0.0f) * force, position);
    prevdistance = distance;
}
slapin

Also this way never gets good results, it never hovers, just either jumps or lays on collision shape.
Strangely, similar code works in Unity. Looks like Bullet was not made for it and something have
to be hacked on low level…

slapin

Well, it looks like the problem is either AngelScript or something…
C++ version of code works fine and stable. Also @Lumak 's Bullet raycast vehicle code works great.

@Lumak do you plan to submit bullet vehicle as standard component to Urho?
I stress-tested it with 100 cars and don’t see much CPU load.
I wonder how Unity people live with JavaScript - looks like JavaScript is much faster than
AngelScript running FixedUpdate… So now I have to rewrite all my tight loops in C++.
Too bad I’m so not into C++, I hope I can glue C code in there, so to maintain sanity…
Hope I will get there eventually…