Page 1 of 1

btRaycastVehicle change speed depending on the surface

Posted: Sun May 20, 2018 7:09 pm
by stefanejro
Hi, I'm creating a racing game using Bullet Physics library and btRaycastVehicle. I would like to change vehicle's speed depending on the surface. For example if vehicle is moving on a concrete road the speed should be normal, but when it goes off road to grass or some other surface the speed should decrease.

I was trying with applying different friction to different surfaces but that does not seem to have any effect. My other idea was to throw a raycast from each wheel and check the underlying surface and manipulate engine force accordingly, however I'm not sure if that is the most efficient way.

Could someone please point me any good solutions for this ? Maybe some code samples ? Seems like a pretty common usecase but I wasn't able to find anything valuable on the internet.

Re: btRaycastVehicle change speed depending on the surface

Posted: Mon May 21, 2018 6:19 pm
by drleviathan
I think the raycast method is what you would want to use, however after a quick perusal of the vehicle code it looks like the btRayCastVehicle is already using raycasts to track the object under each wheel. If you look at the implementation of btRaycastVehicle::rayCast() you'll see that for each wheel the btWheelInfo::m_groundObject is set, and then that value is used in btRaycastVehicle::updateFriction().

Note that btRayCastVehicle::updateFriction() is declared virtual, which means you could derive MyRayCastVehicle class and override that method to call the base class method but also compute a total effective friction of the wheels and use that to affect the vehicle's motor's max speed.

Re: btRaycastVehicle change speed depending on the surface

Posted: Tue May 22, 2018 2:04 pm
by stefanejro
Thank you for response drleviathan ! Sounds like a good approach. I will try this out !

Re: btRaycastVehicle change speed depending on the surface

Posted: Wed May 23, 2018 10:52 pm
by stefanejro
Ok, I found the solution so I will post it here, maybe will be useful for someone.

There is no need for any additional raycasts or anything fancy. The solution is simply setting the desired friction values for the surface's rigid body.

Code: Select all

btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
groundRigidBody->setFriction(10.f);
For example road will have a low friction while some off-road terrain will have high friction which will result in drop of speed. However, the important thing is that setting friction seems not to have any effect if vehicle suspension values are "incorrect". The suspension values that worked in my case where taken directly from the vehicle demo from bullet examples and they are as follows:

Code: Select all

    
btRaycastVehicle::btVehicleTuning tuning;
tuning.m_suspensionStiffness = 20.f;
tuning.m_suspensionDamping = 2.3f;
tuning.m_suspensionCompression = 4.4f;
Previously I was trying with much higher suspension values and for them setting friction even to 999999999 had 0 effect. I don't know the exact reason behind such behavior but anyway the above solution solves the problem.