Opentrack

OpenTrack 4.0

On Linux PC I did usually compile Opentrack with the Wine Glue, patch in my custom appdata folder for Proton and hope that it’s still ABI compliant to Just work™. Alas recent Proton is sandboxed within pressure vessel and the usual approach of memory mapping is simply no longer working, if I got the gist of this right.

So my current strategy is to download and drop the Windows build of Opentrack into the game folder and chain-load the EXE with the game where the Opentrack EXE would listen on UDP while my native Opentrack BIN would send via UDP. A task not made easy with Proton but it is possible. The following snippet may give you some pointers. You will have to adjust it for your needs:

#!/bin/bash
# 359320 is a Steam game app ID, in this case 359320 = Elite Dangerous
export STEAM_APP_ID="359320"
export STEAM_COMPAT_DATA_PATH=/games/steam/steamapps/compatdata/$STEAM_APP_ID
export STEAM_COMPAT_CLIENT_INSTALL_PATH="$HOME/.steam/steam"
cd "/games/steam/steamapps/common/Elite Dangerous/opentrack2/install"
python3 /games/steam/steamapps/common/Proton\ -\ Experimental/proton run opentrack.exe

If you don’t fancy to do this manually or from a script you may also just use the protontricks-launch wrapper of protontricks:

protontricks-launch –appid APPID EXECUTABLE [ARGS]

This one even let’s you pick the app id from a nice little menu when launched e.g. like this: protontricks-launch /games/steam/steamapps/common/Elite\ Dangerous/opentrack2/install/opentrack.exe

Launching OpenTrack in a specific Proton context with protontricks
Launching OpenTrack in a specific Proton context with protontricks

Why running Opentrack twice? The native build performs a lot better with my webcam and every frame really counts here. Reading data via UDP is not much of a burden for Proton. This also saves me the trouble of fiddling with Wine Glue, a painful compile process nobody should endure involving installation of many many additional 32-bit libraries. Hilarious but it works.

Compiling with Wine Glue

You have been warned but this is how it basically works once all required developer packages are installed, that includes the wine-devel packages for i686 (and libevdev if you want virtual joystick support). On Fedora Linux you’d for example also need cmake git qt5-qttools-devel qt5-qtbase-private-devel and procps-ng-devel opencv-devel libevdev-devel. Adapt to your own needs.

git clone https://github.com/opentrack/opentrack
cd opentrack
mkdir build
cd build
ccmake ../
make -j4
make install
./install/bin/opentrack

The important part is to tick the SDK_WINE option or we don’t get the precious Wine Glue. Here, have a video:

Compiling with Tracker-Neuralnet

The neuralnet tracker allows headtracking with just a camera. No LED or reflective stripes are required. It figures out the head position and angle from the actual camera stream via the ONNX libary.

To get this neuralnet tracker input in the first place you’ll need to download the ONNX runtime package first. This is onnxruntime-linux-x64-1.18.1.tgz from https://github.com/microsoft/onnxruntime/releases/tag/v1.18.1 at the time of writing this. My Fedora installation offered 1.15.1 from it’s repo but this was not sufficient and having it installed resulted in failure due to an API mismatch. I didn’t even install onnxruntime-linux-x64-1.18.1.tgz somewhere, just unpacked it in my Downloads folder.

Setting up cmake to compile opentrack with neuralnet tracker by setting the ONNX runtime DIR
Setting up cmake to compile opentrack with neuralnet tracker by setting the ONNX runtime DIR

After that it’s running the configure and make process just as described above with the difference that the output should now list the module tracker-neuralnet as well. On success there will be a new Input called “neuralnet tracker” and I’m amazed how good this works even in a dark room. I can even scratch my nose and it keeps tracking!

How Opentrack works

Please do keep in mind that I never touched any head tracking before so I had to grasp the theory behind all this first.

Funny enough a Kerbal Space Program extension on GitHub provided me with the idea how TrackIR is supposed to function: https://github.com/pizzaoverhead/KerbTrack/blob/master/KerbTrack/TrackIRClient.cs#L45 so let’s clear that one up: The code looks for the registry entry Software\\NaturalPoint\\NATURALPOINT\\NPClient Location that points to the NPClient.dll (or NPClient64.dll) which in turn in loaded by the executable if found and accessed.

So what Opentrack does is once it’s started and configured to use Wine - Windows layer for Unix as Output: It “injects” the key [Software\NaturalPoint\NATURALPOINT\NPClient Location] to the user.reg of the configured Wine/Proton prefix on start. The also started opentrack-wrapper-wine.exe.so is used for the shared memory mapping – means from my understanding from the Opentrack binary to some Wine process. TrackIR.exe is just a dummy that may also be run with Wine but does nothing. It’s apparently for games that check for a process with that name before they initialize head tracking features. Neat, huh?

Wine settings for Opentrack with installed wine glue
Wine settings for Opentrack with installed wine glue

For this to work you have to click on the little hammer symbol next to Output so make sure that your Wine Prefix is properly configured or Opentrack may insert the registry key to the wrong Wine prefix.