basilisk-engine 0.1.21__py3-none-any.whl → 0.1.23__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/__init__.py +15 -15
- basilisk/audio/sound.py +27 -27
- basilisk/bsk_assets/cube.obj +48 -48
- basilisk/collisions/broad/broad_aabb.py +102 -102
- basilisk/collisions/broad/broad_bvh.py +137 -137
- basilisk/collisions/collider.py +95 -95
- basilisk/collisions/collider_handler.py +224 -224
- basilisk/collisions/narrow/contact_manifold.py +95 -95
- basilisk/collisions/narrow/dataclasses.py +34 -34
- basilisk/collisions/narrow/deprecated.py +46 -46
- basilisk/collisions/narrow/epa.py +91 -91
- basilisk/collisions/narrow/gjk.py +66 -66
- basilisk/collisions/narrow/graham_scan.py +24 -24
- basilisk/collisions/narrow/helper.py +29 -29
- basilisk/collisions/narrow/line_intersections.py +106 -106
- basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
- basilisk/config.py +4 -3
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +175 -179
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +165 -213
- basilisk/generic/abstract_bvh.py +15 -15
- basilisk/generic/abstract_custom.py +133 -133
- basilisk/generic/collisions.py +72 -72
- basilisk/generic/input_validation.py +66 -66
- basilisk/generic/math.py +6 -6
- basilisk/generic/matrices.py +35 -35
- basilisk/generic/meshes.py +72 -72
- basilisk/generic/quat.py +142 -142
- basilisk/generic/quat_methods.py +7 -7
- basilisk/generic/raycast_result.py +26 -26
- basilisk/generic/vec3.py +143 -143
- basilisk/input/mouse.py +61 -61
- basilisk/input/path.py +14 -14
- basilisk/input_output/IO_handler.py +93 -0
- basilisk/input_output/__init__.py +0 -0
- basilisk/input_output/clock.py +50 -0
- basilisk/input_output/keys.py +44 -0
- basilisk/input_output/mouse.py +62 -0
- basilisk/input_output/path.py +14 -0
- basilisk/mesh/cube.py +33 -33
- basilisk/mesh/mesh.py +230 -230
- basilisk/mesh/mesh_from_data.py +130 -130
- basilisk/mesh/model.py +271 -271
- basilisk/mesh/narrow_aabb.py +89 -89
- basilisk/mesh/narrow_bvh.py +91 -91
- basilisk/mesh/narrow_primative.py +23 -23
- basilisk/nodes/helper.py +28 -28
- basilisk/nodes/node.py +686 -684
- basilisk/nodes/node_handler.py +97 -96
- basilisk/particles/particle_handler.py +64 -64
- basilisk/particles/particle_renderer.py +92 -92
- basilisk/physics/impulse.py +112 -112
- basilisk/physics/physics_body.py +43 -43
- basilisk/physics/physics_engine.py +35 -35
- basilisk/render/batch.py +105 -105
- basilisk/render/camera.py +267 -222
- basilisk/render/chunk.py +106 -106
- basilisk/render/chunk_handler.py +165 -165
- basilisk/render/frame.py +99 -101
- basilisk/render/framebuffer.py +131 -130
- basilisk/render/image.py +87 -87
- basilisk/render/image_handler.py +120 -122
- basilisk/render/light.py +96 -96
- basilisk/render/light_handler.py +58 -58
- basilisk/render/material.py +219 -219
- basilisk/render/material_handler.py +131 -135
- basilisk/render/post_process.py +139 -139
- basilisk/render/shader.py +109 -110
- basilisk/render/shader_handler.py +83 -80
- basilisk/render/sky.py +120 -120
- basilisk/scene.py +279 -276
- basilisk/shaders/batch.frag +276 -276
- basilisk/shaders/batch.vert +115 -115
- basilisk/shaders/crt.frag +31 -31
- basilisk/shaders/draw.frag +22 -22
- basilisk/shaders/draw.vert +25 -25
- basilisk/shaders/filter.frag +22 -22
- basilisk/shaders/frame.frag +12 -12
- basilisk/shaders/frame.vert +13 -13
- basilisk/shaders/geometry.frag +8 -8
- basilisk/shaders/geometry.vert +41 -41
- basilisk/shaders/normal.frag +59 -59
- basilisk/shaders/normal.vert +96 -96
- basilisk/shaders/particle.frag +71 -71
- basilisk/shaders/particle.vert +84 -84
- basilisk/shaders/sky.frag +9 -9
- basilisk/shaders/sky.vert +13 -13
- {basilisk_engine-0.1.21.dist-info → basilisk_engine-0.1.23.dist-info}/METADATA +45 -38
- basilisk_engine-0.1.23.dist-info/RECORD +109 -0
- {basilisk_engine-0.1.21.dist-info → basilisk_engine-0.1.23.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.21.dist-info/RECORD +0 -103
- {basilisk_engine-0.1.21.dist-info → basilisk_engine-0.1.23.dist-info}/top_level.txt +0 -0
basilisk/generic/vec3.py
CHANGED
|
@@ -1,144 +1,144 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
import numpy as np
|
|
3
|
-
from .abstract_custom import Custom
|
|
4
|
-
|
|
5
|
-
class Vec3(Custom):
|
|
6
|
-
def __init__(self, *args, callback=None):
|
|
7
|
-
self.callback = callback
|
|
8
|
-
self.prev_data = glm.vec3(0.0)
|
|
9
|
-
|
|
10
|
-
if len(args) == 1:
|
|
11
|
-
|
|
12
|
-
if isinstance(args[0], Vec3):
|
|
13
|
-
self.data = glm.vec3(args[0].data)
|
|
14
|
-
self.prev_data = glm.vec3(args[0].prev_data)
|
|
15
|
-
self.callback = args[0].callback
|
|
16
|
-
|
|
17
|
-
elif isinstance(args[0], glm.vec3):
|
|
18
|
-
self.data = args[0]
|
|
19
|
-
|
|
20
|
-
elif isinstance(args[0], tuple) or isinstance(args[0], list) or isinstance(args[0], np.ndarray):
|
|
21
|
-
assert len(args[0]) == 3, f'Vec3: Expected 3 values from incoming vector, got {len(args[0])}'
|
|
22
|
-
self.data = glm.vec3(args[0])
|
|
23
|
-
|
|
24
|
-
else:
|
|
25
|
-
try: self.data = glm.vec3(args[0])
|
|
26
|
-
except: raise ValueError(f'Vec3: Unexpected incoming vector type {args[0]}')
|
|
27
|
-
|
|
28
|
-
elif len(args) == 3: self.data = glm.vec3(*args)
|
|
29
|
-
else: raise ValueError(f'Vec3: Expected either 1 vector or 3 numbers, got {len(args)} values')
|
|
30
|
-
|
|
31
|
-
def apply_function(self, other, func, func_name):
|
|
32
|
-
vec = glm.vec3(self.data)
|
|
33
|
-
|
|
34
|
-
if isinstance(other, (glm.vec3, glm.quat)):
|
|
35
|
-
vec = func(vec, other)
|
|
36
|
-
|
|
37
|
-
elif isinstance(other, tuple) or isinstance(other, list) or isinstance(other, np.ndarray):
|
|
38
|
-
assert len(other) == 3, f'Vec3: Number of added values must be 3, got {len(other)}'
|
|
39
|
-
vec = func(vec, other)
|
|
40
|
-
|
|
41
|
-
elif isinstance(other, Custom): # perserve self.callback over other.callback. this should never be done by the user
|
|
42
|
-
vec = func(vec, other.data)
|
|
43
|
-
|
|
44
|
-
else:
|
|
45
|
-
try: vec = func(vec, other)
|
|
46
|
-
except: raise ValueError(f'Vec3: Not an accepted type for {func_name}, got {type(other)}')
|
|
47
|
-
return Vec3(vec)
|
|
48
|
-
|
|
49
|
-
# unary operators
|
|
50
|
-
def __neg__(self):
|
|
51
|
-
return Vec3(-self.data, callback=self.callback)
|
|
52
|
-
|
|
53
|
-
def __abs__(self):
|
|
54
|
-
return Vec3(abs(self.data), callback=self.callback)
|
|
55
|
-
|
|
56
|
-
# accessor functions
|
|
57
|
-
def __getitem__(self, index):
|
|
58
|
-
assert int(index) == index, f'Vec3: index must be an int, got {type(index)}' # check if index is a float
|
|
59
|
-
assert 0 <= index <= 2, f'Vec3: index out of bounds, got {index}'
|
|
60
|
-
return self.data[index]
|
|
61
|
-
|
|
62
|
-
def __setitem__(self, index, value):
|
|
63
|
-
assert int(index) == index, f'Vec3: index must be an int, got {type(index)}' # check if index is a float
|
|
64
|
-
assert 0 <= index <= 2, f'Vec3: index out of bounds, got {index}'
|
|
65
|
-
try: self.data[index] = value
|
|
66
|
-
except: raise ValueError(f'Vec3: Invalid element type, got {type(value)}')
|
|
67
|
-
|
|
68
|
-
def __delitem__(self, index): # index in a vec cannot be deleted, so we default to zero
|
|
69
|
-
assert int(index) == index, f'Vec3: index must be an int, got {type(index)}' # check if index is a float
|
|
70
|
-
assert 0 <= index <= 2, f'Vec3: index out of bounds, got {index}'
|
|
71
|
-
self.data[index] = 0
|
|
72
|
-
|
|
73
|
-
def __len__(self):
|
|
74
|
-
return 3
|
|
75
|
-
|
|
76
|
-
def __iter__(self):
|
|
77
|
-
return iter(self.data)
|
|
78
|
-
|
|
79
|
-
def __contains__(self, item):
|
|
80
|
-
return item in self.data
|
|
81
|
-
|
|
82
|
-
# override str operators
|
|
83
|
-
def __repr__(self):
|
|
84
|
-
return 'bsk ' + str(self.data)
|
|
85
|
-
|
|
86
|
-
def __str__(self):
|
|
87
|
-
return 'bsk ' + str(self.data)
|
|
88
|
-
|
|
89
|
-
@property
|
|
90
|
-
def data(self): return self._data
|
|
91
|
-
@property
|
|
92
|
-
def x(self): return self.data.x
|
|
93
|
-
@property
|
|
94
|
-
def y(self): return self.data.y
|
|
95
|
-
@property
|
|
96
|
-
def z(self): return self.data.z
|
|
97
|
-
|
|
98
|
-
@data.setter
|
|
99
|
-
def data(self, value: glm.vec3):
|
|
100
|
-
self._data = glm.vec3(value)
|
|
101
|
-
cur = self._data
|
|
102
|
-
prev = self.prev_data
|
|
103
|
-
thresh = 1e-6
|
|
104
|
-
|
|
105
|
-
if self.callback and (abs(cur.x - prev.x) > thresh or abs(cur.y - prev.y) > thresh or abs(cur.z - prev.z) > thresh):
|
|
106
|
-
self.prev_data = glm.vec3(self._data)
|
|
107
|
-
self.callback()
|
|
108
|
-
|
|
109
|
-
@x.setter
|
|
110
|
-
def x(self, value):
|
|
111
|
-
self._data.x = value
|
|
112
|
-
if self.callback and abs(value - self.prev_data.x) > 1e-6:
|
|
113
|
-
self.prev_data.x = value
|
|
114
|
-
self.callback()
|
|
115
|
-
|
|
116
|
-
@y.setter
|
|
117
|
-
def y(self, value):
|
|
118
|
-
self._data.y = value
|
|
119
|
-
if self.callback and abs(value - self.prev_data.y) > 1e-6:
|
|
120
|
-
self.prev_data.y = value
|
|
121
|
-
self.callback()
|
|
122
|
-
|
|
123
|
-
@z.setter
|
|
124
|
-
def z(self, value):
|
|
125
|
-
self._data.z = value
|
|
126
|
-
if self.callback and abs(value - self.prev_data.z) > 1e-6:
|
|
127
|
-
self.prev_data.z = value
|
|
128
|
-
self.callback()
|
|
129
|
-
|
|
130
|
-
class Node():
|
|
131
|
-
|
|
132
|
-
def __init__(self, pos):
|
|
133
|
-
|
|
134
|
-
def callback(): print('calling back')
|
|
135
|
-
self.pos_callback = callback
|
|
136
|
-
self._pos = Vec3(pos, callback=self.pos_callback)
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def pos(self): return self._pos
|
|
140
|
-
|
|
141
|
-
@pos.setter
|
|
142
|
-
def pos(self, value):
|
|
143
|
-
if isinstance(value, Vec3): self._pos.data = value.data
|
|
1
|
+
import glm
|
|
2
|
+
import numpy as np
|
|
3
|
+
from .abstract_custom import Custom
|
|
4
|
+
|
|
5
|
+
class Vec3(Custom):
|
|
6
|
+
def __init__(self, *args, callback=None):
|
|
7
|
+
self.callback = callback
|
|
8
|
+
self.prev_data = glm.vec3(0.0)
|
|
9
|
+
|
|
10
|
+
if len(args) == 1:
|
|
11
|
+
|
|
12
|
+
if isinstance(args[0], Vec3):
|
|
13
|
+
self.data = glm.vec3(args[0].data)
|
|
14
|
+
self.prev_data = glm.vec3(args[0].prev_data)
|
|
15
|
+
self.callback = args[0].callback
|
|
16
|
+
|
|
17
|
+
elif isinstance(args[0], glm.vec3):
|
|
18
|
+
self.data = args[0]
|
|
19
|
+
|
|
20
|
+
elif isinstance(args[0], tuple) or isinstance(args[0], list) or isinstance(args[0], np.ndarray):
|
|
21
|
+
assert len(args[0]) == 3, f'Vec3: Expected 3 values from incoming vector, got {len(args[0])}'
|
|
22
|
+
self.data = glm.vec3(args[0])
|
|
23
|
+
|
|
24
|
+
else:
|
|
25
|
+
try: self.data = glm.vec3(args[0])
|
|
26
|
+
except: raise ValueError(f'Vec3: Unexpected incoming vector type {args[0]}')
|
|
27
|
+
|
|
28
|
+
elif len(args) == 3: self.data = glm.vec3(*args)
|
|
29
|
+
else: raise ValueError(f'Vec3: Expected either 1 vector or 3 numbers, got {len(args)} values')
|
|
30
|
+
|
|
31
|
+
def apply_function(self, other, func, func_name):
|
|
32
|
+
vec = glm.vec3(self.data)
|
|
33
|
+
|
|
34
|
+
if isinstance(other, (glm.vec3, glm.quat)):
|
|
35
|
+
vec = func(vec, other)
|
|
36
|
+
|
|
37
|
+
elif isinstance(other, tuple) or isinstance(other, list) or isinstance(other, np.ndarray):
|
|
38
|
+
assert len(other) == 3, f'Vec3: Number of added values must be 3, got {len(other)}'
|
|
39
|
+
vec = func(vec, other)
|
|
40
|
+
|
|
41
|
+
elif isinstance(other, Custom): # perserve self.callback over other.callback. this should never be done by the user
|
|
42
|
+
vec = func(vec, other.data)
|
|
43
|
+
|
|
44
|
+
else:
|
|
45
|
+
try: vec = func(vec, other)
|
|
46
|
+
except: raise ValueError(f'Vec3: Not an accepted type for {func_name}, got {type(other)}')
|
|
47
|
+
return Vec3(vec)
|
|
48
|
+
|
|
49
|
+
# unary operators
|
|
50
|
+
def __neg__(self):
|
|
51
|
+
return Vec3(-self.data, callback=self.callback)
|
|
52
|
+
|
|
53
|
+
def __abs__(self):
|
|
54
|
+
return Vec3(abs(self.data), callback=self.callback)
|
|
55
|
+
|
|
56
|
+
# accessor functions
|
|
57
|
+
def __getitem__(self, index):
|
|
58
|
+
assert int(index) == index, f'Vec3: index must be an int, got {type(index)}' # check if index is a float
|
|
59
|
+
assert 0 <= index <= 2, f'Vec3: index out of bounds, got {index}'
|
|
60
|
+
return self.data[index]
|
|
61
|
+
|
|
62
|
+
def __setitem__(self, index, value):
|
|
63
|
+
assert int(index) == index, f'Vec3: index must be an int, got {type(index)}' # check if index is a float
|
|
64
|
+
assert 0 <= index <= 2, f'Vec3: index out of bounds, got {index}'
|
|
65
|
+
try: self.data[index] = value
|
|
66
|
+
except: raise ValueError(f'Vec3: Invalid element type, got {type(value)}')
|
|
67
|
+
|
|
68
|
+
def __delitem__(self, index): # index in a vec cannot be deleted, so we default to zero
|
|
69
|
+
assert int(index) == index, f'Vec3: index must be an int, got {type(index)}' # check if index is a float
|
|
70
|
+
assert 0 <= index <= 2, f'Vec3: index out of bounds, got {index}'
|
|
71
|
+
self.data[index] = 0
|
|
72
|
+
|
|
73
|
+
def __len__(self):
|
|
74
|
+
return 3
|
|
75
|
+
|
|
76
|
+
def __iter__(self):
|
|
77
|
+
return iter(self.data)
|
|
78
|
+
|
|
79
|
+
def __contains__(self, item):
|
|
80
|
+
return item in self.data
|
|
81
|
+
|
|
82
|
+
# override str operators
|
|
83
|
+
def __repr__(self):
|
|
84
|
+
return 'bsk ' + str(self.data)
|
|
85
|
+
|
|
86
|
+
def __str__(self):
|
|
87
|
+
return 'bsk ' + str(self.data)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def data(self): return self._data
|
|
91
|
+
@property
|
|
92
|
+
def x(self): return self.data.x
|
|
93
|
+
@property
|
|
94
|
+
def y(self): return self.data.y
|
|
95
|
+
@property
|
|
96
|
+
def z(self): return self.data.z
|
|
97
|
+
|
|
98
|
+
@data.setter
|
|
99
|
+
def data(self, value: glm.vec3):
|
|
100
|
+
self._data = glm.vec3(value)
|
|
101
|
+
cur = self._data
|
|
102
|
+
prev = self.prev_data
|
|
103
|
+
thresh = 1e-6
|
|
104
|
+
|
|
105
|
+
if self.callback and (abs(cur.x - prev.x) > thresh or abs(cur.y - prev.y) > thresh or abs(cur.z - prev.z) > thresh):
|
|
106
|
+
self.prev_data = glm.vec3(self._data)
|
|
107
|
+
self.callback()
|
|
108
|
+
|
|
109
|
+
@x.setter
|
|
110
|
+
def x(self, value):
|
|
111
|
+
self._data.x = value
|
|
112
|
+
if self.callback and abs(value - self.prev_data.x) > 1e-6:
|
|
113
|
+
self.prev_data.x = value
|
|
114
|
+
self.callback()
|
|
115
|
+
|
|
116
|
+
@y.setter
|
|
117
|
+
def y(self, value):
|
|
118
|
+
self._data.y = value
|
|
119
|
+
if self.callback and abs(value - self.prev_data.y) > 1e-6:
|
|
120
|
+
self.prev_data.y = value
|
|
121
|
+
self.callback()
|
|
122
|
+
|
|
123
|
+
@z.setter
|
|
124
|
+
def z(self, value):
|
|
125
|
+
self._data.z = value
|
|
126
|
+
if self.callback and abs(value - self.prev_data.z) > 1e-6:
|
|
127
|
+
self.prev_data.z = value
|
|
128
|
+
self.callback()
|
|
129
|
+
|
|
130
|
+
class Node():
|
|
131
|
+
|
|
132
|
+
def __init__(self, pos):
|
|
133
|
+
|
|
134
|
+
def callback(): print('calling back')
|
|
135
|
+
self.pos_callback = callback
|
|
136
|
+
self._pos = Vec3(pos, callback=self.pos_callback)
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def pos(self): return self._pos
|
|
140
|
+
|
|
141
|
+
@pos.setter
|
|
142
|
+
def pos(self, value):
|
|
143
|
+
if isinstance(value, Vec3): self._pos.data = value.data
|
|
144
144
|
else: self._pos.data = value
|
basilisk/input/mouse.py
CHANGED
|
@@ -1,62 +1,62 @@
|
|
|
1
|
-
import pygame as pg
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
class Mouse():
|
|
5
|
-
def __init__(self, grab=True):
|
|
6
|
-
self.x, self.y = pg.mouse.get_pos()
|
|
7
|
-
self.buttons = pg.mouse.get_pressed()
|
|
8
|
-
self.previous_buttons = pg.mouse.get_pressed()
|
|
9
|
-
self.grab = grab
|
|
10
|
-
|
|
11
|
-
def update(self, events):
|
|
12
|
-
"""
|
|
13
|
-
Updates all mouse state variables.
|
|
14
|
-
Checks for mouse-related events.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
self.x, self.y = pg.mouse.get_pos()
|
|
18
|
-
self.previous_buttons = self.buttons
|
|
19
|
-
self.buttons = pg.mouse.get_pressed()
|
|
20
|
-
|
|
21
|
-
for event in events:
|
|
22
|
-
if event.type == pg.KEYUP:
|
|
23
|
-
if event.key == pg.K_ESCAPE and self.grab:
|
|
24
|
-
# Unlock mouse
|
|
25
|
-
pg.event.set_grab(False)
|
|
26
|
-
pg.mouse.set_visible(True)
|
|
27
|
-
if event.type == pg.MOUSEBUTTONUP and self.grab:
|
|
28
|
-
# Lock mouse
|
|
29
|
-
pg.event.set_grab(True)
|
|
30
|
-
pg.mouse.set_visible(False)
|
|
31
|
-
|
|
32
|
-
def set_pos(self, x, y):
|
|
33
|
-
"""Set the mouse position"""
|
|
34
|
-
pg.mouse.set_pos(x, y)
|
|
35
|
-
|
|
36
|
-
@property
|
|
37
|
-
def click(self): return self.buttons[0] and not self.previous_buttons[0]
|
|
38
|
-
@property
|
|
39
|
-
def left_click(self): return self.buttons[0] and not self.previous_buttons[0]
|
|
40
|
-
@property
|
|
41
|
-
def middle_click(self): return self.buttons[1] and not self.previous_buttons[1]
|
|
42
|
-
@property
|
|
43
|
-
def right_click(self): return self.buttons[2] and not self.previous_buttons[2]
|
|
44
|
-
@property
|
|
45
|
-
def left_down(self): return self.buttons[0]
|
|
46
|
-
@property
|
|
47
|
-
def middle_down(self): return self.buttons[1]
|
|
48
|
-
@property
|
|
49
|
-
def right_down(self): return self.buttons[2]
|
|
50
|
-
|
|
51
|
-
@property
|
|
52
|
-
def grab(self): return self._grab
|
|
53
|
-
|
|
54
|
-
@grab.setter
|
|
55
|
-
def grab(self, value):
|
|
56
|
-
self._grab = value
|
|
57
|
-
if self._grab:
|
|
58
|
-
pg.event.set_grab(True)
|
|
59
|
-
pg.mouse.set_visible(False)
|
|
60
|
-
else:
|
|
61
|
-
pg.event.set_grab(False)
|
|
1
|
+
import pygame as pg
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Mouse():
|
|
5
|
+
def __init__(self, grab=True):
|
|
6
|
+
self.x, self.y = pg.mouse.get_pos()
|
|
7
|
+
self.buttons = pg.mouse.get_pressed()
|
|
8
|
+
self.previous_buttons = pg.mouse.get_pressed()
|
|
9
|
+
self.grab = grab
|
|
10
|
+
|
|
11
|
+
def update(self, events):
|
|
12
|
+
"""
|
|
13
|
+
Updates all mouse state variables.
|
|
14
|
+
Checks for mouse-related events.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
self.x, self.y = pg.mouse.get_pos()
|
|
18
|
+
self.previous_buttons = self.buttons
|
|
19
|
+
self.buttons = pg.mouse.get_pressed()
|
|
20
|
+
|
|
21
|
+
for event in events:
|
|
22
|
+
if event.type == pg.KEYUP:
|
|
23
|
+
if event.key == pg.K_ESCAPE and self.grab:
|
|
24
|
+
# Unlock mouse
|
|
25
|
+
pg.event.set_grab(False)
|
|
26
|
+
pg.mouse.set_visible(True)
|
|
27
|
+
if event.type == pg.MOUSEBUTTONUP and self.grab:
|
|
28
|
+
# Lock mouse
|
|
29
|
+
pg.event.set_grab(True)
|
|
30
|
+
pg.mouse.set_visible(False)
|
|
31
|
+
|
|
32
|
+
def set_pos(self, x, y):
|
|
33
|
+
"""Set the mouse position"""
|
|
34
|
+
pg.mouse.set_pos(x, y)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def click(self): return self.buttons[0] and not self.previous_buttons[0]
|
|
38
|
+
@property
|
|
39
|
+
def left_click(self): return self.buttons[0] and not self.previous_buttons[0]
|
|
40
|
+
@property
|
|
41
|
+
def middle_click(self): return self.buttons[1] and not self.previous_buttons[1]
|
|
42
|
+
@property
|
|
43
|
+
def right_click(self): return self.buttons[2] and not self.previous_buttons[2]
|
|
44
|
+
@property
|
|
45
|
+
def left_down(self): return self.buttons[0]
|
|
46
|
+
@property
|
|
47
|
+
def middle_down(self): return self.buttons[1]
|
|
48
|
+
@property
|
|
49
|
+
def right_down(self): return self.buttons[2]
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def grab(self): return self._grab
|
|
53
|
+
|
|
54
|
+
@grab.setter
|
|
55
|
+
def grab(self, value):
|
|
56
|
+
self._grab = value
|
|
57
|
+
if self._grab:
|
|
58
|
+
pg.event.set_grab(True)
|
|
59
|
+
pg.mouse.set_visible(False)
|
|
60
|
+
else:
|
|
61
|
+
pg.event.set_grab(False)
|
|
62
62
|
pg.mouse.set_visible(True)
|
basilisk/input/path.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# Credit for function: https://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile
|
|
6
|
-
def get_root():
|
|
7
|
-
""" Get absolute path to resource, works for dev and for PyInstaller """
|
|
8
|
-
try:
|
|
9
|
-
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
10
|
-
base_path = sys._MEIPASS
|
|
11
|
-
except Exception:
|
|
12
|
-
base_path = os.path.abspath(".")
|
|
13
|
-
|
|
14
|
-
return base_path + '/basilisk'
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Credit for function: https://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile
|
|
6
|
+
def get_root():
|
|
7
|
+
""" Get absolute path to resource, works for dev and for PyInstaller """
|
|
8
|
+
try:
|
|
9
|
+
# PyInstaller creates a temp folder and stores path in _MEIPASS
|
|
10
|
+
base_path = sys._MEIPASS
|
|
11
|
+
except Exception:
|
|
12
|
+
base_path = os.path.abspath(".")
|
|
13
|
+
|
|
14
|
+
return base_path + '/basilisk'
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import pygame as pg
|
|
2
|
+
from .keys import Keys
|
|
3
|
+
from .mouse import Mouse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class IO:
|
|
7
|
+
keys: Keys=None
|
|
8
|
+
"""Handler for all keyboard inputs"""
|
|
9
|
+
mouse: Mouse=None
|
|
10
|
+
"""Handler for all mouse inputs and mouse settings"""
|
|
11
|
+
events: list=[]
|
|
12
|
+
"""List of all the events in the frame"""
|
|
13
|
+
event_resize: bool=False
|
|
14
|
+
"""Bool for if a resize event has occured this frame"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, engine: ..., grab_mouse: bool=True, caption: bool|None="Basilisk") -> None:
|
|
17
|
+
"""
|
|
18
|
+
Class to handle all inputs and outputs for the engine.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
# Reference to parent engine
|
|
22
|
+
self.engine = engine
|
|
23
|
+
|
|
24
|
+
# Caption attrib
|
|
25
|
+
self.caption = caption
|
|
26
|
+
self.update_caption()
|
|
27
|
+
|
|
28
|
+
# Handlers for key and mouse input
|
|
29
|
+
self.keys = Keys(engine)
|
|
30
|
+
self.mouse = Mouse(grab=grab_mouse)
|
|
31
|
+
|
|
32
|
+
# Expose the mouse on the engine level
|
|
33
|
+
setattr(self.engine, "mouse", self.mouse)
|
|
34
|
+
|
|
35
|
+
# Fill in default values for engine attributes
|
|
36
|
+
self.set_engine_attribiutes()
|
|
37
|
+
|
|
38
|
+
# Update the icon for the window
|
|
39
|
+
pg.display.set_icon(pg.image.load(self.engine.root + '/bsk_assets/basilisk.png'))
|
|
40
|
+
|
|
41
|
+
def update(self) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Update all inputs and check for events
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
# Get events
|
|
47
|
+
self.events = pg.event.get()
|
|
48
|
+
|
|
49
|
+
# Update the keys and the mouse
|
|
50
|
+
self.keys.update()
|
|
51
|
+
self.mouse.update(self.events)
|
|
52
|
+
|
|
53
|
+
# Handle events and update attributes
|
|
54
|
+
self.get_events()
|
|
55
|
+
self.set_engine_attribiutes()
|
|
56
|
+
self.update_caption()
|
|
57
|
+
|
|
58
|
+
def get_events(self) -> None:
|
|
59
|
+
"""
|
|
60
|
+
Loop through all pygame events and make updates as needed
|
|
61
|
+
"""
|
|
62
|
+
|
|
63
|
+
# Clear global events
|
|
64
|
+
self.event_resize = False
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
for event in self.events:
|
|
68
|
+
if event.type == pg.QUIT: # Quit the engine
|
|
69
|
+
self.engine.quit()
|
|
70
|
+
return
|
|
71
|
+
if event.type == pg.VIDEORESIZE:
|
|
72
|
+
# Updates the viewport
|
|
73
|
+
self.event_resize = True
|
|
74
|
+
self.engine.win_size = (event.w, event.h)
|
|
75
|
+
self.engine.ctx.viewport = (0, 0, event.w, event.h)
|
|
76
|
+
self.engine.frame.resize((event.w, event.h))
|
|
77
|
+
# for fbo in self.fbos: fbo.resize()
|
|
78
|
+
|
|
79
|
+
def update_caption(self) -> None:
|
|
80
|
+
"""
|
|
81
|
+
Updates the window caption with either the fps or the window name. Set to 'Basilisk Engine' by default
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
caption = self.caption if self.caption else f"FPS: {round(self.engine.clock.fps)}"
|
|
85
|
+
pg.display.set_caption(caption)
|
|
86
|
+
|
|
87
|
+
def set_engine_attribiutes(self) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Updates engine attributes with this instance's attributes for ease of use
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
setattr(self.engine, "events", self.events)
|
|
93
|
+
setattr(self.engine, "event_resize", self.event_resize)
|
|
File without changes
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import pygame as pg
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Clock:
|
|
5
|
+
delta_time: float=0
|
|
6
|
+
"""The amount of time that passed between the last and current frame"""
|
|
7
|
+
time: float=0
|
|
8
|
+
"""Total time that has passed since the start of the program"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, engine, max_fps=None) -> None:
|
|
11
|
+
"""
|
|
12
|
+
Class to keep track of all time and delta time in the program
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# Reference to the parent engine
|
|
16
|
+
self.engine = engine
|
|
17
|
+
|
|
18
|
+
# Create a pygame clock
|
|
19
|
+
self.clock = pg.Clock()
|
|
20
|
+
self.max_fps = max_fps
|
|
21
|
+
|
|
22
|
+
# Default values for attributes
|
|
23
|
+
self.set_engine_attribiutes()
|
|
24
|
+
|
|
25
|
+
def update(self) -> None:
|
|
26
|
+
"""Ticks the clock"""
|
|
27
|
+
|
|
28
|
+
# Tick the clock and get delta time in seconds
|
|
29
|
+
if self.max_fps: self.delta_time = self.clock.tick(self.max_fps) / 1000
|
|
30
|
+
else: self.delta_time = self.clock.tick() / 1000
|
|
31
|
+
|
|
32
|
+
# Increment the total time by time since last frame
|
|
33
|
+
self.time += self.delta_time
|
|
34
|
+
|
|
35
|
+
self.set_engine_attribiutes()
|
|
36
|
+
|
|
37
|
+
def set_engine_attribiutes(self) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Updates engine attributes with this instance's attributes for ease of use
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
setattr(self.engine, "delta_time", self.delta_time)
|
|
43
|
+
setattr(self.engine, "dt", self.delta_time)
|
|
44
|
+
setattr(self.engine, "time", self.time)
|
|
45
|
+
setattr(self.engine, "fps", self.fps)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def fps(self) -> float:
|
|
50
|
+
return self.clock.get_fps()
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import pygame as pg
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class Keys:
|
|
5
|
+
current_keys: list[bool]
|
|
6
|
+
"""The keys pressed during the current frame"""
|
|
7
|
+
previous_keys: list[bool]
|
|
8
|
+
"""The keys pressed in the last frame"""
|
|
9
|
+
|
|
10
|
+
def __init__(self, engine: ...) -> None:
|
|
11
|
+
"""
|
|
12
|
+
Handler for all keyboard inputs. Stores data from current and previous frames
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# Reference to the parent engine
|
|
16
|
+
self.engine = engine
|
|
17
|
+
|
|
18
|
+
# Fill in default values for current and previous keys to aviod startup errors
|
|
19
|
+
self.current_keys = pg.key.get_pressed()
|
|
20
|
+
self.previous_keys = self.current_keys
|
|
21
|
+
self.set_engine_attribiutes()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def update(self) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Gets all keyboard inputs and propogates last frame inputs
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# Get keyboard input
|
|
30
|
+
self.previous_keys = self.current_keys
|
|
31
|
+
# Propogate input to the last frame
|
|
32
|
+
self.current_keys = pg.key.get_pressed()
|
|
33
|
+
|
|
34
|
+
# Expose the attributes on the engine level
|
|
35
|
+
self.set_engine_attribiutes()
|
|
36
|
+
|
|
37
|
+
def set_engine_attribiutes(self) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Updates engine attributes with this instance's attributes for ease of use
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
setattr(self.engine, "keys", self.current_keys)
|
|
43
|
+
setattr(self.engine, "previous_keys", self.previous_keys)
|
|
44
|
+
setattr(self.engine, "prev_keys", self.previous_keys)
|