Turn your 3Dconnexion SpaceMouse into a virtual Xbox controller.
SpaceMouse Pilot reads your SpaceMouse directly and outputs it as a standard Xbox 360 controller — no drivers, no middleware. Any game or application that accepts controller input will see it as a real gamepad.
The 6-axis input maps naturally to flight controls — tilt to bank, twist to yaw, push up and down for throttle — making it a compelling option for flight-heavy games. Pair it with a keyboard, mouse, or any other input device for everything else.
- Windows 10/11 x64
- A 3Dconnexion SpaceMouse (any model with USB HID support)
- ViGEmBus driver — free, ~2MB, one-time install
- Install the ViGEmBus driver if you haven't already
- Download the latest
SpaceMousePilot_Setup_x.x.x.exefrom Releases - Run the installer
Before launching SpaceMouse Pilot, right-click the 3Dconnexion tray icon and choose Exit. SpaceMouse Pilot reads the device directly — the 3Dconnexion driver will block it if left running.
- Launch SpaceMouse Pilot from the Start menu or desktop shortcut
- Click Start Bridge — both status indicators should turn green
- Launch your game or application and configure it to use controller input
- The SpaceMouse will appear as a standard Xbox 360 controller
Closing the window minimises it to the system tray. The bridge keeps running in the background. Right-click the tray icon to quit.
The default axis range assumes a standard SpaceMouse sensitivity. For best results, calibrate to your specific device:
- Start the bridge first
- Click Calibrate axes
- Push the device to its physical limits on all axes within the countdown window — tilt fully left/right, forward/back, twist fully each way, push up and down
- The bars turn green as each axis is recorded
- Settings are saved automatically when done
Recalibrate any time the feel seems off, or after changing sensitivity settings.
| Tab | What it does |
|---|---|
| Roll / Pitch / Yaw / Collective | Per-axis sensitivity, deadzone, response curve, scale, and invert |
| Mapping | Assign each SpaceMouse axis and button to a gamepad output |
| Performance | Bridge poll rate, UI refresh rate, calibration duration |
Changes take effect immediately. Click Save settings to persist them across sessions.
| Setting | Helicopters | Jets / Fast aircraft |
|---|---|---|
| Curve | 1.8 | 2.2 |
| Deadzone | 0.05 | 0.08 |
| Yaw sensitivity | 0.8 | 0.6 |
| SpaceMouse | Gamepad | In-game |
|---|---|---|
| Tilt left/right (Roll) | Right stick X | Bank / Aileron |
| Tilt forward/back (Pitch) | Right stick Y | Pitch / Elevator |
| Twist (Yaw) | Left stick X | Rudder / Yaw |
| Push up/down (Collective) | Left stick Y | Throttle / Collective |
All mappings are fully reconfigurable in the Mapping tab.
- Too twitchy? Lower sensitivity and raise the curve value — a higher curve gives you more precision near the centre of travel
- Drifting at rest? Increase the deadzone on the affected axis, or recalibrate
- 3DxWare blocking the device? Make sure you exit it from the system tray, not just close the window — it runs in the background by default
- Bridge won't start? Ensure ViGEmBus is installed and your SpaceMouse is plugged in before clicking Start Bridge
What can I use this with? Any game or application that accepts XInput / Xbox controller input on Windows. Flight simulators, space games, and anything with vehicle or aircraft controls are natural fits.
Will this work alongside other controllers? Yes — it appears as an additional controller. Your other input devices continue to work normally.
Do I need to leave SpaceMouse Pilot running while using it? Yes — it needs to stay running (minimised to tray is fine) to maintain the virtual controller connection.
Can I use my SpaceMouse for other things at the same time? Not while the bridge is running, since it takes direct HID access to the device. Click Stop Bridge to hand control back to 3DxWare.
Will this cause issues with anti-cheat? Low risk. The virtual controller is identical to a real Xbox 360 controller from the game's perspective. ViGEmBus is a signed Windows driver used by Steam Input and millions of accessibility tools — it is not flagged as a cheat tool.
- Python 3.10+
- hid — raw HID access to the SpaceMouse (no 3DxWare dependency)
- vgamepad + ViGEmBus — virtual Xbox 360 controller output
- customtkinter — UI
- pystray — system tray
- PyInstaller — bundling to exe
- Inno Setup — installer
SpacemouseEmulator/
├── src/
│ ├── main.py # Entry point, single-instance mutex, IPC
│ ├── ui.py # Full UI — status, meters, settings, tray
│ ├── bridge.py # HID polling, axis processing, gamepad output
│ ├── config.py # Load/save config from %AppData%
│ └── version.py # Single source of truth for version number
├── tools/
│ ├── generate_icon.py # Generates assets/icon.ico at build time
│ ├── fetch_hidapi.py # Downloads hidapi.dll from libusb releases
│ └── write_notes.py # Writes GitHub release notes from CHANGELOG.md
├── installer/
│ └── spacemouse_pilot.iss # Inno Setup script
├── assets/ # Populated at build time (icon, hidapi.dll)
├── CHANGELOG.md # Patch notes per version
├── spacemouse_pilot.spec # PyInstaller spec
├── build.bat # Full build pipeline
└── release.bat # Tag, push, and publish GitHub release
build.batHandles everything: pip dependencies, hidapi.dll download, icon generation, PyInstaller bundle, Inno Setup installer. Output at dist/installer/SpaceMousePilot_Setup_x.x.x.exe.
Requires Python 3.10+ and Inno Setup 6 to be installed.
- Bump
src/version.py - Add an entry to
CHANGELOG.mdfor the new version (optional) git commit -am "bump to x.x.x"build.batrelease.bat
Requires GitHub CLI (gh auth login on first use).
HID direct access — the bridge reads raw int16 values off HID reports instead of going through pyspacemouse, giving full control over normalization. Report 1 is translation (X/Y/Z), Report 2 is rotation (RX/RY/RZ), Report 3 is buttons.
Calibration — samples the physical peak over a configurable window and stores it as scale per axis. processed = clamp(raw / scale, -1, 1) before deadzone/curve/sensitivity are applied.
Single instance — enforced via a named Windows mutex. A second launch signals the running instance over a loopback socket (127.0.0.1:59371) to restore its window, then exits.
Threading — bridge runs on a dedicated daemon thread at configurable poll rate (default 250 Hz). UI polls bridge state via after() at a separate configurable rate (default 30 Hz). All bridge→UI communication is through shared public attributes, safe under Python's GIL.