Skip to content

Commit

Permalink
Added config options and dock
Browse files Browse the repository at this point in the history
  • Loading branch information
cybereality committed Jun 22, 2022
1 parent c366083 commit e9a2dbf
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 19 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ For manual install, download the `addons` folder from this repository and copy i

* Place the `addons` folder, with all contents, into your Godot project root directory.
* To enable the plug-in, click `Project` `Project Settings` `Plugins` and check `Enable` next to the `Godot Space Mouse` entry.
* Use the `Space` dock in the editor to adjust speed or change to object or camera control.
* The 3Dconnexion driver is not needed on any OS. However, if you're on Windows, and have the driver installed, please first open the Godot editor, then open the 3Dconnexion app. You'll see a pop-up with the name of the Godot editor executable. Click `Advanced Settings`, then disable all navigation and zoom controls, as these can conflict with the viewport controls.
* On Linux you will need to allow HID access via udev rules. First, download the file `70-space-mouse.rules` and place this file in the correct directory for your distro, such as `/etc/udev/rules.d/`. Then replug your Space Mouse hardware or run `sudo udevadm control --reload-rules && sudo udevadm trigger` to update the rules.
* For macOS, you must uninstall the 3Dconnexion drivers, as they're incompatible with the plug-in.
Expand Down
73 changes: 73 additions & 0 deletions addons/spacemouse/SpaceDock.tscn
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
[gd_scene format=2]

[node name="Space" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0

[node name="UI" type="VBoxContainer" parent="."]
anchor_left = 0.5
anchor_right = 0.5
anchor_bottom = 1.0
margin_left = -64.0
margin_right = 64.0

[node name="SpacerTop" type="Control" parent="UI"]
margin_right = 128.0
margin_bottom = 6.0
rect_min_size = Vector2( 0, 6 )

[node name="TranslationLabel" type="Label" parent="UI"]
margin_top = 10.0
margin_right = 128.0
margin_bottom = 24.0
text = "Translation Speed:"

[node name="TranslationSpeed" type="HSlider" parent="UI"]
margin_top = 28.0
margin_right = 128.0
margin_bottom = 50.0
rect_min_size = Vector2( 128, 22 )
max_value = 200.0
step = 5.0
value = 100.0
rounded = true
tick_count = 3

[node name="RotationLabel" type="Label" parent="UI"]
margin_top = 54.0
margin_right = 128.0
margin_bottom = 68.0
text = "Rotation Speed:"

[node name="RotationSpeed" type="HSlider" parent="UI"]
margin_top = 72.0
margin_right = 128.0
margin_bottom = 94.0
rect_min_size = Vector2( 128, 22 )
max_value = 200.0
step = 5.0
value = 100.0
rounded = true
tick_count = 3

[node name="SpacerMid" type="Control" parent="UI"]
margin_top = 98.0
margin_right = 128.0
margin_bottom = 100.0
rect_min_size = Vector2( 0, 2 )

[node name="ControlType" type="OptionButton" parent="UI"]
margin_top = 104.0
margin_right = 128.0
margin_bottom = 128.0
rect_min_size = Vector2( 128, 24 )
text = "Object Mode"
items = [ "Object Mode", null, false, 0, null, "Camera Mode", null, false, 1, null ]
selected = 0

[node name="SpacerBottom" type="Control" parent="UI"]
margin_top = 132.0
margin_right = 128.0
margin_bottom = 1080.0
size_flags_horizontal = 3
size_flags_vertical = 3
98 changes: 80 additions & 18 deletions addons/spacemouse/SpaceMouse.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ extends EditorPlugin

# space mouse library interface
onready var spacemouse = preload("res://addons/spacemouse/bin/spacemouse.gdns").new()
# scene for the configuration dock
var space_dock = null
# if the device is connected
var connected = false
# currently selected object
Expand All @@ -25,11 +27,56 @@ var camera_origin = Vector3.ZERO
var offset_speed = 1.0;
# convert raw values into godot axis format
const flip = Vector3(-1.0, 1.0, -1.0)
# default speeds (modified by ui)
const base_translate_speed = 0.16
const base_rotate_speed = 0.0275
# main speed control for motion updates
const translate_speed = 0.16
const rotate_speed = 0.0275
var translate_speed = base_translate_speed
var rotate_speed = base_rotate_speed
# sets viewport camera to the first one
const camera_index = 0
# node to access configuration ui
var translation_speed_ui = null
var rotation_speed_ui = null
var control_type_ui = null
# name for control type
const ControlType = {OBJECT_TYPE = 0, CAMERA_TYPE = 1}
# object or camera control
var control_type = ControlType.OBJECT_TYPE
# adjust fly camera translation
const adjust_translation = 0.24
const adjust_rotation = 0.98


# on start add the configuration dock
func _enter_tree():
# instance the dock
space_dock = preload("res://addons/spacemouse/SpaceDock.tscn").instance()
# attach signals for ui controls
translation_speed_ui = space_dock.get_node("UI/TranslationSpeed")
translation_speed_ui.connect("value_changed", self, "update_config")
rotation_speed_ui = space_dock.get_node("UI/RotationSpeed")
rotation_speed_ui.connect("value_changed", self, "update_config")
control_type_ui = space_dock.get_node("UI/ControlType")
control_type_ui.connect("item_selected", self, "update_config")
# add ui dock to the editor slot
add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_BL, space_dock)

# update the controls on ui changes
func update_config(val):
# scale the translation and rotation speeds
translate_speed = base_translate_speed * (translation_speed_ui.value * 0.01)
rotate_speed = base_rotate_speed * (rotation_speed_ui.value * 0.01)
# toggle camera control type
control_type = control_type_ui.selected

# cleanup on exit
func _exit_tree():
# remove the dock
remove_control_from_docks(space_dock)
# free memory
if is_instance_valid(space_dock):
space_dock.queue_free()

# setup global parameters and connect to device
func _ready():
Expand Down Expand Up @@ -66,22 +113,37 @@ func _process(delta):
# save the camera origin then center at zero for accurate rotation
camera_origin = camera_transform.origin
camera_transform.origin = Vector3.ZERO
# make translation slower the closer you get to the pivot point
offset_speed = (select_origin.distance_to(camera_origin) / 8.0) + 0.01
offset_speed = clamp(offset_speed, 0.01, 8.0)
# transform translation into camera local space
space_translation = camera_transform.xform(space_translation)
# adjust the raw readings into reasonable speeds and apply delta
space_translation *= translate_speed * offset_speed * delta;
space_rotation *= rotate_speed * delta
# move the camera by the latest translation but remove the offset from the pivot
camera_transform.origin += space_translation + camera_origin - select_origin
# rotate the camera by the latest rotation as normal
camera_transform = camera_transform.rotated(camera_transform.basis.x.normalized(), space_rotation.x)
camera_transform = camera_transform.rotated(camera_transform.basis.y.normalized(), space_rotation.y)
camera_transform = camera_transform.rotated(camera_transform.basis.z.normalized(), space_rotation.z)
# adjust the camera back to the real location from the pivot point
camera_transform.origin += select_origin
# object control type
if control_type == ControlType.OBJECT_TYPE:
# make translation slower the closer you get to the pivot point
offset_speed = (select_origin.distance_to(camera_origin) / 8.0) + 0.01
offset_speed = clamp(offset_speed, 0.01, 8.0)
# transform translation into camera local space
space_translation = camera_transform.xform(space_translation)
# adjust the raw readings into reasonable speeds and apply delta
space_translation *= translate_speed * offset_speed * delta;
space_rotation *= rotate_speed * delta
# move the camera by the latest translation but remove the offset from the pivot
camera_transform.origin += space_translation + camera_origin - select_origin
# rotate the camera by the latest rotation as normal
camera_transform = camera_transform.rotated(camera_transform.basis.x.normalized(), space_rotation.x)
camera_transform = camera_transform.rotated(camera_transform.basis.y.normalized(), space_rotation.y)
camera_transform = camera_transform.rotated(camera_transform.basis.z.normalized(), space_rotation.z)
# adjust the camera back to the real location from the pivot point
camera_transform.origin += select_origin
# camera control type
elif control_type == ControlType.CAMERA_TYPE:
# adjust the raw readings into reasonable speeds and apply delta
space_translation *= translate_speed * adjust_translation * delta;
space_rotation *= rotate_speed * adjust_rotation * delta
# rotate the camera in place
camera_transform = camera_transform.rotated(camera_transform.basis.x.normalized(), -space_rotation.x)
camera_transform = camera_transform.rotated(camera_transform.basis.y.normalized(), -space_rotation.y)
camera_transform = camera_transform.rotated(camera_transform.basis.z.normalized(), -space_rotation.z)
# transform translation into camera local space
space_translation = camera_transform.xform(space_translation)
# move the camera back to the original position
camera_transform.origin = camera_origin - space_translation
# apply the updated temporary transform to the actual viewport camera
camera.transform = camera_transform

Expand Down
2 changes: 1 addition & 1 deletion addons/spacemouse/plugin.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
name="Godot Space Mouse"
description="Enables 6 degrees of freedom control for the viewport camera in the Godot editor. Requires a SpaceMouse hardware device from 3Dconnexion."
author="Andres Hernandez"
version="1.3.2"
version="1.4.1"
script="SpaceMouse.gd"

0 comments on commit e9a2dbf

Please sign in to comment.