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.

Files changed (93) hide show
  1. basilisk/__init__.py +15 -15
  2. basilisk/audio/sound.py +27 -27
  3. basilisk/bsk_assets/cube.obj +48 -48
  4. basilisk/collisions/broad/broad_aabb.py +102 -102
  5. basilisk/collisions/broad/broad_bvh.py +137 -137
  6. basilisk/collisions/collider.py +95 -95
  7. basilisk/collisions/collider_handler.py +224 -224
  8. basilisk/collisions/narrow/contact_manifold.py +95 -95
  9. basilisk/collisions/narrow/dataclasses.py +34 -34
  10. basilisk/collisions/narrow/deprecated.py +46 -46
  11. basilisk/collisions/narrow/epa.py +91 -91
  12. basilisk/collisions/narrow/gjk.py +66 -66
  13. basilisk/collisions/narrow/graham_scan.py +24 -24
  14. basilisk/collisions/narrow/helper.py +29 -29
  15. basilisk/collisions/narrow/line_intersections.py +106 -106
  16. basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
  17. basilisk/config.py +4 -3
  18. basilisk/draw/draw.py +100 -100
  19. basilisk/draw/draw_handler.py +175 -179
  20. basilisk/draw/font_renderer.py +28 -28
  21. basilisk/engine.py +165 -213
  22. basilisk/generic/abstract_bvh.py +15 -15
  23. basilisk/generic/abstract_custom.py +133 -133
  24. basilisk/generic/collisions.py +72 -72
  25. basilisk/generic/input_validation.py +66 -66
  26. basilisk/generic/math.py +6 -6
  27. basilisk/generic/matrices.py +35 -35
  28. basilisk/generic/meshes.py +72 -72
  29. basilisk/generic/quat.py +142 -142
  30. basilisk/generic/quat_methods.py +7 -7
  31. basilisk/generic/raycast_result.py +26 -26
  32. basilisk/generic/vec3.py +143 -143
  33. basilisk/input/mouse.py +61 -61
  34. basilisk/input/path.py +14 -14
  35. basilisk/input_output/IO_handler.py +93 -0
  36. basilisk/input_output/__init__.py +0 -0
  37. basilisk/input_output/clock.py +50 -0
  38. basilisk/input_output/keys.py +44 -0
  39. basilisk/input_output/mouse.py +62 -0
  40. basilisk/input_output/path.py +14 -0
  41. basilisk/mesh/cube.py +33 -33
  42. basilisk/mesh/mesh.py +230 -230
  43. basilisk/mesh/mesh_from_data.py +130 -130
  44. basilisk/mesh/model.py +271 -271
  45. basilisk/mesh/narrow_aabb.py +89 -89
  46. basilisk/mesh/narrow_bvh.py +91 -91
  47. basilisk/mesh/narrow_primative.py +23 -23
  48. basilisk/nodes/helper.py +28 -28
  49. basilisk/nodes/node.py +686 -684
  50. basilisk/nodes/node_handler.py +97 -96
  51. basilisk/particles/particle_handler.py +64 -64
  52. basilisk/particles/particle_renderer.py +92 -92
  53. basilisk/physics/impulse.py +112 -112
  54. basilisk/physics/physics_body.py +43 -43
  55. basilisk/physics/physics_engine.py +35 -35
  56. basilisk/render/batch.py +105 -105
  57. basilisk/render/camera.py +267 -222
  58. basilisk/render/chunk.py +106 -106
  59. basilisk/render/chunk_handler.py +165 -165
  60. basilisk/render/frame.py +99 -101
  61. basilisk/render/framebuffer.py +131 -130
  62. basilisk/render/image.py +87 -87
  63. basilisk/render/image_handler.py +120 -122
  64. basilisk/render/light.py +96 -96
  65. basilisk/render/light_handler.py +58 -58
  66. basilisk/render/material.py +219 -219
  67. basilisk/render/material_handler.py +131 -135
  68. basilisk/render/post_process.py +139 -139
  69. basilisk/render/shader.py +109 -110
  70. basilisk/render/shader_handler.py +83 -80
  71. basilisk/render/sky.py +120 -120
  72. basilisk/scene.py +279 -276
  73. basilisk/shaders/batch.frag +276 -276
  74. basilisk/shaders/batch.vert +115 -115
  75. basilisk/shaders/crt.frag +31 -31
  76. basilisk/shaders/draw.frag +22 -22
  77. basilisk/shaders/draw.vert +25 -25
  78. basilisk/shaders/filter.frag +22 -22
  79. basilisk/shaders/frame.frag +12 -12
  80. basilisk/shaders/frame.vert +13 -13
  81. basilisk/shaders/geometry.frag +8 -8
  82. basilisk/shaders/geometry.vert +41 -41
  83. basilisk/shaders/normal.frag +59 -59
  84. basilisk/shaders/normal.vert +96 -96
  85. basilisk/shaders/particle.frag +71 -71
  86. basilisk/shaders/particle.vert +84 -84
  87. basilisk/shaders/sky.frag +9 -9
  88. basilisk/shaders/sky.vert +13 -13
  89. {basilisk_engine-0.1.21.dist-info → basilisk_engine-0.1.23.dist-info}/METADATA +45 -38
  90. basilisk_engine-0.1.23.dist-info/RECORD +109 -0
  91. {basilisk_engine-0.1.21.dist-info → basilisk_engine-0.1.23.dist-info}/WHEEL +1 -1
  92. basilisk_engine-0.1.21.dist-info/RECORD +0 -103
  93. {basilisk_engine-0.1.21.dist-info → basilisk_engine-0.1.23.dist-info}/top_level.txt +0 -0
@@ -1,134 +1,134 @@
1
- import glm
2
- import numpy as np
3
-
4
-
5
- class Custom():
6
-
7
- def normalize(self):
8
- """
9
- Inplace normalizes the vector
10
- """
11
- self._data = glm.normalize(self._data)
12
- return self
13
-
14
- def apply_function(): ... # will be overridden by child custom classes
15
-
16
- # math functions
17
- def add(self, other):
18
- def func(a, b): return a + b
19
- return self.apply_function(other, func, 'addition')
20
-
21
- def subtract(self, other):
22
- def func(a, b): return a - b
23
- return self.apply_function(other, func, 'subtraction')
24
-
25
- def rhs_subtract(self, other):
26
- def func(a, b): return b - a
27
- return self.apply_function(other, func, 'subtraction')
28
-
29
- def multiply(self, other):
30
- def func(a, b): return a * b
31
- return self.apply_function(other, func, 'multiplication')
32
-
33
- def divide(self, other):
34
- def func(a, b): return a / b
35
- return self.apply_function(other, func, 'division')
36
-
37
- def rhs_divide(self, other):
38
- def func(a, b): return b / a
39
- return self.apply_function(other, func, 'division')
40
-
41
- def floor_divide(self, other):
42
- def func(a, b): return a // b
43
- return self.apply_function(other, func, 'division')
44
-
45
- def rhs_floor_divide(self, other):
46
- def func(a, b): return b // a
47
- return self.apply_function(other, func, 'division')
48
-
49
- def mod(self, other):
50
- def func(a, b): return a % b
51
- return self.apply_function(other, func, 'modulus')
52
-
53
- def rhs_mod(self, other):
54
- def func(a, b): return b % a
55
- return self.apply_function(other, func, 'modulus')
56
-
57
- def pow(self, other):
58
- def func(a, b): return a ** b
59
- return self.apply_function(other, func, 'power')
60
-
61
- def rhs_pow(self, other):
62
- def func(a, b): return b ** a
63
- return self.apply_function(other, func, 'power')
64
-
65
- def __add__(self, other): return self.add(other) # this + that
66
- def __radd__(self, other): return self.add(other) # that + this
67
- def __iadd__(self, other): # this += that
68
- self = self.add(other)
69
- return self
70
-
71
- def __sub__(self, other): return self.subtract(other)
72
- def __rsub__(self, other): return self.rhs_subtract(other) # non-commutative
73
- def __isub__(self, other):
74
- self = self.subtract(other)
75
- return self
76
-
77
- def __mul__(self, other): return self.multiply(other)
78
- def __rmul__(self, other): return self.multiply(other)
79
- def __imul__(self, other):
80
- self = self.multiply(other)
81
- return self
82
-
83
- def __truediv__(self, other): return self.divide(other)
84
- def __rtruediv__(self, other): return self.rhs_divide(other) # non-commutative
85
- def __itruediv__(self, other):
86
- self = self.divide(other)
87
- return self
88
-
89
- def __floordiv__(self, other): return self.floor_divide(other)
90
- def __rfloordiv__(self, other): return self.rhs_floor_divide(other) # non-commutative
91
- def __ifloordiv__(self, other):
92
- self = self.floor_divide(other)
93
- return self
94
-
95
- def __mod__(self, other): return self.mod(other)
96
- def __rmod__(self, other): return self.rhs_mod(other)
97
- def __imod__(self, other):
98
- self = self.mod(other)
99
- return self
100
-
101
- def __pow__(self, other): return self.pow(other)
102
- def __rpow__(self, other): return self.rhs_pow(other)
103
- def __ipow__(self, other):
104
- self = self.pow(other)
105
- return self
106
-
107
- # comparison functions
108
- def __eq__(self, other):
109
- if isinstance(other, Custom): return self.data == other.data
110
- return self.data == other
111
-
112
- def __ne__(self, other):
113
- if isinstance(other, Custom): return self.data != other.data
114
- return self.data != other
115
-
116
- def __lt__(self, other):
117
- if isinstance(other, Custom): return self.data < other.data
118
- return self.data < other
119
-
120
- def __gt__(self, other):
121
- if isinstance(other, Custom): return self.data > other.data
122
- return self.data > other
123
-
124
- def __le__(self, other):
125
- if isinstance(other, Custom): return self.data <= other.data
126
- return self.data <= other
127
-
128
- def __ge__(self, other):
129
- if isinstance(other, Custom): return self.data >= other.data
130
- return self.data >= other
131
-
132
- # unary operators
133
- def __pos__(self):
1
+ import glm
2
+ import numpy as np
3
+
4
+
5
+ class Custom():
6
+
7
+ def normalize(self):
8
+ """
9
+ Inplace normalizes the vector
10
+ """
11
+ self._data = glm.normalize(self._data)
12
+ return self
13
+
14
+ def apply_function(): ... # will be overridden by child custom classes
15
+
16
+ # math functions
17
+ def add(self, other):
18
+ def func(a, b): return a + b
19
+ return self.apply_function(other, func, 'addition')
20
+
21
+ def subtract(self, other):
22
+ def func(a, b): return a - b
23
+ return self.apply_function(other, func, 'subtraction')
24
+
25
+ def rhs_subtract(self, other):
26
+ def func(a, b): return b - a
27
+ return self.apply_function(other, func, 'subtraction')
28
+
29
+ def multiply(self, other):
30
+ def func(a, b): return a * b
31
+ return self.apply_function(other, func, 'multiplication')
32
+
33
+ def divide(self, other):
34
+ def func(a, b): return a / b
35
+ return self.apply_function(other, func, 'division')
36
+
37
+ def rhs_divide(self, other):
38
+ def func(a, b): return b / a
39
+ return self.apply_function(other, func, 'division')
40
+
41
+ def floor_divide(self, other):
42
+ def func(a, b): return a // b
43
+ return self.apply_function(other, func, 'division')
44
+
45
+ def rhs_floor_divide(self, other):
46
+ def func(a, b): return b // a
47
+ return self.apply_function(other, func, 'division')
48
+
49
+ def mod(self, other):
50
+ def func(a, b): return a % b
51
+ return self.apply_function(other, func, 'modulus')
52
+
53
+ def rhs_mod(self, other):
54
+ def func(a, b): return b % a
55
+ return self.apply_function(other, func, 'modulus')
56
+
57
+ def pow(self, other):
58
+ def func(a, b): return a ** b
59
+ return self.apply_function(other, func, 'power')
60
+
61
+ def rhs_pow(self, other):
62
+ def func(a, b): return b ** a
63
+ return self.apply_function(other, func, 'power')
64
+
65
+ def __add__(self, other): return self.add(other) # this + that
66
+ def __radd__(self, other): return self.add(other) # that + this
67
+ def __iadd__(self, other): # this += that
68
+ self = self.add(other)
69
+ return self
70
+
71
+ def __sub__(self, other): return self.subtract(other)
72
+ def __rsub__(self, other): return self.rhs_subtract(other) # non-commutative
73
+ def __isub__(self, other):
74
+ self = self.subtract(other)
75
+ return self
76
+
77
+ def __mul__(self, other): return self.multiply(other)
78
+ def __rmul__(self, other): return self.multiply(other)
79
+ def __imul__(self, other):
80
+ self = self.multiply(other)
81
+ return self
82
+
83
+ def __truediv__(self, other): return self.divide(other)
84
+ def __rtruediv__(self, other): return self.rhs_divide(other) # non-commutative
85
+ def __itruediv__(self, other):
86
+ self = self.divide(other)
87
+ return self
88
+
89
+ def __floordiv__(self, other): return self.floor_divide(other)
90
+ def __rfloordiv__(self, other): return self.rhs_floor_divide(other) # non-commutative
91
+ def __ifloordiv__(self, other):
92
+ self = self.floor_divide(other)
93
+ return self
94
+
95
+ def __mod__(self, other): return self.mod(other)
96
+ def __rmod__(self, other): return self.rhs_mod(other)
97
+ def __imod__(self, other):
98
+ self = self.mod(other)
99
+ return self
100
+
101
+ def __pow__(self, other): return self.pow(other)
102
+ def __rpow__(self, other): return self.rhs_pow(other)
103
+ def __ipow__(self, other):
104
+ self = self.pow(other)
105
+ return self
106
+
107
+ # comparison functions
108
+ def __eq__(self, other):
109
+ if isinstance(other, Custom): return self.data == other.data
110
+ return self.data == other
111
+
112
+ def __ne__(self, other):
113
+ if isinstance(other, Custom): return self.data != other.data
114
+ return self.data != other
115
+
116
+ def __lt__(self, other):
117
+ if isinstance(other, Custom): return self.data < other.data
118
+ return self.data < other
119
+
120
+ def __gt__(self, other):
121
+ if isinstance(other, Custom): return self.data > other.data
122
+ return self.data > other
123
+
124
+ def __le__(self, other):
125
+ if isinstance(other, Custom): return self.data <= other.data
126
+ return self.data <= other
127
+
128
+ def __ge__(self, other):
129
+ if isinstance(other, Custom): return self.data >= other.data
130
+ return self.data >= other
131
+
132
+ # unary operators
133
+ def __pos__(self):
134
134
  return self
@@ -1,73 +1,73 @@
1
- import glm
2
- from ..generic.vec3 import Vec3
3
- from ..generic.quat import Quat
4
-
5
-
6
- def collide_aabb_aabb(top_right1: glm.vec3, bottom_left1: glm.vec3, top_right2: glm.vec3, bottom_left2: glm.vec3, epsilon:float=1e-7) -> bool:
7
- """
8
- Determines if two aabbs are colliding
9
- """
10
- return all(bottom_left1[i] <= top_right2[i] + epsilon and epsilon + top_right1[i] >= bottom_left2[i] for i in range(3))
11
-
12
- def collide_aabb_line(top_right: glm.vec3, bottom_left: glm.vec3, position: glm.vec3, forward: glm.vec3) -> bool: # TODO check algorithm
13
- """
14
- Determines if an infinite line intersects with an AABB
15
- """
16
- tmin, tmax = -1e10, 1e10
17
- for i in range(3):
18
- if forward[i]: # if forward[i] is not 0 to avoid division errors
19
-
20
- deno = 1 / forward[i]
21
- tlow = (bottom_left[i] - position[i]) * deno
22
- thigh = (top_right[i] - position[i]) * deno
23
- if deno < 0: tlow, thigh = thigh, tlow
24
- tmin = max(tmin, tlow)
25
- tmax = min(tmax, thigh)
26
- if tmax <= tmin: return False
27
-
28
- elif position[i] + 1e-7 < bottom_left[i] or position[i] > top_right[i] + 1e-7: return False
29
-
30
- return True
31
-
32
- def moller_trumbore(point:glm.vec3, vec:glm.vec3, triangle:list[glm.vec3], epsilon:float=1e-7) -> glm.vec3:
33
- """
34
- Determines where a line intersects with a triangle and where that intersection occurred
35
- """
36
- edge1, edge2 = triangle[1] - triangle[0], triangle[2] - triangle[0]
37
- ray_cross = glm.cross(vec, edge2)
38
- det = glm.dot(edge1, ray_cross)
39
-
40
- # if the ray is parallel to the triangle
41
- if abs(det) < epsilon: return None
42
-
43
- inv_det = 1 / det
44
- s = point - triangle[0]
45
- u = glm.dot(s, ray_cross) * inv_det
46
-
47
- if (u < 0 and abs(u) > epsilon) or (u > 1 and abs(u - 1) > epsilon): return None
48
-
49
- s_cross = glm.cross(s, edge1)
50
- v = glm.dot(vec, s_cross) * inv_det
51
-
52
- if (v < 0 and abs(v) > epsilon) or (u + v > 1 and abs(u + v - 1) > epsilon): return None
53
-
54
- t = glm.dot(edge2, s_cross) * inv_det
55
- if t > epsilon: return point + vec * t
56
- return None
57
-
58
- def get_sat_axes(rotation1: Quat, rotation2: Quat) -> list[glm.vec3]:
59
- """
60
- Gets the axes for SAT from obb rotation matrices
61
- """
62
- axes = []
63
- axes.extend(glm.transpose(glm.mat3_cast(rotation1.data)))
64
- axes.extend(glm.transpose(glm.mat3_cast(rotation2.data)))
65
-
66
- # crossed roots
67
- for i in range(0, 3):
68
- for j in range(3, 6):
69
- cross = glm.cross(axes[i], axes[j])
70
- if glm.length2(cross) < 1e-6: continue
71
- axes.append(glm.normalize(cross))
72
-
1
+ import glm
2
+ from ..generic.vec3 import Vec3
3
+ from ..generic.quat import Quat
4
+
5
+
6
+ def collide_aabb_aabb(top_right1: glm.vec3, bottom_left1: glm.vec3, top_right2: glm.vec3, bottom_left2: glm.vec3, epsilon:float=1e-7) -> bool:
7
+ """
8
+ Determines if two aabbs are colliding
9
+ """
10
+ return all(bottom_left1[i] <= top_right2[i] + epsilon and epsilon + top_right1[i] >= bottom_left2[i] for i in range(3))
11
+
12
+ def collide_aabb_line(top_right: glm.vec3, bottom_left: glm.vec3, position: glm.vec3, forward: glm.vec3) -> bool: # TODO check algorithm
13
+ """
14
+ Determines if an infinite line intersects with an AABB
15
+ """
16
+ tmin, tmax = -1e10, 1e10
17
+ for i in range(3):
18
+ if forward[i]: # if forward[i] is not 0 to avoid division errors
19
+
20
+ deno = 1 / forward[i]
21
+ tlow = (bottom_left[i] - position[i]) * deno
22
+ thigh = (top_right[i] - position[i]) * deno
23
+ if deno < 0: tlow, thigh = thigh, tlow
24
+ tmin = max(tmin, tlow)
25
+ tmax = min(tmax, thigh)
26
+ if tmax <= tmin: return False
27
+
28
+ elif position[i] + 1e-7 < bottom_left[i] or position[i] > top_right[i] + 1e-7: return False
29
+
30
+ return True
31
+
32
+ def moller_trumbore(point:glm.vec3, vec:glm.vec3, triangle:list[glm.vec3], epsilon:float=1e-7) -> glm.vec3:
33
+ """
34
+ Determines where a line intersects with a triangle and where that intersection occurred
35
+ """
36
+ edge1, edge2 = triangle[1] - triangle[0], triangle[2] - triangle[0]
37
+ ray_cross = glm.cross(vec, edge2)
38
+ det = glm.dot(edge1, ray_cross)
39
+
40
+ # if the ray is parallel to the triangle
41
+ if abs(det) < epsilon: return None
42
+
43
+ inv_det = 1 / det
44
+ s = point - triangle[0]
45
+ u = glm.dot(s, ray_cross) * inv_det
46
+
47
+ if (u < 0 and abs(u) > epsilon) or (u > 1 and abs(u - 1) > epsilon): return None
48
+
49
+ s_cross = glm.cross(s, edge1)
50
+ v = glm.dot(vec, s_cross) * inv_det
51
+
52
+ if (v < 0 and abs(v) > epsilon) or (u + v > 1 and abs(u + v - 1) > epsilon): return None
53
+
54
+ t = glm.dot(edge2, s_cross) * inv_det
55
+ if t > epsilon: return point + vec * t
56
+ return None
57
+
58
+ def get_sat_axes(rotation1: Quat, rotation2: Quat) -> list[glm.vec3]:
59
+ """
60
+ Gets the axes for SAT from obb rotation matrices
61
+ """
62
+ axes = []
63
+ axes.extend(glm.transpose(glm.mat3_cast(rotation1.data)))
64
+ axes.extend(glm.transpose(glm.mat3_cast(rotation2.data)))
65
+
66
+ # crossed roots
67
+ for i in range(0, 3):
68
+ for j in range(3, 6):
69
+ cross = glm.cross(axes[i], axes[j])
70
+ if glm.length2(cross) < 1e-6: continue
71
+ axes.append(glm.normalize(cross))
72
+
73
73
  return axes
@@ -1,67 +1,67 @@
1
- import numpy as np
2
- import glm
3
- from ..render.image import Image
4
-
5
-
6
- def validate_float(module: str, name: str, value: float | int | glm.float32) -> float:
7
- if isinstance(value, float) or isinstance(value, int):
8
- return float(value)
9
- elif isinstance(value, glm.float32):
10
- return float(value.value)
11
- else:
12
- raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected float.")
13
-
14
- def validate_glm_vec3(module: str, name: str, value: tuple | list | glm.vec3 | np.ndarray) -> glm.vec3:
15
- if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
16
- if len(value) != 3: raise ValueError(f"{module}: Invalid number of values for {name}. Expected 3 values, got {len(value)} values")
17
- return glm.vec3(value)
18
- elif isinstance(value, glm.vec3) or isinstance(value, int) or isinstance(value, float):
19
- return glm.vec3(value)
20
- else:
21
- raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected glm.vec3")
22
-
23
- def validate_tuple3(module: str, name: str, value: tuple | list | glm.vec3 | np.ndarray) -> tuple:
24
- if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
25
- if len(value) != 3: raise ValueError(f"{module}: Invalid number of values for {name}. Expected 3 values, got {len(value)} values")
26
- return tuple(value)
27
- elif isinstance(value, glm.vec3):
28
- return (value.x, value.y, value.z)
29
- if isinstance(value, int) or isinstance(value, float):
30
- return (value, value, value)
31
- else:
32
- raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected tuple of size 3")
33
-
34
- def validate_image(module: str, name: str, value: Image | None) -> Image | None:
35
- """Accepts none as a value for no image"""
36
- if isinstance(value, Image) or isinstance(value, type(None)):
37
- return value
38
- else:
39
- raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected bsk.Image or None")
40
-
41
- def validate_color(module: str, name: str, value: tuple | list | np.ndarray | int | float | None) -> tuple:
42
- if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
43
- if len(value) == 4:
44
- return tuple(map(lambda x: x / 255, value))
45
- elif len(value) == 3:
46
- return (*tuple(map(lambda x: x / 255, value)), 1.0)
47
- else:
48
- raise TypeError(f"{module}: Invalid number of values for {name}. Expected 3 or 4 values, got {len(value)} values")
49
- elif isinstance(value, int) or isinstance(value, float):
50
- v = value / 255
51
- return (v, v, v, 1.0)
52
- else:
53
- raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected tuple of size 3 or 4")
54
-
55
- def validate_rect(rect) -> tuple:
56
- if not (isinstance(rect, tuple) or isinstance(rect, list) or isinstance(rect, np.ndarray)):
57
- raise TypeError(f'Invalid rect type: {type(rect)}. Expected a tuple, list, or numpy array')
58
- if len(rect) != 4:
59
- raise TypeError(f'Invalid number of rect values. Expected 4 values, got {len(rect)}')
60
- return list(rect)
61
-
62
- def validate_point(point) -> tuple:
63
- if not (isinstance(point, tuple) or isinstance(point, list) or isinstance(point, np.ndarray)):
64
- raise TypeError(f'Invalid rect type: {type(point)}. Expected a tuple, list, or numpy array')
65
- if len(point) != 2:
66
- raise TypeError(f'Invalid number of rect values. Expected 2 values, got {len(point)}')
1
+ import numpy as np
2
+ import glm
3
+ from ..render.image import Image
4
+
5
+
6
+ def validate_float(module: str, name: str, value: float | int | glm.float32) -> float:
7
+ if isinstance(value, float) or isinstance(value, int):
8
+ return float(value)
9
+ elif isinstance(value, glm.float32):
10
+ return float(value.value)
11
+ else:
12
+ raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected float.")
13
+
14
+ def validate_glm_vec3(module: str, name: str, value: tuple | list | glm.vec3 | np.ndarray) -> glm.vec3:
15
+ if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
16
+ if len(value) != 3: raise ValueError(f"{module}: Invalid number of values for {name}. Expected 3 values, got {len(value)} values")
17
+ return glm.vec3(value)
18
+ elif isinstance(value, glm.vec3) or isinstance(value, int) or isinstance(value, float):
19
+ return glm.vec3(value)
20
+ else:
21
+ raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected glm.vec3")
22
+
23
+ def validate_tuple3(module: str, name: str, value: tuple | list | glm.vec3 | np.ndarray) -> tuple:
24
+ if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
25
+ if len(value) != 3: raise ValueError(f"{module}: Invalid number of values for {name}. Expected 3 values, got {len(value)} values")
26
+ return tuple(value)
27
+ elif isinstance(value, glm.vec3):
28
+ return (value.x, value.y, value.z)
29
+ if isinstance(value, int) or isinstance(value, float):
30
+ return (value, value, value)
31
+ else:
32
+ raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected tuple of size 3")
33
+
34
+ def validate_image(module: str, name: str, value: Image | None) -> Image | None:
35
+ """Accepts none as a value for no image"""
36
+ if isinstance(value, Image) or isinstance(value, type(None)):
37
+ return value
38
+ else:
39
+ raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected bsk.Image or None")
40
+
41
+ def validate_color(module: str, name: str, value: tuple | list | np.ndarray | int | float | None) -> tuple:
42
+ if isinstance(value, tuple) or isinstance(value, list) or isinstance(value, np.ndarray):
43
+ if len(value) == 4:
44
+ return tuple(map(lambda x: x / 255, value))
45
+ elif len(value) == 3:
46
+ return (*tuple(map(lambda x: x / 255, value)), 1.0)
47
+ else:
48
+ raise TypeError(f"{module}: Invalid number of values for {name}. Expected 3 or 4 values, got {len(value)} values")
49
+ elif isinstance(value, int) or isinstance(value, float):
50
+ v = value / 255
51
+ return (v, v, v, 1.0)
52
+ else:
53
+ raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected tuple of size 3 or 4")
54
+
55
+ def validate_rect(rect) -> tuple:
56
+ if not (isinstance(rect, tuple) or isinstance(rect, list) or isinstance(rect, np.ndarray)):
57
+ raise TypeError(f'Invalid rect type: {type(rect)}. Expected a tuple, list, or numpy array')
58
+ if len(rect) != 4:
59
+ raise TypeError(f'Invalid number of rect values. Expected 4 values, got {len(rect)}')
60
+ return list(rect)
61
+
62
+ def validate_point(point) -> tuple:
63
+ if not (isinstance(point, tuple) or isinstance(point, list) or isinstance(point, np.ndarray)):
64
+ raise TypeError(f'Invalid rect type: {type(point)}. Expected a tuple, list, or numpy array')
65
+ if len(point) != 2:
66
+ raise TypeError(f'Invalid number of rect values. Expected 2 values, got {len(point)}')
67
67
  return list(point)
basilisk/generic/math.py CHANGED
@@ -1,7 +1,7 @@
1
- import glm
2
-
3
- def triple_product(vector1, vector2, vector3) -> glm.vec3:
4
- """
5
- Computes (1 x 2) x 3
6
- """
1
+ import glm
2
+
3
+ def triple_product(vector1, vector2, vector3) -> glm.vec3:
4
+ """
5
+ Computes (1 x 2) x 3
6
+ """
7
7
  return glm.cross(glm.cross(vector1, vector2), vector3)
@@ -1,36 +1,36 @@
1
- import glm
2
- from ..generic.vec3 import Vec3
3
- from ..generic.quat import Quat
4
-
5
-
6
- # transform matrices
7
- def get_model_matrix(position: Vec3, scale: Vec3, rotation: Quat) -> glm.mat4x4:
8
- """
9
- Gets projection matrix from object data
10
- """
11
- translation_matrix = glm.translate(glm.mat4(1.0), position.data)
12
- rotation_matrix = glm.mat4_cast(rotation.data)
13
- scale_matrix = glm.scale(glm.mat4(1.0), scale.data)
14
- model_matrix = translation_matrix * glm.transpose(rotation_matrix) * scale_matrix
15
- return model_matrix
16
-
17
- def get_scale_matrix(scale: glm.vec3) -> glm.mat3x3:
18
- """
19
- Gets the scaling matrix from a scale vector
20
- """
21
- return glm.mat3x3(
22
- scale.x, 0, 0,
23
- 0, scale.y, 0,
24
- 0, 0, scale.z
25
- )
26
-
27
- # inertia tensors
28
- def compute_inertia_moment(t:list[glm.vec3], i:int) -> float:
29
- return t[0][i] ** 2 + t[1][i] * t[2][i] + \
30
- t[1][i] ** 2 + t[0][i] * t[2][i] + \
31
- t[2][i] ** 2 + t[0][i] * t[1][i]
32
-
33
- def compute_inertia_product(t:list[glm.vec3], i:int, j:int) -> float:
34
- return 2 * t[0][i] * t[0][j] + t[1][i] * t[2][j] + t[2][i] * t[1][j] + \
35
- 2 * t[1][i] * t[1][j] + t[0][i] * t[2][j] + t[2][i] * t[0][j] + \
1
+ import glm
2
+ from ..generic.vec3 import Vec3
3
+ from ..generic.quat import Quat
4
+
5
+
6
+ # transform matrices
7
+ def get_model_matrix(position: Vec3, scale: Vec3, rotation: Quat) -> glm.mat4x4:
8
+ """
9
+ Gets projection matrix from object data
10
+ """
11
+ translation_matrix = glm.translate(glm.mat4(1.0), position.data)
12
+ rotation_matrix = glm.mat4_cast(rotation.data)
13
+ scale_matrix = glm.scale(glm.mat4(1.0), scale.data)
14
+ model_matrix = translation_matrix * glm.transpose(rotation_matrix) * scale_matrix
15
+ return model_matrix
16
+
17
+ def get_scale_matrix(scale: glm.vec3) -> glm.mat3x3:
18
+ """
19
+ Gets the scaling matrix from a scale vector
20
+ """
21
+ return glm.mat3x3(
22
+ scale.x, 0, 0,
23
+ 0, scale.y, 0,
24
+ 0, 0, scale.z
25
+ )
26
+
27
+ # inertia tensors
28
+ def compute_inertia_moment(t:list[glm.vec3], i:int) -> float:
29
+ return t[0][i] ** 2 + t[1][i] * t[2][i] + \
30
+ t[1][i] ** 2 + t[0][i] * t[2][i] + \
31
+ t[2][i] ** 2 + t[0][i] * t[1][i]
32
+
33
+ def compute_inertia_product(t:list[glm.vec3], i:int, j:int) -> float:
34
+ return 2 * t[0][i] * t[0][j] + t[1][i] * t[2][j] + t[2][i] * t[1][j] + \
35
+ 2 * t[1][i] * t[1][j] + t[0][i] * t[2][j] + t[2][i] * t[0][j] + \
36
36
  2 * t[2][i] * t[2][j] + t[0][i] * t[1][j] + t[1][i] * t[0][j]