Skip to content

Commit 4584d3c

Browse files
committed
Separate Camera and SystemCamera
1 parent 0ad1cd3 commit 4584d3c

File tree

2 files changed

+103
-88
lines changed

2 files changed

+103
-88
lines changed

demosys/scene/camera.py

Lines changed: 102 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,9 @@ def __init__(self, fov=60, aspect=1.0, near=1, far=100):
3535
# Yaw and Pitch
3636
self.yaw = -90.0
3737
self.pitch = 0.0
38-
self.mouse_sensitivity = 0.5
39-
self.last_x = None
40-
self.last_y = None
4138

4239
# World up vector
4340
self._up = Vector3([0.0, 1.0, 0.0])
44-
# Position movement states
45-
self._xdir = STILL
46-
self._zdir = STILL
47-
self._ydir = STILL
48-
self._last_time = 0
49-
# Velocity in axis units per second
50-
self.velocity = 10.0
5141

5242
# Projection attributes
5343
self.projection = None
@@ -67,6 +57,107 @@ def set_position(self, x, y, z):
6757
"""
6858
self.position = Vector3([x, y, z])
6959

60+
@property
61+
def view_matrix(self):
62+
"""
63+
:return: The current view matrix for the camera
64+
"""
65+
self._update_yaw_and_pitch()
66+
return self._gl_look_at(self.position, self.position + self.dir, self._up)
67+
68+
def _update_yaw_and_pitch(self):
69+
"""
70+
Updates the camera vectors based on the current yaw and pitch
71+
"""
72+
front = Vector3([0.0, 0.0, 0.0])
73+
front.x = cos(radians(self.yaw)) * cos(radians(self.pitch))
74+
front.y = sin(radians(self.pitch))
75+
front.z = sin(radians(self.yaw)) * cos(radians(self.pitch))
76+
77+
self.dir = vector.normalise(front)
78+
self.right = vector.normalise(vector3.cross(self.dir, self._up))
79+
self.up = vector.normalise(vector3.cross(self.right, self.dir))
80+
81+
def set_projection(self, fov=None, aspect=None, near=None, far=None):
82+
"""
83+
Update projection parameters and return the new version
84+
85+
:param fov: Field of view
86+
:param aspect: Aspect ratio
87+
:param near: Near plane
88+
:param far: Far plane
89+
:return: Projection matrix
90+
"""
91+
self.fov = fov or self.fov
92+
self.near = near or self.near
93+
self.far = far or self.far
94+
self.aspect = aspect or self.aspect
95+
self.projection = matrix44.create_perspective_projection_matrix(
96+
self.fov, self.aspect, self.near, self.far)
97+
98+
return self.projection
99+
100+
def look_at(self, vec=None, pos=None):
101+
"""
102+
Look at a specific point
103+
104+
:param vec: Vector3 position
105+
:param pos: python list [x, y, x]
106+
:return: Camera matrix
107+
"""
108+
if pos:
109+
vec = Vector3(pos)
110+
if vec is None:
111+
raise ValueError("vector or pos must be set")
112+
return self._gl_look_at(self.position, vec, self._up)
113+
114+
def _gl_look_at(self, pos, target, up):
115+
"""
116+
The standard lookAt method
117+
118+
:param pos: current position
119+
:param target: target position to look at
120+
:param up: direction up
121+
"""
122+
z = vector.normalise(pos - target)
123+
x = vector.normalise(vector3.cross(vector.normalise(up), z))
124+
y = vector3.cross(z, x)
125+
126+
translate = matrix44.create_identity()
127+
translate[3][0] = -pos.x
128+
translate[3][1] = -pos.y
129+
translate[3][2] = -pos.z
130+
131+
rotate = matrix44.create_identity()
132+
rotate[0][0] = x[0] # -- X
133+
rotate[1][0] = x[1]
134+
rotate[2][0] = x[2]
135+
rotate[0][1] = y[0] # -- Y
136+
rotate[1][1] = y[1]
137+
rotate[2][1] = y[2]
138+
rotate[0][2] = z[0] # -- Z
139+
rotate[1][2] = z[1]
140+
rotate[2][2] = z[2]
141+
142+
return matrix44.multiply(translate, rotate)
143+
144+
145+
class SystemCamera(Camera):
146+
"""System camera controlled by mouse and keyboard"""
147+
def __init__(self, fov=60, aspect=1.0, near=1, far=100):
148+
# Position movement states
149+
self._xdir = STILL
150+
self._zdir = STILL
151+
self._ydir = STILL
152+
self._last_time = 0
153+
# Velocity in axis units per second
154+
self.velocity = 10.0
155+
self.mouse_sensitivity = 0.5
156+
self.last_x = None
157+
self.last_y = None
158+
159+
super().__init__(fov=fov, aspect=aspect, near=near, far=far)
160+
70161
def move_state(self, direction, activate):
71162
"""
72163
Set the camera position move state
@@ -116,20 +207,7 @@ def rot_state(self, x, y):
116207
if self.pitch < -85.0:
117208
self.pitch = -85.0
118209

119-
self.update_yaw_and_pitch()
120-
121-
def update_yaw_and_pitch(self):
122-
"""
123-
Updates the camera vectors based on the current yaw and pitch
124-
"""
125-
front = Vector3([0.0, 0.0, 0.0])
126-
front.x = cos(radians(self.yaw)) * cos(radians(self.pitch))
127-
front.y = sin(radians(self.pitch))
128-
front.z = sin(radians(self.yaw)) * cos(radians(self.pitch))
129-
130-
self.dir = vector.normalise(front)
131-
self.right = vector.normalise(vector3.cross(self.dir, self._up))
132-
self.up = vector.normalise(vector3.cross(self.right, self.dir))
210+
self._update_yaw_and_pitch()
133211

134212
@property
135213
def view_matrix(self):
@@ -162,66 +240,3 @@ def view_matrix(self):
162240
self.position -= self.up * self.velocity * t
163241

164242
return self._gl_look_at(self.position, self.position + self.dir, self._up)
165-
166-
def set_projection(self, fov=None, aspect=None, near=None, far=None):
167-
"""
168-
Update projection parameters and return the new version
169-
170-
:param fov: Field of view
171-
:param aspect: Aspect ratio
172-
:param near: Near plane
173-
:param far: Far plane
174-
:return: Projection matrix
175-
"""
176-
self.fov = fov or self.fov
177-
self.near = near or self.near
178-
self.far = far or self.far
179-
self.aspect = aspect or self.aspect
180-
self.projection = matrix44.create_perspective_projection_matrix(
181-
self.fov, self.aspect, self.near, self.far)
182-
return self.projection
183-
184-
def look_at(self, vec=None, pos=None):
185-
"""
186-
Look at a specific point
187-
188-
:param vec: Vector3 position
189-
:param pos: python list [x, y, x]
190-
:return: Camera matrix
191-
"""
192-
if pos:
193-
vec = Vector3(pos)
194-
if vec is None:
195-
raise ValueError("vector or pos must be set")
196-
return self._gl_look_at(self.position, vec, self._up)
197-
198-
def _gl_look_at(self, pos, target, up):
199-
"""
200-
The standard lookAt method
201-
202-
:param pos: current position
203-
:param target: target position to look at
204-
:param up: direction up
205-
"""
206-
z = vector.normalise(pos - target)
207-
x = vector.normalise(vector3.cross(vector.normalise(self._up), z))
208-
y = vector3.cross(z, x)
209-
210-
translate = matrix44.create_identity()
211-
translate[3][0] = -pos.x
212-
translate[3][1] = -pos.y
213-
translate[3][2] = -pos.z
214-
215-
rotate = matrix44.create_identity()
216-
rotate[0][0] = x[0] # -- X
217-
rotate[1][0] = x[1]
218-
rotate[2][0] = x[2]
219-
rotate[0][1] = y[0] # -- Y
220-
rotate[1][1] = y[1]
221-
rotate[2][1] = y[2]
222-
rotate[0][2] = z[0] # -- Z
223-
rotate[1][2] = z[1]
224-
rotate[2][2] = z[2]
225-
226-
# return matrix44.multiply(rotate, translate)
227-
return matrix44.multiply(translate, rotate)

demosys/view/controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def run(manager=None):
4242

4343
# Set up the default system camera
4444
global CAMERA
45-
CAMERA = camera.Camera(aspect=Effect.window_aspect, fov=60.0, near=1, far=1000)
45+
CAMERA = camera.SystemCamera(aspect=Effect.window_aspect, fov=60.0, near=1, far=1000)
4646
Effect.sys_camera = CAMERA
4747

4848
# Initialize Effects

0 commit comments

Comments
 (0)