-
Notifications
You must be signed in to change notification settings - Fork 5
/
camera_control.py
157 lines (133 loc) · 4.71 KB
/
camera_control.py
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
# Load further needed Panda3D modules
from direct.gui.DirectGui import DirectFrame
from direct.gui.DirectButton import DirectButton
from direct.showbase import DirectObject
from panda3d.core import Vec3
from handler import Handler
def reset_camera(base):
"""
Set camera to default position.
"""
base.camera.setPos(0, -4, 2)
base.camera.lookAt(0, 0, 1)
class CameraControl(DirectObject.DirectObject, Handler):
"""
This class takes care of the commands to the camera, e.g. event handling, setting up the update task and more.
The accept-calls are only working if panda has its own top level window and key presses are propagated to it.
"""
def __init__(self, base, handler):
"""
Set up trigger, get movement directions and create event handling.
"""
super().__init__()
# Save handler instance to update debug mode
self.handler = handler
# Trigger to tell where the camera is supposed to go
self.forward_trig = 0
self.right_trig = 0
self.up_trig = 0
self.heading_trig = 0
self.pitch_trig = 0
# Store the movement needed to go in each direction (updated in task)
self.forward = 0
self.right = 0
self.up = 0
# Event handling for key down events
self.accept('w', self.set_forward_trig, [1])
self.accept('s', self.set_forward_trig, [-1])
self.accept('a', self.set_right_trig, [-1])
self.accept('d', self.set_right_trig, [1])
self.accept('shift', self.set_up_trig, [1])
self.accept('control', self.set_up_trig, [-1])
self.accept('q', self.set_heading_trig, [1])
self.accept('e', self.set_heading_trig, [-1])
self.accept('r', self.set_pitch_trig, [1])
self.accept('f', self.set_pitch_trig, [-1])
self.accept('f1', self.debug)
# Event handling for key up events
self.accept('w-up', self.set_forward_trig, [0])
self.accept('s-up', self.set_forward_trig, [0])
self.accept('a-up', self.set_right_trig, [0])
self.accept('d-up', self.set_right_trig, [0])
self.accept('shift-up', self.set_up_trig, [0])
self.accept('control-up', self.set_up_trig, [0])
self.accept('q-up', self.set_heading_trig, [0])
self.accept('e-up', self.set_heading_trig, [0])
self.accept('r-up', self.set_pitch_trig, [0])
self.accept('f-up', self.set_pitch_trig, [0])
# Start task to move camera in desired direction
base.taskMgr.add(self.cam_move_task, "CamMoveTask", extraArgs=[base], appendTask=True)
# Create button to reset camera position and orientation
frame = DirectFrame(frameColor=(.1, .1, .1, .7), frameSize=(-.22, .22, -.05, .08), pos=(-1.1, 0, -0.94))
button = DirectButton(text="Reset Camera", frameSize=(-4, 4, -.5, 1), scale=.05, command=reset_camera, extraArgs=[base])
button.reparentTo(frame)
def set_forward_trig(self, trig):
"""
Event handling function for for/backward movement command.
"""
self.forward_trig = trig
def set_right_trig(self, trig):
"""
Event handling function for left/right movement command.
"""
self.right_trig = trig
def set_up_trig(self, trig):
"""
Event handling function for up/downward movement command.
"""
self.up_trig = trig
def set_heading_trig(self, trig):
"""
Event handling function for heading rotation command.
"""
self.heading_trig = trig
def set_pitch_trig(self, trig):
"""
Event handling function for pitch rotation command.
"""
self.pitch_trig = trig
def debug(self):
"""
Show extra debug info.
"""
if self.handler.bullet_debug_node.isHidden():
self.handler.bullet_debug_node.show()
self.handler.drone_manager.set_debug(True)
else:
self.handler.bullet_debug_node.hide()
self.handler.drone_manager.set_debug(False)
def cam_move_task(self, base, task):
"""
Task function for actually updating the position of the camera.
"""
# Get current position, reset delta
cur_pos = base.camera.getPos()
cur_hpr = base.camera.getHpr()
delta_pos = Vec3(0, 0, 0)
# Update the movement needed to go in each direction (rotation changes these)
self.forward = base.camera.getQuat().getForward()
self.right = base.camera.getQuat().getRight()
self.up = base.camera.getQuat().getUp()
# Check if movement is wanted
if self.forward_trig == 1:
delta_pos += self.forward
elif self.forward_trig == -1:
delta_pos -= self.forward
if self.right_trig == 1:
delta_pos += self.right
elif self.right_trig == -1:
delta_pos -= self.right
if self.up_trig == 1:
delta_pos += self.up
elif self.up_trig == -1:
delta_pos -= self.up
# Fine tune delta and move camera
delta_pos.normalize()
delta_pos *= .05
base.camera.setPos(cur_pos + delta_pos)
# Rotate camera as wanted
delta_heading = self.heading_trig
delta_pitch = self.pitch_trig
base.camera.setHpr(cur_hpr.getX() + delta_heading, cur_hpr.getY() + delta_pitch, 0)
# As its a task, continue with next iteration
return task.cont