basilisk-engine 0.1.18__py3-none-any.whl → 0.1.20__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 +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 -206
- 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/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 +684 -684
- basilisk/nodes/node_handler.py +96 -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 +221 -211
- basilisk/render/chunk.py +106 -106
- basilisk/render/chunk_handler.py +165 -165
- 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 +110 -110
- basilisk/render/shader_handler.py +80 -80
- basilisk/render/sky.py +120 -120
- basilisk/scene.py +276 -276
- basilisk/shaders/batch.frag +276 -276
- basilisk/shaders/batch.vert +115 -115
- basilisk/shaders/crt.frag +31 -31
- basilisk/shaders/draw.frag +22 -21
- basilisk/shaders/draw.vert +25 -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.18.dist-info → basilisk_engine-0.1.20.dist-info}/METADATA +38 -45
- basilisk_engine-0.1.20.dist-info/RECORD +103 -0
- {basilisk_engine-0.1.18.dist-info → basilisk_engine-0.1.20.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.18.dist-info/RECORD +0 -103
- {basilisk_engine-0.1.18.dist-info → basilisk_engine-0.1.20.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
|
basilisk/generic/collisions.py
CHANGED
|
@@ -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)
|
basilisk/generic/matrices.py
CHANGED
|
@@ -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]
|