Specialization Project - Vehicle Modeling with PhysX
So I've had an interest for racing games ever since I played Gran Turismo for the Playstation a long time ago. Racing games are fun, engaging and can bring an emergent type of gameplay where you hone your skills to become the best driver possible in various environments. It doesn't matter if it's more of an simulation style or an arcade style of racing. You're mostly looking to thread that needle, evolve as a driver and get a good feel for the driving-model that a racing game delivers.
I've always wondered how to implement vehicle-physics and wanted to know what variables reflect a driving-model and how to adjust them in a meaningful way, such as for how the vehicle handles and drives. So for my specialization project I decided to look into whats necessary in that regard.
- To learn how to implement vehicles with PhysX
- To learn what physical properties change the handling/drive of a vehicle
- 5 weeks half-time
- Implemented using an in-house game engine (DirectX11, PhysX)
Vehicle Initialization in PhysX:
To setup a vehicle using PhysX requires alot of different steps as I used an in-house game engine that is used for other game projects. Firstly there has to be an exisiting implementation of PhysX to even initialize the Vehicle SDK section but already having that I used the official documentation for the Vehicle SDK to setup a simple vehicle-implementation. The biggest take-away from the documentation is that there are mainly three steps to configure your vehicles creation.
//pseudo-code for creating a 4-wheeled vehicle PxVehicleWheelsSimData* wheelSimulationData = PxVehicleWheelsSimData::allocate(4); //holds configuration data for the wheels SetupWheelsSimulationData(wheelSimulationData ); //setup the wheels
PxVehicleDriveSimData4W driveSimulationData; //holds configuration data for the driving model SetupDriveSimulationData(driveSimulationData); //setup the driving model
PxRigidDynamic* vehicleActor = myPhysics.createRigidDynamic(startPose); //holds the physics data for the vehicle SetupVehicleActor(vehicleActor); //setup the physics object
Each setup-function goes more into depth in configuring the variables that describes how the vehicle drives, handles and is represented in a physical sense. There are alot of settings to go through and it took quite a while to initialize the full system to get it to work. There is also some things to consider while using the PhysX Vehicle SDK and that is how you update the vehicle. Since a vehicle is a part of a physical environment you need to make sure you have material properties that reflect the surface you drive on as well as frictional values that suit the type of feel your looking for. The way the vehicle updates in PhysX is that it shoots raycasts from each wheelsuspension to approximate the best physics simulation dependent on the frictional pairs between the wheels and the surface. I chose to use physical properties for the surface that was close to tarmac to simulate the feeling of driving on a normal road but of course you can change the material properties to simulate other surfaces such as gravel or snow.
So which variables matter for a vehicle to handle/drive a certain way? The PhysX Vehicle SDK provides alot of configuration possibilities when it comes to how a vehicle drives. My approach was to expose most of the variables to a user-interface so I could easily configure and iterate upon them while being in-game. I added support to change dimensions, gear ratios, engine data as well as steering and suspension behaviour. Here is an example of setting up the vehicles physics dimensions and properties.
The method of changing the properties of a vehicle immediately really helped with the iteration process of transforming the vehicle into the desired outcome. For example, physics properties do alot for the handling and drive of a vehicle, whether it be how the wheels are placed but also what masses and moment of intertia there exists on the physics object. When using a configuration tool like this it is also easy to save the configurations for different kinds of vehicles or different setups on a vehicle. It was also a way for me to easily line up the 3d-models of the vehicle with the chassis and wheels being separate models.
There were alot of small things to do to get the vehicle in a working state but once I got it going it was easy to iterate on all the different variables that concerns the driving model. However, I ran into some small hiccups when I started to implement a simple follow-camera for the vehicle. Since the physics-simulation updates in a different frequency on a fixed framerate compared to the logic I got some jittering artifacts on my graphics, especially when the vehicle had a high velocity. To fix that I had to do some math between each physics frame to make sure i had the right postion for the vehicle each frame on the logic side. I tried with both extrapolation of velocities and predicting the position and interpolation of positions between each physics frame. The interpolation tended to look more smooth so I went with that instead and that solved my jittering problem. The drawback is that the updating of the graphics is one frame behind but it doesn't matter that much if the experience is smoother.
There are alot more things I would like to implement and experiment with in the future. Since alot of the time in this project was to get the vehicle working I did not have much time to fix much of the gameplay features a racing game normally includes. Such as tracks with different surfaces and more vehicle models to choose from. If I had more time I would definately look into getting different surfaces to work properly and also include a more varying terrain, to stress the physical properties of the vehicle.
- Created an implementation of PhysX Vehicle SDK
- Setup an environment for configurating vehicles