Add support for 3DConnexion's SpaceMouse devices.#45
Conversation
EllaFoxo
left a comment
There was a problem hiding this comment.
Some code quality improvements for your clanker :)
| function applySpaceMouse() { | ||
| if (!controls.enabled) return; | ||
|
|
||
| const gamepads = navigator.getGamepads ? navigator.getGamepads() : []; |
There was a problem hiding this comment.
Break out gamepad selection into a separate reusable function
| } | ||
| } | ||
|
|
||
| if (!sm) return; |
There was a problem hiding this comment.
Don't silently fail if no space mouse is found. Report back a bool or int return result so that the function's caller is notified of the presence (or not) of a space mouse.
| // Smooth deadzone mapping. | ||
| // Instead of a step discontinuity (a < threshold ? 0 : a) that causes sudden camera | ||
| // jumps when crossing the threshold, we scale smoothly from 0.0 to 1.0 after the deadzone. | ||
| const deadzone = 0.08; |
There was a problem hiding this comment.
Deadzone should be configurable, not hardcoded.
| const tz = ax1; | ||
| const ty = -ax2; | ||
|
|
||
| if (tx !== 0 || ty !== 0 || tz !== 0) { |
There was a problem hiding this comment.
I'd like some in-line comment documentation here to explain the math behind what is going on. Looks to be calculating the axis positional change delta, and applying that directly to the camera controls. Perhaps this could be broken up into separate functions, one that handles the math, one that does camera transforms.
| transSpeed = (orthoCamera.top / orthoCamera.zoom) * 0.04; | ||
| } | ||
|
|
||
| _tmpV1.set(0, 0, 1).applyQuaternion(camera.quaternion).normalize(); |
There was a problem hiding this comment.
_tmpV1, _tmpV2 etc are all meaningless variables. Give them a suitable name. Doesn't matter if they're temporary allocations; code needs to be readable.
| _needsRender = true; | ||
| } | ||
|
|
||
| const pitch = ax3; |
There was a problem hiding this comment.
Would have been nice to have pitch/roll/yaw comments on the original axis declaration, so we're able to determine which axis does what movement. Can then continue setting a constant later.
| const yaw = -ax5; | ||
|
|
||
| if (pitch !== 0 || roll !== 0 || yaw !== 0) { | ||
| const rotSpeed = 0.02; |
There was a problem hiding this comment.
Another place we don't want to hardcode.
| function applySpaceMouse() { | ||
| if (!controls.enabled) return; | ||
|
|
||
| const gamepads = navigator.getGamepads ? navigator.getGamepads() : []; |
There was a problem hiding this comment.
Gamepad API should be the fallback - WebHID is preferential if support in the browser is there (currently only Edge, Chrome and Opera). Direct HID input is going to yield more control if you can get it.
https://developer.mozilla.org/en-US/docs/Web/API/WebHID_API
https://developer.mozilla.org/en-US/docs/Web/API/HIDInputReportEvent
| let transSpeed = 2.0; | ||
| if (_isPerspective) { | ||
| const dist = camera.position.distanceTo(pivot); | ||
| transSpeed = dist * 0.02; |
There was a problem hiding this comment.
Magic values for 2.0, 0.02, 0.04. Same for the dollyDelta and camera.zoom later. What are they? What are they doing to the speed and zoom? Document them, and/or make them constant. Where appropriate, provide them as a field in the function header.
This was vibe-coded as well :-)
Unfortunately browser support for these devices seems to be poll-based and so the function has to run on every iteration, so the function has been optimized to cache as much as possible. Performance on my machine was good.
Tested with my SpaceMouse.