3D mouse support

Hello,

I would like to read events from an 3Dconnexion SpaceNavigator input device, but SDL does not seem to see it when
using the SDL_Joystick functions (SDL_NumJoysticks, SDL_JoystickNameForIndex, etc…). Using a Xbox controller works just fine, so I don’t think this is a problem of permission nor a missing subsystem initialization.

I’m running SDL 2.0.3 on a Gentoo machine.

Following Gentoo’s Wiki page on SpaceNavigator (https://wiki.gentoo.org/wiki/SpaceNavigator), I managed to have the 3D mouse work with both Xorg as a mean to control the cursor and as real 6 DoF device using spacenavd (tested successfully with Blender and a few other simple programs from spacenavd), meaning my device can indeed be used.

Thinking this might be a problem with spacenavd, I contacted them. They told me that SDL might not support 6 DoF devices and that libspnav should be used to read from their driver.

This thread (https://forums.libsdl.org/viewtopic.php?t=3207&sid=c96eba79a6eb04a43eef01b7766bc30e) led me to believe SDL already supports 3Dconnexion devices. Is it not so? Why not?

According to some project’s new updates (http://sourceforge.net/p/foxgui/mailman/message/1212815/),

* Added 3DConnexion SpaceNavigator support (currently under Unix only). The SpaceNavigator device 
  is a 6DOF motion controller; if your working with 3D software, you'll probably want to get one 
  of these things. However, even if you're just fond of using Google Earth, you'll probably 
  going to find this thing very useful.
  To get this device working on Linux, a recent Xorg X Server (7.3 or later) with USB HID XDevice 
  support is needed. Of course, HID support in the linux kernel also needs to be enabled.
  Other than that, no special device drivers are required. However, some minor configuration files 
  need to be changed to allow X11 to recognize the device. Simply include the following line in 
  the "ServerLayout" section of your Xorg.conf file (typically located in the /etc/X11 directory on 
  your system).

  	InputDevice    "SpaceBall" "SpaceBall"

  Also, add a new "InputDevice" section in your Xorg.conf file:

  Section "InputDevice"
  	Identifier  "SpaceBall"
  	Driver      "evdev"
  	Option	    "Name"   "3Dconnexion*"
  	Option	    "Pass"   "3"
          Option      "Mode"   "Relative"
          Option      "XRelativeAxisMap"  "0"
          Option      "YRelativeAxisMap"  "1"
          Option      "ZRelativeAxisMap"  "2"
          Option      "RXRelativeAxisMap" "3"
          Option      "RYRelativeAxisMap" "4"
          Option      "RZRelativeAxisMap" "5"
  	Option	    "ZRelativeAxisButtons" "off"
  EndSection

  After these changes, you should of course restart the X Server. There is no need for any additional 
  driver modules; the new evdev device capability in the X Server does all the hard work.

And indeed, using this Xorg configuration does seem to work: evtest gives me the readings I want, without having spacenavd running:

Event: time 1432647671.764737, -------------- SYN_REPORT ------------
Event: time 1432647671.772676, type 2 (EV_REL), code 4 (REL_RY), value -2
Event: time 1432647671.772676, -------------- SYN_REPORT ------------
Event: time 1432647671.780738, type 2 (EV_REL), code 0 (REL_X), value 51
Event: time 1432647671.780738, type 2 (EV_REL), code 1 (REL_Y), value -10
Event: time 1432647671.780738, -------------- SYN_REPORT ------------
Event: time 1432647671.796646, type 2 (EV_REL), code 0 (REL_X), value 38

Now I’m confused… Shouldn’t SDL see the device then? Is there perhaps some relation to the “JOYSTICK” flag mentionned here (http://www.3dconnexion.com/forum/viewtopic.php?t=3307)? If so, is there a way to enable said flag?

I want my program to support as many 3D mouse models as possible, making the use of libspnav an issue, and I feel considering them as being SDL_Joysticks would make a very nice layer of abstraction. Has any of you used a 6 DoF device in their project? Is using specific libraries the generally accepted solution?

I think I figured out what the JOYSTICK flag is. I was looking for it at the wrong place, expecting it to be a Xorg setting. Turns out it should be set before that, at udev level.
I now have an udev rule to ensures that the device gets

Code:
ENV{ID_INPUT_JOYSTICK}=“1”, ENV{ID_CLASS}=“joystick”

Tada! SDL can now see my device :D. But wait! There’s still a (pretty big) problem:

Found 1 joystick(s)

Joystick Name: '3Dconnexion SpaceNavigator’
Joystick GUID: 030000006d04000026c6000011010000
Joystick Number: 0
Number of Axes: 0
Number of Buttons: 2
Number of Hats: 0
Number of Balls: 1
GameController:
not a gamepad

That’s not quite correct. Yes, there are 2 buttons (which SDL seems to read properly :slight_smile: ), but there should be 6 axes.
Instead, it reads 1 ball. The ball actually gives values from REL_X and REL_Y, which I see as a good sign, but only read positive values (thought I suspect this is just because that’s what’s expected from ‘ball’ inputs).

From this thread (http://sourceforge.net/p/spacenav/mailman/message/27607490/), I believe that in my case (I have an USB device), spacenavd should indeed not be required.

Honestly, I would have given up if not for the fact that evtest taunts me by reading from my device without any trouble. Well, at least I’ve learned more about Xorg and udev, so that’s good.

I’m currently looking into how to alter what SDL is reading when looking for the number of axes, buttons, hats and balls (just in case the axes values are there but not read). Any advice is welcome.

Message-ID: <1432662334.m2f.47995 at forums.libsdl.org>
Content-Type: text/plain; charset=“iso-8859-1”

I think I figured out what the JOYSTICK flag is. I was looking for it at the
wrong place, expecting it to be a Xorg setting. Turns out it should be set
before that, at udev level.
I now have an udev rule to ensures that the device gets

Code:
ENV{ID_INPUT_JOYSTICK}=“1”, ENV{ID_CLASS}=“joystick”

Tada! SDL can now see my device :D. But wait! There’s still a (pretty big)
problem:

Found 1 joystick(s)

Joystick Name: '3Dconnexion SpaceNavigator’
Joystick GUID: 030000006d04000026c6000011010000
Joystick Number: 0
Number of Axes: 0
Number of Buttons: 2
Number of Hats: 0
Number of Balls: 1
GameController:
not a gamepad

That’s not quite correct. Yes, there are 2 buttons (which SDL seems to read
properly :slight_smile: ), but there should be 6 axes.
Instead, it reads 1 ball. The ball actually gives values from REL_X and
REL_Y, which I see as a good sign, but only read positive values (thought I
suspect this is just because that’s what’s expected from ‘ball’ inputs).

From this thread (http://sourceforge.net/p/spacenav/mailman/message/27607490/),
I believe that in my case (I have an USB device), spacenavd should indeed
not be required.

Honestly, I would have given up if not for the fact that evtest taunts me by
reading from my device without any trouble. Well, at least I’ve learned more
about Xorg and udev, so that’s good.

I’m currently looking into how to alter what SDL is reading when looking for
the number of axes, buttons, hats and balls (just in case the axes values are
there but not read). Any advice is welcome.

Just to make it clear, the last time that I checked SDL didn’t support
6DOF input. If you want SDL to support it then you’ll need to find a
way to add a new message that ALLOWS them to be supported. I would be
surprised if enough space is reliably available in the structure, so I
suggest two messages, one for the “high bits”, and another for the
"low". If you’re unwilling to do this, then I advise sticking with
either emulated-joystick behavior, or accessing it more directly.> Date: Tue, 26 May 2015 17:45:34 +0000

From: “Astrophobia”
To: sdl at lists.libsdl.org
Subject: Re: [SDL] 3D mouse support

So, after doing other things, I came back to this and solved it.
This is caused by the events being “relative” whereas SDL only considers “absolute” events for joysticks (“relative” are interpreted as 'Balls", as seen in my previous post). I’m surprised no one replied to this thread to tell me this.
It would not be such a problem if either:

  • The SpaceNavigator reported itself as having “absolutes” axis.
  • SDL supported “Balls” with more than 2 axis.

I’m developping a program that deals with the former (as some think the SpaceNavigator should report in “absolute” anyways). If you are suffering the same issue, you can find it on GitHub (https://github.com/nsensfel/relabsd).[/url]