basilisk-engine 0.1.22__py3-none-any.whl → 0.1.24__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of basilisk-engine might be problematic. Click here for more details.

basilisk/nodes/node.py CHANGED
@@ -97,9 +97,10 @@ class Node():
97
97
 
98
98
  # parents
99
99
  self.node_handler = None
100
- self.scene = None
101
- self.chunk = None
102
- self.parent = None
100
+ self.scene = None
101
+ self.engine = None
102
+ self.chunk = None
103
+ self.parent = None
103
104
 
104
105
  # lazy update variables
105
106
  self.needs_geometric_center = True # pos
@@ -194,18 +195,19 @@ class Node():
194
195
  self.internal_scale.callback = scale_callback
195
196
  self.internal_rotation.callback = rotation_callback
196
197
 
197
- def init_scene(self, scene):
198
+ def init_scene(self, scene: ...) -> None:
198
199
  """
199
200
  Updates the scene of the node
200
201
  """
201
202
  self.scene = scene
203
+ self.engine = scene.engine
202
204
  self.node_handler = scene.node_handler
203
205
 
204
206
  # Update materials
205
207
  self.write_materials()
206
208
 
207
209
  # Update the mesh
208
- self.mesh = self.mesh if self.mesh else self.scene.engine.cube
210
+ self.mesh = self.mesh if self.mesh else self.engine.cube
209
211
 
210
212
  # Update physics and collider
211
213
  if self.physics_body: self.physics_body.physics_engine = scene.physics_engine
@@ -387,14 +389,14 @@ class Node():
387
389
  if isinstance(self.material, list):
388
390
  mtl_index_list = []
389
391
  for mtl in self._mtl_list:
390
- self.node_handler.scene.material_handler.add(mtl)
392
+ self.engine.material_handler.add(mtl)
391
393
  mtl_index_list.append(mtl.index)
392
394
  mtl_index_list.append(mtl.index)
393
395
  mtl_index_list.append(mtl.index)
394
396
  self._material = mtl_index_list
395
397
 
396
398
  if isinstance(self.material, type(None)):
397
- self.material = self.scene.material_handler.base
399
+ self.material = self.engine.material_handler.base
398
400
 
399
401
 
400
402
  def __repr__(self) -> str:
@@ -555,16 +557,16 @@ class Node():
555
557
  else:
556
558
  mtl_index_list = []
557
559
  for mtl in self._mtl_list:
558
- self.node_handler.scene.material_handler.add(mtl)
560
+ self.engine.material_handler.add(mtl)
559
561
  mtl_index_list.append(mtl.index)
560
562
  mtl_index_list.append(mtl.index)
561
563
  mtl_index_list.append(mtl.index)
562
564
  self._material = mtl_index_list
563
565
  elif isinstance(value, Material):
564
566
  self._material = value
565
- if self.node_handler: self.node_handler.scene.material_handler.add(value)
567
+ if self.node_handler: self.engine.material_handler.add(value)
566
568
  elif isinstance(value, type(None)):
567
- if self.scene: self._material = self.scene.material_handler.base
569
+ if self.engine: self._material = self.engine.material_handler.base
568
570
  else: self._material = None
569
571
 
570
572
  else: raise TypeError(f'Node: Invalid material value type {type(value)}')
@@ -19,6 +19,7 @@ class NodeHandler():
19
19
  """
20
20
 
21
21
  self.scene = scene
22
+ self.engine = scene.engine
22
23
  self.nodes = []
23
24
  self.chunk_handler = ChunkHandler(scene)
24
25
 
@@ -49,9 +50,9 @@ class NodeHandler():
49
50
  for n in node.get_all(): # gets all nodes including the node to be added
50
51
 
51
52
  # Update scene Handlers
52
- self.scene.shader_handler.add(n.shader)
53
- if not n.material: n.material = self.scene.material_handler.base
54
- self.scene.material_handler.add(n.material)
53
+ self.engine.shader_handler.add(n.shader)
54
+ if not n.material: n.material = self.engine.material_handler.base
55
+ self.engine.material_handler.add(n.material)
55
56
 
56
57
  # Update the node attributes
57
58
  n.init_scene(self.scene)
@@ -43,7 +43,7 @@ class ParticleHandler:
43
43
  # Get material ID
44
44
  if material == None: material_index = 0
45
45
  elif isinstance(material, Material):
46
- self.scene.material_handler.add(material)
46
+ self.scene.engine.material_handler.add(material)
47
47
  material_index = material.index
48
48
  else: raise ValueError(f'particle_handler.add: Invalid particle material type: {type(material)}')
49
49
 
@@ -31,7 +31,7 @@ class ParticleRenderer:
31
31
  root = scene.engine.root
32
32
  if shader: self.shader = shader
33
33
  else: self.shader = Shader(scene.engine, vert=root + '/shaders/particle.vert', frag=root + '/shaders/particle.frag')
34
- scene.shader_handler.add(self.shader)
34
+ scene.engine.shader_handler.add(self.shader)
35
35
 
36
36
  self.particle_cube_size = 25
37
37
 
basilisk/render/camera.py CHANGED
@@ -12,7 +12,7 @@ FAR = 350
12
12
 
13
13
  # Camera movement constants
14
14
  SPEED = 10
15
- SENSITIVITY = 0.15
15
+ SENSITIVITY = 0.15/180
16
16
 
17
17
  class Camera:
18
18
  engine: ...
@@ -24,7 +24,7 @@ class Camera:
24
24
  position: glm.vec3
25
25
  """Location of the camera (maters)"""
26
26
 
27
- def __init__(self, position=(0, 0, 20), yaw=-90, pitch=0) -> None:
27
+ def __init__(self, position=(0, 0, 20), rotation=(1, 0, 0, 0)) -> None:
28
28
  """
29
29
  Camera object to get view and projection matricies. Movement built in
30
30
  """
@@ -32,21 +32,13 @@ class Camera:
32
32
  # Back references
33
33
  self.scene = None
34
34
  self.engine = None
35
+ # transformations
36
+ self.rotation = glm.quat(rotation)
37
+ self.position = glm.vec3(position)
35
38
  # fov
36
39
  self.fov = 50
37
40
  # The initial aspect ratio of the screen
38
41
  self.aspect_ratio = 1.0
39
- # Position
40
- self.position = glm.vec3(position)
41
- # k vector for vertical movement
42
- self.UP = glm.vec3(0, 1, 0)
43
- # Movement vectors
44
- self.up = glm.vec3(0, 1, 0)
45
- self.right = glm.vec3(1, 0, 0)
46
- self.forward = glm.vec3(0, 0, -1)
47
- # Look directions in degrees
48
- self.yaw = yaw
49
- self.pitch = pitch
50
42
  # View matrix
51
43
  self.m_view = self.get_view_matrix()
52
44
  # Projection matrix
@@ -57,23 +49,9 @@ class Camera:
57
49
  Updates the camera view matrix
58
50
  """
59
51
 
60
- self.update_camera_vectors()
52
+ # self.update_camera_vectors()
61
53
  self.m_view = self.get_view_matrix()
62
54
 
63
- def update_camera_vectors(self) -> None:
64
- """
65
- Computes the forward vector based on the pitch and yaw. Computes horizontal and vertical vectors with cross product.
66
- """
67
- yaw, pitch = glm.radians(self.yaw), glm.radians(self.pitch)
68
-
69
- self.forward.x = glm.cos(yaw) * glm.cos(pitch)
70
- self.forward.y = glm.sin(pitch)
71
- self.forward.z = glm.sin(yaw) * glm.cos(pitch)
72
-
73
- self.forward = glm.normalize(self.forward)
74
- self.right = glm.normalize(glm.cross(self.forward, self.UP))
75
- self.up = glm.normalize(glm.cross(self.right, self.forward))
76
-
77
55
  def use(self):
78
56
  # Updated aspect ratio of the screen
79
57
  self.aspect_ratio = self.engine.win_size[0] / self.engine.win_size[1]
@@ -104,11 +82,28 @@ class Camera:
104
82
  @property
105
83
  def position(self): return self._position
106
84
  @property
107
- def direction(self): return self.forward
85
+ def rotation(self) -> glm.quat: return self._rotation
86
+ @property
87
+ def direction(self): return self.rotation * (0, 0, -1)
88
+ @property
89
+ def forward(self): return self.rotation * (0, 0, -1)
90
+ @property
91
+ def pitch(self): return glm.pitch(self.rotation)
92
+ @property
93
+ def yaw(self): return glm.yaw(self.rotation)
94
+ @property
95
+ def roll(self): return glm.roll(self.rotation)
108
96
  @property
109
- def horizontal(self): return glm.normalize(self.forward.xz)
97
+ def UP(self):
98
+ up = (self.rotation.x, self.rotation.y, self.rotation.z)
99
+ up = (0, 1, 0) # TODO ensure that this works with all up vectors
100
+ return glm.normalize(up) if glm.length2(up) > 1e-7 else glm.vec3(0, 1, 0)
110
101
  @property
111
- def rotation(self): return glm.conjugate(glm.quatLookAt(self.forward, self.UP))
102
+ def right(self): return glm.normalize(glm.cross(self.forward, self.UP))
103
+ @property
104
+ def up(self): return glm.normalize(glm.cross(self.right, self.forward))
105
+ @property
106
+ def horizontal(self): return glm.normalize(glm.cross(self.UP, self.right))
112
107
  @property
113
108
  def fov(self): return self._fov
114
109
 
@@ -128,15 +123,48 @@ class Camera:
128
123
  self._position = glm.vec3(value)
129
124
  else: raise TypeError(f'Camera: Invalid position value type {type(value)}')
130
125
 
126
+ @rotation.setter
127
+ def rotation(self, value):
128
+ if isinstance(value, (glm.vec3, glm.quat)): self._rotation = glm.quat(value)
129
+ elif isinstance(value, (Vec3, Quat)): self._rotation = glm.quat(value.data)
130
+ elif isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
131
+ if not (2 < len(value) < 5): raise ValueError(f'Camera: Invalid number of values for rotation. Expected 3 or 4, got {len(value)}')
132
+ self._position = glm.quat(value)
133
+ else:
134
+ try:
135
+ self._rotation = glm.quat(value)
136
+ except:
137
+ raise TypeError(f'Camera: Invalid rotation value type {type(value)}')
138
+
131
139
  @direction.setter
132
140
  def direction(self, value: tuple | list | glm.vec3 | np.ndarray | Vec3):
133
- if isinstance(value, glm.vec3): self.forward = glm.normalize(glm.vec3(value))
141
+ if isinstance(value, glm.vec3): self.forward = glm.normalize(value)
134
142
  elif isinstance(value, Vec3): self.forward = glm.normalize(value.data)
135
143
  elif isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
136
144
  if len(value) != 3: raise ValueError(f'Camera: Invalid number of values for direction. Expected 3, got {len(value)}')
137
- self.forward = glm.normalize(glm.vec3(value))
145
+ self.forward = glm.normalize(value)
138
146
  else: raise TypeError(f'Camera: Invalid direction value type {type(value)}')
139
147
 
148
+ @forward.setter
149
+ def forward(self, value):
150
+ self._rotation = glm.quatLookAt(value, self.UP)
151
+
152
+ @pitch.setter
153
+ def pitch(self, value):
154
+ self._rotation = glm.quat((value, self.yaw, self.roll))
155
+
156
+ @yaw.setter
157
+ def yaw(self, value):
158
+ self._rotation = glm.quat((self.pitch, value, self.roll))
159
+
160
+ @roll.setter
161
+ def roll(self, value):
162
+ self._rotation = glm.quat((self.pitch, self.yaw, value))
163
+
164
+ @UP.setter
165
+ def UP(self, value):
166
+ self._rotation = glm.quatLookAt(self.forward, value)
167
+
140
168
  @fov.setter
141
169
  def fov(self, value):
142
170
  self._fov = value
@@ -144,8 +172,8 @@ class Camera:
144
172
 
145
173
 
146
174
  class FreeCamera(Camera):
147
- def __init__(self, position=(0, 0, 20), yaw=-90, pitch=0):
148
- super().__init__(position, yaw, pitch)
175
+ def __init__(self, position=(0, 0, 20), rotation=(1, 0, 0, 0)):
176
+ super().__init__(position, rotation)
149
177
 
150
178
  def update(self) -> None:
151
179
  """
@@ -154,18 +182,22 @@ class FreeCamera(Camera):
154
182
 
155
183
  self.move()
156
184
  self.rotate()
157
- self.update_camera_vectors()
185
+ # self.update_camera_vectors()
158
186
  self.m_view = self.get_view_matrix()
159
187
 
160
188
  def rotate(self) -> None:
161
189
  """
162
190
  Rotates the camera based on the amount of mouse movement.
163
191
  """
164
- rel_x, rel_y = pg.mouse.get_rel()
165
- self.yaw += rel_x * SENSITIVITY
166
- self.pitch -= rel_y * SENSITIVITY
167
- self.yaw = self.yaw % 360
168
- self.pitch = max(-89, min(89, self.pitch))
192
+ rel_x, rel_y = self.engine.mouse.relative
193
+
194
+ yaw_rotation = glm.angleAxis(SENSITIVITY * rel_x, -self.UP)
195
+ pitch_rotation = glm.angleAxis(SENSITIVITY * rel_y, -self.right)
196
+ new_rotation = yaw_rotation * pitch_rotation * self.rotation
197
+
198
+ v_new = new_rotation * self.UP
199
+ pitch_angle = glm.degrees(glm.acos(glm.clamp(glm.dot(v_new, self.UP), -1.0, 1.0)))
200
+ self.rotation = new_rotation if pitch_angle < 89 else yaw_rotation * self.rotation
169
201
 
170
202
  def move(self) -> None:
171
203
  """
@@ -185,11 +217,16 @@ class FreeCamera(Camera):
185
217
  self.position += self.UP * velocity
186
218
  if keys[pg.K_LSHIFT]:
187
219
  self.position -= self.UP * velocity
220
+
221
+ class FixedCamera(FreeCamera):
222
+ def __init__(self, position=(0, 0, 20), rotation=(1, 0, 0, 0)):
223
+ super().__init__(position, rotation)
188
224
 
225
+ def move(self): pass
189
226
 
190
227
  class FollowCamera(FreeCamera):
191
- def __init__(self, parent, position=(0, 0, 20), yaw=-90, pitch=0, offset=(0, 0, 0)):
192
- super().__init__(position, yaw, pitch)
228
+ def __init__(self, parent, position=(0, 0, 20), rotation=(1, 0, 0, 0), offset=(0, 0, 0)):
229
+ super().__init__(position, rotation)
193
230
  self.parent = parent
194
231
  self.offest = glm.vec3(offset)
195
232
 
@@ -201,11 +238,11 @@ class FollowCamera(FreeCamera):
201
238
  self.position = self.parent.position + self.offest
202
239
 
203
240
  class OrbitCamera(FreeCamera):
204
- def __init__(self, parent, position=(0, 0, 20), yaw=-90, pitch=0, distance=5, offset=(0, 0)):
241
+ def __init__(self, parent, position=(0, 0, 20), rotation=(1, 0, 0, 0), distance=5, offset=(0, 0)):
205
242
  self.parent = parent
206
243
  self.distance = distance
207
244
  self.offset = glm.vec2(offset)
208
- super().__init__(position, yaw, pitch)
245
+ super().__init__(position, rotation)
209
246
 
210
247
  def get_view_matrix(self) -> glm.mat4x4:
211
248
  return glm.lookAt(self.position, self.parent.position, self.up)
@@ -214,9 +251,8 @@ class OrbitCamera(FreeCamera):
214
251
  """
215
252
  Moves the camera to the parent node
216
253
  """
217
-
218
254
  self.position = self.parent.position - glm.normalize(self.forward) * self.distance
219
255
 
220
256
  class StaticCamera(Camera):
221
- def __init__(self, position=(0, 0, 20), yaw=-90, pitch=0):
222
- super().__init__(position, yaw, pitch)
257
+ def __init__(self, position=(0, 0, 20), rotation=(1, 0, 0, 0)):
258
+ super().__init__(position, rotation)
basilisk/render/frame.py CHANGED
@@ -11,26 +11,22 @@ class Frame:
11
11
  vao: mgl.VertexArray=None
12
12
  framebuffer: mgl.Framebuffer=None
13
13
 
14
- def __init__(self, scene, resolution=1, filter=(mgl.LINEAR, mgl.LINEAR)) -> None:
14
+ def __init__(self, engine, scale: float=1.0, linear_filter: bool=False) -> None:
15
15
  """
16
16
  Basilisk render destination.
17
17
  Can be used to render to the screen or for headless rendering
18
18
  """
19
19
 
20
- self.scene = scene
21
- self.engine = scene.engine
22
- self.ctx = scene.ctx
20
+ self.engine = engine
21
+ self.ctx = engine.ctx
23
22
 
24
23
  # Load framebuffer
25
- self.resolution = resolution
26
- self.filter = filter
27
- size = tuple(map(lambda x: int(x * self.resolution), self.engine.win_size))
28
- self.framebuffer = Framebuffer(self.engine, size=size, filter=self.filter)
29
- self.ping_pong_buffer = Framebuffer(self.engine, size=size, filter=self.filter)
24
+ self.framebuffer = Framebuffer(self.engine, scale=scale, linear_filter=linear_filter)
25
+ self.ping_pong_buffer = Framebuffer(self.engine, scale=scale, linear_filter=linear_filter)
30
26
 
31
27
  # Load Shaders
32
28
  self.shader = Shader(self.engine, self.engine.root + '/shaders/frame.vert', self.engine.root + '/shaders/frame.frag')
33
- self.scene.shader_handler.add(self.shader)
29
+ self.engine.shader_handler.add(self.shader)
34
30
 
35
31
  # Load VAO
36
32
  self.vbo = self.ctx.buffer(np.array([[-1, -1, 0, 0, 0], [1, -1, 0, 1, 0], [1, 1, 0, 1, 1], [-1, 1, 0, 0, 1], [-1, -1, 0, 0, 0], [1, 1, 0, 1, 1]], dtype='f4'))
@@ -64,7 +60,6 @@ class Frame:
64
60
  """
65
61
 
66
62
  self.framebuffer.use()
67
- self.clear()
68
63
 
69
64
  def add_post_process(self, post_process: PostProcess) -> PostProcess:
70
65
  """
@@ -89,9 +84,8 @@ class Frame:
89
84
  Resize the frame to the given size. None for window size
90
85
  """
91
86
 
92
- size = tuple(map(lambda x: int(x * self.resolution), self.engine.win_size))
93
- self.framebuffer.resize(size)
94
- self.ping_pong_buffer.resize(size)
87
+ self.framebuffer.resize()
88
+ self.ping_pong_buffer.resize()
95
89
 
96
90
  def __del__(self) -> None:
97
91
  """