basilisk-engine 0.1.8__py3-none-any.whl → 0.1.10__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 +14 -14
- basilisk/audio/sound.py +28 -32
- 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 +2 -2
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +179 -179
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +206 -202
- 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 +23 -23
- basilisk/generic/vec3.py +143 -143
- basilisk/input/mouse.py +61 -61
- basilisk/input/path.py +14 -14
- 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 +682 -682
- basilisk/nodes/node_handler.py +95 -95
- basilisk/particles/particle_handler.py +63 -63
- basilisk/particles/particle_renderer.py +87 -87
- basilisk/physics/impulse.py +112 -112
- basilisk/physics/physics_body.py +43 -43
- basilisk/physics/physics_engine.py +35 -35
- basilisk/render/batch.py +86 -86
- basilisk/render/camera.py +206 -206
- basilisk/render/chunk.py +99 -99
- basilisk/render/chunk_handler.py +154 -154
- basilisk/render/frame.py +101 -101
- basilisk/render/framebuffer.py +130 -130
- basilisk/render/image.py +87 -87
- basilisk/render/image_handler.py +122 -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 +135 -135
- basilisk/render/post_process.py +132 -132
- basilisk/render/shader.py +109 -109
- basilisk/render/shader_handler.py +79 -79
- basilisk/render/sky.py +120 -120
- basilisk/scene.py +264 -264
- basilisk/shaders/batch.frag +276 -276
- basilisk/shaders/batch.vert +115 -115
- basilisk/shaders/crt.frag +31 -31
- basilisk/shaders/draw.frag +21 -21
- basilisk/shaders/draw.vert +21 -21
- 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.8.dist-info → basilisk_engine-0.1.10.dist-info}/METADATA +45 -39
- basilisk_engine-0.1.10.dist-info/RECORD +103 -0
- {basilisk_engine-0.1.8.dist-info → basilisk_engine-0.1.10.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.8.dist-info/RECORD +0 -103
- {basilisk_engine-0.1.8.dist-info → basilisk_engine-0.1.10.dist-info}/top_level.txt +0 -0
basilisk/generic/meshes.py
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
import numpy as np
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# transformations
|
|
6
|
-
def transform_points(points: np.ndarray, model_matrix: glm.mat4x4) -> list[glm.vec3]:
|
|
7
|
-
"""
|
|
8
|
-
Transforms the mesh points to world space
|
|
9
|
-
"""
|
|
10
|
-
return [model_matrix * pt for pt in points]
|
|
11
|
-
|
|
12
|
-
# bvh
|
|
13
|
-
def get_aabb_surface_area(top_right: glm.vec3, bottom_left: glm.vec3) -> float:
|
|
14
|
-
"""
|
|
15
|
-
Returns the surface area of the AABB
|
|
16
|
-
"""
|
|
17
|
-
diagonal = top_right - bottom_left
|
|
18
|
-
return 2 * (diagonal.x * diagonal.y + diagonal.y * diagonal.z + diagonal.x * diagonal.z)
|
|
19
|
-
|
|
20
|
-
def get_extreme_points_np(points: np.ndarray) -> tuple[glm.vec3, glm.vec3]:
|
|
21
|
-
"""
|
|
22
|
-
Returns the top right and bottom left points of the aabb encapsulating the points
|
|
23
|
-
"""
|
|
24
|
-
top_right = glm.vec3(-1e10)
|
|
25
|
-
bottom_left = glm.vec3(1e10)
|
|
26
|
-
for pt in points:
|
|
27
|
-
for i in range(3):
|
|
28
|
-
if top_right[i] < pt[i]: top_right[i] = pt[i]
|
|
29
|
-
if bottom_left[i] > pt[i]: bottom_left[i] = pt[i]
|
|
30
|
-
return top_right, bottom_left
|
|
31
|
-
|
|
32
|
-
def get_aabb_line_collision(top_right:glm.vec3, bottom_left:glm.vec3, point:glm.vec3, vec:glm.vec3) -> bool:
|
|
33
|
-
"""
|
|
34
|
-
Determines if a line has collided with an aabb
|
|
35
|
-
"""
|
|
36
|
-
tmin, tmax = -1e10, 1e10
|
|
37
|
-
for i in range(3):
|
|
38
|
-
if vec[i] != 0:
|
|
39
|
-
inv_dir = 1.0 / vec[i]
|
|
40
|
-
t1 = (bottom_left[i] - point[i]) * inv_dir
|
|
41
|
-
t2 = (top_right[i] - point[i]) * inv_dir
|
|
42
|
-
t1, t2 = min(t1, t2), max(t1, t2)
|
|
43
|
-
tmin = max(tmin, t1)
|
|
44
|
-
tmax = min(tmax, t2)
|
|
45
|
-
if tmin > tmax: return False
|
|
46
|
-
elif point[i] < bottom_left[i] or point[i] > top_right[i]: return False
|
|
47
|
-
return tmax >= 0 and tmin <= 1
|
|
48
|
-
|
|
49
|
-
def moller_trumbore(point:glm.vec3, vec:glm.vec3, triangle:list[glm.vec3], epsilon:float=1e-7) -> glm.vec3 | None:
|
|
50
|
-
"""
|
|
51
|
-
Determines where a line intersects with a triangle and where that intersection occurred
|
|
52
|
-
"""
|
|
53
|
-
edge1, edge2 = triangle[1] - triangle[0], triangle[2] - triangle[0]
|
|
54
|
-
ray_cross = glm.cross(vec, edge2)
|
|
55
|
-
det = glm.dot(edge1, ray_cross)
|
|
56
|
-
|
|
57
|
-
# if the ray is parallel to the triangle
|
|
58
|
-
if abs(det) < epsilon: return None
|
|
59
|
-
|
|
60
|
-
inv_det = 1 / det
|
|
61
|
-
s = point - triangle[0]
|
|
62
|
-
u = glm.dot(s, ray_cross) * inv_det
|
|
63
|
-
|
|
64
|
-
if (u < 0 and abs(u) > epsilon) or (u > 1 and abs(u - 1) > epsilon): return None
|
|
65
|
-
|
|
66
|
-
s_cross = glm.cross(s, edge1)
|
|
67
|
-
v = glm.dot(vec, s_cross) * inv_det
|
|
68
|
-
|
|
69
|
-
if (v < 0 and abs(v) > epsilon) or (u + v > 1 and abs(u + v - 1) > epsilon): return None
|
|
70
|
-
|
|
71
|
-
t = glm.dot(edge2, s_cross) * inv_det
|
|
72
|
-
if t > epsilon: return point + vec * t
|
|
1
|
+
import glm
|
|
2
|
+
import numpy as np
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# transformations
|
|
6
|
+
def transform_points(points: np.ndarray, model_matrix: glm.mat4x4) -> list[glm.vec3]:
|
|
7
|
+
"""
|
|
8
|
+
Transforms the mesh points to world space
|
|
9
|
+
"""
|
|
10
|
+
return [model_matrix * pt for pt in points]
|
|
11
|
+
|
|
12
|
+
# bvh
|
|
13
|
+
def get_aabb_surface_area(top_right: glm.vec3, bottom_left: glm.vec3) -> float:
|
|
14
|
+
"""
|
|
15
|
+
Returns the surface area of the AABB
|
|
16
|
+
"""
|
|
17
|
+
diagonal = top_right - bottom_left
|
|
18
|
+
return 2 * (diagonal.x * diagonal.y + diagonal.y * diagonal.z + diagonal.x * diagonal.z)
|
|
19
|
+
|
|
20
|
+
def get_extreme_points_np(points: np.ndarray) -> tuple[glm.vec3, glm.vec3]:
|
|
21
|
+
"""
|
|
22
|
+
Returns the top right and bottom left points of the aabb encapsulating the points
|
|
23
|
+
"""
|
|
24
|
+
top_right = glm.vec3(-1e10)
|
|
25
|
+
bottom_left = glm.vec3(1e10)
|
|
26
|
+
for pt in points:
|
|
27
|
+
for i in range(3):
|
|
28
|
+
if top_right[i] < pt[i]: top_right[i] = pt[i]
|
|
29
|
+
if bottom_left[i] > pt[i]: bottom_left[i] = pt[i]
|
|
30
|
+
return top_right, bottom_left
|
|
31
|
+
|
|
32
|
+
def get_aabb_line_collision(top_right:glm.vec3, bottom_left:glm.vec3, point:glm.vec3, vec:glm.vec3) -> bool:
|
|
33
|
+
"""
|
|
34
|
+
Determines if a line has collided with an aabb
|
|
35
|
+
"""
|
|
36
|
+
tmin, tmax = -1e10, 1e10
|
|
37
|
+
for i in range(3):
|
|
38
|
+
if vec[i] != 0:
|
|
39
|
+
inv_dir = 1.0 / vec[i]
|
|
40
|
+
t1 = (bottom_left[i] - point[i]) * inv_dir
|
|
41
|
+
t2 = (top_right[i] - point[i]) * inv_dir
|
|
42
|
+
t1, t2 = min(t1, t2), max(t1, t2)
|
|
43
|
+
tmin = max(tmin, t1)
|
|
44
|
+
tmax = min(tmax, t2)
|
|
45
|
+
if tmin > tmax: return False
|
|
46
|
+
elif point[i] < bottom_left[i] or point[i] > top_right[i]: return False
|
|
47
|
+
return tmax >= 0 and tmin <= 1
|
|
48
|
+
|
|
49
|
+
def moller_trumbore(point:glm.vec3, vec:glm.vec3, triangle:list[glm.vec3], epsilon:float=1e-7) -> glm.vec3 | None:
|
|
50
|
+
"""
|
|
51
|
+
Determines where a line intersects with a triangle and where that intersection occurred
|
|
52
|
+
"""
|
|
53
|
+
edge1, edge2 = triangle[1] - triangle[0], triangle[2] - triangle[0]
|
|
54
|
+
ray_cross = glm.cross(vec, edge2)
|
|
55
|
+
det = glm.dot(edge1, ray_cross)
|
|
56
|
+
|
|
57
|
+
# if the ray is parallel to the triangle
|
|
58
|
+
if abs(det) < epsilon: return None
|
|
59
|
+
|
|
60
|
+
inv_det = 1 / det
|
|
61
|
+
s = point - triangle[0]
|
|
62
|
+
u = glm.dot(s, ray_cross) * inv_det
|
|
63
|
+
|
|
64
|
+
if (u < 0 and abs(u) > epsilon) or (u > 1 and abs(u - 1) > epsilon): return None
|
|
65
|
+
|
|
66
|
+
s_cross = glm.cross(s, edge1)
|
|
67
|
+
v = glm.dot(vec, s_cross) * inv_det
|
|
68
|
+
|
|
69
|
+
if (v < 0 and abs(v) > epsilon) or (u + v > 1 and abs(u + v - 1) > epsilon): return None
|
|
70
|
+
|
|
71
|
+
t = glm.dot(edge2, s_cross) * inv_det
|
|
72
|
+
if t > epsilon: return point + vec * t
|
|
73
73
|
return None
|
basilisk/generic/quat.py
CHANGED
|
@@ -1,143 +1,143 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
import numpy as np
|
|
3
|
-
from .abstract_custom import Custom
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class Quat(Custom):
|
|
7
|
-
def __init__(self, *args, callback=None):
|
|
8
|
-
self.callback = callback
|
|
9
|
-
self.prev_data = glm.quat(1, 0, 0, 0)
|
|
10
|
-
|
|
11
|
-
if len(args) == 1:
|
|
12
|
-
|
|
13
|
-
if isinstance(args[0], Quat):
|
|
14
|
-
self.data = glm.quat(args[0].data)
|
|
15
|
-
self.prev_data = glm.quat(args[0].prev_data)
|
|
16
|
-
self.callback = args[0].callback
|
|
17
|
-
|
|
18
|
-
elif isinstance(args[0], glm.quat):
|
|
19
|
-
self.data = args[0]
|
|
20
|
-
|
|
21
|
-
elif isinstance(args[0], tuple) or isinstance(args[0], list) or isinstance(args[0], np.ndarray):
|
|
22
|
-
assert 2 < len(args[0]) < 5, f'Quat: Expected 3 or 4 values from incoming vector, got {len(args[0])}'
|
|
23
|
-
self.data = glm.quat(args[0])
|
|
24
|
-
|
|
25
|
-
else:
|
|
26
|
-
try: self.data = glm.quat(args[0])
|
|
27
|
-
except: raise ValueError(f'Quat: Unexpected incoming quaternion type {args[0]}')
|
|
28
|
-
|
|
29
|
-
elif 2 < len(args) < 5: self.data = glm.quat(*args)
|
|
30
|
-
else: raise ValueError(f'Quat: Expected either a vector, quaternion, or 3 or 4 numbers, got {len(args)} values')
|
|
31
|
-
|
|
32
|
-
def apply_function(self, other, func, func_name):
|
|
33
|
-
quat = glm.quat(self.data)
|
|
34
|
-
|
|
35
|
-
if isinstance(other, (glm.vec3, glm.quat)):
|
|
36
|
-
quat = func(quat, other)
|
|
37
|
-
|
|
38
|
-
elif isinstance(other, (tuple, list, np.ndarray)):
|
|
39
|
-
assert 2 < len(other) < 5, f'Quat: Expected 3 or 4 values from incoming vector, got {len(other)}'
|
|
40
|
-
quat = func(quat, other)
|
|
41
|
-
|
|
42
|
-
elif isinstance(other, Custom):
|
|
43
|
-
quat = func(quat, other.data)
|
|
44
|
-
|
|
45
|
-
else:
|
|
46
|
-
try: quat = func(quat, other)
|
|
47
|
-
except: raise ValueError(f'Quat: Not an accepted type for {func_name}, got {type(other)}')
|
|
48
|
-
return Quat(quat)
|
|
49
|
-
|
|
50
|
-
# unary operators
|
|
51
|
-
def __neg__(self):
|
|
52
|
-
return Quat(-self.data, callback=self.callback)
|
|
53
|
-
|
|
54
|
-
def __abs__(self):
|
|
55
|
-
return Quat(abs(self.data), callback=self.callback)
|
|
56
|
-
|
|
57
|
-
# accessor functions
|
|
58
|
-
def __getitem__(self, index):
|
|
59
|
-
assert int(index) == index, f'Quat: index must be an int, got {type(index)}' # check if index is a float
|
|
60
|
-
assert 0 <= index <= 3, f'Quat: index out of bounds, got {index}'
|
|
61
|
-
return self.data[index]
|
|
62
|
-
|
|
63
|
-
def __setitem__(self, index, value):
|
|
64
|
-
assert int(index) == index, f'Quat: index must be an int, got {type(index)}' # check if index is a float
|
|
65
|
-
assert 0 <= index <= 3, f'Quat: index out of bounds, got {index}'
|
|
66
|
-
try: self.data[index] = value
|
|
67
|
-
except: raise ValueError(f'Quat: Invalid element type, got {type(value)}')
|
|
68
|
-
|
|
69
|
-
def __delitem__(self, index): # cannot delete an index from a quaternion, so we set the value to zero instead
|
|
70
|
-
assert int(index) == index, f'Quat: index must be an int, got {type(index)}' # check if index is a float
|
|
71
|
-
assert 0 <= index <= 3, f'Quat: index out of bounds, got {index}'
|
|
72
|
-
self.data[index] = 0
|
|
73
|
-
|
|
74
|
-
def __len__(self):
|
|
75
|
-
return 4
|
|
76
|
-
|
|
77
|
-
def __iter__(self):
|
|
78
|
-
return iter(self.data)
|
|
79
|
-
|
|
80
|
-
def __contains__(self, item):
|
|
81
|
-
return item in self.data
|
|
82
|
-
|
|
83
|
-
# override str operators
|
|
84
|
-
def __repr__(self):
|
|
85
|
-
return 'bsk' + str(self.data)
|
|
86
|
-
|
|
87
|
-
def __str__(self):
|
|
88
|
-
return 'bsk ' + str(self.data)
|
|
89
|
-
|
|
90
|
-
@property
|
|
91
|
-
def data(self): return self._data
|
|
92
|
-
@property
|
|
93
|
-
def w(self): return self.data.w
|
|
94
|
-
@property
|
|
95
|
-
def x(self): return self.data.x
|
|
96
|
-
@property
|
|
97
|
-
def y(self): return self.data.y
|
|
98
|
-
@property
|
|
99
|
-
def z(self): return self.data.z
|
|
100
|
-
|
|
101
|
-
@data.setter
|
|
102
|
-
def data(self, value: glm.vec3 | glm.quat):
|
|
103
|
-
self._data = glm.quat(value)
|
|
104
|
-
cur = self._data
|
|
105
|
-
prev = self.prev_data
|
|
106
|
-
thresh = 1e-6
|
|
107
|
-
|
|
108
|
-
if self.callback and (abs(cur.w - prev.w) > thresh or abs(cur.x - prev.x) > thresh or abs(cur.y - prev.y) > thresh or abs(cur.z - prev.z) > thresh):
|
|
109
|
-
self.prev_data = glm.quat(self._data)
|
|
110
|
-
self.callback()
|
|
111
|
-
self.normalize()
|
|
112
|
-
|
|
113
|
-
@w.setter
|
|
114
|
-
def w(self, value):
|
|
115
|
-
self.data.w = value
|
|
116
|
-
if self.callback and abs(value - self.prev_data.w) > 1e-6:
|
|
117
|
-
self.prev_data.w = value
|
|
118
|
-
self.callback()
|
|
119
|
-
self.normalize()
|
|
120
|
-
|
|
121
|
-
@x.setter
|
|
122
|
-
def x(self, value):
|
|
123
|
-
self._data.x = value
|
|
124
|
-
if self.callback and abs(value - self.prev_data.x) > 1e-6:
|
|
125
|
-
self.prev_data.x = value
|
|
126
|
-
self.callback()
|
|
127
|
-
self.normalize()
|
|
128
|
-
|
|
129
|
-
@y.setter
|
|
130
|
-
def y(self, value):
|
|
131
|
-
self._data.y = value
|
|
132
|
-
if self.callback and abs(value - self.prev_data.y) > 1e-6:
|
|
133
|
-
self.prev_data.y = value
|
|
134
|
-
self.callback()
|
|
135
|
-
self.normalize()
|
|
136
|
-
|
|
137
|
-
@z.setter
|
|
138
|
-
def z(self, value):
|
|
139
|
-
self._data.z = value
|
|
140
|
-
if self.callback and abs(value - self.prev_data.z) > 1e-6:
|
|
141
|
-
self.prev_data.z = value
|
|
142
|
-
self.callback()
|
|
1
|
+
import glm
|
|
2
|
+
import numpy as np
|
|
3
|
+
from .abstract_custom import Custom
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Quat(Custom):
|
|
7
|
+
def __init__(self, *args, callback=None):
|
|
8
|
+
self.callback = callback
|
|
9
|
+
self.prev_data = glm.quat(1, 0, 0, 0)
|
|
10
|
+
|
|
11
|
+
if len(args) == 1:
|
|
12
|
+
|
|
13
|
+
if isinstance(args[0], Quat):
|
|
14
|
+
self.data = glm.quat(args[0].data)
|
|
15
|
+
self.prev_data = glm.quat(args[0].prev_data)
|
|
16
|
+
self.callback = args[0].callback
|
|
17
|
+
|
|
18
|
+
elif isinstance(args[0], glm.quat):
|
|
19
|
+
self.data = args[0]
|
|
20
|
+
|
|
21
|
+
elif isinstance(args[0], tuple) or isinstance(args[0], list) or isinstance(args[0], np.ndarray):
|
|
22
|
+
assert 2 < len(args[0]) < 5, f'Quat: Expected 3 or 4 values from incoming vector, got {len(args[0])}'
|
|
23
|
+
self.data = glm.quat(args[0])
|
|
24
|
+
|
|
25
|
+
else:
|
|
26
|
+
try: self.data = glm.quat(args[0])
|
|
27
|
+
except: raise ValueError(f'Quat: Unexpected incoming quaternion type {args[0]}')
|
|
28
|
+
|
|
29
|
+
elif 2 < len(args) < 5: self.data = glm.quat(*args)
|
|
30
|
+
else: raise ValueError(f'Quat: Expected either a vector, quaternion, or 3 or 4 numbers, got {len(args)} values')
|
|
31
|
+
|
|
32
|
+
def apply_function(self, other, func, func_name):
|
|
33
|
+
quat = glm.quat(self.data)
|
|
34
|
+
|
|
35
|
+
if isinstance(other, (glm.vec3, glm.quat)):
|
|
36
|
+
quat = func(quat, other)
|
|
37
|
+
|
|
38
|
+
elif isinstance(other, (tuple, list, np.ndarray)):
|
|
39
|
+
assert 2 < len(other) < 5, f'Quat: Expected 3 or 4 values from incoming vector, got {len(other)}'
|
|
40
|
+
quat = func(quat, other)
|
|
41
|
+
|
|
42
|
+
elif isinstance(other, Custom):
|
|
43
|
+
quat = func(quat, other.data)
|
|
44
|
+
|
|
45
|
+
else:
|
|
46
|
+
try: quat = func(quat, other)
|
|
47
|
+
except: raise ValueError(f'Quat: Not an accepted type for {func_name}, got {type(other)}')
|
|
48
|
+
return Quat(quat)
|
|
49
|
+
|
|
50
|
+
# unary operators
|
|
51
|
+
def __neg__(self):
|
|
52
|
+
return Quat(-self.data, callback=self.callback)
|
|
53
|
+
|
|
54
|
+
def __abs__(self):
|
|
55
|
+
return Quat(abs(self.data), callback=self.callback)
|
|
56
|
+
|
|
57
|
+
# accessor functions
|
|
58
|
+
def __getitem__(self, index):
|
|
59
|
+
assert int(index) == index, f'Quat: index must be an int, got {type(index)}' # check if index is a float
|
|
60
|
+
assert 0 <= index <= 3, f'Quat: index out of bounds, got {index}'
|
|
61
|
+
return self.data[index]
|
|
62
|
+
|
|
63
|
+
def __setitem__(self, index, value):
|
|
64
|
+
assert int(index) == index, f'Quat: index must be an int, got {type(index)}' # check if index is a float
|
|
65
|
+
assert 0 <= index <= 3, f'Quat: index out of bounds, got {index}'
|
|
66
|
+
try: self.data[index] = value
|
|
67
|
+
except: raise ValueError(f'Quat: Invalid element type, got {type(value)}')
|
|
68
|
+
|
|
69
|
+
def __delitem__(self, index): # cannot delete an index from a quaternion, so we set the value to zero instead
|
|
70
|
+
assert int(index) == index, f'Quat: index must be an int, got {type(index)}' # check if index is a float
|
|
71
|
+
assert 0 <= index <= 3, f'Quat: index out of bounds, got {index}'
|
|
72
|
+
self.data[index] = 0
|
|
73
|
+
|
|
74
|
+
def __len__(self):
|
|
75
|
+
return 4
|
|
76
|
+
|
|
77
|
+
def __iter__(self):
|
|
78
|
+
return iter(self.data)
|
|
79
|
+
|
|
80
|
+
def __contains__(self, item):
|
|
81
|
+
return item in self.data
|
|
82
|
+
|
|
83
|
+
# override str operators
|
|
84
|
+
def __repr__(self):
|
|
85
|
+
return 'bsk' + str(self.data)
|
|
86
|
+
|
|
87
|
+
def __str__(self):
|
|
88
|
+
return 'bsk ' + str(self.data)
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def data(self): return self._data
|
|
92
|
+
@property
|
|
93
|
+
def w(self): return self.data.w
|
|
94
|
+
@property
|
|
95
|
+
def x(self): return self.data.x
|
|
96
|
+
@property
|
|
97
|
+
def y(self): return self.data.y
|
|
98
|
+
@property
|
|
99
|
+
def z(self): return self.data.z
|
|
100
|
+
|
|
101
|
+
@data.setter
|
|
102
|
+
def data(self, value: glm.vec3 | glm.quat):
|
|
103
|
+
self._data = glm.quat(value)
|
|
104
|
+
cur = self._data
|
|
105
|
+
prev = self.prev_data
|
|
106
|
+
thresh = 1e-6
|
|
107
|
+
|
|
108
|
+
if self.callback and (abs(cur.w - prev.w) > thresh or abs(cur.x - prev.x) > thresh or abs(cur.y - prev.y) > thresh or abs(cur.z - prev.z) > thresh):
|
|
109
|
+
self.prev_data = glm.quat(self._data)
|
|
110
|
+
self.callback()
|
|
111
|
+
self.normalize()
|
|
112
|
+
|
|
113
|
+
@w.setter
|
|
114
|
+
def w(self, value):
|
|
115
|
+
self.data.w = value
|
|
116
|
+
if self.callback and abs(value - self.prev_data.w) > 1e-6:
|
|
117
|
+
self.prev_data.w = value
|
|
118
|
+
self.callback()
|
|
119
|
+
self.normalize()
|
|
120
|
+
|
|
121
|
+
@x.setter
|
|
122
|
+
def x(self, value):
|
|
123
|
+
self._data.x = value
|
|
124
|
+
if self.callback and abs(value - self.prev_data.x) > 1e-6:
|
|
125
|
+
self.prev_data.x = value
|
|
126
|
+
self.callback()
|
|
127
|
+
self.normalize()
|
|
128
|
+
|
|
129
|
+
@y.setter
|
|
130
|
+
def y(self, value):
|
|
131
|
+
self._data.y = value
|
|
132
|
+
if self.callback and abs(value - self.prev_data.y) > 1e-6:
|
|
133
|
+
self.prev_data.y = value
|
|
134
|
+
self.callback()
|
|
135
|
+
self.normalize()
|
|
136
|
+
|
|
137
|
+
@z.setter
|
|
138
|
+
def z(self, value):
|
|
139
|
+
self._data.z = value
|
|
140
|
+
if self.callback and abs(value - self.prev_data.z) > 1e-6:
|
|
141
|
+
self.prev_data.z = value
|
|
142
|
+
self.callback()
|
|
143
143
|
self.normalize()
|
basilisk/generic/quat_methods.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
def rotate_vec_by_quat(vec: glm.vec3, quat: glm.quat) -> glm.vec3:
|
|
5
|
-
"""
|
|
6
|
-
Rotates a vector by a quaternion. Probably just dont use this, just a reminder of how glm works with quaternions
|
|
7
|
-
"""
|
|
1
|
+
import glm
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def rotate_vec_by_quat(vec: glm.vec3, quat: glm.quat) -> glm.vec3:
|
|
5
|
+
"""
|
|
6
|
+
Rotates a vector by a quaternion. Probably just dont use this, just a reminder of how glm works with quaternions
|
|
7
|
+
"""
|
|
8
8
|
return vec * quat
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import glm
|
|
2
|
-
from ..nodes.node import Node
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class RaycastResult:
|
|
6
|
-
node: Node | None
|
|
7
|
-
"""The node that the raycast hit. Is None if no object was hit"""
|
|
8
|
-
position: glm.vec3
|
|
9
|
-
"""The node that the raycast hit"""
|
|
10
|
-
|
|
11
|
-
def __init__(self, node: Node | None, position: glm.vec3):
|
|
12
|
-
"""
|
|
13
|
-
Container for returning raycast results.
|
|
14
|
-
Contains the node hit and the global position the raycast hit at.
|
|
15
|
-
"""
|
|
16
|
-
|
|
17
|
-
self.node = node
|
|
18
|
-
self.position = position
|
|
19
|
-
|
|
20
|
-
def __bool__(self):
|
|
21
|
-
return bool(self.node)
|
|
22
|
-
|
|
23
|
-
def __repr__(self):
|
|
1
|
+
import glm
|
|
2
|
+
from ..nodes.node import Node
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class RaycastResult:
|
|
6
|
+
node: Node | None
|
|
7
|
+
"""The node that the raycast hit. Is None if no object was hit"""
|
|
8
|
+
position: glm.vec3
|
|
9
|
+
"""The node that the raycast hit"""
|
|
10
|
+
|
|
11
|
+
def __init__(self, node: Node | None, position: glm.vec3):
|
|
12
|
+
"""
|
|
13
|
+
Container for returning raycast results.
|
|
14
|
+
Contains the node hit and the global position the raycast hit at.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
self.node = node
|
|
18
|
+
self.position = position
|
|
19
|
+
|
|
20
|
+
def __bool__(self):
|
|
21
|
+
return bool(self.node)
|
|
22
|
+
|
|
23
|
+
def __repr__(self):
|
|
24
24
|
return f'<Raycast | Node: {self.node}, Position: {self.position}>'
|