OpenNDOF is an open-source Windows bridge for 3DConnexion 6-DOF (six degrees-of-freedom) input devices. It reads raw HID reports directly — no proprietary driver or SDK required — and exposes live sensor and button data via a clean .NET API and a WPF dashboard application.
OpenNDOF is a free, open-source Windows application that enables 3DConnexion 6-DOF input devices (SpacePilot, SpaceNavigator, SpaceExplorer, SpaceTraveler, SpaceBall, Aerion NDOF) to work without the proprietary 3DConnexion driver. No installation or activation required — simply plug in your device and use it with AutoCAD, SolidWorks, Blender, Maya, and any other application that supports the TDxInput COM API.
Perfect for users who want to: • Resurrect and repurpose legacy 3DConnexion hardware • Avoid driver updates and compatibility issues • Use their devices on minimal Windows installations • Customize sensitivity and macro buttons per-application • Contribute to open-source 3D input technology
Features zero-driver architecture, live 6-axis readout, button macros, named profiles with per-axis scaling, SpacePilot LCD display support with full Unicode/emoji rendering, and a clean WPF dashboard for real-time visualization and configuration.
- Zero-driver operation — communicates directly with the HID interface; the 3DConnexion driver does not need to be installed.
- TDxInput COM server — registers as a drop-in replacement for the official 3DConnexion COM server so AutoCAD, SolidWorks, Blender, Maya and any other TDxInput-aware application works transparently.
- Live 6-axis readout — Translation (TX/TY/TZ) and Rotation (RX/RY/RZ) at full device rate.
- Button events — all device buttons reported as a
KeyboardStatesnapshot. - Named profiles — per-axis sensitivity scaling and dead-zone, stored in
%APPDATA%\OpenNDOF\profiles.json. - SpacePilot LCD support — 240×64 monochrome display driven via reverse-engineered HID feature reports; full Unicode and emoji support.
- WPF dashboard — real-time axis bars, 3-D viewport cube, LCD page, and configuration sliders.
| Device | VID | PID | LCD |
|---|---|---|---|
| SpaceNavigator | 046D |
C626 |
— |
| SpaceExplorer | 046D |
C627 |
— |
| SpacePilot | 046D |
C625 |
✔ 240×64 |
| SpaceTraveler | 046D |
C623 |
— |
| SpaceBall 5000 | 046D |
C621 / C622 |
— |
| Aerion NDOF | 03EB |
2013 |
— |
Adding a new device: See Adding a New Device below.
- Windows 10 / 11 (64-bit)
- .NET 10 Runtime
- The device must be plugged in via USB; Bluetooth is not supported.
git clone https://github.com/bpmcgill/OpenNDOF.git
cd OpenNDOF
dotnet builddotnet run --project src\OpenNDOF.AppPlug in your device, navigate to Dashboard, and click Connect.
Add a reference to OpenNDOF.Core and OpenNDOF.HID:
using OpenNDOF.Core.Devices;
using OpenNDOF.HID;
var hid = HidController.Instance;
var profiles = new ProfileManager();
var device = new SpaceDevice(hid, profiles);
device.SensorUpdated += (_, s) => Console.WriteLine(s);
device.KeyboardUpdated += (_, k) => Console.WriteLine(string.Join(", ", k.PressedKeys));
device.Connect();
Console.ReadLine();
device.Dispose();OpenNDOF.HID — raw Win32 HID read/write (P/Invoke, no external deps)
OpenNDOF.Core
├─ Com/
│ ├─ ComInterfaces.cs — [ComVisible] interface definitions (ISimpleDevice, ISensor, IKeyboard…)
│ ├─ Device.cs — TDxInput.Device CoClass (root COM object)
│ ├─ Sensor.cs — TDxInput.Sensor CoClass + SensorInput event
│ ├─ Keyboard.cs — TDxInput.Keyboard CoClass + KeyDown/KeyUp events
│ ├─ ValueTypes.cs — Vector3D / AngleAxis COM value objects
│ └─ ComServer.cs — shared SpaceDevice singleton for COM activation
├─ Devices/
│ ├─ KnownDevices.cs — VID/PID catalogue + DeviceType enum
│ ├─ SpaceDevice.cs — connection, report parsing, profile application
│ └─ SpacePilotLcd.cs — 240×64 LCD renderer (GDI → 1-bit page format)
├─ Input/
│ ├─ SensorState.cs — immutable 6-axis snapshot
│ └─ KeyboardState.cs — immutable button snapshot
└─ Profiles/
└─ ProfileManager.cs — JSON persistence, named profiles
OpenNDOF.App — WPF UI (WPF-UI / Fluent design)
OpenNDOF.Tests — unit tests
| Report ID | Length | Meaning |
|---|---|---|
0x01 |
7 bytes | Translation axes (TX, TY, TZ as signed 16-bit LE) |
0x02 |
7 bytes | Rotation axes (RX, RY, RZ as signed 16-bit LE) |
0x03 |
variable | Button bitfield (1 bit per button, LSB first) |
The 240×64 display is driven with HID feature reports:
| Report ID | Payload | Purpose |
|---|---|---|
0x12 |
[id, 0, 0, 0x2F, ...] |
Suppress firmware redraws |
0x0C |
[id, page, col, 0] |
Set write cursor (page 0–7, col 0–239) |
0x0D |
[id, c0…c6] |
Write 7 column bytes; bit 0 = top row of page |
Each page is a horizontal band of 8 pixel rows. Text is rendered with GDI TextRenderer (for emoji fallback) to a 32bpp Bitmap, thresholded to 1-bit, then packed into the page/column format before transmission.
AutoCAD, SolidWorks, Blender, Maya, and many other 3D applications communicate with 3DConnexion devices through the TDxInput COM API. OpenNDOF implements this API and can be registered as the system-wide COM server so these applications receive input from your device through OpenNDOF — no 3DxWare driver needed.
# From the OpenNDOF.Core build output directory:
.\Register-ComServer.ps1This writes the required HKLM\SOFTWARE\Classes\CLSID and ProgID registry keys
pointing at TDxInput.comhost.dll (the .NET COM host built alongside the project).
.\Register-ComServer.ps1 -UnregisterWhen a host application calls CoCreateInstance("TDxInput.Device"), Windows loads
TDxInput.comhost.dll which activates the .NET Device COM class. That class
connects to the shared SpaceDevice singleton and forwards live HID data as
standard ISensor.SensorInput and IKeyboard.KeyDown/KeyUp COM events — exactly
what the official driver would have sent.
| COM Object | CLSID | Purpose |
|---|---|---|
TDxInput.Device |
82C5AB54-... |
Root object; host apps CoCreateInstance this |
TDxInput.Sensor |
85004B00-... |
Fires SensorInput with 6-axis data |
TDxInput.Keyboard |
25BBE090-... |
Fires KeyDown / KeyUp per button |
TDxInput.TDxInfo |
1A960ECE-... |
Reports driver revision string |
Profiles are stored in %APPDATA%\OpenNDOF\profiles.json.
[
{
"Name": "default",
"ScaleTx": 1.0, "ScaleTy": 1.0, "ScaleTz": 1.0,
"DeadzoneTrans": 0.05,
"ScaleRx": 1.0, "ScaleRy": 1.0, "ScaleRz": 1.0,
"DeadzoneRot": 0.05
}
]- Scale values multiply the normalised axis value (±1 full scale).
- Deadzone suppresses small movements below the threshold.
-
Find the VID/PID. Plug the device in and check Device Manager → Details → Hardware IDs, or use a tool like USBDeview.
-
Add it to
KnownDevices.cs:new(0x046D, 0xC62B, "SpaceMouse Pro", DeviceType.SpaceNavigator),
Reuse an existing
DeviceTypeif the HID report format matches, or add a new enum value if it differs. -
Verify the report format. Connect the device, run the app in Debug, and watch the Output window for
[LCD]/ raw report traces. The 3DConnexion common protocol (reports0x01/0x02/0x03) is shared across almost all devices without a screen. -
LCD support (if the device has a display): implement a renderer similar to
SpacePilotLcd.csand call it fromSpaceDevice.TryConnectDevicewhenDeviceInfo.Typematches. -
Add a row to the Supported Devices table in this README.
OpenNDOF implements comprehensive exception handling to provide a crash-free experience:
- Profile I/O: Load failures gracefully recover with defaults; save failures are logged and reported to the user
- Input Validation: Profile names are validated at entry points; invalid inputs fail fast with clear error messages
- Macro Execution: Button press errors are isolated and logged without affecting HID polling
- User Feedback: All user-facing operations provide snackbar notifications (success, error, and detailed messages)
- Diagnostics: Structured debug logging for troubleshooting and development
See Error Handling Guide for detailed documentation on exception strategies and best practices.
Pull requests are welcome. Please:
- Keep changes focused on a single concern per PR.
- Add or update unit tests in
OpenNDOF.Testsfor any logic changes. - Do not commit
%APPDATA%\OpenNDOF\profiles.jsonor any generated files underobj/.
The majority of this project is released under the MIT License — see LICENSE.
| Component | License | Notes |
|---|---|---|
OpenNDOF.HID |
MIT or LGPL 2.1 | See NOTICE — if any HID enumeration code was derived from the Aerion SpaceNav Win32 driver, those files are LGPL 2.1 |
| LCD protocol (SpacePilotLcd.cs) | MIT | Protocol reverse-engineered by jtsiomb/3dxdisp (GPL v2); no source copied |
See NOTICE for full attribution details.