• Projects
  • 3Dconnexion Space Mouse Support in Godot

Thanks @Megalomaniak . I should be able to figure it out, I have a bunch of computers for testing, though that will probably be a good idea once I am ready to release something.

Oh yeah, that is dirt simple. Okay. I will probably go with that, because I don't think I could release it into the wild only supporting Linux. Though let me work with what I have for now and finish the rest of it and see if it is even worthwhile.

Hmm, the Connexion forums say that their wireless devices are harder to use through HID. That's annoying. I have no use for a wireless connexion, I wasn't planning on getting one (the Enterprise model has no wireless option anyway).

I also see that the official Linux sdk hasn't been updated in 17 years, so it may be a little out of date. Probably a good idea to go with libspnav instead. πŸ™‚

    So I made some progress. I can now move the viewport camera around. The axis are all messed up, so I'll need to do some math, but both translation and rotation are getting correct values from the device.

    My issue now is that after moving with the spacenav, if you use the mouse/keyboard to move it snaps back to the previous position (before you moved with the spacenav). I guess the editor has it's own copy of the transform it uses, so I may have to hook into that rather than modifying the camera directly. Hopefully that is possible with a plugin and won't need source access.

    I also had to rewrite the function to find the camera. That code works for a game, but not in the editor. In the editor you have to find the Viewports and then get the Camera from that. Here is the new function.

    func find_camera(node, list) :
    	if node is Viewport:
    		var camera = node.get_camera()
    		list.append(camera)
    		return list
    	for child in node.get_children():
    		find_camera(child, list)
    	return list

    And you can call it like this:

    var editor = get_editor_interface()
    var viewport = editor.get_editor_viewport()
    var results = find_camera(viewport, [])
    var camera = results[1]

    The number 1 is needed because I have 1 user camera in my scene (results[0], the first editor camera is results[1]). If I had more, that would be a different number. It would also be a higher number if you used the split view for multiple view angles in the editor. I'll have to figure out a way to determine where you are looking rather than hard-coding the index.

    Kojack I also see that the official Linux sdk hasn't been updated in 17 years, so it may be a little out of date. Probably a good idea to go with libspnav instead. πŸ™‚

    Yeah, the fact that they haven't updated the Linux SDK in 2 decades doesn't make me eager to support them. Like it's not even a lot of work, the drivers are fairly simple and they basically abandoned Linux.

    So I kept looking into it, and no, it is not possible without a source code change. The editor camera transform is controlled by a class called Cursor and is updated in the file spatial_editor_plugin.cpp. However, it holds it's own state, it does not read it from the editor viewport camera. Meaning even though I can move the camera, the state is not maintained (as soon as you start altering the camera with the mouse or keyboard it will revert to the previous state). So it's not going to work. Sorry, @Kojack

    Oh well. Thanks for looking into it.

    I guess I'll just hack the Godot source. πŸ™‚

    I'm guessing you were in version 3.4? In 4.0 there's no spatial_editor_plugin.cpp file, but there's a node_3d_editor_plugin.cpp which contains mouse and keyboard controls.
    I found that back when I first started looking into this, I could probably easily add hard coded support for my own input library, but it won't help anyone else (and especially not non-windows users). But fine for myself.

    Well, if I can get scons to let me. Can't say I'm a fan.

    Yes, I'm on 3.4.4. But 4.0 is similar in the file your found (Spatial was renamed to Node3D in Godot 4.0, but works almost the same). I know I could get it working with a recompile, but I don't wish to do that as it will only work for me. Might still be worth trying just to see how it feels, but the idea was to release it as a plugin to help other people.

    That said, I still have full control over user created Nodes. Meaning the Space Navigator could be used to position/orient objects, or move user cameras. This is less common, but still could be useful. I already tried it, I can get the selected object like this:

    var editor = get_editor_interface()
    var selection = editor.get_selection()

    And then do whatever I want. However, I really wanted to use it to fly around the scene.

    One other option is to spoof input, which would get passed to the editor. I know I can trigger fake mouse/keyboard events, but this will greatly limit the kind of 6DOF controls I want. However, it could be a compromise.

    Okay, so I decided I have to finish this. I started editing the Godot source code, it's actually not that complicated (I guess those 15 years of learning C++ finally came in handy). I have the position pretty close to working. Right now it is in global space, so I have to convert it into the camera space, but I solved the issue of the mouse/keyboard interference. The rotation should not be difficult either. It's getting late now, but I think I can have it all working tomorrow.

    It will take longer to get the space navigator to work cross-platform, though I can submit my commit and hope it gets merged in the meantime. My changes have nothing to do with the space navigator, it just allows altering the camera position/orientation. This could also be useful for AR/VR or for accessibility. For example, people could develop plugins that allow neck or mouth controllers to move the camera. So I think there is a good chance they will take my merge.

      cybereality
      Cool
      Another potential use for control of the editor view is adding camera view shortcuts. Like place the camera looking at a part of your scene then bind that transform to a key. There's already the 6 axis view shortcuts, but no free view recording that I can see.

      For some reason I can't get release builds of 4.0 to work (comes up with an error about missing .pck), but debug builds work fine (but slower). Probably some setting got messed up when I followed some online instructions to get godot compiling from visual studio (although still routed through scons, annoyingly).

      It's working!!! @Kojack @Megalomaniak

      I gave up the idea of editing the source code. Though I did get it sort of working, that Cursor class is used for too much and it was causing all sorts of crazy bugs. Even if I did finish it, there was the problem of the z axis, so there was always going to be some jump. I decided to just use what was available as a plugin. This means the 6DOF state is not saved, but it doesn't mess up the normal function of the mouse and keyboard. I'll have to add cross-platform support for the extension, but the plugin itself is fully working.

        cybereality It might be handy to have a 5DOF mode. I find roll can get annoying at times in editors. πŸ™‚
        Cool work though!

        I actually find roll helpful since it gives you a difference perspective. This is important in 3D because you are literally missing a dimension. It's sort of like how traditional artists back in the day were told to view their drawings in a mirror, because it shows you things you can't see normally.

        Still, a turntable mode might have it's uses too. And a fly mode. But for initial support these can probably be considered "fluff".

        Then again, if you are using the Connexion sdk, the control panel can already disable roll (at least on windows).

          I guess it is sort of a turntable. It rotates around the selected object right now. You can kind of still fly wherever, since you have full control, but it gets difficult if you move more than around 6 units from the center (of the current object). Fly mode I can look into. I have tried it before on other apps and it never worked well. But it's worth investigating.

          Kojack Then again, if you are using the Connexion sdk, the control panel can already disable roll (at least on windows).

          Yes, I can put in some options. That shouldn't be an issue. I have to do that anyway to control the speed.

            cybereality I guess linux may not have the same thing. But in windows there's already a configuration panel in the drivers for apps that use the sdk which gives axis scales, turning axes on/off, etc.