Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to support 3dconnexion SpaceMouse in a GLFW C++ application?

I would like to add support of a 3dconnexion SpaceMouse device in a cross-platform (Windows, Linux, Mac) 3D C++ application based on glfw library.

I downloaded 3DxWare_SDK_v4-0-2_r17624 from the device vendor, and looked at the simplest C++ sample: 3DxTraceNL. Unfortunately, it is really huge: its source code (.cpp+.h+.hpp) weights more than 200Kb, even if we do not add here 100+Kb of navlib headers, which is the base of the application. The sample includes tons of code for Camera, Matrices, Transforms, Navigation models and so on, which I already have in my application and do not want to replace just to support new device.

What I basically look for is how to register for and receive SpaceMouse events in glfw framework. The processing of events I will will write by myself. Even if you could suggest a glfw-compatible solution for one particular platform, that would be great.

like image 660
Fedor Avatar asked Sep 14 '25 18:09

Fedor


1 Answers

The solution I found is to use HIDAPI to communicate with SpaceMouse device (which is available on Windows, Linux and Mac) instead of 3DxWare_SDK.

One has to create an std::thread that will in a loop

  1. Enumerate the devices with hid_enumerate. vendor_id argument is either 0x046d for classical devices or 0x256f for wireless devices.
  2. If a device is found, connect to it with hid_open_path.
  3. Periodically read messages from the connected device using hid_read or hid_read_timeout.
  4. As soon as the message is received, notify the application with glfwPostEmptyEvent() in case it is waiting in glfwWaitEvents().

In GLFW event processing loop, check that new message is arrived somewhere near glfwPollEvents() call.

The messages from SpaceMouse devices are rather simple and contain at most 13 bytes:

  1. If the first byte is 3, then this message contains the status of device's buttons in the following bits.
  2. If the first byte is 2, then the following 6 bytes contain the torque (rotation) of device's handle.
  3. If the first byte is 1, then the following 6 bytes contain the shift (translation) of device's handle. If the message has 13 bytes in length, the the last 6 bytes contain the rotation data.

One can find a similar implementation in open-source MeshLib, see class SpaceMouseHandlerHidapi.

like image 71
Fedor Avatar answered Sep 17 '25 08:09

Fedor