basilisk-engine 0.1.2__py3-none-any.whl → 0.1.3__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 (82) hide show
  1. basilisk/__init__.py +11 -11
  2. basilisk/bsk_assets/cube.obj +48 -48
  3. basilisk/collisions/broad/broad_aabb.py +102 -102
  4. basilisk/collisions/broad/broad_bvh.py +137 -137
  5. basilisk/collisions/collider.py +95 -83
  6. basilisk/collisions/collider_handler.py +225 -228
  7. basilisk/collisions/narrow/contact_manifold.py +90 -90
  8. basilisk/collisions/narrow/dataclasses.py +33 -27
  9. basilisk/collisions/narrow/deprecated.py +46 -46
  10. basilisk/collisions/narrow/epa.py +91 -91
  11. basilisk/collisions/narrow/gjk.py +66 -66
  12. basilisk/collisions/narrow/graham_scan.py +24 -24
  13. basilisk/collisions/narrow/helper.py +29 -29
  14. basilisk/collisions/narrow/line_intersections.py +106 -106
  15. basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
  16. basilisk/config.py +2 -2
  17. basilisk/draw/draw.py +100 -100
  18. basilisk/draw/draw_handler.py +180 -210
  19. basilisk/draw/font_renderer.py +28 -28
  20. basilisk/engine.py +195 -195
  21. basilisk/generic/abstract_bvh.py +15 -15
  22. basilisk/generic/abstract_custom.py +133 -133
  23. basilisk/generic/collisions.py +70 -70
  24. basilisk/generic/input_validation.py +67 -28
  25. basilisk/generic/math.py +6 -6
  26. basilisk/generic/matrices.py +33 -33
  27. basilisk/generic/meshes.py +72 -72
  28. basilisk/generic/quat.py +137 -137
  29. basilisk/generic/quat_methods.py +7 -7
  30. basilisk/generic/raycast_result.py +24 -0
  31. basilisk/generic/vec3.py +143 -143
  32. basilisk/input/mouse.py +61 -59
  33. basilisk/mesh/cube.py +33 -33
  34. basilisk/mesh/mesh.py +230 -230
  35. basilisk/mesh/mesh_from_data.py +132 -132
  36. basilisk/mesh/model.py +271 -271
  37. basilisk/mesh/narrow_aabb.py +89 -89
  38. basilisk/mesh/narrow_bvh.py +91 -91
  39. basilisk/mesh/narrow_primative.py +23 -23
  40. basilisk/nodes/helper.py +29 -0
  41. basilisk/nodes/node.py +681 -617
  42. basilisk/nodes/node_handler.py +95 -118
  43. basilisk/particles/particle_handler.py +63 -54
  44. basilisk/particles/particle_renderer.py +87 -87
  45. basilisk/physics/impulse.py +112 -112
  46. basilisk/physics/physics_body.py +43 -43
  47. basilisk/physics/physics_engine.py +35 -35
  48. basilisk/render/batch.py +86 -86
  49. basilisk/render/camera.py +204 -199
  50. basilisk/render/chunk.py +99 -99
  51. basilisk/render/chunk_handler.py +154 -154
  52. basilisk/render/frame.py +181 -181
  53. basilisk/render/image.py +75 -75
  54. basilisk/render/image_handler.py +122 -122
  55. basilisk/render/light.py +96 -96
  56. basilisk/render/light_handler.py +58 -58
  57. basilisk/render/material.py +219 -219
  58. basilisk/render/material_handler.py +135 -135
  59. basilisk/render/shader.py +109 -109
  60. basilisk/render/shader_handler.py +79 -79
  61. basilisk/render/sky.py +120 -120
  62. basilisk/scene.py +250 -210
  63. basilisk/shaders/batch.frag +276 -276
  64. basilisk/shaders/batch.vert +115 -115
  65. basilisk/shaders/draw.frag +21 -21
  66. basilisk/shaders/draw.vert +21 -21
  67. basilisk/shaders/filter.frag +22 -22
  68. basilisk/shaders/frame.frag +12 -12
  69. basilisk/shaders/frame.vert +13 -13
  70. basilisk/shaders/geometry.frag +8 -8
  71. basilisk/shaders/geometry.vert +41 -41
  72. basilisk/shaders/normal.frag +59 -59
  73. basilisk/shaders/normal.vert +96 -96
  74. basilisk/shaders/particle.frag +71 -71
  75. basilisk/shaders/particle.vert +84 -84
  76. basilisk/shaders/sky.frag +9 -9
  77. basilisk/shaders/sky.vert +13 -13
  78. {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/METADATA +45 -38
  79. basilisk_engine-0.1.3.dist-info/RECORD +97 -0
  80. {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/WHEEL +1 -1
  81. basilisk_engine-0.1.2.dist-info/RECORD +0 -95
  82. {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.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,71 +1,71 @@
1
- import glm
2
-
3
-
4
- 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:
5
- """
6
- Determines if two aabbs are colliding
7
- """
8
- return all(bottom_left1[i] <= top_right2[i] + epsilon and epsilon + top_right1[i] >= bottom_left2[i] for i in range(3))
9
-
10
- def collide_aabb_line(top_right: glm.vec3, bottom_left: glm.vec3, position: glm.vec3, forward: glm.vec3) -> bool: # TODO check algorithm
11
- """
12
- Determines if an infinite line intersects with an AABB
13
- """
14
- tmin, tmax = -1e10, 1e10
15
- for i in range(3):
16
- if forward[i]: # if forward[i] is not 0 to avoid division errors
17
-
18
- deno = 1 / forward[i]
19
- tlow = (bottom_left[i] - position[i]) * deno
20
- thigh = (top_right[i] - position[i]) * deno
21
- if deno < 0: tlow, thigh = thigh, tlow
22
- tmin = max(tmin, tlow)
23
- tmax = min(tmax, thigh)
24
- if tmax <= tmin: return False
25
-
26
- elif position[i] + 1e-7 < bottom_left[i] or position[i] > top_right[i] + 1e-7: return False
27
-
28
- return True
29
-
30
- def moller_trumbore(point:glm.vec3, vec:glm.vec3, triangle:list[glm.vec3], epsilon:float=1e-7) -> glm.vec3:
31
- """
32
- Determines where a line intersects with a triangle and where that intersection occurred
33
- """
34
- edge1, edge2 = triangle[1] - triangle[0], triangle[2] - triangle[0]
35
- ray_cross = glm.cross(vec, edge2)
36
- det = glm.dot(edge1, ray_cross)
37
-
38
- # if the ray is parallel to the triangle
39
- if abs(det) < epsilon: return None
40
-
41
- inv_det = 1 / det
42
- s = point - triangle[0]
43
- u = glm.dot(s, ray_cross) * inv_det
44
-
45
- if (u < 0 and abs(u) > epsilon) or (u > 1 and abs(u - 1) > epsilon): return None
46
-
47
- s_cross = glm.cross(s, edge1)
48
- v = glm.dot(vec, s_cross) * inv_det
49
-
50
- if (v < 0 and abs(v) > epsilon) or (u + v > 1 and abs(u + v - 1) > epsilon): return None
51
-
52
- t = glm.dot(edge2, s_cross) * inv_det
53
- if t > epsilon: return point + vec * t
54
- return None
55
-
56
- def get_sat_axes(rotation1: glm.quat, rotation2: glm.quat) -> list[glm.vec3]:
57
- """
58
- Gets the axes for SAT from obb rotation matrices
59
- """
60
- axes = []
61
- axes.extend(glm.transpose(glm.mat3_cast(rotation1)))
62
- axes.extend(glm.transpose(glm.mat3_cast(rotation2)))
63
-
64
- # crossed roots
65
- for i in range(0, 3):
66
- for j in range(3, 6):
67
- cross = glm.cross(axes[i], axes[j])
68
- if glm.length2(cross) < 1e-6: continue
69
- axes.append(glm.normalize(cross))
70
-
1
+ import glm
2
+
3
+
4
+ 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:
5
+ """
6
+ Determines if two aabbs are colliding
7
+ """
8
+ return all(bottom_left1[i] <= top_right2[i] + epsilon and epsilon + top_right1[i] >= bottom_left2[i] for i in range(3))
9
+
10
+ def collide_aabb_line(top_right: glm.vec3, bottom_left: glm.vec3, position: glm.vec3, forward: glm.vec3) -> bool: # TODO check algorithm
11
+ """
12
+ Determines if an infinite line intersects with an AABB
13
+ """
14
+ tmin, tmax = -1e10, 1e10
15
+ for i in range(3):
16
+ if forward[i]: # if forward[i] is not 0 to avoid division errors
17
+
18
+ deno = 1 / forward[i]
19
+ tlow = (bottom_left[i] - position[i]) * deno
20
+ thigh = (top_right[i] - position[i]) * deno
21
+ if deno < 0: tlow, thigh = thigh, tlow
22
+ tmin = max(tmin, tlow)
23
+ tmax = min(tmax, thigh)
24
+ if tmax <= tmin: return False
25
+
26
+ elif position[i] + 1e-7 < bottom_left[i] or position[i] > top_right[i] + 1e-7: return False
27
+
28
+ return True
29
+
30
+ def moller_trumbore(point:glm.vec3, vec:glm.vec3, triangle:list[glm.vec3], epsilon:float=1e-7) -> glm.vec3:
31
+ """
32
+ Determines where a line intersects with a triangle and where that intersection occurred
33
+ """
34
+ edge1, edge2 = triangle[1] - triangle[0], triangle[2] - triangle[0]
35
+ ray_cross = glm.cross(vec, edge2)
36
+ det = glm.dot(edge1, ray_cross)
37
+
38
+ # if the ray is parallel to the triangle
39
+ if abs(det) < epsilon: return None
40
+
41
+ inv_det = 1 / det
42
+ s = point - triangle[0]
43
+ u = glm.dot(s, ray_cross) * inv_det
44
+
45
+ if (u < 0 and abs(u) > epsilon) or (u > 1 and abs(u - 1) > epsilon): return None
46
+
47
+ s_cross = glm.cross(s, edge1)
48
+ v = glm.dot(vec, s_cross) * inv_det
49
+
50
+ if (v < 0 and abs(v) > epsilon) or (u + v > 1 and abs(u + v - 1) > epsilon): return None
51
+
52
+ t = glm.dot(edge2, s_cross) * inv_det
53
+ if t > epsilon: return point + vec * t
54
+ return None
55
+
56
+ def get_sat_axes(rotation1: glm.quat, rotation2: glm.quat) -> list[glm.vec3]:
57
+ """
58
+ Gets the axes for SAT from obb rotation matrices
59
+ """
60
+ axes = []
61
+ axes.extend(glm.transpose(glm.mat3_cast(rotation1)))
62
+ axes.extend(glm.transpose(glm.mat3_cast(rotation2)))
63
+
64
+ # crossed roots
65
+ for i in range(0, 3):
66
+ for j in range(3, 6):
67
+ cross = glm.cross(axes[i], axes[j])
68
+ if glm.length2(cross) < 1e-6: continue
69
+ axes.append(glm.normalize(cross))
70
+
71
71
  return axes
@@ -1,28 +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):
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_image(module: str, name: str, value: Image | None) -> Image | None:
24
- """Accepts none as a value for no image"""
25
- if isinstance(value, Image) or isinstance(value, type(None)):
26
- return value
27
- else:
28
- raise TypeError(f"{module}: Invalid {name} value type {type(value)}. Expected bsk.Image or None")
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
+ 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,34 +1,34 @@
1
- import glm
2
-
3
-
4
- # transform matrices
5
- def get_model_matrix(position: glm.vec3, scale: glm.vec3, rotation: glm.quat) -> glm.mat4x4:
6
- """
7
- Gets projection matrix from object data
8
- """
9
- translation_matrix = glm.translate(glm.mat4(1.0), position)
10
- rotation_matrix = glm.mat4_cast(rotation)
11
- scale_matrix = glm.scale(glm.mat4(1.0), scale)
12
- model_matrix = translation_matrix * glm.transpose(rotation_matrix) * scale_matrix
13
- return model_matrix
14
-
15
- def get_scale_matrix(scale: glm.vec3) -> glm.mat3x3:
16
- """
17
- Gets the scaling matrix from a scale vector
18
- """
19
- return glm.mat3x3(
20
- scale.x, 0, 0,
21
- 0, scale.y, 0,
22
- 0, 0, scale.z
23
- )
24
-
25
- # inertia tensors
26
- def compute_inertia_moment(t:list[glm.vec3], i:int) -> float:
27
- return t[0][i] ** 2 + t[1][i] * t[2][i] + \
28
- t[1][i] ** 2 + t[0][i] * t[2][i] + \
29
- t[2][i] ** 2 + t[0][i] * t[1][i]
30
-
31
- def compute_inertia_product(t:list[glm.vec3], i:int, j:int) -> float:
32
- return 2 * t[0][i] * t[0][j] + t[1][i] * t[2][j] + t[2][i] * t[1][j] + \
33
- 2 * t[1][i] * t[1][j] + t[0][i] * t[2][j] + t[2][i] * t[0][j] + \
1
+ import glm
2
+
3
+
4
+ # transform matrices
5
+ def get_model_matrix(position: glm.vec3, scale: glm.vec3, rotation: glm.quat) -> glm.mat4x4:
6
+ """
7
+ Gets projection matrix from object data
8
+ """
9
+ translation_matrix = glm.translate(glm.mat4(1.0), position)
10
+ rotation_matrix = glm.mat4_cast(rotation)
11
+ scale_matrix = glm.scale(glm.mat4(1.0), scale)
12
+ model_matrix = translation_matrix * glm.transpose(rotation_matrix) * scale_matrix
13
+ return model_matrix
14
+
15
+ def get_scale_matrix(scale: glm.vec3) -> glm.mat3x3:
16
+ """
17
+ Gets the scaling matrix from a scale vector
18
+ """
19
+ return glm.mat3x3(
20
+ scale.x, 0, 0,
21
+ 0, scale.y, 0,
22
+ 0, 0, scale.z
23
+ )
24
+
25
+ # inertia tensors
26
+ def compute_inertia_moment(t:list[glm.vec3], i:int) -> float:
27
+ return t[0][i] ** 2 + t[1][i] * t[2][i] + \
28
+ t[1][i] ** 2 + t[0][i] * t[2][i] + \
29
+ t[2][i] ** 2 + t[0][i] * t[1][i]
30
+
31
+ def compute_inertia_product(t:list[glm.vec3], i:int, j:int) -> float:
32
+ return 2 * t[0][i] * t[0][j] + t[1][i] * t[2][j] + t[2][i] * t[1][j] + \
33
+ 2 * t[1][i] * t[1][j] + t[0][i] * t[2][j] + t[2][i] * t[0][j] + \
34
34
  2 * t[2][i] * t[2][j] + t[0][i] * t[1][j] + t[1][i] * t[0][j]