New Plugin: CollieMouse - Alternative Controller for Space Navigator

Become a member of the CGSociety

Connect, Share, and Learn with our Large Growing CG Art Community. It's Free!

THREAD CLOSED
 
Thread Tools Search this Thread Display Modes
  12 December 2012
New Plugin: CollieMouse - Alternative Controller for Space Navigator

Do you own a Space Navigator or another compatible 3D mouse from 3Dconnexion? Are you frustrated with the lack of love the internal controller/driver for the 3D mouse gets from Maxon? Well, here is the easy alternative.

CollieMouse 1.0.zip
(Currently PC only, R13 or R14!)



  • No more tilting horizon - the "heading" movement is the same as in the mouse view control.
  • Can control "flat" views - front, top, right...
  • Full control over speed, direction, activation, and even the refresh flags!
  • Uses the navigation and pivot settings that have been introduced with R13
  • Y/Z swap, dominant axis, speedup, separate settings for 2D views...
  • Stores up to 5 presets in the preferences
You can test the full plugin on your system with the zip file under the link - no traps, no serials, no nag screens. If you like it, you may want to contribute something for future plugin development; see the manual (included) for details.

Have fun.
 
  12 December 2012
I put my hand up for Mac version if poss. Always found 3d connexion to be a bit of a fizzer. More customization would be very welcome
 
  12 December 2012
I'll have to get a new paper weight now. Actually the real fate of my Space navigator is that it's used to apply pressure on a flawed wire connected to my Boss companion speakers and allows the module to actually function as it should. It's had that role for about 2 years.

Any plans to release for R12?

Great idea for a plugin though, I'll be sure to check it out.
__________________
۩PRIST

 
  12 December 2012
realtime capture support? (capuchino)
 
  12 December 2012
another vote for mac version.
 
  12 December 2012
Hmm, well... I don't own a Mac, so the chances of a Mac version are currently not so good. Voting won't cut it - anybody want to donate an old Mac? It would still require a rewrite of some message queue code - this is not done by just recompiling the plugin on a Mac with a new project file.

R12 (and earlier) - unfortunately (well, in this context at least) Maxon changed the viewport management and view navigation API with R13. R12 is simply not compatible enough, which would make an extensive rewrite necessary. Not gonna happen since R12 is now two versions outdated.

Capturing the camera movement? Currently not, but this is an interesting idea to record e.g. walkthroughs. I may look into that. Feel free to describe the idea in detail, because right now I have the feeling that just recording frame by frame will not be enough.
 
  12 December 2012
I downloaded and installed the plugin to try it out.
I remember that the internal 3D mouse controller dialog box had to remain open in order to work, but this has been fixed by Maxon a few versions ago. Since then the only thing I was missing was support for the orthogonal views. Now with this Colliemouse plugin, we finally have control over those orthogonal views ... but we're back to having the dialog box open for it to work. No big deal, but a small annoyance to update all the layouts.
 
  12 December 2012
Originally Posted by C4DS: but we're back to having the dialog box open for it to work. No big deal, but a small annoyance to update all the layouts.


The reason for that is quite simple.

In order to poll 3D mouse messages, you have to create (or reuse) a message queue, which is a basic functionality of Windows' windows. In the C4D API there are no methods to access the main window message queue (or, in fact, any other message queue); plus you have to change some of the queue window's properties.

Thus, CollieMouse opens an (invisible) additional window and adds it as a child window to the dialog (for which I can get a window handle). That window then handles all the message stuff. But if you close the dialog... all the child windows are gone, and so is the messaging.

Naturally, the Maxon programmers can do better by simply using internal functions that are not available in their API.

The only way to overcome the limitation would be to attach the messaging windows to the main window instead. I am afraid this may lead to unwanted (and perhaps stability-affecting) effects, and may require far more insight into the window handling of C4D than available for a plugin programmer.
 
  12 December 2012
I didn't find in the limitation description any mention of the workplane in perspective view.
Since R14 the user is able to alter the workplane, rotating it relative to the original workplane. The internal 3D mouse controller does take this new workplane as reference, but the Colliemouse controller does not which results in erratic behaviour.

Another thing I noticed is that when I used the CollieMouse plugin and quit Cinema4D, that the application doesn't close completely. In Taskmanager the Cinema4D exe is still visible (Win7 64 bit running C4D in 64 bit)

Last edited by C4DS : 12 December 2012 at 10:21 AM. Reason: edit
 
  12 December 2012
Originally Posted by C4DS: I didn't find in the limitation description any mention of the workplane in perspective view.
Since R14 the user is able to alter the workplane, rotating it relative to the original workplane. The internal 3D mouse controller does take this new workplane as reference, but the Colliemouse controller does not which results in erratic behaviour.

Another thing I noticed is that when I used the CollieMouse plugin and quit Cinema4D, that the application doesn't close completely. In Taskmanager the Cinema4D exe is still visible (Win7 64 bit running C4D in 64 bit)


Thanks for the hints.

The current version is compiled against the R13 API and therefore does not know anything about R14 novelties like workplane changes. I will take note to have a look at workplanes once I get to a "pure" R14 version.

Not sure what you mean by "The internal 3D mouse controller does take this new workplane as reference". The internal controller does not use the "rotation around world Y" option and always operates in a "freeflight" mode that only considers the camera coordinate system. Thus, for the internal controller, the workplane simply has no effect at all, and reorienting the camera in respect to the new workplane is sufficient to make it work. I don't quite see that the behavior of the internal controller has actually changed since R13 or before, or that the behavior of the internal controller depends in any way on the workplane.

You can actually return to that "freeflight" behavior by doing the following on the Options page:
- Check the "Banking active" checkbox to enable all 6 degrees of freedom
- Uncheck "Dominant only" to make "diagonal" motion more fluent
- Uncheck "Rotate H around world Y axis"
This will enable the CollieMouse controller to work similar to the internal controller, and empower you to work with tilted workplanes.

Of course I agree that the behavior of the controller in the default mode should (at least optional) use the workplane Y for heading rotations, since that is the main grid that you see. I will include something like this for the R14 version (as well as the "rotated 2D view" thing).

As for the hanging process when closing C4D: I can confirm that there is an issue. Funny, works in R13, so maybe I need to have a look at the sequence of windows closing here...
 
  12 December 2012
very cool

My space navigator has been collecting dust, maybe this will give it a reason to exist!

Q: How hard would it be to add DirectInput / OSC / MIDI controller support to the plug in? I've been meaning to write an "alternative input device" viewport camera controller plug in for a while, but it seems like you're 80% of the way there already! If you're already controlling the camera via windows messages, sounds like it would be mostly an issue of generating the corresponding events for each controller input.

(there are some DirectInput / joystick / MIDI plug ins, but they are mostly about input recording, animation control, etc. whereas I'm looking for interactive UI & viewport control)
 
  01 January 2013
Originally Posted by selmo: Q: How hard would it be to add DirectInput / OSC / MIDI controller support to the plug in? I've been meaning to write an "alternative input device" viewport camera controller plug in for a while, but it seems like you're 80% of the way there already! If you're already controlling the camera via windows messages, sounds like it would be mostly an issue of generating the corresponding events for each controller input.

(there are some DirectInput / joystick / MIDI plug ins, but they are mostly about input recording, animation control, etc. whereas I'm looking for interactive UI & viewport control)


I guess that depends on the type of controller, the nature of the messages, and the interface that the native driver provides.

If you have a device that outputs Windows messages through its driver, and these messages contain delta/relative values in six degrees of freedom, then that would be comparatively easy to achieve. The message loop polling from CollieMouse just disassembles the message data (the format is actually a bit cryptic) and calls two methods: Rotate (H, P, B) and Translate (X, Y, Z). These calls completely separate the message "backend" and the viewport "frontend".

If your device has no driver, or the driver works through some other than Windows messaging, then the message backend wouldn't work. In fact, using any other driver (even if it uses WMs) will probably require recoding large parts of the backend (hopefully that device comes with example code ).

That is still manageable since the backend doesn't contain very much code. The majority of the CollieMouse code goes into evaluating the Rotate and Translate functions, getting the behavior of the camera right depending on the options in CollieMouse and in the C4D basic viewport system, and replicating the various modes of the C4D navigation.

If your device has a different kind of output -- like absolute values instead of deltas, or a different number of axes -- the frontend would need adaption as well. I assume it would still be possible to keep the options and modes intact, but the behavioral evaluation might be different (especially with less axes). Can't really say because it depends on the kind of controller.

This is all fairly theoretical anyway, since I don't own any MIDI controller or OSC device to check that. Best I could try is a joystick (through DirectInput), and due to its low number of axes / degrees of freedom, this would be fairly inferior to a Space Navigator, so why bother?
 
  01 January 2013
Originally Posted by Cairyn: The message loop polling from CollieMouse just disassembles the message data (the format is actually a bit cryptic) and calls two methods: Rotate (H, P, B) and Translate (X, Y, Z). These calls completely separate the message "backend" and the viewport "frontend".
<snip>
That is still manageable since the backend doesn't contain very much code. The majority of the CollieMouse code goes into evaluating the Rotate and Translate functions, getting the behavior of the camera right depending on the options in CollieMouse and in the C4D basic viewport system, and replicating the various modes of the C4D navigation.


By separating the backend from the frontend, you've made it extensible. In theory, anyone could make a backend for any appropriate device if they knew the windows messages and message data you expect. Then all the C4D calls to manage the viewport camera is handled by your front end. Which is what I mean by when I said you're 80% of the way already.

Originally Posted by Cairyn: This is all fairly theoretical anyway, since I don't own any MIDI controller or OSC device to check that.


There will always be more devices than you can own and test and support. You don't want to get into that arms race. I think if you exposed the messaging protocol you use to connect the backend to the frontend, that would be enough for others to extend it for other devices. It's then just a "simple matter of programming" to create a glue layer between whatever the device SDK offers and sending windows messages with delta offsets.

Basically you're providing a windows message queue interface to the C4D camera and input system. Let others do the work of supporting every oddball toy they want to see work.

Originally Posted by Cairyn: due to its low number of axes / degrees of freedom, this would be fairly inferior to a Space Navigator, so why bother?


A joystick is a relatively weak example of the usefulness of DirectInput...the API supports a wide range of devices with any number of axes, including 6dof controllers like the Logitech Cyberman II. I've got boxes full of joysticks, joypads, and other weirder input devices (for, uh, reasons.... let's just call it a hobby).

OSC and MIDI support would be another backend that further extends the range into toy and pro audio gear, providing tasty collections of analog sliders, knobs, wheels, etc. (and two way display communication, if one dared to open that can of worms)

I can give you a simple example from what's on my (cluttered) desk. Beyond my customized keyboard and 13 button mouse, I've got a space navigator, a contour shuttle, and a Logitech G13. The shuttle is useful for timeline and video work, but I find the space navigator too fiddly and under / over reactive and eventually makes my hand cramp up. The G13 is mostly an LCD display and an array of programmable buttons, but it also has a small 2D analog thumbstick, which I can operate without losing my left hand's position on the keys. Even with just two axes, it would be very handy to orbit the camera around a model, for example.

Since you've built it in modules, I think this can be handled without adding much code to what you have now. If you document the windows messaging info for your front end, I can whip up a sample DirectInput backend to test it against.
 
  01 January 2013
Originally Posted by selmo: Since you've built it in modules, I think this can be handled without adding much code to what you have now. If you document the windows messaging info for your front end, I can whip up a sample DirectInput backend to test it against.


Yeah, I see what you are aiming at. It is important to know here that CollieMouse only accepts a limited number of raw input events.

First, it registers only for raw input from usage page 1 (generic desktop controls), usage 8 (multi-axis controller) as defined in the RAWINPUTDEVICE structure. So you need to send messages according to this device type.

After that, CollieMouse receives WM_INPUT messages and calls its own method DetermineMovement (hwnd, wParam, lParam) as usual from the message loop. In that method, the lParam is disassembled into the RawInput components:
HRAWINPUT hRawInput = reinterpret_cast<HRAWINPUT>(lParam);
  UINT dwSize=0;
  if (::GetRawInputData(hRawInput, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER)) != 0) {...error...}
  BYTE saRawInput[RAWINPUTSIZE];
  PRAWINPUT pRawInput = reinterpret_cast<PRAWINPUT>(saRawInput);
  if (::GetRawInputData(hRawInput, RID_INPUT, pRawInput, &dwSize, sizeof(RAWINPUTHEADER)) != dwSize) {...error...}
  if (pRawInput->header.dwType != RIM_TYPEHID) {...ignore...}
  RID_DEVICE_INFO sRidDeviceInfo;
  	sRidDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
  	dwSize = sizeof(RID_DEVICE_INFO);
  	if (GetRawInputDeviceInfo(pRawInput->header.hDevice,	RIDI_DEVICEINFO,	&sRidDeviceInfo,	&dwSize) == dwSize)
  	{
  		if (sRidDeviceInfo.hid.dwVendorId == VENDOR_ID) // vendor = 0x46d
  


...so, not only the device type must fit, but also the vendor. I guess you can use that ID for a test, but CollieMouse does not make a difference between several devices and vendors then, so all the input would flow into the same functions. Well, maybe that even makes sense since you wouldn't want to have multiple camera controllers active at the same time.

If you want CollieMouse to handle the raw input device identification more flexibly, you would need to make the registration and the vendor accessible through the GUI.

After getting the raw input in pRawInput, you can now read the specific movement data out of that variable: (continuing code)
if (pRawInput->data.hid.bRawData[0] == 0x01)
 			{ // Translation vector
 				short* pnData = reinterpret_cast<short*>(&pRawInput->data.hid.bRawData[1]);
 				short x = pnData[0];
 				short y = pnData[1];
 				short z = pnData[2];
 				return Translate(x, -z, -y); // axis system of HID is not the same as of C4D!
 			}
 			else if (pRawInput->data.hid.bRawData[0] == 0x02)
 			{ // Directed rotation vector (NOT Euler)
 				short* pnData = reinterpret_cast<short*>(&pRawInput->data.hid.bRawData[1]);
 				short rX = pnData[0];
 				short rY = pnData[1];
 				short rZ = pnData[2];
 				return Rotate(-rZ, rX, -rY); // axis system of HID is not the same as of C4D!
 			}
 


Buttons are currently not interpreted but could be read here as well. Note that the error handling code and the debug output are all missing from this code. I have been working from an example of the access code is available from 3Dconnexion directly, so it's all just addressing the data received from the SpaceMouse. Other multi-axis controllers may structure the raw data differently, that's why the Vendor ID check blocks raw input events from other manufacturer's devices.

Now, if you generate a WM_INPUT message from your device driver, you could reverse the process and build a raw input structure that CollieMouse could read... I'm curious with what you come up with...
 
  01 January 2013
OK, a short recap to make sure I understand the flow:

1. You register with windows to receive RAWINPUTDEVICE (page 1/ usage 8) messages, which will come in as WM_INPUT messages.

2. The space navigator sends WM_INPUT messages with a RAWINPUT structure in the lParam. (or do you receive space navigator input and create a RAWINPUT / WM_INPUT yourself?)

3. You receive the WM_INPUT, and if it's an HID with a VendorID of 0x46d, you forward it to your method DetermineMovement(). Otherwise you ignore it (or error out)

5. DetermineMovement() looks at the RAWINPUT HID RawData[0] to determine if it's a translation (1) or rotation (2). The 3 axes are stored in the next three data elements, as shorts.

6. You then pass that along to whatever postprocessing you do and make the C4D API calls to move the camera.

So by sending your HWND an WM_INPUT with a RAWINPUT structure that reports as an HID Vendor ID 0x46d, CollieMouse should not know the difference between my inputs and a real space navigator.... This may end up being easier since many devices, incl DirectInput stuff, actually use the rawinput stuff at a lower layer anyway.

Some quick questions:
- Where is the "line" between your backend and front end?
- Is your standalone window the HWND that receives the WM_INPUT, and therefore where I should direct my WM_INPUT messages? Or perhaps since you've already registered to listen, maybe I just generate the WM_INPUT messages system wide and let windows direct them to your registered listener window....
-What are the expected ranges for the 3 axes?
-Having another backend emulate vendor ID 0x46d is probably OK for testing, but likely to cause problems in the long run, so if this works out, you probably want to expose the expected ID via the GUI.

(I realize most people following this thread could care less at this point, but this info may be of use to someone else wanting to support an oddball input device at some point in the future...)
 
Thread Closed share thread



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
CGSociety
Society of Digital Artists
www.cgsociety.org

Powered by vBulletin
Copyright 2000 - 2006,
Jelsoft Enterprises Ltd.
Minimize Ads
Forum Jump
Miscellaneous

All times are GMT. The time now is 12:14 PM.


Powered by vBulletin
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.