Files
solvecraft/docs/3d-mouse.md
T
Colin Faulkingham 3cdc68aaf1 Viewport: opt-in model zoom and Traced 3D mouse orbit (#7435) (#7991)
* claim: #7435

* Viewport: the 3D mouse, the bridge and drag-zoom stop at the model, like the wheel (#7435)

The wheel and pinch hold the model point under the cursor, so the view
comes up to the surface and stops there. Every other zoom path passed no
anchor, so the 3D mouse cap, the navigation bridge and drag-zoom zoomed
straight through the surface into the body.

A device has no pointer, so the cap and the bridge now hold the model
point in the middle of the view; drag-zoom holds the point under the
pointer, like the wheel. With "Zoom to the cursor" off the old
zoom-through-the-model behaviour stays, as it does for the wheel.

The orbit half of the issue is a design decision and is untouched.

* Viewport: drag-zoom holds the point where the drag started (#7435)

The zoom anchor followed the moving pointer, so the zoom slid away from
what was pressed on as the drag went on. It now holds the press point,
the way the wheel holds the point under the cursor.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 3D mouse: turn around the model in the middle of the view (#7435)

The cap and the navigation bridge turned the view around the view's
centre, which after a pan or from far away sits behind the face, so the
part swung away while it turned. They now turn around the model point in
the middle of the view (the middle of the bodies in view over empty
space), and keep it still on screen. Preferences > Navigation > "Turn
around the model in the middle of the view" switches back to the old
behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 3D mouse: keep the turning point until the cap is back at rest (#7435)

The point the cap turns around was picked again every frame, so it slid
to whatever came into the middle as the view moved. It's now chosen when
the cap leaves rest and kept until the cap comes back, the way a mouse
orbit keeps the point it started on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 3D mouse: show the point the view turns around (#7435)

While the cap turns the view, a faint ball in the accent colour marks the
model point it turns around, so it's clear what the turn holds still. The
point is now picked when the cap starts turning, not when it only pans or
zooms, so a pan shows no ball.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* 3D mouse: orbit is a choice of Traced or Classic (#7435)

The checkbox becomes a two-way choice on the 3D mouse section's form:
Traced turns around the model in the middle of the view when the turn
begins and marks it with a faint ball; Classic turns around the view's
centre as before. Traced stays the default.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Docs: the 3D mouse's Traced and Classic orbit (#7435)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Make model zoom and traced orbit opt-in (#7435)

---------

Co-authored-by: nomadsgalaxy <16734355+nomadsgalaxy@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 17:49:15 +00:00

6.8 KiB
Raw Permalink Blame History

3D mouse

On Windows, macOS and Linux, SolidCraft detects a connected 3D mouse through its HID multi-axis controller interface: a 3Dconnexion SpaceNavigator or SpaceMouse, or a homemade device that declares itself one. Move the cap to pan and zoom, and tilt or twist it to rotate the 3D view. By default, zoom can pass through the model and orbit turns around the view's centre, as in earlier versions. Two preferences opt into holding the model:

  • Preferences › Navigation › Stop zoom at the model (zoom_stop_at_model, off by default) makes the cap and navigation bridge zoom toward the surface in the middle of the view and stop there. Drag-zoom holds the model point where the drag began. The wheel and pinch keep their separate Zoom to the cursor preference; neither setting changes the other.
  • Preferences › Navigation › 3D mouse › Orbit defaults to Classic. Choose Traced (space_mouse_model_pivot: true) to turn around the model point in the middle of the view when the turn begins. A faint ball marks that point until the cap is back at rest. Over empty space, the pivot is the middle of the bodies in view. The navigation bridge uses the same preference, but picks the point each frame because device apps do not report rest.

While editing a sketch, the cap pans and zooms without changing the sketch's initial view. After you adjust the view with the navigation cube, the cap can rotate it too. The Navigation page in Preferences has an on/off switch, a speed control and, for each of the cap's six axes, an invert switch and a speed for the 3D mouse. The web app reads it too, through the browser; Firefox needs a 3DxWare setting first (see Getting started › 3D mouse in the browser).

With 3DxWare on Windows, SolidCraft follows 3DxWare's profile for it when there is one, and 3DxWare's object mode (tilt to roll, twist to spin) until there is. The mouse-wheel turns that 3DxWare makes from the cap's motion are ignored, so the view doesn't zoom in steps as the cap tilts.

On Linux SolidCraft reads the 3D mouse through spacenavd when that daemon runs (its socket /var/run/spnav.sock), so what you set in spnavcfg (swapped or inverted axes, sensitivity, dead zones) applies as it does in other programs, and no udev rule is needed. With nothing set there, the motion is the same as without the daemon. Without spacenavd, SolidCraft reads /dev/hidrawN directly, so the logged-in user needs access to the device. A udev rule that adds the uaccess tag does that, for example /etc/udev/rules.d/70-3d-mouse.rules for USB devices with 3Dconnexion's vendor id, and for its Bluetooth ones (where idVendor isn't set, so the HID id is matched instead):

SUBSYSTEM=="hidraw", ATTRS{idVendor}=="256f", TAG+="uaccess"
SUBSYSTEM=="hidraw", KERNELS=="0005:256F:*", TAG+="uaccess"

Older SpaceNavigators use Logitech's vendor id 046d, so add a rule with their product id (see lsusb) instead of matching every Logitech device. A homemade device needs a rule with its own vendor and product id. Reload with sudo udevadm control --reload && sudo udevadm trigger, then replug the device. The Flatpak sandbox does not expose hidraw devices, so the 3D mouse only works with native builds there for now.

On Windows and macOS, with more than one 3D mouse connected, SolidCraft reads the one in use. For example, a 3Dconnexion Universal Receiver with nothing paired may sit next to a SpaceMouse on a cable. The first device found is read until another one moves, and then that one is. The Navigation page names the device being read, and its calibration applies.

SolidCraft finds the axes from the device's report descriptor, so it doesn't matter how a device lays them out: translation and rotation in separate reports (3Dconnexion's wired devices), all six in one (its wireless ones and most homemade devices), after the buttons, or narrower than 16 bits. Each axis is scaled from the range the descriptor declares.

On macOS SolidCraft talks to the 3Dconnexion driver (3DxWare) when it is installed, through the driver's client API (crates/threedx-client; the framework is loaded at run time, never bundled). The driver keeps the device to itself, and sends it only to a program it can identify: SolidCraft as an .app (the packaged app). Without the driver, or with its helper not running, SolidCraft reads the device through IOKit like on Windows.

SolidCraft does not follow 3DxWare's profile on macOS. Its default is 3DxWare's object mode.

Device apps: the navigation bridge

Some homemade input devices come with a program of their own that reads the device and turns its knobs, rings and buttons into navigation (profiles, sensitivity, button actions). Such a program can move SolidCraft's view directly instead of emulating mouse drags, so the mouse pointer stays the user's and both can be used at once. Turn on Navigate with a device app on this computer in Preferences › Navigation › 3D mouse (off by default) and set the port the program listens on (8765 unless the program says otherwise). The desktop app then connects to 127.0.0.1:<port>, retries every second while nothing answers, and shows Connected with the program's name once it is. Only the window with focus moves, and not on the start page or while a file dialog is open.

The program is the server; SolidCraft connects and first sends one line, {"t":"hello","app":"solidcraft","version":"<version>"}. Then the program sends one JSON object per line (UTF-8, \n-terminated, at most 4096 bytes); anything else, and any message SolidCraft doesn't know, is ignored:

Message Meaning
{"t":"hello","server":"MAKMOUSE","device":"MAKMOUSE"} The program's name (shown in Preferences) and, optionally, a name in the device's USB manufacturer or product string. A 3D mouse with that name is then left to the program, so its motion doesn't reach the view twice.
{"t":"axis","x":4.0,"y":-2.5} Motion since the last message, in points: it orbits as a drag of that many points would (the model follows), or pans or zooms in the current mode. Where the view can't turn (a sketch being edited, a flat page) an orbit pans.
{"t":"zoom","d":1.0} Zoom steps (8 % of the distance each); positive zooms in, as a wheel turned forward. Reverse zoom direction applies. Stops at the model only when Stop zoom at the model is on.
{"t":"mode","mode":"pan","on":true} What axis drives: orbit (the default), pan or zoom (up zooms in, 8 points a step). "on":false goes back to orbit.
{"t":"view","name":"iso"} A standard view: front, back, left, right, top, bottom, iso, or fit to frame everything.

Values that aren't finite numbers count as none, and each is limited to ±10 000 per message and per frame. The protocol is the one the MAKMOUSE driver app uses for its add-ins.