@@ -13,17 +13,16 @@ const EXPECTED_PROJECTION = PROJECTION_ORTHOGONAL
1313@export var movement_speed = 1.1
1414@export var bounding_planes : Array [Plane ] = []
1515@export_group ("Rotation" )
16- @export var mouse_rotation_speed = 0.005
16+ @export var mouse_rotation_speed = 0.005 # [rad/px]
1717@export var arrowkey_rotation_speed = 2 # [rad/s]
1818@export var default_y_rotation_degrees = 0.0
1919@export var reference_plane_for_rotation = Plane (Vector3 .UP , 0.0 )
2020@export_group ("View" )
2121@export var visible_height_min = - 10
2222@export var visible_height_max = 10
2323
24- var _pivot_point_2d = null
25- var _pivot_point_3d = null
26- var _camera_point_3d = null
24+ var _mouse_pos_when_rotation_started = null
25+ var _camera_global_pos_when_rotation_started = null
2726
2827
2928func _ready ():
@@ -79,8 +78,10 @@ func _try_handling_movement(delta: float) -> bool:
7978 * Vector2 (movement_speed , movement_speed * 2.0 )
8079 * size
8180 )
82- var camera_move_vector = Vector3 (scaled_screen_move_vector .x , 0 , scaled_screen_move_vector .y )
83- camera_move_vector = camera_move_vector .rotated (Vector3 (0 , 1 , 0 ), rotation .y )
81+ var camera_move_vector = (
82+ Vector3 (scaled_screen_move_vector .x , 0 , scaled_screen_move_vector .y )
83+ . rotated (Vector3 (0 , 1 , 0 ), rotation .y )
84+ )
8485 global_translate (camera_move_vector )
8586 _align_position_to_bounding_planes ()
8687 return true
@@ -135,7 +136,7 @@ func _try_handling_arrowkey_rotation(delta: float):
135136 * arrowkey_rotation_speed
136137 )
137138 if not is_zero_approx (angle_radians ):
138- _rotate_by ( angle_radians )
139+ _rotate_from_reference_position_by ( global_position , angle_radians )
139140
140141
141142func _try_handling_mouse_rotation (event : InputEvent ):
@@ -146,19 +147,21 @@ func _try_handling_mouse_rotation(event: InputEvent):
146147 _start_rotation (event )
147148 elif not event .is_pressed () and event .button_index == MOUSE_BUTTON_MIDDLE :
148149 _stop_rotation ()
149- elif event is InputEventMouseMotion :
150+ elif event is InputEventMouseMotion and _is_rotating () :
150151 var mouse_pos = event .position
151- if _is_rotating ():
152- _rotate (mouse_pos )
152+ var angle_radians = (
153+ (mouse_pos .x - _mouse_pos_when_rotation_started .x ) * mouse_rotation_speed
154+ )
155+ _rotate_from_reference_position_by (_camera_global_pos_when_rotation_started , angle_radians )
153156
154157
155158func _reset_rotation ():
156- var pivot_point_3d = _calculate_pivot_point_3d ()
157- if pivot_point_3d == null :
159+ var pivot_point = _calculate_pivot_point ()
160+ if pivot_point == null :
158161 return
159162 var camera_point_3d = global_transform .origin
160163 var camera_point_2d = Vector2 (camera_point_3d .x , camera_point_3d .z )
161- var pivot_point_2d = Vector2 (pivot_point_3d .x , pivot_point_3d .z )
164+ var pivot_point_2d = Vector2 (pivot_point .x , pivot_point .z )
162165 var pivot_to_camera_distance_2d = camera_point_2d .distance_to (pivot_point_2d )
163166 var new_camera_point_2d = (
164167 pivot_point_2d
@@ -170,54 +173,38 @@ func _reset_rotation():
170173 global_transform .origin = Vector3 (
171174 new_camera_point_2d .x , camera_point_3d .y , new_camera_point_2d .y
172175 )
173- global_transform = global_transform .looking_at (pivot_point_3d , Vector3 (0 , 1 , 0 ))
176+ global_transform = global_transform .looking_at (pivot_point , Vector3 (0 , 1 , 0 ))
174177
175178
176179func _start_rotation (event : InputEvent ):
177- _pivot_point_3d = _calculate_pivot_point_3d ()
178- if _pivot_point_3d != null :
179- _pivot_point_2d = event .position
180- _camera_point_3d = global_transform .origin
180+ _mouse_pos_when_rotation_started = event .position
181+ _camera_global_pos_when_rotation_started = global_transform .origin
181182
182183
183184func _stop_rotation ():
184- _pivot_point_2d = null
185-
186-
187- func _rotate (mouse_pos : Vector2 ):
188- var strength = mouse_pos .x - _pivot_point_2d .x
189- var camera_point_2d = Vector2 (_camera_point_3d .x , _camera_point_3d .z )
190- var pivot_point_2d = Vector2 (_pivot_point_3d .x , _pivot_point_3d .z )
191- var diff_vec = camera_point_2d - pivot_point_2d
192- var rotated_diff_vec = diff_vec .rotated (strength * mouse_rotation_speed )
193- var new_camera_point_2d = pivot_point_2d + rotated_diff_vec
194- global_transform .origin = Vector3 (
195- new_camera_point_2d .x , _camera_point_3d .y , new_camera_point_2d .y
196- )
197- global_transform = global_transform .looking_at (_pivot_point_3d , Vector3 (0 , 1 , 0 ))
185+ _mouse_pos_when_rotation_started = null
198186
199187
200- func _rotate_by ( angle_radians : float ):
201- var pivot_point_3d = _calculate_pivot_point_3d ()
202- if pivot_point_3d == null :
188+ func _rotate_from_reference_position_by ( reference_position : Vector3 , angle_radians : float ):
189+ var pivot_point = _calculate_pivot_point ()
190+ if pivot_point == null :
203191 return
204- var camera_point_3d = global_transform .origin
205- var camera_point_2d = Vector2 (camera_point_3d .x , camera_point_3d .z )
206- var pivot_point_2d = Vector2 (pivot_point_3d .x , pivot_point_3d .z )
207- var diff_vec = camera_point_2d - pivot_point_2d
208- var rotated_diff_vec = diff_vec .rotated (angle_radians )
209- var new_camera_point_2d = pivot_point_2d + rotated_diff_vec
210- global_transform .origin = Vector3 (
211- new_camera_point_2d .x , camera_point_3d .y , new_camera_point_2d .y
192+
193+ var diff_vec_yless = reference_position * Vector3 (1 , 0 , 1 ) - pivot_point * Vector3 (1 , 0 , 1 )
194+ var rotated_diff_vec_yless = diff_vec_yless .rotated (- Vector3 .UP , angle_radians )
195+ var rotated_reference_position = (
196+ pivot_point
197+ + Vector3 (rotated_diff_vec_yless .x , reference_position .y , rotated_diff_vec_yless .z )
212198 )
213- global_transform = global_transform .looking_at (pivot_point_3d , Vector3 (0 , 1 , 0 ))
199+ global_position = rotated_reference_position
200+ global_transform = global_transform .looking_at (pivot_point , Vector3 .UP )
214201
215202
216203func _is_rotating () -> bool :
217- return _pivot_point_2d != null
204+ return _mouse_pos_when_rotation_started != null
218205
219206
220- func _calculate_pivot_point_3d () -> Vector3 :
207+ func _calculate_pivot_point () -> Vector3 :
221208 var screen_center_pos_2d = get_viewport ().size / 2.0
222209 return get_ray_intersection_with_plane (screen_center_pos_2d , reference_plane_for_rotation )
223210
@@ -261,7 +248,7 @@ func _align_camera_far_to_size(a_size: float):
261248
262249
263250func _align_position_to_bounding_planes ():
264- var pivot_point = _calculate_pivot_point_3d ()
251+ var pivot_point = _calculate_pivot_point ()
265252 var aligned_pivot_point = _clamp_position_to_bounding_planes (pivot_point )
266253 var diff = aligned_pivot_point - pivot_point
267254 global_transform .origin += diff
0 commit comments