Introduction
That was mostly a spare time experiment for me to have some idea about Source SDK's capabilities. The repository can be found on https://github.com/dyanikoglu/source-sdk-bullet-physics
The Story
While browsing through game developement related repositories in Github, I've found someone was able to inject a different physics engine into Source SDK https://github.com/DrChat/Gmod-vphysics. After playing around with the project, I've decided to take over the project, and make further improvements. That was nice opportunity for me to discover Source SDK.
As first step, I had to remove whole Bullet SDK source code from upstream repository, and add Bullet SDK Github repository https://github.com/bulletphysics/bullet3 as a git submodule into my fork. With that way, Bullet SDK related commits will be completely separated from the actual work on Source SDK, and at the same time, I will be able to merge recent changes from upstream Bullet SDK repository easily. Talking about recent changes of Bullet SDK, the upstream repository was using an ancient version of Bullet, so I had to update the version, and fix lots of API change related compile errors in injection code.
As second step, I've tried to get more clean & well defined workflow for building the binaries for Bullet SDK & Source. To achieve a faster build workflow, I've utilized CMake to automate majority of Bullet's building process.
After setting up the new workflow, I've started investigating the existing physics injection source code by debugging, and tried to find bottlenecks on various scenarios. Since the injection is highly experimental, it had lots of under the hood issues as expected.
The biggest problem with existing injection code was the utilization of old multithreaded modules of Bullet. Those modules were deprecated like 4-5 years ago, and was replaced with more powerful and modern techniques later. I've had to rewrite physics environment initialization part of the injection source with those new multithreaded modules: https://github.com/dyanikoglu/source-sdk-bullet-physics/commit/154fff24f15e30ec130f3262a3f191793671d839 & https://github.com/dyanikoglu/source-sdk-bullet-physics/commit/d62c5870792c3e66c4750c63e9b3a4c8b6ed307d
After getting new multithreaded modules working, I've did some stress tests, and discovered some bottlenecks on the injection source code. I've did various commits to increase performance during scenes with lots of physics objects:
Complexity optimization for LedgeToConvex function. Previously was O(n^2), now it's O(nlgn) in worst case thanks to pre-sorting of triangles: https://github.com/dyanikoglu/source-sdk-bullet-physics/commit/1e63ba860b5dd7dcf7f7410e2d88270ffcb07aee
More modern approach for handling CCD (Continuous Collision Detection): https://github.com/dyanikoglu/source-sdk-bullet-physics/commit/7dfa36ac8af5b1ce895d8c90d02ca1acfb36b467
Micro-optimization by reordering collision pair checks with their frequencies: https://github.com/dyanikoglu/source-sdk-bullet-physics/commit/40412f0505b607d9b49f2d063d922503afd25c27
... and other optimizations mostly related with finding optimal configuration parameters of Bullet SDK for Source.
Results
As the final result, I was able to have somewhat stable gameplay with lots of physics bodies flying around, and was able to maintain 200+ FPS most of the time (I was probably jamming during the recording, please ignore the music if it's not your style 🙂):
... and of course, the injection didn't work in some cases, and caused some funny ragdoll physics 🙂 :
At the end, it was an interesting experiment for me to see an ancient game engine running a modern physics SDK, but of course with serious amount of issues.
Comments