forked from TWew/CADLikeOrbit_Camera
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCADLikeOrbit_Camera.gd
303 lines (246 loc) · 9.15 KB
/
CADLikeOrbit_Camera.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
extends Camera
export var ZOOMSPEED = 0.15
export var ROTATIONSPEED = 0.5 * PI/180 #rad/screenpixel
export var DEFAULTFOCALDIST = 10
export var DEFAULTPANDIST = 10
export var RAYLENGTH = 100000
export var USEFOCALPOINTSPHERE = true
export var FocalPointSphereRadius = 0.2
export(Color, RGB) var FocalPointSphereColor = Color.red
export var IfNoObjPickedRotateAroundOrigin = false
export var InputMapActionZoom = "Zooming"
export var InputMapActionPan = "Panning"
export var RotateUsingZoomPlusPan = true
export var InputMapActionRotate = "Rotating"
export var InputMapActionZoomIn = "ZoomingIn"
export var InputMapActionZoomOut = "ZoomingOut"
signal CamZoom_start
signal CamZoom_stop
signal CamPan_start
signal CamPan_stop
signal CamRotate_start
signal CamRotate_stop
enum CamAction {ZOOMIN, ZOOMOUT, ZOOM, ROTATE, PAN, SELECT}
var act_pos2d = Vector2(0,0)
var last_pos2d = Vector2(0,0)
var actpandist = 0
var focalpoint = Vector3(0,0,0)
# Enabled/disabled camera controls
var zoom_enabled = true
var pan_enabled = true
var rotate_enabled = true
func _ready():
#Add needed Child Objects (Not Visible in the Scene-Tree)
var newRayCast = RayCast.new()
newRayCast.name = "RayCast"
add_child(newRayCast)
newRayCast.set_owner(self)
var newSphere = CSGMesh.new()
newSphere.name = "FocalpointSphere"
newSphere.mesh = SphereMesh.new()
newSphere.scale = Vector3(FocalPointSphereRadius, FocalPointSphereRadius, FocalPointSphereRadius)
newSphere.mesh.material = SpatialMaterial.new()
newSphere.mesh.material.albedo_color = FocalPointSphereColor
add_child(newSphere)
newSphere.set_owner(self)
#No Action a Scene-Start
CamAction.ZOOM = false
CamAction.PAN = false
CamAction.ROTATE = false
#Check for InputMap Errors
if len(InputMap.get_action_list(InputMapActionZoomIn)) == 0 or \
len(InputMap.get_action_list(InputMapActionZoomOut)) == 0 or \
len(InputMap.get_action_list(InputMapActionPan)) == 0 or \
(len(InputMap.get_action_list(InputMapActionRotate)) == 0 and not RotateUsingZoomPlusPan):
print(self.name + " Error: Can't find defined InputMap Actions!")
var sol = "Solution: Change the Input Map Parameters or add "
sol += "new InputMap-Action's with the defined Names: %s, %s, %s"
sol = sol % [InputMapActionZoom, InputMapActionPan, InputMapActionRotate]
print(sol)
func Zooming():
if last_pos2d != Vector2(0,0):
var Zoomdist = (last_pos2d[1]-act_pos2d[1])*ZOOMSPEED
translate_object_local(Vector3(0,0,Zoomdist))
"""
Meant to be used with the mouse scroll wheel, zooms in or out one step for each
step of the wheel.
"""
func ZoomingInOut(dir):
var Zoomdist = dir * ZOOMSPEED
# Prevent the user from zooming past the origin
# if self.transform.origin.y < 0:
# Zoomdist = -self.transform.origin.y
translate_object_local(Vector3(0,0,Zoomdist))
func Panning():
#is there a t-1 Action? No, then get Focalpoint
if last_pos2d == Vector2(0,0):
#Orient RayCast
var RayCastPose = global_transform.inverse()
RayCastPose.origin = Vector3(0,0,0)
$RayCast.transform = RayCastPose
$RayCast.force_update_transform()
#Get 3d-Focalpoint for t-1
var raynormal = project_ray_normal(act_pos2d)
$RayCast.cast_to = raynormal * RAYLENGTH
$RayCast.force_raycast_update()
if $RayCast.is_colliding():
focalpoint = $RayCast.get_collision_point()
else:
focalpoint = global_transform.origin + raynormal.normalized() * DEFAULTPANDIST
#Distnace/Vectorlength from Camorigin to Focalpoint
actpandist = (focalpoint - global_transform.origin).length()
else:
#Calc new Cam origin
var focalpose = global_transform
focalpose.origin = focalpoint
var raynormal = project_ray_normal(act_pos2d) #Ray in Global Csys
var raynormal_refCam = global_transform.basis.inverse() * raynormal
global_transform.origin = focalpose * -Transform.IDENTITY.translated(raynormal_refCam.normalized() * actpandist).origin
#Set Focalpointsphere if activated
if USEFOCALPOINTSPHERE:
$FocalpointSphere.global_transform.origin = (global_transform * Transform.IDENTITY.translated(raynormal_refCam.normalized() * actpandist)).origin
$FocalpointSphere.visible = true
func Rotating():
#is there a t-1 Action? No, then get Focalpoint
if last_pos2d == Vector2(0,0):
#Orient RayCast
var RayCastPose = global_transform.inverse()
RayCastPose.origin = Vector3(0,0,0)
$RayCast.transform = RayCastPose
$RayCast.force_update_transform()
#Get 3d-Focalpoint for t-1
var raynormal = project_ray_normal(act_pos2d)
$RayCast.cast_to = raynormal * RAYLENGTH
$RayCast.force_raycast_update()
if $RayCast.is_colliding():
focalpoint = $RayCast.get_collision_point()
else:
if IfNoObjPickedRotateAroundOrigin:
focalpoint = Vector3(0,0,0) # if not Object Picked then use Worldspace Origin as focalpoint
else:
focalpoint = global_transform.origin + (raynormal.normalized() * DEFAULTFOCALDIST)
#Set Focalpointsphere if activated
if USEFOCALPOINTSPHERE:
$FocalpointSphere.global_transform.origin = focalpoint
$FocalpointSphere.visible = true
else: #Rotate
#Calc new Camtransformation
var focalpose = global_transform
focalpose.origin = focalpoint
var VFocalP2Cam = (focalpose.inverse() * global_transform).origin
global_transform = focalpose * \
Transform.IDENTITY.rotated(Vector3(1,0,0), (last_pos2d[1]-act_pos2d[1])*ROTATIONSPEED) * \
Transform.IDENTITY.rotated(Vector3(0,1,0), (last_pos2d[0]-act_pos2d[0])*ROTATIONSPEED) * \
Transform.IDENTITY.translated(VFocalP2Cam)
"""
Checks to see if the raycast is colliding with anything, meaning that it should be selected.
"""
func Selecting():
var from = project_ray_origin(act_pos2d)
var to = from + project_ray_normal(act_pos2d) * RAYLENGTH
$RayCast.origin = from
$RayCast.cast_to = to
$RayCast.force_raycast_update()
if $RayCast.is_colliding():
print("HERE")
# Orient RayCast
# var RayCastPose = global_transform.inverse()
# RayCastPose.origin = Vector3(0,0,0)
# $RayCast.transform = RayCastPose
# $RayCast.force_update_transform()
# Get 3d-Focalpoint for t-1
# var raynormal = project_ray_normal(act_pos2d)
# $RayCast.cast_to = raynormal * RAYLENGTH
# $RayCast.force_raycast_update()
# if $RayCast.is_colliding():
# focalpoint = $RayCast.get_collision_point()
# print("HERE")
# Is there a t-1 Action? No, then get Focalpoint
# if last_pos2d == Vector2(0,0):
# warning-ignore:unused_argument
func _process(delta):
#Match Input-Action to Camera-Operation
if Input.is_action_just_pressed(InputMapActionZoom):
emit_signal("CamZoom_start")
CamAction.ZOOM = true
last_pos2d = Vector2(0,0)
if Input.is_action_just_released(InputMapActionZoom):
emit_signal("CamZoom_stop")
CamAction.ZOOM = false
# Zoom in (assumes mouse scroll wheel)
if Input.is_action_just_released("ZoomingIn"):
emit_signal("CamZoom_start")
CamAction.ZOOMIN = true
# Zoom out (assumes mouse scroll wheel)
if Input.is_action_just_released("ZoomingOut"):
emit_signal("CamZoom_start")
CamAction.ZOOMOUT = true
if Input.is_action_just_pressed(InputMapActionPan):
emit_signal("CamPan_start")
CamAction.PAN = true
last_pos2d = Vector2(0,0)
if Input.is_action_just_released(InputMapActionPan):
emit_signal("CamPan_stop")
CamAction.PAN = false
if $FocalpointSphere.visible:
$FocalpointSphere.visible = false
# If the user is holding down the Control key, they want to select geometry
if Input.is_action_pressed("mouse_select"):
CamAction.SELECT = true
else:
CamAction.SELECT = false
#Rotate by using the Key-Combination of Zoom and Pan, or by using a
#seperate InputMap-Event
if RotateUsingZoomPlusPan:
if Input.is_action_pressed(InputMapActionPan) and \
Input.is_action_just_pressed(InputMapActionZoom):
emit_signal("CamRotate_start")
CamAction.ROTATE = true
if CamAction.ZOOM:
emit_signal("CamZoom_stop")
CamAction.ZOOM = false
elif CamAction.PAN:
emit_signal("CamPan_stop")
CamAction.PAN = false
last_pos2d = Vector2(0,0)
if CamAction.ROTATE and (Input.is_action_just_released(InputMapActionPan) or \
Input.is_action_just_released(InputMapActionZoom)):
emit_signal("CamRotate_stop")
CamAction.ROTATE = false
if Input.is_action_pressed(InputMapActionPan):
emit_signal("CamPan_start")
CamAction.PAN = true
if Input.is_action_pressed(InputMapActionZoom):
emit_signal("CamZoom_start")
CamAction.Zoom = true
last_pos2d = Vector2(0,0)
if $FocalpointSphere.visible:
$FocalpointSphere.visible = false
else:
if Input.is_action_just_pressed(InputMapActionRotate):
emit_signal("CamRotate_start")
CamAction.ROTATE = true
last_pos2d = Vector2(0,0)
if Input.is_action_just_released(InputMapActionRotate):
emit_signal("CamRotate_stop")
CamAction.ROTATE = false
if $FocalpointSphere.visible:
$FocalpointSphere.visible = false
act_pos2d = get_viewport().get_mouse_position()
if CamAction.ZOOM and zoom_enabled:
Zooming()
if CamAction.ZOOMIN and zoom_enabled:
ZoomingInOut(-1)
CamAction.ZOOMIN = false
emit_signal("CamZoom_stop")
if CamAction.ZOOMOUT and zoom_enabled:
ZoomingInOut(1)
CamAction.ZOOMOUT = false
emit_signal("CamZoom_stop")
if CamAction.PAN and pan_enabled:
Panning()
if CamAction.ROTATE and rotate_enabled:
Rotating()
if CamAction.SELECT:
Selecting()
last_pos2d = act_pos2d